ReturnMeFast
- Category: Misc
- 150 points
- Solved by JCTF Team
Solution
We connect to the challenge and interact with it:
$ nc returnmefast.chal.intentsummit.org 9999
INPUT> fdsf
NotTheJsonIWasLookingFor
INPUT> {}
NoCommand No field command in data.
INPUT> {"command": 1}
BadUserName No username field.
INPUT> {"command": 1, "username": "username"}
Unicorn me asap. Starting the game: username -> [(1, 2), (1, 5), (10, 14), (7, 8), (3, 6), (6, 9), (4, 5), (11, 16)].
INPUT>
... snipped ...
$ nc returnmefast.chal.intentsummit.org 9999
INPUT> {"command": 1, "username": "username"}
Unicorn me asap. Starting the game: username -> [(6, 11), (1, 6), (13, 18), (2, 3), (4, 9), (2, 7), (5, 8), (8, 9)].
INPUT> {"command":2,"username":"username"}
MissingX86Unicorn Missing asm field.
INPUT> {"command":2,"username":"username","asm":"9"}
BadX86AsmHex The format of your asm code was not right. Look at unicorns for examples.
INPUT> {"command":2,"username":"username","asm":"909090909090909090"}
BadUnicornLength 9
... snipped ...
INPUT> {"command": 1, "username": "username"}
Unicorn me asap. Starting the game: username -> [(6, 9), (4, 8), (8, 12), (7, 11), (4, 8), (1, 4), (5, 3), (12, 17)].
INPUT> {"command":2,"username":"usernane","asm":"909090909090909090"}
BadUserName
INPUT> {"command":2,"username":"username","asm":"909090909090909090"}
BadEaxVal Val was 0
So what we have seen?
The server challenge us to send it a spesified length of bytes that are hex-encoded x86 assembly which should probably set the value of the EAX
register to a provided value. To evaluate our code it uses unicorn-engine
, also it expects us to return the answers pretty fast.
To overcome the challenge we create the following script:
from pwn import *
from ast import literal_eval
import json
r = remote("returnmefast.chal.intentsummit.org", 9999)
def send_start():
r.recvuntil(b"INPUT> ")
r.sendline(json.dumps({"command": 1, "username": "username"}).encode())
def parse_ch():
ret = r.recvuntil(b"INPUT> ")
return literal_eval(f"[{(ret.partition(b'[')[2].partition(b']')[0]).decode()}]")
def send_asm(sz, val):
nh = asm(f'add eax, {val}')
r.sendline(json.dumps({"command": 2, "username": "username", "asm": nh.hex()+"90"*(sz-len(nh))}).encode())
print(r.recvuntil(b"INPUT> "))
send_start()
ch = parse_ch()
print(ch)
for val, sz in ch:
print(sz, val)
send_asm(sz, val)
We run the script:
$ python3 script.py
[+] Opening connection to returnmefast.chal.intentsummit.org on port 9999: Done
[(6, 10), (4, 8), (8, 13), (3, 5), (3, 6), (7, 8), (3, 5), (12, 13)]
10 6
b'Good!. Go to the next step.\nINPUT> '
8 4
b'Good!. Go to the next step.\nINPUT> '
13 8
b'Good!. Go to the next step.\nINPUT> '
5 3
b'Good!. Go to the next step.\nINPUT> '
6 3
b'Good!. Go to the next step.\nINPUT> '
8 7
b'Good!. Go to the next step.\nINPUT> '
5 3
b'Good!. Go to the next step.\nINPUT> '
13 12
b'INTENT{we1Rd_unkn0wn_m4Chin3S_ar3_mY_J4m}\nINPUT> '
[*] Closed connection to returnmefast.chal.intentsummit.org port 9999
We got the flag: INTENT{we1Rd_unkn0wn_m4Chin3S_ar3_mY_J4m}
.