FUDCon Notes on my Security Exploits Session
Posted: 2011-11-10T10:17:35+05:30I was asked by a couple of people for notes on the security exploits session that I conducted at FUDCon. I had posted the code samples on the talk page, but that is probably a little terse, so here’s a little write-up to support the code samples. To repeat what I had said multiple times earlier; I am not a security researcher, not even a security freak. This topic was suggested to me by Amit Shah, and I developed an interest in it due to my original interest, which is operating systems tools. The preparation of this talk got me interested in security, but only through the perspective of operating systems tools and programs, so I am still relatively indifferent to the subject of web-based security.
I started preparing for the session fairly late; i.e. 2 days before FUDCon. I am a little familiar with glibc code and with the way the compiler, linker, loader, etc. work on Linux, so that helped me understand a lot of the concepts behind exploits fairly easily. But concepts != working code and getting exploit code to work was the real challenge, especially when I had just about 3 evenings+nights for it. I had started with an idea of showing stack smashing and privilege escalation examples, but given the time constraint, audience level (college students) and also the constraint of my knowledge, I decided to restrict it to stack based attacks. All of the examples have a buffer which is being written to without checking for bounds of that buffer, typically with an strcpy.
The shellcode sample:
The shellcode sample as well as the final vulnerability demo (smash.c and vulnerable.c) were derived from the article Stack Smashing for Fun and Profit. That is a great article that explains in much more detail than I went into in my session, as to how the shellcode exploit can be developed.The core idea of this is:
- Obtain the binary equivalent of execve (name[0], name, NULL ) where name = {“/bin/sh”, NULL}
- Append additional data to the binary data and pass it to the buffer copy routine (strcpy) in such a way that, it writes the location of the first instruction in the above binary equivalent into the location of the return address
I spent a lot of time trying to figure out where this was set and finally found the -z option of the linker. So to write out a binary that sets up an executable stack, I had to call the linker with -z execstack. This finally enabled me to get the shellcode working.
The actual exploit
Once the shellcode was done, I could get the final vulnerability working and I immediately set about trying it. The exploit is based on the above shellcode example, except for one difference. The shellcode example is just that, an example. It is not an actual exploit; it is just a roundabout way to get a shell. The exploit I was about to do was a real crack. The idea now is to accept a string as input, which is then fed in to make a regular and buggy program provide you with a shell.
To imagine how this would work, think of the program that gives you a login prompt. In the context of this exploit, you should be able to input a crafted string into this login prompt and have it give you a shell without actually knowing the password! This is what the actual exploit ought to look like.
Again, writing the exploit was the easy part; getting it to run was quite another thing altogether. The exploit works as follows:
- Pages of memory are generally mapped at the same addresses for processes, so the top of stack for a process can be a good starting estimate for the top of stack for another process. From that point on, you need a finite number of guesses to get to the point in stack where the instructions have been injected
- The smash program records its own top of stack and prepares a string such that it the return address will be overwritten by the top of stack address. The string obviously begins with shell code. To improve the chances of hitting valid instructions in the code, the buffer is written over by a lot of single-byte NOP instructions just before the shellcode instructions
- The smash program executes a shell with an environment variable exported ($EGG). This environment variable can now be used to execute the vulnerable program within that shell. This could have been done differently too, like storing the output to a file and executing the vulnerable program with input from that file. So the way input is given doesn’t really matter here
echo 0 > /proc/sys/kernel/randomize_va_space
Even with this, my example would not execute by itself and would end with a SIGILL. I suspect this has something to do with the fact that my systm is x86_64 while the samples are all 32-bit. Our overflow string does not seem to agree with the instruction set on my system. In any case, it seems to run just fine inside a debugger. So if you run smash to get a shell, run gdb vulnerable and then run it with $EGG, you get the shell! At least I had a demo now.
Jump to libc
While I was trying out the shellcode example, I continued thinking about various other ways in which I could get a shell. One of the methods I thought of was to overwrite the return address with the address of the system() glibc call and pass the string via stack. I later found out via Huzaifa that this is in fact a documented way to exploit unchecked buffers on stack. Huzaifa also said that I may be missing out on something there and gave me some tips on finding the right resources for this. I still could not get this working, but at least I found out why the exploit did not work.
This exploit seemed attractive to me because it does not require an executable stack. The instructions I want to execute are already there in memory. So I only have to overwrite the return address and continue writing “/bin/sh” on the stack. I first tried with x86_64 in this case, because I was going by my own idea at that time. I soon figured out that the system() function on x86_64 did not take function arguments from stack. It took the argument from the %rdi register. My devious plan had been foiled! I did not give up however and looked at the system() implementation on i686. This retained the old behaviour of popping arguments from the stack, so my exploit was still possible here.
Not. My code was correct, but every time I run the program, the address of system() had just 3 bytes set. So it would always look something like: 0x00aabbcc. This was bad news because this meant that I cannot continue writing the shell string into the stack (strcpy stops copying when it encounters a 0x0). This means that I can call system() (like I was able to on x86_64 too), but I cannot pass it an argument. After trying enough number of times, I concluded that this must be a security feature. This was backed up by the tip Huzaifa had shared with me to (ironically) get the exploit to work. This was perhaps the first documentation of a return to libc exploit by Solar Designer. In his explanation, Solar designer mentioned that a way to fix this would be to ensure a 0x00 in the address, which is precisely what is happening here.
This obviously does not deny the fact that such an exploit can be carried out if you want to call functions that do not have arguments. Think for example, of a function that executes a shell ;)
Conclusion
The last modify example was a simple little trick I wrote on the last day to demonstrate how buffer overflows work and how they can be used to alter program flow. That again is not an exploit at all. At most, it can be called… a buffer overflow ;)
I had even more fun preparing for this session than actually presenting it because it taught me a lot more than I could ever have done by just reading literature. I hope those who attended my session at FUDCon enjoyed the session too.
FUDCon Pune 2011 Day 3: Hack and eat
Posted: 2011-11-07T03:44:55+05:30The last day of FUDCon. I had not slept much the last couple of nights, so I slept in a little late. Due to this I reached the venue late too and found that a lot of the speakers had reached late and that seemed to have got the volunteers (understandably) a little annoyed. All of the action was to happen just in the auditorium and the seminar halls this time and I stuck mostly to the auditorium for most of the day. I had planned to work on the libgqpid library, but I had not decided what it is that I was going to do. I started off by writing my day 1 post. That was quickly followed by lunch, where we hogged on pizzas.
I told Kushal by that time that I will work on autotoolizing libgqpid since he was busy working on his book. I started working on that after lunch, quickly finding out that there are a few things that wouldn’t work very easily there.
libgqpid is a wrapper around the apache c++ client library and the library check for the qpid client library would have to be in c++. autotools does not have any macros for c++ library checks, so I had to write a check that looked like this:
AC_LANG_PUSH([C++])After this one little hurdle it was pretty much smooth sailing and the result was a pull request to Kushal for the patch. By early evening, everyone was done and ready to go. The volunteers, especially the girls were very excited about getting their pictures clicked and were calling all of the major organizers (Rahul, Amit, Satya, etc.) to get their pictures clicked with them. It was pretty entertaining to watch.AC_MSG_CHECKING([if qpid c++ client libraries are present]) AC_LINK_IFELSE( [AC_LANG_PROGRAM([#include <qpid/messaging/Connection.h>], [qpid::messaging::Connection con])], [QPID_LIBS=“$LIBS”], [AC_MSG_ERROR([qpid c++ client development libraries not found])])
AC_LANG_POP
This was followed by a cake, which was mostly eaten and the rest of it smeared on Rahul and Jared’s faces. To end the event, we had a feedback session with the volunteers and they gave us a few good tips on how we could have done some things better.
By the time we were back at Magarpatta City, everyone looked tired. Rahul had organized a parting dinner at the Cocoon for all the speakers and organizers, which was a lot of fun. I had a great time chatting with Heherson, Izhar, Arun S A G, Srishti Sethi, Anurag and Eugene Teo. After dinner it was time to head back home.
We did a lot of things right in this event and kudos to Rahul, Amit Shah and all of the core team for getting together a really great event. I hope that at least some of all of those college students make the transition from being users to being contributors, especially contributing code to Fedora and upstream projects.
FUDCon Pune 2011 Day 2: Me, followed by lunch, followed by me, followed by me...
Posted: 2011-11-07T03:12:47+05:30The title pretty much summarizes what most of my day looked like on day 2 of FUDCon. Well, not exacly, but it comes quite close. I had three sessions lined up in a single day and I was worried that I might lose my voice by the end of it. Ankur Sinha had all of 4 talks in the single day, so I was definitely better off that him.
The day started with Harish Pillay’s keynote on the community architecture team. The turnout on day 2 was less than that on day 1, which was a little surprising. Most of them trickled later in the day, so it meant that a large number of the attendees in Harish’s talk were Red Hatters and the CoEP volunteers. We probably started a little too early for a Saturday.
Immediately following that was my session on qpid messaging. The attendance in the session was modest (about 8-10 people), but the best part was that they were very involved in the session and that made the session worthwhile. Mrugesh Karnik also joined the session mid-way and asked some really good questions that actually helped my session. We ended up doing a queue design for a fictitious stock trading system and I was able to show how the design could scale very easily with a qpid messaging broker in place. Unfortunately, most of the attendees did not have laptops, so I could not engage them in a hands-on session. In fact, that was my story of the day to a large extent. I had intended all my sessions to be hands-on, but most of it never really materialized because most of the audience did not have laptops.
After the qpid session, I spent some time chatting with Sankarshan, Mrugesh, Anurag and Nisha over lunch. After that I decided to double-check my exploit code samples because it was the one session that I had never done before and it was something that is not my area of expertise. The only aspect of the exploits that I was really comfortable with was how they worked and how I could explain that using the usual tools like gdb, objdump, etc.
I was sitting in the speakers lounge cleaning up my examples when Aditya Patawari came in and asked me about my session. That reminded me that I had to actually go into the session :D We quickly left for the classroom and found pjp finishing up his python session, which had a packed audience. Once he was done, a lot of people left, which led me to think that even this talk was going to have a modest audience. However, people trickled in as I was about to begin and by the time I did begin, the room was full.
The exploits session was probably one of the best sessions I have done so far, mainly because I personally enjoyed it. The audience also consisted of people who were interested (exploits are sexy, as someone said later) and I got a lot of questions during and after the session. The talk also seemed to give some people from the audience the impression that I am a security expert, which is flattering but incorrect.
Then came the awesome part where Pai and Yogesh Babar followed up my session with impromptu sessions, which the audience lapped up eagerly as well. Pai talked about extensibility of postgresql by making it call routines in perl (typical dinosaur stuff ;) ) and Yogesh did a talk on kdump. I learnt later that Rahul Sundaram did something similar in one of the seminar halls by asking the audience to “ask him anything about Fedora and Open Source”. Pretty cool stuff.
After Pai and Yogesh were done, it was again time for me to get on to the platform for another session, this time on autotools. This was something I had done multiple times with the same examples, so it was pretty uneventful.
Day 2 was probably awaited by a lot of people for another reason – the FUDPub! We went to Park Estique near Vimaan Nagar for dinner. There was loud music and bling bling lights and food and drink. I enjoyed the food and drink; the lights gave my a headache and the loud music was, well, too loud. In any case it was fun chatting with people and having the really good food.
Like the first day, I did not get to attend any other sessions, this time for a different reason. I’ll probably submit less sessions in the next conference so that I actually get to attend other sessions and meet and talk to more people. I did meet a lot of interesting people on day 2, so all of that hectic schedule was completely worth it.
Comments are closed.