728x90
반응형
1. intro
코딩이 조금 귀찮긴 했지만 재밋는 문제였다.
2. code 및 분석
2.1. code
#!/usr/bin/env python3
from Crypto.Util.number import bytes_to_long, long_to_bytes
from utils import listener # this is cryptohack's server-side module and not part of python
import base64
import codecs
import random
FLAG = "crypto{????????????????????}"
ENCODINGS = [
"base64",
"hex",
"rot13",
"bigint",
"utf-8",
]
with open('/usr/share/dict/words') as f:
WORDS = [line.strip().replace("'", "") for line in f.readlines()]
class Challenge():
def __init__(self):
self.challenge_words = ""
self.stage = 0
def create_level(self):
self.stage += 1
self.challenge_words = "_".join(random.choices(WORDS, k=3))
encoding = random.choice(ENCODINGS)
if encoding == "base64":
encoded = base64.b64encode(self.challenge_words.encode()).decode() # wow so encode
elif encoding == "hex":
encoded = self.challenge_words.encode().hex()
elif encoding == "rot13":
encoded = codecs.encode(self.challenge_words, 'rot_13')
elif encoding == "bigint":
encoded = hex(bytes_to_long(self.challenge_words.encode()))
elif encoding == "utf-8":
encoded = [ord(b) for b in self.challenge_words]
return {"type": encoding, "encoded": encoded}
#
# This challenge function is called on your input, which must be JSON
# encoded
#
def challenge(self, your_input):
if self.stage == 0:
return self.create_level()
elif self.stage == 100:
self.exit = True
return {"flag": FLAG}
if self.challenge_words == your_input["decoded"]:
return self.create_level()
return {"error": "Decoding fail"}
listener.start_server(port=13377)
2.2. 분석
서버의 파일에서 특정 문자열을 가져온 다음, base64, hex, rot13, bigint, utf-8로 encoding 한 뒤 출력해준다.
이를 decoding하여 json 형식으로 값을 보내주면 된다.
3. exploit
복호화야 어떻게든 하면 되는데, json 형식으로 값의 전송이 다소 힘들었다...
검색에 검색을 거듭한 뒤에야 할 수 있었음 ㅋ
from pwn import *
from Crypto.Util.number import *
import codecs
import json
p = remote ('socket.cryptohack.org', 13377)
dec = ''
def rcv():
p.recvuntil(b': ')
typ = p.recvuntil(b',')[:-1]
p.recvuntil(b': ')
enc = p.recvuntil(b'}')[:-1]
return typ,enc
for i in range(100):
typ,enc = rcv()
dec = ''
if b'base64' in typ:
dec = base64.b64decode(enc[1:-1])
if b'hex' in typ:
dec = long_to_bytes(int(enc[1:-1],16))
if b'rot' in typ:
dec = codecs.decode((enc[1:-1]).decode(),'rot_13').encode()
if b'big' in typ:
dec = long_to_bytes(int(enc[1:-1],16))
if b'utf' in typ:
enc = eval(enc)
for i in range(len(enc)):
dec += chr(enc[i])
dec = dec.encode()
pay = {"type": typ[1:-1].decode(), "decoded":dec.decode()}
p.send(json.dumps(pay))
print(dec)
p.interactive()
┌──(kali㉿kali)-[~/Downloads]
└─$ python solve.py
[+] Opening connection to socket.cryptohack.org on port 13377: Done
/home/kali/Downloads/solve.py:34: BytesWarning: Text is not bytes; assuming ASCII, no guarantees. See https://docs.pwntools.com/#bytes
p.send(json.dumps(pay))
b'starter_headquarters_networks'
b'neighbor_translator_cassette'
b'internet_recipe_suffered'
...
b'dallas_analog_honest'
b'herb_moore_shoe'
b'bo_glucose_ultimate'
b'concentration_pdas_impressive'
[*] Switching to interactive mode
{"flag": "crypto{3nc0d3_d3c0d3_3nc0d3}"}
[*] Got EOF while reading in interactive
728x90
반응형
'Wargame > Cryptohack' 카테고리의 다른 글
Network Attacks (0) | 2023.02.13 |
---|---|
Legendre Symbol (0) | 2023.02.13 |
Quadratic Residues (0) | 2023.02.08 |
Modular Inverting (0) | 2023.02.06 |
Modular Arithmetic 2 (0) | 2023.02.03 |