summaryrefslogtreecommitdiffstats
path: root/ncat/scripts/p0fme.py
diff options
context:
space:
mode:
Diffstat (limited to 'ncat/scripts/p0fme.py')
-rwxr-xr-xncat/scripts/p0fme.py97
1 files changed, 97 insertions, 0 deletions
diff --git a/ncat/scripts/p0fme.py b/ncat/scripts/p0fme.py
new file mode 100755
index 0000000..5f4d42e
--- /dev/null
+++ b/ncat/scripts/p0fme.py
@@ -0,0 +1,97 @@
+#!/usr/bin/python
+
+from __future__ import print_function # logging, python2-only.
+
+"""
+A script that reads data generated by p0f -f p0f.log, looking for all entries
+about an IP read from NCAT_REMOTE_ADDR environment variable. Then it prints out
+all the information it has found. To try it out, run "p0f -i any -o p0f.log"
+and ncat -l -k --sh-exec "python p0fme.py".
+
+Script tested under Python versions 2.7 and 3.3.
+"""
+
+P0F_LOG_FILE = "p0f.log"
+
+import datetime # logging
+import sys # logging
+import os # environ
+import time # sleeping to wait for data
+import sys # to flush STDOUT
+
+
+def expand_ipv6(ip):
+ """
+ Expands short IPv6 address like ::1 into an expanded form without trailing
+ zeros. Copied from:
+
+ http://svn.python.org/projects/python/tags/r31b1/Lib/ipaddr.py
+
+ (Py3 standard library; added some modifications to match p0f's output data)
+ """
+
+ new_ip = []
+ hextet = ip.split('::')
+ sep = len(hextet[0].split(':')) + len(hextet[1].split(':'))
+ new_ip = hextet[0].split(':')
+
+ for _ in range(8 - sep):
+ new_ip.append('0')
+ new_ip += hextet[1].split(':')
+
+ # Now need to make sure every hextet is 4 lower case characters.
+ # If a hextet is < 4 characters, we've got missing leading 0's.
+ ret_ip = []
+ for hextet in new_ip:
+ if hextet == '':
+ hextet = '0'
+ ret_ip.append(hextet.lower())
+ return ':'.join(ret_ip)
+
+
+def split_by_equals(str_):
+ ret = str_.split('=')
+ return ret[0], ''.join(ret[1:])
+
+if __name__ == "__main__":
+ try:
+ ip = os.environ['NCAT_REMOTE_ADDR']
+ if os.environ['NCAT_PROTO'] != 'TCP':
+ sys.exit("ERROR: This script works for TCP servers only!")
+ except KeyError:
+ sys.exit("ERROR: This script has to be run from inside of Ncat.")
+ print("[%s] Got a request from %s" % (
+ datetime.datetime.now().isoformat(' '), ip), file=sys.stderr)
+
+ print("Hold on, I'm collecting data on you...")
+ sys.stdout.flush()
+ time.sleep(3.0)
+
+ if ':' in ip: # We need to expand IPv6 addresses in a specific way.
+ ip = expand_ipv6(ip)
+ result = {}
+
+ # Reading the log backward will give us more recent results.
+ for line in reversed(open(P0F_LOG_FILE).readlines()):
+
+ without_date = line.split('] ')
+ if without_date == ['\n']:
+ continue
+ without_date = ''.join(without_date[1:])
+
+ # Create a key-value dictionary out of the '|'-separated substrings.
+ properties = dict(map(split_by_equals, without_date.split('|')))
+
+ if not properties['cli'].startswith(ip):
+ continue # Not the IP we're looking for, check next one.
+
+ for key in properties:
+ if not key in result or result[key] == '???':
+ result[key] = properties[key]
+
+ if not result:
+ print("Got nothing on you. Try again and I will, though.")
+
+ # Now that we've finished, print out the results.
+ for key in sorted(result):
+ print("%s: %s" % (key, result[key].rstrip()))