This file is indexed.

/usr/share/nginx-naxsi/naxsi-ui/nx_intercept.py is in nginx-naxsi-ui 1.4.6-1ubuntu3.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#!/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()