Friday, January 6, 2017

[VulnHub] Tr0ll: 2 Privilege Escalation Walkthrough

If you've made it to the low privilege shell in Tr0ll: 2 by exploiting the Bash Shellshock vulnerability, you've probably quickly found the "nothing_to_see_here" directory and the three doors that go along with it.

Each "door" contains a binary owned by root with the SUID bit set. These files will randomly switch directories every few minutes. The one that should be exploited is the largest sized binary (8401). When executed it asks for a user input, which strongly suggests I will be buffer overflowing my way to root. I first open gdb and send a string of 1000 "A's" through the debugger to see if the program crashes. Simply entering 'r "AAAA..."' into the gdb console will do this.

So after entering in the A's you'll see the program did indeed crash. Typing in "i r" (short for "info registers"), the registers and their contents will be displayed. The main register we're looking at here is the EIP register which contains the value "0x41414141" (41414141 is "AAAA" converted from ASCII to hex). EIP is code for "instruction pointer". This register controls the execution flow of a program. By modifying EIP, you can essentially redirect execution flow to an address of your choosing.

Also, after examining the ESP register located at address 0xbffff8c0 (this may be different in your environment) by typing "x 0xbffff8c0" (short for "examine 0xbffff8c0") into the gdb console, I see the string overwrote ESP as well. This is the ideal spot to send EIP.

However, first I'll need to find the exact point in which the string overwrites EIP. To do this, I use a program built in to Kali Linux (pattern_create.rb). This program basically creates a predictable string so we can see exactly where EIP is overwritten. I ask for a string length of 1000 characters once again.

Now that I have the string, I send it through the program which once again crashes.

Now I can copy the contents of EIP and plop it in another program (pattern_offset.rb) and find the exact spot in which EIP is overwritten.

Now that I know EIP is 268 bytes in, I modify my input a little. I use python to print 268 "A's" followed by 4 "B's" which should overwrite EIP.

Perfect! I see EBP still contains the "A's" and EIP now contains the "B's" (42 in hex) like I'd planned. I check to see if ASLR is enabled. I do this by checking the "/proc/sys/kernel/randomize_va_space" file. If the value within the file is 2, it means ASLR is enabled, if it's 0 then it's been disabled. I find out it is disabled, which means ESP should contain a predictable address once our buffer length is set.

Before I check the address at ESP, I add 16 no operation or "NOP" ("\x90") instructions to the buffer. The NOPs will make sure the shellcode will smoothly make it to ESP. After I add the 16 NOPs, my pre-shellcode buffer length is set, so I can take note of the ESP register and I can overwrite EIP.

So from there, I see ESP is at the address 0xbffffb80 (again, note this may be different for you). I replace the "B's" in my buffer with the address in little endian format. My buffer now has 268 "A's" followed by the address of ESP in little endian format ("\x80\xfb\xff\xbf") followed by 16 NOP instructions ("\x90"). Now a shellcode of my choosing can be added to the buffer and will be executed within the SUID binary as the root user. I choose a simple 23 byte "/bin/sh" shellcode.

Now that my final buffer is set, I run the program with my small python script appended and I get a beautiful root shell.

Boom. It's that easy. Of course, if you ignore everything you just read, you could just use Dirty COW and pop a root shell that way.