#!/usr/bin/env python from __future__ import with_statement from time import strftime, strptime import sys # nmaparse.py # Copyright (C) 2008 Marcin Wielgoszewski (tssci-security.com) # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . __author__ = 'Marcin Wielgoszewski' __version__ = '0.6' DB_HOST = 'hostname' DB_UNAME = 'username' DB_PASSWD = 'password' DB_NAME = 'database' def delete_labels(line): line[0] = line[0].replace('Host: ', '') line[1] = line[1].replace('Ports: ', '') line[2] = line[2].replace('OS: ', '') line[3] = line[3].replace('Seq Index: ', '') line[4] = line[4].replace('IPID Seq: ', '') line[4] = line[4].replace('\n', '') return line def d1_replace(d): d[1] = d[1].replace('///', '/') d[1] = d[1].replace('//', '/') d[1] = d[1].replace('/,', ',') d[1] = d[1].rstrip('/') return d[1].split(', ') def expand_ports(d): ports = d1_replace(d) ret = [] for i in range(len(ports)): ret.append(list(d[:1])) # append IP/hostname j = 0 for k in ports: k = k.split('/', 4) if len(k) == 4: k.append('') # append a missing version field ret[j].extend(k + list(d[2:])) # append ports and rest of results j += 1 return ret def parse_gnmap(infile): infile = infile.readlines() date = strftime("%Y-%m-%d %H:%M:%S", strptime(infile[0].strip()[27:51])) flags = infile[0].strip()[56:] scan = [line.split('\t') for line in infile[1:-1]] scan_results = [] for line in scan: if len(line) == 4: line.insert(2, '') # insert field for missing OS line = delete_labels(line) line.append(date) line.append(flags) scan_results.extend(expand_ports(line)) return scan_results def insert_gnmap(results): """For corresponding database schema, see: http://www.tssci-security.com/upload/nmaparse_py/nmapdb.sql """ import MySQLdb try: db = MySQLdb.connect(DB_HOST, DB_UNAME, DB_PASSWD, DB_NAME) except MySQLdb.Error, e: print """Error %d: %s""" % (e.args[0], e.args[1]) sys.exit (1) c = db.cursor() results_rows = 0 while results: small_results, results = results[:100], results[100:] c.executemany("""INSERT INTO results (host, port, protocol, state, service, version, os, seqIndex, ipidSeq, scandate, scanflags) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""", (small_results)) results_rows += c.rowcount print """Number of rows inserted: %d results""" % results_rows def main(): results = [] for args in sys.argv[1:]: with open(args, 'rU') as infile: results += parse_gnmap(infile) insert_gnmap(results) if __name__ == "__main__": if len(sys.argv) < 2: print """This program parses *.gnmap files.""" print """Usage: nmap.py results1.gnmap results2.gnmap""" sys.exit(1) else: main()