Created
November 27, 2020 16:03
-
-
Save nbareil/07307dee653ef3400cd3ece0c7a35799 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
FROM ubuntu:bionic | |
RUN apt-get update && \ | |
apt-get install -y git libglib2.0-dev zlib1g-dev autoconf automake libtool \ | |
libpcap-dev libnet-dev \ | |
python-pip python-setuptools python-nids && \ | |
apt-get clean && \ | |
apt-get autoclean | |
RUN cd /tmp && \ | |
git clone https://github.com/MITRECND/pynids.git && \ | |
cd pynids && \ | |
git checkout 6a385a3593bfddb78f64c144e01369c31a4f23fa && \ | |
python setup.py install && \ | |
rm -fr /tmp/libnids | |
RUN pip install https://github.com/MITRECND/htpy/archive/RELEASE_0.31.zip | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/bin/env python | |
import nids | |
import htpy | |
import traceback | |
import logging | |
import urlparse | |
import re | |
import argparse | |
conn = {} | |
states = {} | |
chunks_resp = {} | |
chunks_req = {} | |
def request_headers_ready(cp, obj): | |
uri = cp.get_uri() | |
log.debug("URI: %r" % uri) | |
if uri["path"] != "/my/c2/dispatcher/": | |
return htpy.HTP_OK | |
cookies = cp.get_request_header("Cookie") | |
if not "magic" in cookies: | |
# server did not answer with the magic keyword | |
return htpy.HTP_OK | |
cp.register_request_body_data(body_request_ready) | |
chunks_resp[obj] = [] | |
chunks_req[obj] = [] | |
cp.register_response_body_data(body_response_ready) | |
cp.register_response_complete(response_complete_callback) | |
cp.register_request_complete(request_complete_callback) | |
return htpy.HTP_OK | |
def body_response_ready(data, length, obj): | |
if not data: | |
return htpy.HTP_OK | |
chunks_resp[obj].append(data[:length]) | |
return htpy.HTP_OK | |
def body_request_ready(data, length, obj): | |
if not data: | |
return htpy.HTP_OK | |
chunks_req[obj].append(data[:length]) | |
return htpy.HTP_OK | |
def request_complete_callback(cp, obj): | |
data = "".join(chunks_req[obj]) | |
del chunks_req[obj] | |
# params = urlparse.parse_qs(data) | |
# XXX: Uses data or params | |
return htpy.HTP_OK | |
def response_complete_callback(cp, obj): | |
data = "".join(chunks_resp[obj]) | |
del chunks_resp[obj] | |
# XXX: Work on the data | |
return htpy.HTP_OK | |
def tcp_callback(tcp): | |
try: | |
return _tcp_callback(tcp) | |
except Exception as err: | |
log.error("ERROR: %s" % err) | |
traceback.print_exc() | |
def new_tcp(tcp): | |
log.debug("New conn") | |
conn[tcp.addr] = htpy.connp() | |
conn[tcp.addr].set_obj(tcp.addr) | |
tcp.client.collect = 1 | |
tcp.server.collect = 1 | |
conn[tcp.addr].register_request_headers(request_headers_ready) | |
def incoming_data(tcp): | |
if tcp.client.count_new: | |
log.debug("SERVER -> CLIENT: New data") | |
conn[tcp.addr].res_data(tcp.client.data[: tcp.client.count_new]) | |
elif tcp.server.count_new: | |
log.debug("CLIENT -> SERVER: New data") | |
conn[tcp.addr].req_data(tcp.server.data[: tcp.server.count_new]) | |
else: | |
log.error("ERROR: Invalid state") | |
def destroy_tcp(tcp): | |
# del(conn[tcp.addr]) | |
pass | |
end_states = (nids.NIDS_CLOSE, nids.NIDS_TIMEOUT, nids.NIDS_RESET) | |
def _tcp_callback(tcp): | |
# print 'tcp_callback' | |
if tcp.nids_state == nids.NIDS_JUST_EST: | |
new_tcp(tcp) | |
elif tcp.nids_state == nids.NIDS_DATA: | |
incoming_data(tcp) | |
elif tcp.nids_state in end_states: | |
destroy_tcp(tcp) | |
else: | |
print "WARN: Invalid NIDS state" | |
def main(): | |
global log | |
parser = argparse.ArgumentParser() | |
parser.add_argument( | |
"--verbose", "-v", action="count", default=2, help="Increase verbosity" | |
) | |
parser.add_argument( | |
"--read", | |
"-r", | |
action="store", | |
help="read this pcap file", | |
dest="fname", | |
metavar="FILENAME", | |
required=True, | |
) | |
options = parser.parse_args() | |
verbosity = max(1, 50 - 10 * (options.verbose)) | |
logging.basicConfig(format="%(levelname)-5s: %(message)s", level=verbosity) | |
log = logging.getLogger() | |
nids.chksum_ctl([("0.0.0.0/0", False)]) | |
nids.param("pcap_filter", "vlan and tcp and (port 443 or port 80)") | |
nids.param("scan_num_hosts", 0) | |
nids.param("filename", options.fname) | |
nids.init() | |
nids.register_tcp(tcp_callback) | |
try: | |
nids.run() | |
except nids.error, e: | |
print "nids/pcap error:", e | |
except Exception, e: | |
print "misc. exception (runtime error in user callback?):", e | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment