blob: b07a8d5a2ee2c2b14558720870d3d368d1192197 [file] [log] [blame] [raw]
#!/usr/bin/env python
from twisted.web import http
from twisted.internet import protocol
from twisted.internet import reactor, threads
from ConfigParser import ConfigParser
from nx_parser import signature_parser
import urllib
import pprint
import socket
import SQLWrapper
import getopt
import sys
import re
conf_path = ''
class InterceptHandler(http.Request):
def process(self):
if self.getHeader('Orig_args'):
args = {'GET' : self.getHeader('Orig_args')}
method = 'GET'
elif self.args:
args = {'POST': self.args}
method = 'POST'
else:
method = 'GET'
args = {}
args['Cookie'] = self.getHeader('Cookie')
args['Referer'] = self.getHeader('Referer')
sig = self.getHeader("naxsi_sig")
print self
if sig is None:
print "no naxsi_sig header ?"
print self
self.finish()
return
url = sig.split('&uri=')[1].split('&')[0]
print "+ "+url
fullstr = method + ' ' + url + ' ' + ','.join([x + ' : ' + str(args.get(x, 'No Value !')) for x in args.keys()])
threads.deferToThread(self.background, fullstr, sig)
self.finish()
return
def background(self, fullstr, sig):
wrapper = SQLWrapper.SQLWrapper(conf_path)
wrapper.connect()
parser = signature_parser(wrapper)
parser.wrapper.StartInsert()
parser.sig_to_db(fullstr, sig)
parser.wrapper.StopInsert()
# parser.wrapper.close()
class InterceptProtocol(http.HTTPChannel):
requestFactory = InterceptHandler
class InterceptFactory(http.HTTPFactory):
protocol = InterceptProtocol
def usage():
print 'Usage: python nx_intercept [-h,--help] [-q,--quiet] [-l,--log-file /path/to/logfile] [-c, --conf-file naxsi-ui-learning.conf] '
def fill_db(files, conf_path):
wrapper = SQLWrapper.SQLWrapper(conf_path)
wrapper.connect()
sig = ''
if re.match("[a-z0-9]+$", wrapper.dbname) == False:
print 'bad db name :)'
exit(-2)
wrapper.drop_database()
wrapper.create_db()
wrapper.select_db(wrapper.dbname)
#wrapper.exec()
print "Filling db with %s (TABLES WILL BE DROPPED !)" % ' '.join(files)
# parser = signature_parser(wrapper)
parser = signature_parser(wrapper)
parser.wrapper.StartInsert()
for filename in files:
with open(filename, 'r') as fd:
for line in fd:
fullstr = ''
if 'NAXSI_FMT' in line:
l = line.split(", ")
date = ' '.join(l[0].split()[:2])
sig = l[0].split('NAXSI_FMT:')[1][1:]
l = l[1:]
request_args = {}
for i in l:
s = i.split(':')
request_args[s[0]] = urllib.unquote(''.join(s[1:]))
fullstr = request_args.get('request', 'None')[2:-1] + ' Referer : ' + request_args.get('referrer', ' "None"')[2:-1].strip('"\n') + ',Cookie : ' + request_args.get('cookie', ' "None"')[2:-1]
if sig != '' and fullstr != '':
parser.sig_to_db(fullstr, sig, date=date)
parser.wrapper.StopInsert()
if __name__ == '__main__':
try:
opts, args = getopt.getopt(sys.argv[1:], 'c:hl:', ['conf-file', 'help', 'log-file'])
except getopt.GetoptError, err:
print str(err)
usage()
sys.exit(42)
has_conf = False
logs_path = []
for o, a in opts:
if o in ('-h', '--help'):
usage()
sys.exit(0)
if o in ('-a', '--add-monitoring'):
if has_conf is False:
print "Conf File must be specified first !"
exit(42)
add_monitoring(a, conf_path)
exit(42)
if o in ('-l', '--log-file'):
if has_conf is False:
print "Conf File must be specified first !"
exit(42)
logs_path.append(a)
if o in ('-c', '--conf-file'):
has_conf = True
conf_path = a
if has_conf is False:
print 'Conf file is mandatory !'
exit(-42)
if len(logs_path) > 0:
fill_db(logs_path, conf_path)
exit(0)
fd = open(conf_path, 'r')
conf = ConfigParser()
conf.readfp(fd)
try:
port = int(conf.get('nx_intercept', 'port'))
except:
print "No port in conf file ! Using default port (8080)"
port = 8080
fd.close()
reactor.listenTCP(port, InterceptFactory())
reactor.run()