This repository was archived by the owner on Jan 29, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Expand file tree
/
Copy pathhttp.py
More file actions
245 lines (188 loc) · 7.23 KB
/
http.py
File metadata and controls
245 lines (188 loc) · 7.23 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
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
"""
HTTP related methods used by Empire.
Includes URI validation/checksums, as well as the base
http server (EmpireServer) and its modified request
handler (RequestHandler).
These are the first places URI requests are processed.
"""
from BaseHTTPServer import BaseHTTPRequestHandler
import BaseHTTPServer, threading, ssl, os, string, random
from pydispatch import dispatcher
import re
import json
# Empire imports
import encryption
import helpers
#TODO: place this in a config
def default_page():
"""
Returns the default page for this server.
"""
page = "<html><body><h1>It works!</h1>"
page += "<p>This is the default web page for this server.</p>"
page += "<p>The web server software is running but no content has been added, yet.</p>"
page += "</body></html>"
return page
###############################################################
#
# Host2lhost helper.
#
###############################################################
def host2lhost(s):
"""
Return lhost for Empire's native listener from Host value
"""
reg = r'(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)'
res = re.findall( reg, s)
return res[0] if len(res) == 1 else '0.0.0.0'
###############################################################
#
# Checksum helpers.
#
###############################################################
def checksum8(s):
"""
Add up all character values and mods the total by 256.
"""
return sum([ord(ch) for ch in s]) % 0x100
###############################################################
#
# HTTP servers and handlers.
#
###############################################################
class RequestHandler(BaseHTTPRequestHandler):
"""
Main HTTP handler we're overwriting in order to modify the HTTPServer behavior.
"""
# retrieve the server headers from the common config
serverVersion = helpers.get_config('server_version')[0]
# fake out our server headers base
BaseHTTPRequestHandler.server_version = serverVersion
BaseHTTPRequestHandler.sys_version = ""
def do_GET(self):
# get the requested path and the client IP
resource = self.path
clientIP = self.client_address[0]
sessionID = None
cookie = self.headers.getheader("Cookie")
if cookie:
# search for a SESSIONID value in the cookie
parts = cookie.split(";")
for part in parts:
if "SESSIONID" in part:
# extract the sessionID value
name, sessionID = part.split("=", 1)
# fire off an event for this GET (for logging)
message = "[*] {resource} requested from {session_id} at {client_ip}".format(
resource=resource,
session_id=sessionID,
client_ip=clientIP
)
signal = json.dumps({
'print': True,
'message': message
})
dispatcher.send(signal, sender="empire")
# get the appropriate response from the agent handler
(code, responsedata) = self.server.agents.process_get(self.server.server_port, clientIP, sessionID, resource)
# write the response out
self.send_response(code)
self.end_headers()
self.wfile.write(responsedata)
self.wfile.flush()
# self.wfile.close() # causes an error with HTTP comms
def do_POST(self):
resource = self.path
clientIP = self.client_address[0]
sessionID = None
cookie = self.headers.getheader("Cookie")
if cookie:
# search for a SESSIONID value in the cookie
parts = cookie.split(";")
for part in parts:
if "SESSIONID" in part:
# extract the sessionID value
name, sessionID = part.split("=", 1)
# fire off an event for this POST (for logging)
message = "[*] Post to {resource} from {session_id} at {client_ip}".format(
resource=resource,
session_id=sessionID,
client_ip=clientIP
)
signal = json.dumps({
'print': True,
'message': message
})
dispatcher.send(signal, sender="empire")
# read in the length of the POST data
if self.headers.getheader('content-length'):
length = int(self.headers.getheader('content-length'))
postData = self.rfile.read(length)
# get the appropriate response for this agent
(code, responsedata) = self.server.agents.process_post(self.server.server_port, clientIP, sessionID, resource, postData)
# write the response out
self.send_response(code)
self.end_headers()
self.wfile.write(responsedata)
self.wfile.flush()
# self.wfile.close() # causes an error with HTTP comms
# supress all the stupid default stdout/stderr output
def log_message(*arg):
pass
class EmpireServer(threading.Thread):
"""
Version of a simple HTTP[S] Server with specifiable port and
SSL cert. Defaults to HTTP is no cert is specified.
Uses agents.RequestHandler handle inbound requests.
"""
def __init__(self, handler, lhost='0.0.0.0', port=80, cert=''):
# set to False if the listener doesn't successfully start
self.success = True
try:
threading.Thread.__init__(self)
self.server = None
self.server = BaseHTTPServer.HTTPServer((lhost, int(port)), RequestHandler)
# pass the agent handler object along for the RequestHandler
self.server.agents = handler
self.port = port
self.serverType = "HTTP"
# wrap it all up in SSL if a cert is specified
if cert and cert != "":
self.serverType = "HTTPS"
cert = os.path.abspath(cert)
self.server.socket = ssl.wrap_socket(self.server.socket, certfile=cert, server_side=True)
message = "[*] Initializing HTTPS server on {port}".format(port=port)
else:
message = "[*] Initializing HTTP server on {port}".format(port=port)
signal = json.dumps({
'print': True,
'message': message
})
dispatcher.send(signal, sender="empire")
except Exception as e:
self.success = False
# shoot off an error if the listener doesn't stand up
message = "[!] Error starting listener on port {}: {}".format(port, e)
signal = json.dumps({
'print': True,
'message': message
})
dispatcher.send(signal, sender="empire")
def base_server(self):
return self.server
def run(self):
try: self.server.serve_forever()
except: pass
def shutdown(self):
# shut down the server/socket
self.server.shutdown()
self.server.socket.close()
self.server.server_close()
self._Thread__stop()
# make sure all the threads are killed
for thread in threading.enumerate():
if thread.isAlive():
try:
thread._Thread__stop()
except:
pass