From 8e78057ac84a61451f4bf23b30d471f50973b8ee Mon Sep 17 00:00:00 2001
From: Bernardo Damele <bernardo.damele@gmail.com>
Date: Tue, 7 Dec 2010 12:33:47 +0000
Subject: [PATCH] Added counter of total HTTP(s) requests done during detection
 phase

---
 lib/controller/checks.py     | 35 +++++++++++++++++++++--------------
 lib/controller/controller.py |  3 ++-
 lib/core/option.py           |  1 +
 3 files changed, 24 insertions(+), 15 deletions(-)

diff --git a/lib/controller/checks.py b/lib/controller/checks.py
index b9b441293..5bc2bd572 100644
--- a/lib/controller/checks.py
+++ b/lib/controller/checks.py
@@ -269,6 +269,7 @@ def checkSqlInjection(place, parameter, value):
                     # as we are changing parameters value, which will result
                     # most definitely with a different content
                     kb.pageTemplate, _ = Request.queryPage(agent.payload(place, parameter, value, origValue), place, content=True)
+                    kb.testCount += 1
                 elif where == 3:
                     origValue = ""
                     kb.pageTemplate = kb.originalPage
@@ -306,12 +307,15 @@ def checkSqlInjection(place, parameter, value):
                         # the False response content
                         conf.matchRatio = None
                         _ = Request.queryPage(cmpPayload, place)
+                        kb.testCount += 1
 
                         # Compare True and False response contents
                         trueResult = Request.queryPage(reqPayload, place)
+                        kb.testCount += 1
 
                         if trueResult:
                             falseResult = Request.queryPage(cmpPayload, place)
+                            kb.testCount += 1
 
                             if not falseResult:
                                 infoMsg = "%s parameter '%s' is '%s' injectable " % (place, parameter, title)
@@ -320,13 +324,12 @@ def checkSqlInjection(place, parameter, value):
                                 kb.paramMatchRatio[(place, parameter)] = conf.matchRatio
                                 injectable = True
 
-                        kb.paramMatchRatio[(place, parameter)] = conf.matchRatio
-
                     # In case of error-based or UNION query SQL injections
                     elif method == PAYLOAD.METHOD.GREP:
                         # Perform the test's request and grep the response
                         # body for the test's <grep> regular expression
                         reqBody, _ = Request.queryPage(reqPayload, place, content=True)
+                        kb.testCount += 1
                         output = extractRegexResult(check, reqBody, re.DOTALL | re.IGNORECASE)
 
                         if output:
@@ -343,28 +346,32 @@ def checkSqlInjection(place, parameter, value):
                     elif method == PAYLOAD.METHOD.TIME:
                         # Store old value of socket timeout
                         pushValue(socket.getdefaulttimeout())
+
                         # Set socket timeout to 2 minutes as some
                         # time based checks can take awhile
                         socket.setdefaulttimeout(120)
+
                         # Perform the test's request and check how long
                         # it takes to get the response back
                         start = time.time()
+
                         _ = Request.queryPage(reqPayload, place)
+                        kb.testCount += 1
                         duration = calculateDeltaSeconds(start)
 
-                        if check.isdigit():
-                            if duration >= int(check):
-                                infoMsg = "%s parameter '%s' is '%s' injectable " % (place, parameter, title)
-                                logger.info(infoMsg)
+                        # Threat sleep and delayed (heavy query) differently
+                        if check.isdigit() and duration >= int(check):
+                            infoMsg = "%s parameter '%s' is '%s' injectable " % (place, parameter, title)
+                            logger.info(infoMsg)
 
-                                injectable = True
-                        elif check == "[DELAYED]":
-                            if duration >= max(TIME_MIN_DELTA, kb.responseTime):
-                                infoMsg = "%s parameter '%s' is '%s' injectable " % (place, parameter, title)
-                                logger.info(infoMsg)
+                            injectable = True
+                        elif check == "[DELAYED]" and duration >= max(TIME_MIN_DELTA, kb.responseTime):
+                            infoMsg = "%s parameter '%s' is '%s' injectable " % (place, parameter, title)
+                            logger.info(infoMsg)
 
-                                injectable = True
-                        # Restore old value of socket timeout
+                            injectable = True
+
+                        # Restore value of socket timeout
                         socket.setdefaulttimeout(popValue())
 
                 # If the injection test was successful feed the injection
@@ -398,7 +405,7 @@ def checkSqlInjection(place, parameter, value):
                     injection.data[stype].comment = comment
                     injection.data[stype].pageTemplate = kb.pageTemplate
 
-                    if "details" in test:
+                    if hasattr(test, "details"):
                         for detailKey, detailValue in test.details.items():
                             if detailKey == "dbms" and injection.dbms is None:
                                 injection.dbms = detailValue
diff --git a/lib/controller/controller.py b/lib/controller/controller.py
index 4517896ba..6e2e2c112 100644
--- a/lib/controller/controller.py
+++ b/lib/controller/controller.py
@@ -114,7 +114,8 @@ def __formatInjection(inj):
     return data
 
 def __showInjections():
-    header = "sqlmap identified the following injection points"
+    header = "sqlmap identified the following injection points "
+    header += "with %d HTTP(s) requests" % kb.testCount
     data = ""
 
     for inj in kb.injections:
diff --git a/lib/core/option.py b/lib/core/option.py
index 083923805..28820ff38 100644
--- a/lib/core/option.py
+++ b/lib/core/option.py
@@ -1186,6 +1186,7 @@ def __setKnowledgeBaseAttributes():
     kb.userAgents      = None
     kb.valueStack      = []
     kb.redirectSetCookie = None
+    kb.testCount       = 0
 
 def __saveCmdline():
     """