Skip to content

Commit

Permalink
Improved malleable_redirector's proxy handling action
Browse files Browse the repository at this point in the history
  • Loading branch information
mgeeky committed Jan 23, 2020
1 parent d90483e commit 9fa0ae9
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 15 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1 @@
*.pyc
*.pyc
3 changes: 1 addition & 2 deletions optionsparser.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,7 @@ def parse_options(opts, version):
else:
opts['log'] = sys.stdout

if opts['log']: opts['log'] = os.path.normpath(opts['log'])
if opts['plugin']: opts['plugin'] = os.path.normpath(opts['plugin'])
if opts['log'] and opts['log'] != sys.stdout: opts['log'] = os.path.normpath(opts['log'])
if opts['cakey']: opts['cakey'] = os.path.normpath(opts['cakey'])
if opts['certdir']: opts['certdir'] = os.path.normpath(opts['certdir'])
if opts['certkey']: opts['certkey'] = os.path.normpath(opts['certkey'])
Expand Down
28 changes: 18 additions & 10 deletions plugins/malleable_redirector.py
Original file line number Diff line number Diff line change
Expand Up @@ -312,20 +312,25 @@ def response_handler(self, req, req_body, res, res_body):

def drop_action(self, req, req_body, res, res_body):
if self.proxyOptions['log_dropped'] == True:
if req_body == None: req_body = ''
else: req_body = req_body.decode()
req_headers = req.headers
if req_body != None and len(req_body) > 0:
req_body = '\r\n' + req_body
else:
req_body = ''

u = urlparse(req.path)
scheme, netloc, path = u.scheme, u.netloc, (u.path + '?' + u.query if u.query else u.path)

req_headers = ProxyRequestHandler.filter_headers(req.headers)
request = '{} {} {}\r\n{}\r\n{}'.format(
req.command, req.path, 'HTTP/1.1', req_headers, req_body
request = '{} {} {}\r\n{}{}'.format(
req.command, path, 'HTTP/1.1', req_headers, req_body
)

self.logger.info('DROPPED REQUEST:\n\n{}'.format(request))
self.logger.err('== DROPPED INVALID C2 REQUEST ==:\n\n{}'.format(request))

if self.proxyOptions['drop_action'] == 'reset':
return DropConnectionException('Not a conformant beacon request.')

if self.proxyOptions['drop_action'] == 'redirect':
elif self.proxyOptions['drop_action'] == 'redirect':
if self.is_request:
return DontFetchResponseException('Not a conformant beacon request.')

Expand All @@ -347,10 +352,13 @@ def drop_action(self, req, req_body, res, res_body):

return res_body.encode()

if self.proxyOptions['drop_action'] == 'proxy':
req.path = self.proxyOptions['drop_url']
elif self.proxyOptions['drop_action'] == 'proxy':
self.logger.dbg('Proxying forward...')

return req_body
if self.is_request:
return req_body

return res_body

def drop_check(self, req, req_body):
# User-agent conformancy
Expand Down
10 changes: 9 additions & 1 deletion pluginsloader.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,14 @@ def load(self, path):
self.logger.dbg('Decomposed as: %s' % str(decomposed))

plugin = decomposed['path'].strip()

if not os.path.isfile(plugin):
_plugin = os.path.normpath(os.path.join(os.path.dirname(__file__), 'plugins/{}'.format(plugin)))
if os.path.isfile(_plugin):
plugin = _plugin
elif os.path.isfile(_plugin+'.py'):
plugin = _plugin + '.py'

name = os.path.basename(plugin).lower().replace('.py', '')

if name in self.plugins or name in ['iproxyplugin', '__init__']:
Expand Down Expand Up @@ -149,4 +157,4 @@ def load(self, path):
except ImportError as e:
self.logger.err('Couldn\'t load specified plugin: "%s". Error: %s' % (plugin, e))
if self.options['debug']:
raise
raise
10 changes: 9 additions & 1 deletion proxy2.py
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,7 @@ class Response(object):
logger.err('Exception catched in request_handler: {}'.format(str(e)))

req_path_full = ''
if not req.path: req.path = '/'
if req.path[0] == '/':
if isinstance(self.connection, ssl.SSLSocket):
req_path_full = "https://%s%s" % (req.headers['Host'], req.path)
Expand Down Expand Up @@ -326,7 +327,11 @@ class Response(object):
conn = self.tls.conns[origin]

if req_body == None: req_body = ''
else: req_body = req_body.decode()
else:
try:
req_body = req_body.decode()
except AttributeError:
pass

request = '{} {} {}\r\n{}\r\n{}'.format(
self.command, path, 'HTTP/1.1', req_headers, req_body
Expand All @@ -336,6 +341,7 @@ class Response(object):
conn.request(self.command, path.strip(), req_body.strip(), dict(req_headers))
res = conn.getresponse()
res_body = res.read()
if type(res_body) == str: res_body = str.encode(res_body)
conn.close()

except Exception as e:
Expand Down Expand Up @@ -372,6 +378,7 @@ class Response(object):
except:
self.wfile.write(b'\r\n')

if type(res_body) == str: res_body = str.encode(res_body)
self.wfile.write(res_body)
self.wfile.flush()

Expand Down Expand Up @@ -525,6 +532,7 @@ def _parse_qsl(s):
except ValueError:
res_body_text = res_body
elif content_type.startswith('text/html'):
if type(res_body) == str: res_body = str.encode(res_body)
m = re.search(r'<title[^>]*>\s*([^<]+?)\s*</title>', res_body.decode(), re.I)
if m:
logger.trace("==== HTML TITLE ====\n%s\n" % html.unescape(m.group(1)), color=ProxyLogger.colors_map['cyan'])
Expand Down

0 comments on commit 9fa0ae9

Please sign in to comment.