def alltokens(val, flags): if flags & libinjection.FLAG_QUOTE_SINGLE: contextstr = 'single' elif flags & libinjection.FLAG_QUOTE_DOUBLE: contextstr = 'double' else: contextstr = 'none' if flags & libinjection.FLAG_SQL_ANSI: commentstr = 'ansi' elif flags & libinjection.FLAG_SQL_MYSQL: commentstr = 'mysql' else: raise RuntimeException("bad quote context") parse = { 'comment': commentstr, 'quote': contextstr } args = [] sqlstate = libinjection.sqli_state() libinjection.sqli_init(sqlstate, val, flags) count = 0 while count < 25: count += 1 ok = libinjection.sqli_tokenize(sqlstate) if ok == 0: break args.append(print_token(sqlstate.current)) parse['tokens'] = args args = [] fingerprint = libinjection.sqli_fingerprint(sqlstate, flags) vec = sqlstate.tokenvec for i in range(len(sqlstate.fingerprint)): args.append(print_token(vec[i])) parse['folds'] = args parse['sqli'] = bool(libinjection.sqli_blacklist(sqlstate) and libinjection.sqli_not_whitelist(sqlstate)) parse['fingerprint'] = fingerprint # todo add stats return parse
def alltokens(val, flags): if flags & libinjection.FLAG_QUOTE_SINGLE: contextstr = 'single' elif flags & libinjection.FLAG_QUOTE_DOUBLE: contextstr = 'double' else: contextstr = 'none' if flags & libinjection.FLAG_SQL_ANSI: commentstr = 'ansi' elif flags & libinjection.FLAG_SQL_MYSQL: commentstr = 'mysql' else: raise RuntimeException("bad quote context") parse = { 'comment': commentstr, 'quote': contextstr } args = [] sqlstate = libinjection.sqli_state() libinjection.sqli_init(sqlstate, val, flags) count = 0 while count < 25: count += 1 ok = libinjection.sqli_tokenize(sqlstate) if ok == 0: break args.append(print_token(sqlstate.current)) parse['tokens'] = args args = [] fingerprint = libinjection.sqli_fingerprint(sqlstate, flags) for i in range(len(sqlstate.fingerprint)): args.append(print_token(libinjection.sqli_get_token(sqlstate,i))) parse['folds'] = args parse['sqli'] = bool(libinjection.sqli_blacklist(sqlstate) and libinjection.sqli_not_whitelist(sqlstate)) parse['fingerprint'] = fingerprint # todo add stats return parse
def get_fingerprints(self): #unquote = urllib.unquote #detectsqli = libinjection.detectsqli ids = self.request.arguments.get('id', []) if len(ids) == 1: formvalue = ids[0] else: formvalue = '' args = [] extra = {} qssqli = False sqlstate = libinjection.sqli_state() allfp = {} for name,values in self.request.arguments.iteritems(): if name == 'type': continue fps = [] val = values[0] val = urllib.unquote(val) if len(val) == 0: continue libinjection.sqli_init(sqlstate, val, 0) pat = libinjection.sqli_fingerprint(sqlstate, libinjection.FLAG_QUOTE_NONE | libinjection.FLAG_SQL_ANSI) issqli = bool(libinjection.sqli_blacklist(sqlstate)) fps.append(['unquoted', 'ansi', issqli, pat]) pat = libinjection.sqli_fingerprint(sqlstate, libinjection.FLAG_QUOTE_NONE | libinjection.FLAG_SQL_MYSQL) issqli = bool(libinjection.sqli_blacklist(sqlstate)) fps.append(['unquoted', 'mysql', issqli, pat]) pat =libinjection.sqli_fingerprint(sqlstate, libinjection.FLAG_QUOTE_SINGLE | libinjection.FLAG_SQL_ANSI) issqli = bool(libinjection.sqli_blacklist(sqlstate)) fps.append(['single', 'ansi', issqli, pat]) pat = libinjection.sqli_fingerprint(sqlstate, libinjection.FLAG_QUOTE_SINGLE | libinjection.FLAG_SQL_MYSQL) issqli = bool(libinjection.sqli_blacklist(sqlstate)) fps.append(['single', 'mysql', issqli, pat]) pat = libinjection.sqli_fingerprint(sqlstate, libinjection.FLAG_QUOTE_DOUBLE | libinjection.FLAG_SQL_MYSQL) issqli = bool(libinjection.sqli_blacklist(sqlstate)) fps.append(['double', 'mysql', issqli, pat]) allfp[name] = { 'value': breakify(breakapart(val)), 'fingerprints': fps } for name,values in self.request.arguments.iteritems(): if name == 'type': continue for val in values: # do it one more time include cut-n-paste was already url-encoded val = urllib.unquote(val) if len(val) == 0: continue # swig returns 1/0, convert to True False libinjection.sqli_init(sqlstate, val, 0) issqli = bool(libinjection.is_sqli(sqlstate)) # True if any issqli values are true qssqli = qssqli or issqli val = breakapart(val) pat = sqlstate.fingerprint if not issqli: pat = 'see below' args.append([name, val, issqli, pat]) self.render("form.html", title='libjection sqli diagnositc', version = libinjection.LIBINJECTION_VERSION, is_sqli=qssqli, args=args, allfp = allfp, formvalue=formvalue )
def get_fingerprints(self): #unquote = urllib.unquote #detectsqli = libinjection.detectsqli ids = self.request.arguments.get('id', []) if len(ids) == 1: formvalue = ids[0] else: formvalue = '' args = [] extra = {} qssqli = False sqlstate = libinjection.sqli_state() allfp = {} for name,values in self.request.arguments.iteritems(): if name == 'type': continue fps = [] val = values[0] val = urllib.unquote(val) if len(val) == 0: continue libinjection.sqli_init(sqlstate, val, 0) pat = libinjection.sqli_fingerprint(sqlstate, libinjection.FLAG_QUOTE_NONE | libinjection.FLAG_SQL_ANSI) issqli = bool(libinjection.sqli_blacklist(sqlstate) and libinjection.sqli_not_whitelist(sqlstate)) fps.append(['unquoted', 'ansi', issqli, pat]) pat = libinjection.sqli_fingerprint(sqlstate, libinjection.FLAG_QUOTE_NONE | libinjection.FLAG_SQL_MYSQL) issqli = bool(libinjection.sqli_blacklist(sqlstate) and libinjection.sqli_not_whitelist(sqlstate)) fps.append(['unquoted', 'mysql', issqli, pat]) pat = libinjection.sqli_fingerprint(sqlstate, libinjection.FLAG_QUOTE_SINGLE | libinjection.FLAG_SQL_ANSI) issqli = bool(libinjection.sqli_blacklist(sqlstate) and libinjection.sqli_not_whitelist(sqlstate)) fps.append(['single', 'ansi', issqli, pat]) pat = libinjection.sqli_fingerprint(sqlstate, libinjection.FLAG_QUOTE_SINGLE | libinjection.FLAG_SQL_MYSQL) issqli = bool(libinjection.sqli_blacklist(sqlstate) and libinjection.sqli_not_whitelist(sqlstate)) fps.append(['single', 'mysql', issqli, pat]) pat = libinjection.sqli_fingerprint(sqlstate, libinjection.FLAG_QUOTE_DOUBLE | libinjection.FLAG_SQL_MYSQL) issqli = bool(libinjection.sqli_blacklist(sqlstate) and libinjection.sqli_not_whitelist(sqlstate)) fps.append(['double', 'mysql', issqli, pat]) allfp[name] = { 'value': breakify(breakapart(val)), 'fingerprints': fps } for name,values in self.request.arguments.iteritems(): if name == 'type': continue for val in values: # do it one more time include cut-n-paste was already url-encoded val = urllib.unquote(val) if len(val) == 0: continue # swig returns 1/0, convert to True False libinjection.sqli_init(sqlstate, val, 0) issqli = bool(libinjection.is_sqli(sqlstate)) # True if any issqli values are true qssqli = qssqli or issqli val = breakapart(val) pat = sqlstate.fingerprint if not issqli: pat = 'see below' args.append([name, val, issqli, pat]) self.add_header('Cache-Control', 'no-cache, no-store, must-revalidate') self.add_header('Pragma', 'no-cache') self.add_header('Expires', '0') self.add_header('X-Content-Type-Options', 'nosniff') self.add_header('X-XSS-Protection', '0') self.render("form.html", title='libjection sqli diagnostic', version = libinjection.version(), is_sqli=qssqli, args=args, allfp = allfp, formvalue=formvalue, ssl_protocol=self.request.headers.get('X-SSL-Protocol', ''), ssl_cipher=self.request.headers.get('X-SSL-Cipher', '') )
# part one, normal decode target = urllib.unquote_plus(qs['id'][0]) # 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) targetutf8 = target.encode('utf-8') libinjection.sqli_init(sstate, targetutf8, 0) sqli = bool(libinjection.is_sqli(sstate)) return (target, sqli, sstate.fingerprint, data['remote_ip']) if __name__ == '__main__': 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) == 1: fname = '/var/log/apache2/access-json.log' else: fname = sys.argv[1]
# 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" "-"