Description: Welcome to Part 9 of the Buffer Overflow Primer. If you have not already done so, please start this series by viewing Part 1. The Buffer Overflow Primer requires that you know at least some basic Assembly Language. I have created a series of Assembly Language video tutorials for Hackers here, for those not familiar with the language.
In this video we will do a hands on demo of exploiting a stack protected by NX using the Return to Libc exploitation process. We use GDB and attach it to the vulnerable program to find the address of "/bin/bash" in it's memory. Once this address is found, we modify Ret2libc.c and launch the attack on the vulnerable program. The successful exploitation leads to spawning of a shell. As we are using a 2.6 kernel in the video, we temporarily disable the ASLR feature. We will look at how to exploit a buffer overflow in presence of ASLR in a later video. Please download ExploitMe.c, Ret2Libc.c and GetEnvironmentVarAddr.c to follow the video.
Tags: tools ,
Disclaimer: We are a infosec video aggregator and this video is linked from an external website. The original author may be different from the user re-posting/linking it here. Please do not assume the authors to be same without verifying.
It felt so good getting this code to work on my computer. However I had a few inconsistencies. I am running ubuntu 10.10 with the 2.6.35-25 kernel. First off, I had to turn stack protection off when compiling, -fno-stack-protector
Also, when I went to get the address for system in libc, p system returned a 3 bit value instead of a 4bit value, on a limb, I only wrote 3 bits to exitAddr and systemAddr char arrays in the Ret2Libc. Other than that, SUCCESS!!!!!
Awesome! I had chosen a much older platform to easily demonstrate these concepts but later realized most people might just want to try this out on the latest platforms by turning the protections off.
If you have the time, can you make a quick video of how you did this in Ubuntu 10? I will add that as the 10th video in this group with full credit to you. Only condition, it need to have voice in it and no rock music in the background :)
upon further testing, I realized that I did not get the example to completely run correctly, I realized that while the overflow worked, I had misrepresented some addresses and the instead of spawning a new shell, it just returned to the previous shell. I did not notice this because I did not have the ksh install and I told the system() command to launch /bin/bash. Long story short when bash spawns, it looks identical on my computer. HOWEVER, I discovered that the reason the injected code did not work was because I had 3bit addresses, therefore the last bit was either appended with a NOP or when I later attempted to correct the code, a 0x00 which terminates the string. Therefore the variable BUF is null terminated after the first address is overwritten. This means that the system command is executed but everything after that does not get overflowed on the stack because everything after the NULL is not placed in the buffer. This means that I am going to have to write some assembly code and place it in the 80 bytes of what we thought was unimportant data such that the code correctly appends 00's to the addresses of the system and exit functions as well as allow for reference to the myshell variable. I'm afraid this is a learning process for me so it might take me some time, but you better expect a detailed video with a working solution soon. :)
I guess life is full of surprises :)
Sometimes, I feel it teaches one more when things do not work as desired.
So please, take your time and create a follow up video when you are done. I will post it with the series.
Just correcting what sailboat said, it's not bits like you said "p system returned a 3 bit value instead of a 4bit value", it's byte. Just that. xP
I'm trying to do this on ubuntu 9.10, kernel 2.6.31-22, and I'm getting the same trouble. Some videos just didn't work because of the protections against stack, but when I figure it out, I contact here! =D
That's all. Vivek thank you for everything! Thank you for sharing your knowledge and experiences! You helped me A LOT to understand these things! I left a comment in every video, because I'm really grateful! Maybe some day we meet in some Black Hat or another conference! \o/
Thank you once more!
Best wishes!
I went ahead like you did, but when I need to see the exactly address that is storing the "/bin/ksh", I get this:
(gdb) x/1s 0xbffffc79
0xbffffc79: "ll=/bin/ksh"
(gdb) x/1s 0xbffffc80
0xbffffc80: "/ksh"
I can't see! Please help me! =D
I can't succeded doing on my Slackware 13.1 VM. In the last step, when I press 'Enter' to earn my new shell, it gaves segmentation fault... =/
I'm very sad! Because everything was working so good on slack! Can you help me?!
I review my code and everything is perfect, just one thing was odd. In the address of "Exit", in ret2libc.c, It looks like this: \x00\x4f\xe8\xb7, I had a null byte on the shellcode! Do you think that's because mine don't work?
And an other great collection. Can't wait to find out how to bypass the other types of protection.
Btw, Vivek. The book "The shellcoders handbook" that you recommended is it still up to date looking at the new types of security you discussed?
Just to say hi and continue with the awesome videos. Explanations are very vividly and easy to understand. Thank you and continue this great contribution. Word is spread out here in Macedonia about these videos and ppl love them! Thanks again Vivek. Cheers ;)
I have a question, when I execute the GetEnvironmentVarAddr.c programm I get the address of my variable, but when I close my session and open it again,I get a different address of the same variable. Can anyone explain me why it is happening?
Thanks!
M.Corleone this is happening because when you run any program, it's almost always allocate memory in a different place. It's not guaranteed that the address will be the same in another time, because depend of the process running on memory, and another things. You should study how the Operational System manage the memory and the process. I'd hope to be helpful.
xplt ,thanks for your answer.
You're welcome! If you need something, I'll try to help! =D
Cheers! o/
"(gdb) x/1s 0xbffffc79
0xbffffc79: "ll=/bin/ksh"
(gdb) x/1s 0xbffffc80
0xbffffc80: "/ksh"
I can't see! Please help me! =D"
I had this problem to, the way I fixed it is by changing the name of the local variable. Changing it to myshelll instead of myshell I got it to work:
0xbffff84d: "myshelll=/bin/sh"
(gdb) x /1s 0xbffff84f
0xbffff84f: "shelll=/bin/sh"
(gdb) x /1s 0xbffff850
0xbffff850: "helll=/bin/sh"
(gdb) x /1s 0xbffff854
0xbffff854: "l=/bin/sh"
(gdb) x /1s 0xbffff855
0xbffff855: "=/bin/sh"
(gdb) x /1s 0xbffff856
0xbffff856: "/bin/sh"
Also Vivek, thanks for these great videos!
Thanks, I've very much enjoyed this series.
I'm also wondering if the future video on how to circumvent ASLR protection, discussed in this video, has been included elsewhere?
Thank you vivek for your tutorials and hard work. I am really enjoying even though I done them before, but I learnt more. Can you make some video on Canary Attacks, I hardly could exploit the basic buffer with canary, but with a hint, that I knew what was the canary string.
Very good video. I think you should make a video on bypassing both ASLR and NX at the same time. Most operating systems have both installed by default, and no tutorial has taught how to bypass both.
hi why does one need to create a sep env variable for "/bin/ksh". Why cant we just store it in a string as done in the previous examples
No, because it you store the value on a string on the stack, the NX protection will forbid you to execute code stores on stack frame.
Im been trying the example but found a problem, my system and exit memory directions ends on 00, so the Ret2lib string gets corrupted and i end up with a buffer full or crap.
If i made the same steps changin both exit and systems memory locations to end on ff, i can print the stack while debugging exploitme2 and see the buffer correctly loaded.
How can i get rid of this problem ?
Vivek this videos are great !!!!!
Thank you !!
I have been having the same problem, estenole. The null bytes in my system and exit addresses will not let this program work. I'd really appreciate if anyone has some insight as to how to get around this.
Thanks for the videos regardless. They are excellent!
Really excellent awesome amazing videos sir..super rocking performance.. and we need more videos like this sir....
(gdb) x/1s 0xbfe5a800
0xbfe5a800: <Address 0xbfe5a800="" out="" of="" bounds="">
any help
BTW amazing video..!!!
^^ i am trying to locate the address of myshell
test
<script>
document.write("test");
</script>
now its displaying just empty strings at the address of myshell
Great series Vivek ,
but i have problem
this is the output
(gdb) p system
$1 = {<text variable,="" no="" debug="" info="">} 0x168950 <system>
the address is starting with 0x00
which means null termiator when adding it to my enviroment variable
how can i solve it?
There is whole procedure [ASCII armor bypass + return to plt] explained here:
http://dl.packetstormsecurity.net/papers/attack/lewt4-bypass.pdf
I couldn't make it work yet
FYI: This is still doable with latest debian squeeze [Disabling ASLR of course]. This document helped a lot: http://www.exploit-db.com/download_pdf/17131, remember the adress of exit can not contain a single null byte, in my case I had to use exit+4. Thanks Vivek for your efforts!
Linux desktop 2.6.32-38-generic
2012 i686 GNU/Linux
Ubuntu 10.04.4 LTS
worked almost!
in the last step i got the message:
"stack smashing detected.. "
guess i´ll have to turn this off as well.
What should I do if the address from GetEnvironmentVarAddr is out of bounds? I dont know where to start with solving this.
Hi Vivek,
I'm deeply grateful to you for bringing all this valuable knowledge in a brilliant manner !
One thing I miss is the slides because they're needed for constant reference.
Regarding Ret2libc, I couldn't manage to gain a shell at first because I had an address with \x20 (ASCII SPACE). Besides, I think some techniques you present are not necessary at first:
- we can build a buffer just with printf/perl/python (no need for GetEnvironmentVarAddr.c and Ret2Libc.c)
- '/bin/sh' is in libc (no need for an env variable)
my solution is working with NX and ASLR enabled on a Fedora 16:
export BUF="$(python -c 'import struct; print "\x41" * 84 + struct.pack("<i", 0x49dbd5b0)="" +="" struct.pack("<i",="" 0x49db2050)+="" struct.pack("<i",="" 0x49ee512e)')"="" .="" exploitme="" "$buf"="" #="" notice="" the="" quotes="" !!="">
It doesn't working in 64bit arch. (VM)
I am getting bash shell but not ksh shell. what do i need to tweak ? also could you post 64bit buffer overflow videos because there are no any single document about 64bit buffer overflow.
@sailboat - do you have 64bit OS?
Thanks for this awesome series, Vivek! I have enjoyed this series and the assembly language series. I consult as an ethical hacker, my background is appsec and in March started a job as an ethical hacker. I started out with the Pen Testing With BackTrack course and I discovered your website trying to further my understanding of python and buffer overflow. I purchased your python course and I have enjoyed it, but I have not completed it yet. I am going to go back and completed the course once I am finished with the PWB course since the lab time is limited. Although more lab time can be purchased, I need to complete the course. I look forward to completing the python course and I plan to look into your other courses once I complete the python course. Keep up the great work, your videos are very helpful.
i got a segmentation fault in last step
am running Ubuntu 12.04 LTS
Finally got it to work on Backtrack 64bit with:
gcc -ggdb -m32 -mpreferred-stack-boundary=2 -fno-stack-protector -o Ret2Libc Ret2Libc.c
and I used x/200s environ to find /bin/bash
Hope this helps ! Great Job Vivek, You have created an amazing site !
Thank you, Vivek, for this explaination but you have forgotten to explain us what the -mpreferred-stack-boundary=2 and the -fno-stack-protector makes. In my case this two gcc-parameters makes six-digit of hex-addresses. E. g. (gdb) p system $1 = {<text variable,="" no="" debug="" info="">} 0x168950 <system>. What could be the reason? But if I compiled all of this programms on my ubuntu 10.10 pc without these two parameters or with the -z execstack parameter then it makes eight-digit of hex-addresses. E. g. (gdb) p system $1 = {<text variable,="" no="" debug="" info="">} 0xb7fa2e90 <system>.
I know your stack was in this time new but today it is old and that tutorial have a bug. In your demonstration you fired gdb ./ExploitMe2 up and than you searched the addresses of the system-call and of the exit-call. But that exit-call that you had taken was in my two cases wrong. I took this _exit-call and it works perfectly.