[Assignment-4] added tcpproxy
This commit is contained in:
parent
ac334954e6
commit
4c97dbb963
20 changed files with 1443 additions and 0 deletions
|
|
@ -0,0 +1,38 @@
|
|||
#!/usr/bin/env python3
|
||||
import os
|
||||
|
||||
|
||||
class Module:
|
||||
def __init__(self, incoming=False, verbose=False, options=None):
|
||||
# extract the file name from __file__. __file__ is proxymodules/name.py
|
||||
self.name = os.path.splitext(os.path.basename(__file__))[0]
|
||||
self.description = 'Find HTTP Digest Authentication and replace it with a Basic Auth'
|
||||
self.verbose = verbose
|
||||
self.realm = 'tcpproxy'
|
||||
|
||||
if options is not None:
|
||||
if 'realm' in options.keys():
|
||||
self.realm = bytes(options['realm'], 'ascii')
|
||||
|
||||
def detect_linebreak(self, data):
|
||||
line = data.split(b'\n', 1)[0]
|
||||
if line.endswith(b'\r'):
|
||||
return b'\r\n'
|
||||
else:
|
||||
return b'\n'
|
||||
|
||||
def execute(self, data):
|
||||
delimiter = self.detect_linebreak(data)
|
||||
lines = data.split(delimiter)
|
||||
for index, line in enumerate(lines):
|
||||
if line.lower().startswith(b'www-authenticate: digest'):
|
||||
lines[index] = b'WWW-Authenticate: Basic realm="%s"' % self.realm
|
||||
return delimiter.join(lines)
|
||||
|
||||
def help(self):
|
||||
h = '\trealm: use this instead of the default "tcpproxy"\n'
|
||||
return h
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print('This module is not supposed to be executed alone!')
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
#!/usr/bin/env python3
|
||||
import os.path as path
|
||||
|
||||
|
||||
class Module:
|
||||
def __init__(self, incoming=False, verbose=False, options=None):
|
||||
# extract the file name from __file__. __file__ is proxymodules/name.py
|
||||
self.name = path.splitext(path.basename(__file__))[0]
|
||||
self.description = 'Print a hexdump of the received data'
|
||||
self.incoming = incoming # incoming means module is on -im chain
|
||||
self.len = 16
|
||||
if options is not None:
|
||||
if 'length' in options.keys():
|
||||
self.len = int(options['length'])
|
||||
|
||||
def help(self):
|
||||
return '\tlength: bytes per line (int)'
|
||||
|
||||
def execute(self, data):
|
||||
# this is a pretty hex dumping function directly taken from
|
||||
# http://code.activestate.com/recipes/142812-hex-dumper/
|
||||
result = []
|
||||
digits = 2
|
||||
for i in range(0, len(data), self.len):
|
||||
s = data[i:i + self.len]
|
||||
hexa = ' '.join(['%0*X' % (digits, x) for x in s])
|
||||
text = ''.join([chr(x) if 0x20 <= x < 0x7F else '.' for x in s])
|
||||
result.append("%04X %-*s %s" % (i, self.len * (digits + 1), hexa, text))
|
||||
print("\n".join(result))
|
||||
return data
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print ('This module is not supposed to be executed alone!')
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
#!/usr/bin/env python3
|
||||
import os.path as path
|
||||
|
||||
|
||||
class Module:
|
||||
def __init__(self, incoming=False, verbose=False, options=None):
|
||||
# extract the file name from __file__. __file__ is proxymodules/name.py
|
||||
self.name = path.splitext(path.basename(__file__))[0]
|
||||
self.description = 'Prepend HTTP response header'
|
||||
self.server = None
|
||||
if options is not None:
|
||||
if 'server' in options.keys():
|
||||
self.server = bytes(options['server'], 'ascii')
|
||||
|
||||
# source will be set by the proxy thread later on
|
||||
self.source = None
|
||||
|
||||
def execute(self, data):
|
||||
if self.server is None:
|
||||
self.server = bytes(self.source[0], 'ascii')
|
||||
|
||||
http = b"HTTP/1.1 200 OK\r\n"
|
||||
http += b"Server: %s\r\n" % self.server
|
||||
http += b"Connection: keep-alive\r\n"
|
||||
http += b"Content-Length: %d\r\n" % len(data)
|
||||
|
||||
return http + b"\r\n" + data
|
||||
|
||||
def help(self):
|
||||
h = '\tserver: remote source, used in response Server header\n'
|
||||
return h
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print('This module is not supposed to be executed alone!')
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
#!/usr/bin/env python3
|
||||
import os.path as path
|
||||
|
||||
|
||||
class Module:
|
||||
def __init__(self, incoming=False, verbose=False, options=None):
|
||||
# extract the file name from __file__. __file__ is proxymodules/name.py
|
||||
self.name = path.splitext(path.basename(__file__))[0]
|
||||
self.description = 'Prepend HTTP header'
|
||||
self.incoming = incoming # incoming means module is on -im chain
|
||||
self.targethost = None
|
||||
self.targetport = None
|
||||
if options is not None:
|
||||
if 'host' in options.keys():
|
||||
self.targethost = bytes(options['host'], 'ascii')
|
||||
if 'port' in options.keys():
|
||||
self.targetport = bytes(options['port'], 'ascii')
|
||||
|
||||
# destination will be set by the proxy thread later on
|
||||
self.destination = None
|
||||
|
||||
def execute(self, data):
|
||||
if self.targethost is None:
|
||||
self.targethost = bytes(self.destination[0], 'ascii')
|
||||
if self.targetport is None:
|
||||
self.targetport = bytes(str(self.destination[1]), 'ascii')
|
||||
http = b"POST /to/%s/%s HTTP/1.1\r\n" % (self.targethost, self.targetport)
|
||||
http += b"Host: %s\r\n" % self.targethost
|
||||
|
||||
http += b"Connection: keep-alive\r\n"
|
||||
http += b"Content-Length: %d\r\n" % len(data)
|
||||
return http + b"\r\n" + str(data)
|
||||
|
||||
def help(self):
|
||||
h = '\thost: remote target, used in request URL and Host header\n'
|
||||
h += '\tport: remote target port, used in request URL\n'
|
||||
return h
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print('This module is not supposed to be executed alone!')
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
#!/usr/bin/env python3
|
||||
import os.path as path
|
||||
|
||||
|
||||
class Module:
|
||||
def __init__(self, incoming=False, verbose=False, options=None):
|
||||
# extract the file name from __file__. __file__ is proxymodules/name.py
|
||||
self.name = path.splitext(path.basename(__file__))[0]
|
||||
self.description = 'Remove HTTP header from data'
|
||||
self.incoming = incoming # incoming means module is on -im chain
|
||||
|
||||
def detect_linebreak(self, data):
|
||||
line = data.split(b'\n', 1)[0]
|
||||
if line.endswith(b'\r'):
|
||||
return b'\r\n' * 2
|
||||
else:
|
||||
return b'\n' * 2
|
||||
|
||||
def execute(self, data):
|
||||
delimiter = self.detect_linebreak(data)
|
||||
if delimiter in data:
|
||||
data = data.split(delimiter, 1)[1]
|
||||
return data
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print('This module is not supposed to be executed alone!')
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# THIS MODULE DOES NOT WORK AND WILL BE REPLACED, DO NOT USE
|
||||
|
||||
import os.path as path
|
||||
import platform
|
||||
if 'java' in platform.system().lower():
|
||||
import java.io as io
|
||||
from com.thoughtworks.xstream import XStream
|
||||
from java.lang import Exception
|
||||
|
||||
|
||||
class Module:
|
||||
def __init__(self, incoming=False, verbose=False, options=None):
|
||||
self.is_jython = 'java' in platform.system().lower()
|
||||
# extract the file name from __file__. __file__ is proxymodules/name.py
|
||||
self.name = path.splitext(path.basename(__file__))[0]
|
||||
self.description = 'Serialization or deserialization of Java objects' if self.is_jython else \
|
||||
'Serialization or deserialization of Java objects (needs jython)'
|
||||
self.incoming = incoming # incoming means module is on -im chain
|
||||
self.execute = self.error
|
||||
|
||||
if options is not None:
|
||||
if 'mode' in options.keys():
|
||||
if 'deserial' in options['mode']:
|
||||
self.execute = self.deserial
|
||||
elif 'serial' in options['mode']:
|
||||
self.execute = self.serial
|
||||
|
||||
def help(self):
|
||||
return '\tmode: [serial|deserial] select deserialization (to XML) or serialization (to Java object)'
|
||||
|
||||
def deserial(self, data):
|
||||
if not self.is_jython:
|
||||
print ('[!] This module can only be used in jython!')
|
||||
return data
|
||||
|
||||
try:
|
||||
# turn data into a Java object
|
||||
bis = io.ByteArrayInputStream(data)
|
||||
ois = io.ObjectInputStream(bis)
|
||||
obj = ois.readObject()
|
||||
|
||||
# converting Java object to XML structure
|
||||
xs = XStream()
|
||||
xml = xs.toXML(obj)
|
||||
return xml
|
||||
except Exception as e:
|
||||
print ('[!] Caught Exception. Could not convert.\n')
|
||||
return data
|
||||
|
||||
def serial(self, data):
|
||||
if not self.is_jython:
|
||||
print ('[!] This module can only be used in jython!')
|
||||
return data
|
||||
try:
|
||||
# Creating XStream object and creating Java object from XML structure
|
||||
xs = XStream()
|
||||
serial = xs.fromXML(data)
|
||||
|
||||
# writing created Java object to and serializing it with ObjectOutputStream
|
||||
bos = io.ByteArrayOutputStream()
|
||||
oos = io.ObjectOutputStream(bos)
|
||||
oos.writeObject(serial)
|
||||
|
||||
# I had a problem with signed vs. unsigned bytes, hence the & 0xff
|
||||
return "".join([chr(x & 0xff) for x in bos.toByteArray().tolist()])
|
||||
except Exception as e:
|
||||
print ('[!] Caught Exception. Could not convert.\n')
|
||||
return data
|
||||
|
||||
def error(self, data):
|
||||
print ('[!] Unknown mode. Please specify mode=[serial|deserial].')
|
||||
return data
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print ('This module is not supposed to be executed alone!')
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
#!/usr/bin/env python3
|
||||
import os.path as path
|
||||
import time
|
||||
|
||||
|
||||
class Module:
|
||||
def __init__(self, incoming=False, verbose=False, options=None):
|
||||
# extract the file name from __file__. __file__ is proxymodules/name.py
|
||||
self.name = path.splitext(path.basename(__file__))[0]
|
||||
self.description = 'Log data in the module chain. Use in addition to general logging (-l/--log).'
|
||||
self.incoming = incoming # incoming means module is on -im chain
|
||||
self.find = None # if find is not None, this text will be highlighted
|
||||
# file: the file name, format is (in|out)-20160601-112233.13413
|
||||
self.file = ('in-' if incoming else 'out-') + \
|
||||
time.strftime('%Y%m%d-%H%M%S.') + str(time.time()).split('.')[1]
|
||||
if options is not None:
|
||||
if 'file' in options.keys():
|
||||
self.file = options['file']
|
||||
self.handle = None
|
||||
|
||||
def __del__(self):
|
||||
if self.handle is not None:
|
||||
self.handle.close()
|
||||
|
||||
def execute(self, data):
|
||||
if self.handle is None:
|
||||
self.handle = open(self.file, 'wb', 0) # unbuffered
|
||||
print('Logging to file', self.file)
|
||||
logentry = bytes(time.strftime('%Y%m%d-%H%M%S') + ' ' + str(time.time()) + '\n', 'ascii')
|
||||
logentry += data
|
||||
logentry += b'-' * 20 + b'\n'
|
||||
self.handle.write(logentry)
|
||||
return data
|
||||
|
||||
def help(self):
|
||||
h = '\tfile: name of logfile'
|
||||
return h
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print('This module is not supposed to be executed alone!')
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
#!/usr/bin/env python3
|
||||
import os.path as path
|
||||
import paho.mqtt.client as mqtt
|
||||
from distutils.util import strtobool
|
||||
|
||||
|
||||
class Module:
|
||||
def __init__(self, incoming=False, verbose=False, options=None):
|
||||
# extract the file name from __file__. __file__ is proxymodules/name.py
|
||||
self.name = path.splitext(path.basename(__file__))[0]
|
||||
self.description = 'Publish the data to an MQTT server'
|
||||
self.incoming = incoming # incoming means module is on -im chain
|
||||
self.client_id = ''
|
||||
self.username = None
|
||||
self.password = None
|
||||
self.server = None
|
||||
self.port = 1883
|
||||
self.topic = ''
|
||||
self.hex = False
|
||||
if options is not None:
|
||||
if 'clientid' in options.keys():
|
||||
self.client_id = options['clientid']
|
||||
if 'server' in options.keys():
|
||||
self.server = options['server']
|
||||
if 'username' in options.keys():
|
||||
self.username = options['username']
|
||||
if 'password' in options.keys():
|
||||
self.password = options['password']
|
||||
if 'port' in options.keys():
|
||||
try:
|
||||
self.port = int(options['port'])
|
||||
if self.port not in range(1, 65536):
|
||||
raise ValueError
|
||||
except ValueError:
|
||||
print(f'port: invalid port {options["port"]}, using default {self.port}')
|
||||
if 'topic' in options.keys():
|
||||
self.topic = options['topic'].strip()
|
||||
if 'hex' in options.keys():
|
||||
try:
|
||||
self.hex = bool(strtobool(options['hex']))
|
||||
except ValueError:
|
||||
print(f'hex: {options["hex"]} is not a bool value, falling back to default value {self.hex}.')
|
||||
|
||||
if self.server is not None:
|
||||
self.mqtt = mqtt.Client(self.client_id)
|
||||
if self.username is not None or self.password is not None:
|
||||
self.mqtt.username_pw_set(self.username, self.password)
|
||||
self.mqtt.connect(self.server, self.port)
|
||||
else:
|
||||
self.mqtt = None
|
||||
|
||||
def execute(self, data):
|
||||
if self.mqtt is not None:
|
||||
|
||||
if self.hex is True:
|
||||
self.mqtt.publish(self.topic, data.hex())
|
||||
else:
|
||||
self.mqtt.publish(self.topic, data)
|
||||
return data
|
||||
|
||||
def help(self):
|
||||
h = '\tserver: server to connect to, required\n'
|
||||
h += ('\tclientid: what to use as client_id, default is empty\n'
|
||||
'\tusername: username\n'
|
||||
'\tpassword: password\n'
|
||||
'\tport: port to connect to, default 1883\n'
|
||||
'\ttopic: topic to publish to, default is empty\n'
|
||||
'\thex: encode data as hex before sending it. AAAA becomes 41414141.')
|
||||
return h
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print('This module is not supposed to be executed alone!')
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
#!/usr/bin/env python3
|
||||
import os.path as path
|
||||
|
||||
|
||||
class Module:
|
||||
def __init__(self, incoming=False, verbose=False, options=None):
|
||||
# extract the file name from __file__. __file__ is proxymodules/name.py
|
||||
self.name = path.splitext(path.basename(__file__))[0]
|
||||
self.description = 'Replace gzip in the list of accepted encodings ' \
|
||||
'in a HTTP request with booo.'
|
||||
self.incoming = incoming # incoming means module is on -im chain
|
||||
# I chose to replace gzip instead of removing it to keep the parsing
|
||||
# logic as simple as possible.
|
||||
|
||||
def execute(self, data):
|
||||
try:
|
||||
# split at \r\n\r\n to split the request into header and body
|
||||
header, body = data.split(b'\r\n\r\n', 1)
|
||||
except ValueError:
|
||||
# no \r\n\r\n, so probably not HTTP, we can go now
|
||||
return data
|
||||
# now split the header string into its lines
|
||||
headers = header.split(b'\r\n')
|
||||
|
||||
for h in headers:
|
||||
if h.lower().startswith(b'accept-encoding:') and b'gzip' in h:
|
||||
headers[headers.index(h)] = h.replace(b'gzip', b'booo')
|
||||
break
|
||||
|
||||
return b'\r\n'.join(headers) + b'\r\n\r\n' + body
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print('This module is not supposed to be executed alone!')
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
#!/usr/bin/env python3
|
||||
import os
|
||||
import re
|
||||
|
||||
|
||||
class Module:
|
||||
def __init__(self, incoming=False, verbose=False, options=None):
|
||||
# extract the file name from __file__. __file__ is proxymodules/name.py
|
||||
self.name = os.path.splitext(os.path.basename(__file__))[0]
|
||||
self.description = 'Replace text on the fly by using regular expressions in a file or as module parameters'
|
||||
self.verbose = verbose
|
||||
self.search = None
|
||||
self.replace = None
|
||||
self.filename = None
|
||||
self.separator = ':'
|
||||
|
||||
if options is not None:
|
||||
if 'search' in options.keys():
|
||||
self.search = bytes(options['search'], 'ascii')
|
||||
if 'replace' in options.keys():
|
||||
self.replace = bytes(options['replace'], 'ascii')
|
||||
if 'file' in options.keys():
|
||||
self.filename = options['file']
|
||||
try:
|
||||
open(self.filename)
|
||||
except IOError as ioe:
|
||||
print("Error opening %s: %s" % (self.filename, ioe.strerror))
|
||||
self.filename = None
|
||||
if 'separator' in options.keys():
|
||||
self.separator = options['separator']
|
||||
|
||||
def execute(self, data):
|
||||
pairs = [] # list of (search, replace) tuples
|
||||
if self.search is not None and self.replace is not None:
|
||||
pairs.append((self.search, self.replace))
|
||||
|
||||
if self.filename is not None:
|
||||
for line in open(self.filename).readlines():
|
||||
try:
|
||||
search, replace = line.split(self.separator, 1)
|
||||
pairs.append((bytes(search.strip(), 'ascii'), bytes(replace.strip(), 'ascii')))
|
||||
except ValueError:
|
||||
# line does not contain separator and will be ignored
|
||||
pass
|
||||
|
||||
for search, replace in pairs:
|
||||
# TODO: verbosity
|
||||
data = re.sub(search, replace, data)
|
||||
|
||||
return data
|
||||
|
||||
def help(self):
|
||||
h = '\tsearch: string or regular expression to search for\n'
|
||||
h += ('\treplace: string the search string should be replaced with\n')
|
||||
h += ('\tfile: file containing search:replace pairs, one per line\n')
|
||||
h += ('\tseparator: define a custom search:replace separator in the file, e.g. search#replace\n')
|
||||
h += ('\n\tUse at least file or search and replace (or both).\n')
|
||||
return h
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print('This module is not supposed to be executed alone!')
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
#!/usr/bin/env python3
|
||||
import os.path as path
|
||||
from distutils.util import strtobool
|
||||
|
||||
|
||||
class Module:
|
||||
def __init__(self, incoming=False, verbose=False, options=None):
|
||||
# extract the file name from __file__. __file__ is proxymodules/name.py
|
||||
self.name = path.splitext(path.basename(__file__))[0]
|
||||
self.description = 'Print the size of the data passed to the module'
|
||||
self.verbose = verbose
|
||||
self.source = None
|
||||
self.destination = None
|
||||
self.incoming = incoming
|
||||
if options is not None:
|
||||
if 'verbose' in options.keys():
|
||||
self.verbose = bool(strtobool(options['verbose']))
|
||||
|
||||
def execute(self, data):
|
||||
size = len(data)
|
||||
msg = "Received %d bytes" % size
|
||||
if self.verbose:
|
||||
msg += " from %s:%d" % self.source
|
||||
msg += " for %s:%d" % self.destination
|
||||
print(msg)
|
||||
return data
|
||||
|
||||
def help(self):
|
||||
h = '\tverbose: override the global verbosity setting'
|
||||
return h
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print('This module is not supposed to be executed alone!')
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
#!/usr/bin/env python2
|
||||
import os.path as path
|
||||
import time
|
||||
from distutils.util import strtobool
|
||||
|
||||
|
||||
class Module:
|
||||
def __init__(self, incoming=False, verbose=False, options=None):
|
||||
# extract the file name from __file__. __file__ is proxymodules/name.py
|
||||
self.name = path.splitext(path.basename(__file__))[0]
|
||||
self.description = 'Change HTTP responses of a certain size to 404.'
|
||||
self.incoming = incoming # incoming means module is on -im chain
|
||||
self.size = 2392 # if a response has this value as content-length, it will become a 404
|
||||
self.verbose = False
|
||||
self.custom = False
|
||||
self.rewriteall = False # will we block the first occurence?
|
||||
self.firstfound = False # have we found the first occurence yet?
|
||||
self.resetinterval = None # if we haven't found a fitting response in this many seconds, reset the state and set first to False again
|
||||
self.timer = time.time()
|
||||
if options is not None:
|
||||
if 'size' in options.keys():
|
||||
try:
|
||||
self.size = int(options['size'])
|
||||
except ValueError:
|
||||
pass # use the default if you can't parse the parameter
|
||||
if 'verbose' in options.keys():
|
||||
self.verbose = bool(strtobool(options['verbose']))
|
||||
if 'custom' in options.keys():
|
||||
try:
|
||||
with open(options['custom'], 'rb') as handle:
|
||||
self.custom = handle.read()
|
||||
except Exception:
|
||||
print('Can\'t open custom error file, not using it.')
|
||||
self.custom = False
|
||||
if 'rewriteall' in options.keys():
|
||||
self.rewriteall = bool(strtobool(options['rewriteall']))
|
||||
if 'reset' in options.keys():
|
||||
try:
|
||||
self.resetinterval = float(options['reset'])
|
||||
except ValueError:
|
||||
pass # use the default if you can't parse the parameter
|
||||
|
||||
def execute(self, data):
|
||||
contentlength = b'content-length: ' + bytes(str(self.size), 'ascii')
|
||||
if data.startswith(b'HTTP/1.1 200 OK') and contentlength in data.lower():
|
||||
if self.resetinterval is not None:
|
||||
t = time.time()
|
||||
if t - self.timer >= self.resetinterval:
|
||||
if self.verbose:
|
||||
print('Timer elapsed')
|
||||
self.firstfound = False
|
||||
self.timer = t
|
||||
if self.rewriteall is False and self.firstfound is False:
|
||||
# we have seen this response size for the first time and are not blocking the first one
|
||||
self.firstfound = True
|
||||
if self.verbose:
|
||||
print('Letting this response through')
|
||||
return data
|
||||
if self.custom is not False:
|
||||
data = self.custom
|
||||
if self.verbose:
|
||||
print('Replaced response with custom response')
|
||||
else:
|
||||
data = data.replace(b'200 OK', b'404 Not Found', 1)
|
||||
if self.verbose:
|
||||
print('Edited return code')
|
||||
return data
|
||||
|
||||
def help(self):
|
||||
h = '\tsize: if a response has this value as content-length, it will become a 404\n'
|
||||
h += ('\tverbose: print a message if a string is replaced\n'
|
||||
'\tcustom: path to a file containing a custom response, will replace the received response\n'
|
||||
'\trewriteall: if set, it will rewrite all responses. Default is to let the first on through'
|
||||
'\treset: number of seconds after which we will reset the state and will let the next response through.')
|
||||
return h
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print('This module is not supposed to be executed alone!')
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
import os.path as path
|
||||
import json
|
||||
import socket
|
||||
|
||||
class Module:
|
||||
def __init__(self, incoming=False, verbose=False, options=None):
|
||||
# extract the file name from __file__. __file__ is proxymodules/name.py
|
||||
self.name = path.splitext(path.basename(__file__))[0]
|
||||
self.description = 'Simply print the received data as text'
|
||||
self.incoming = incoming # incoming means module is on -im chain
|
||||
self.find = None # if find is not None, this text will be highlighted
|
||||
|
||||
def execute(self, data):
|
||||
print(f"Incoming data: {data}")
|
||||
|
||||
### Work with data here ###
|
||||
# data_json = json.loads(data)
|
||||
# data_json["content"] = "Blablabla"
|
||||
# data = json.dumps(data_json)
|
||||
# print(f"Outgoing data: {data}")
|
||||
# return data + "\n"
|
||||
|
||||
print(f"Outgoing data: {data}")
|
||||
return data
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print('This module is not supposed to be executed alone!')
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
#!/usr/bin/env python3
|
||||
import os.path as path
|
||||
from codecs import decode, lookup
|
||||
|
||||
|
||||
class Module:
|
||||
def __init__(self, incoming=False, verbose=False, options=None):
|
||||
# extract the file name from __file__. __file__ is proxymodules/name.py
|
||||
self.name = path.splitext(path.basename(__file__))[0]
|
||||
self.description = 'Simply print the received data as text'
|
||||
self.incoming = incoming # incoming means module is on -im chain
|
||||
self.find = None # if find is not None, this text will be highlighted
|
||||
self.codec = 'latin_1'
|
||||
if options is not None:
|
||||
if 'find' in options.keys():
|
||||
self.find = bytes(options['find'], 'ascii') # text to highlight
|
||||
if 'color' in options.keys():
|
||||
self.color = bytes('\033[' + options['color'] + 'm', 'ascii') # highlight color
|
||||
else:
|
||||
self.color = b'\033[31;1m'
|
||||
if 'codec' in options.keys():
|
||||
codec = options['codec']
|
||||
try:
|
||||
lookup(codec)
|
||||
self.codec = codec
|
||||
except LookupError:
|
||||
print(f"{self.name}: {options['codec']} is not a valid codec, using {self.codec}")
|
||||
|
||||
|
||||
def execute(self, data):
|
||||
if self.find is None:
|
||||
print(decode(data, self.codec))
|
||||
else:
|
||||
pdata = data.replace(self.find, self.color + self.find + b'\033[0m')
|
||||
print(decode(pdata, self.codec))
|
||||
return data
|
||||
|
||||
def help(self):
|
||||
h = '\tfind: string that should be highlighted\n'
|
||||
h += ('\tcolor: ANSI color code. Will be wrapped with \\033[ and m, so'
|
||||
' passing 32;1 will result in \\033[32;1m (bright green)')
|
||||
return h
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print('This module is not supposed to be executed alone!')
|
||||
Loading…
Add table
Add a link
Reference in a new issue