Saturday, May 09, 2026 AM03:21:24 HKT
This commit is contained in:
+213
@@ -0,0 +1,213 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import datetime
|
||||
import json
|
||||
import sys
|
||||
from urlparse import *
|
||||
import urllib
|
||||
import libinjection
|
||||
|
||||
from tornado import template
|
||||
from tornado.escape import *
|
||||
|
||||
import re
|
||||
import calendar
|
||||
|
||||
months = {
|
||||
'Jan':'01',
|
||||
'Feb':'02',
|
||||
'Mar':'03',
|
||||
'Apr':'04',
|
||||
'May':'05',
|
||||
'Jun':'06',
|
||||
'Jul':'07',
|
||||
'Aug':'08',
|
||||
'Sep':'09',
|
||||
'Oct':'10',
|
||||
'Nov':'11',
|
||||
'Dec':'12'
|
||||
}
|
||||
|
||||
# "time_iso8601":"2013-08-04T03:51:18+00:00"
|
||||
def parse_date(datestr):
|
||||
elems = (
|
||||
datestr[7:11],
|
||||
months[datestr[3:6]],
|
||||
datestr[0:2],
|
||||
datestr[12:14],
|
||||
datestr[15:17],
|
||||
datestr[18:20],
|
||||
)
|
||||
|
||||
return ( "{0}-{1}-{2}T{3}:{4}:{5}+00:00".format(*elems), calendar.timegm( [ int(i) for i in elems] ) )
|
||||
|
||||
|
||||
apachelogre = re.compile(r'^(\S*) (\S*) (\S*) \[([^\]]+)\] \"([^"\\]*(?:\\.[^"\\]*)*)\" (\S*) (\S*) \"([^"\\]*(?:\\.[^"\\]*)*)\" \"([^"]*)\" \"([^"]*)\"')
|
||||
|
||||
def parse_apache(line):
|
||||
mo = apachelogre.match(line)
|
||||
if not mo:
|
||||
return None
|
||||
(time_iso, timestamp) = parse_date(mo.group(4))
|
||||
try:
|
||||
(method, uri, protocol) = mo.group(5).split(' ', 2)
|
||||
except ValueError:
|
||||
(method, uri, protocol) = ('-', '-', '-')
|
||||
data = {
|
||||
'remote_addr': mo.group(1),
|
||||
'time_iso8601': time_iso,
|
||||
'timestamp' : timestamp,
|
||||
'request_protocol': protocol,
|
||||
'request_method': method,
|
||||
'request_uri': uri,
|
||||
'request_length': '',
|
||||
'request_time': '',
|
||||
'status': mo.group(6),
|
||||
'bytes_sent': '',
|
||||
'body_bytes-sent': int(mo.group(7)),
|
||||
'http_referrer': mo.group(8),
|
||||
'http_user_agent': mo.group(9),
|
||||
'ssl_cipher': '',
|
||||
'ssl_protocol': ''
|
||||
}
|
||||
return data
|
||||
|
||||
# http://stackoverflow.com/questions/312443/how-do-you-split-a-list-into-evenly-sized-chunks-in-python
|
||||
def chunks(l, n):
|
||||
"""
|
||||
Yield successive n-sized chunks from l.
|
||||
"""
|
||||
for i in xrange(0, len(l), n):
|
||||
yield l[i:i+n]
|
||||
|
||||
def breakify(s):
|
||||
output = ""
|
||||
for c in chunks(s, 40):
|
||||
output += c
|
||||
if ' ' not in c:
|
||||
output += ' '
|
||||
return output
|
||||
|
||||
def doline(line):
|
||||
|
||||
line = line.replace("\\x", "%").strip()
|
||||
try:
|
||||
data = json.loads(line)
|
||||
except ValueError, e:
|
||||
data = parse_apache(line)
|
||||
|
||||
if data is None:
|
||||
sys.stderr.write("BAD LINE: {0}\n".format(line))
|
||||
return None
|
||||
|
||||
if not data.get('request_uri','').startswith("/diagnostics"):
|
||||
return None
|
||||
|
||||
urlparts = urlparse(data['request_uri'])
|
||||
if len(urlparts.query) == 0:
|
||||
return None
|
||||
|
||||
qsl = [ x.split('=', 1) for x in urlparts.query.split('&') ]
|
||||
|
||||
target = None
|
||||
for k,v in qsl:
|
||||
if k == 'id':
|
||||
target = v
|
||||
break
|
||||
|
||||
if target is None:
|
||||
#print "no 'id'"
|
||||
return None
|
||||
|
||||
# part one, normal decode
|
||||
target = urllib.unquote_plus(target)
|
||||
|
||||
# do it again, but preserve '+'
|
||||
target = urllib.unquote(target)
|
||||
|
||||
sstate = libinjection.sqli_state()
|
||||
# BAD the string created by target.encode is stored in
|
||||
# sstate but not reference counted, so it can get
|
||||
# deleted by python
|
||||
# libinjection.sqli_init(sstate, target.encode('utf-8'), 0)
|
||||
|
||||
# instead make a temporary var in python
|
||||
# with the same lifetime as sstate (above)
|
||||
try:
|
||||
targetutf8 = target.encode('utf-8')
|
||||
#targetutf8 = target
|
||||
except UnicodeDecodeError, e:
|
||||
targetutf8 = target
|
||||
#if type(target) == str:
|
||||
# sys.stderr.write("Target is a string\n")
|
||||
#if type(target) == unicode:
|
||||
# sys.stderr.write("Target is unicde\n")
|
||||
#sys.stderr.write("OOps: {0}\n".format(e))
|
||||
#sys.stderr.write("Encode error: {0}\n".format(target))
|
||||
|
||||
|
||||
try:
|
||||
libinjection.sqli_init(sstate, targetutf8, 0)
|
||||
except TypeError:
|
||||
sys.stderr.write("fail in decode: {0}".format(targetutf8))
|
||||
if type(target) == str:
|
||||
sys.stderr.write("Target is a string\n")
|
||||
if type(target) == unicode:
|
||||
sys.stderr.write("Target is unicde\n")
|
||||
return None
|
||||
|
||||
sqli = bool(libinjection.is_sqli(sstate))
|
||||
|
||||
return (target, sqli, sstate.fingerprint, data['remote_addr'])
|
||||
|
||||
if __name__ == '__main__':
|
||||
s = """
|
||||
174.7.27.149 - - [29/Jul/2013:01:30:19 +0000] "GET /diagnostics?id=x|x||1&type=fingerprints HTTP/1.1" 200 1327 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.72 Safari/537.36" "-"
|
||||
"""
|
||||
s = """
|
||||
{"timestamp":1371091563,"remote_ip":"219.110.171.2","request":"/diagnostics?id=1+UNION+ALL+SELECT+1<<<&type=fingerprints","method":"GET","status":200,"user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/536.30.1 (KHTML, like Gecko) Version/6.0.5 Safari/536.30.1","referrer":"https://libinjection.client9.com/diagnostics","duration_usec":160518 }
|
||||
{"timestamp":1371091563,"remote_ip":"219.110.171.2","request":"/diagnostics?id=2+UNION+ALL+SELECT+1<<<&type=fingerprints","method":"GET","status":200,"user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/536.30.1 (KHTML, like Gecko) Version/6.0.5 Safari/536.30.1","referrer":"https://libinjection.client9.com/diagnostics","duration_usec":160518 }
|
||||
"""
|
||||
if len(sys.argv) == 2:
|
||||
fh = open(sys.argv[1], 'r')
|
||||
else:
|
||||
fh = sys.stdin
|
||||
|
||||
targets = set()
|
||||
table = []
|
||||
for line in fh:
|
||||
parts = doline(line.strip())
|
||||
if parts is None:
|
||||
continue
|
||||
|
||||
# help it render in HTML
|
||||
if parts[0] in targets:
|
||||
continue
|
||||
else:
|
||||
targets.add(parts[0])
|
||||
|
||||
# add link
|
||||
# add form that might render ok in HTML
|
||||
# is sqli
|
||||
# fingerprint
|
||||
table.append( (
|
||||
"/diagnostics?id=" + url_escape(parts[0]),
|
||||
breakify(parts[0].replace(',', ', ').replace('/*', ' /*')),
|
||||
parts[1],
|
||||
parts[2],
|
||||
parts[3]
|
||||
)
|
||||
)
|
||||
|
||||
table = reversed(table)
|
||||
|
||||
loader = template.Loader(".")
|
||||
|
||||
txt = loader.load("logtable.html").generate(
|
||||
table=table,
|
||||
now = str(datetime.datetime.now()),
|
||||
ssl_protocol='',
|
||||
ssl_cipher=''
|
||||
)
|
||||
|
||||
print txt
|
||||
Reference in New Issue
Block a user