mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2024-11-22 09:36:35 +03:00
Minor bug fixes to --os-shell (altought web backdoor functionality still to be reviewed).
Minor common library code refactoring. Code cleanup. Set back the default User-Agent to sqlmap for comparison algorithm reasons. Updated THANKS.
This commit is contained in:
parent
5121a4dcba
commit
16b4530bbe
|
@ -27,6 +27,9 @@ Pierre Chifflier <pollux@debian.org>
|
|||
for uploading the sqlmap 0.6.2 Debian package to the official Debian
|
||||
project repository
|
||||
|
||||
Ulises U. Cune <ulises2k@gmail.com>
|
||||
for reporting a bug
|
||||
|
||||
Stefano Di Paola <stefano.dipaola@wisec.it>
|
||||
for suggesting good features
|
||||
|
||||
|
@ -80,6 +83,9 @@ Anant Kochhar <anant.kochhar@secureyes.net>
|
|||
Alexander Kornbrust <ak@red-database-security.com>
|
||||
for reporting a couple of bugs
|
||||
|
||||
Nicolas Krassas <krasn@ans.gr>
|
||||
for reporting a bug
|
||||
|
||||
Guido Landi <lists@keamera.org>
|
||||
for the great technical discussions
|
||||
for Microsoft SQL Server 2000 and Microsoft SQL Server 2005
|
||||
|
|
|
@ -64,7 +64,7 @@ class Magic:
|
|||
try:
|
||||
magic_close(self.cookie)
|
||||
except Exception, e:
|
||||
print "got thig: ", e
|
||||
print "got this:", e
|
||||
|
||||
|
||||
_magic_mime = None
|
||||
|
|
|
@ -27,7 +27,6 @@ Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
import re
|
||||
import time
|
||||
|
||||
from lib.controller.action import action
|
||||
from lib.core.agent import agent
|
||||
from lib.core.common import randomInt
|
||||
from lib.core.common import randomStr
|
||||
|
@ -295,9 +294,9 @@ def checkStability():
|
|||
infoMsg = "testing if the url is stable, wait a few seconds"
|
||||
logger.info(infoMsg)
|
||||
|
||||
firstPage, firstHeaders = Request.queryPage(content=True)
|
||||
firstPage, _ = Request.queryPage(content=True)
|
||||
time.sleep(1)
|
||||
secondPage, secondHeaders = Request.queryPage(content=True)
|
||||
secondPage, _ = Request.queryPage(content=True)
|
||||
|
||||
condition = firstPage == secondPage
|
||||
|
||||
|
|
|
@ -36,7 +36,6 @@ from lib.core.common import readInput
|
|||
from lib.core.data import conf
|
||||
from lib.core.data import kb
|
||||
from lib.core.data import logger
|
||||
from lib.core.exception import sqlmapConnectionException
|
||||
from lib.core.exception import sqlmapNotVulnerableException
|
||||
from lib.core.session import setInjection
|
||||
from lib.core.target import createTargetDirs
|
||||
|
@ -105,7 +104,6 @@ def start():
|
|||
logger.info(infoMsg)
|
||||
|
||||
hostCount = 0
|
||||
receivedCookies = []
|
||||
cookieStr = ""
|
||||
setCookieAsInjectable = True
|
||||
|
||||
|
|
|
@ -33,7 +33,6 @@ from lib.core.data import kb
|
|||
from lib.core.data import queries
|
||||
from lib.core.data import temp
|
||||
from lib.core.exception import sqlmapNoneDataException
|
||||
from lib.core.exception import sqlmapUnsupportedDBMSException
|
||||
|
||||
|
||||
class Agent:
|
||||
|
|
|
@ -141,9 +141,9 @@ def formatDBMSfp(versions=None):
|
|||
|
||||
|
||||
def formatFingerprintString(values, chain=" or "):
|
||||
string = "|".join([v for v in values])
|
||||
strJoin = "|".join([v for v in values])
|
||||
|
||||
return string.replace("|", chain)
|
||||
return strJoin.replace("|", chain)
|
||||
|
||||
|
||||
def formatFingerprint(target, info):
|
||||
|
@ -224,73 +224,91 @@ def getHtmlErrorFp():
|
|||
|
||||
|
||||
def getDocRoot():
|
||||
"""
|
||||
This method returns the web application document root based on the
|
||||
detected absolute files paths in the knowledge base.
|
||||
"""
|
||||
|
||||
docRoot = None
|
||||
|
||||
if kb.absFilePaths:
|
||||
logMsg = "retrieved the possible injectable "
|
||||
logMsg += "file absolute system paths: "
|
||||
logMsg += "'%s'" % ", ".join(path for path in kb.absFilePaths)
|
||||
logger.info(logMsg)
|
||||
if kb.os == "Windows":
|
||||
defaultDocRoot = "C:\\Inetput\\wwwroot\\"
|
||||
else:
|
||||
warnMsg = "unable to retrieve the injectable file "
|
||||
warnMsg += "absolute system path"
|
||||
logger.warn(warnMsg)
|
||||
defaultDocRoot = "/var/www/"
|
||||
|
||||
if kb.absFilePaths:
|
||||
for absFilePath in kb.absFilePaths:
|
||||
if conf.path in absFilePath:
|
||||
absFilePathWin = None
|
||||
|
||||
if re.search("([\w]\:[\/\\\\]+)", absFilePath):
|
||||
absFilePathWin = absFilePath
|
||||
absFilePath = absFilePath[2:].replace("\\", "/")
|
||||
|
||||
absFilePath = os.path.normpath(absFilePath)
|
||||
|
||||
if os.path.dirname(conf.path) in absFilePath:
|
||||
index = absFilePath.index(conf.path)
|
||||
docRoot = absFilePath[:index]
|
||||
|
||||
if absFilePathWin:
|
||||
docRoot = "C:\\%s" % docRoot.replace("/", "\\")
|
||||
|
||||
break
|
||||
|
||||
if docRoot:
|
||||
logMsg = "retrieved the remote web server "
|
||||
logMsg += "document root: '%s'" % docRoot
|
||||
logger.info(logMsg)
|
||||
infoMsg = "retrieved the web server document root: '%s'" % docRoot
|
||||
logger.info(infoMsg)
|
||||
else:
|
||||
warnMsg = "unable to retrieve the remote web server "
|
||||
warnMsg += "document root"
|
||||
warnMsg = "unable to retrieve the web server document root"
|
||||
logger.warn(warnMsg)
|
||||
|
||||
message = "please provide the web server document root "
|
||||
message += "[%s]: " % defaultDocRoot
|
||||
inputDocRoot = readInput(message, default=defaultDocRoot)
|
||||
|
||||
if inputDocRoot:
|
||||
docRoot = inputDocRoot
|
||||
else:
|
||||
docRoot = defaultDocRoot
|
||||
|
||||
return docRoot
|
||||
|
||||
|
||||
def getDirectories():
|
||||
"""
|
||||
This method calls a function that returns the web application document
|
||||
root and injectable file absolute system path.
|
||||
|
||||
@return: a set of paths (document root and absolute system path).
|
||||
@rtype: C{set}
|
||||
@todo: replace this function with a site crawling functionality.
|
||||
"""
|
||||
|
||||
def getDirs():
|
||||
directories = set()
|
||||
|
||||
kb.docRoot = getDocRoot()
|
||||
if kb.os == "Windows":
|
||||
defaultDir = "C:\\Inetput\\wwwroot\\test\\"
|
||||
else:
|
||||
defaultDir = "/var/www/test/"
|
||||
|
||||
if kb.docRoot:
|
||||
directories.add(kb.docRoot)
|
||||
if kb.absFilePaths:
|
||||
infoMsg = "retrieved web server full paths: "
|
||||
infoMsg += "'%s'" % ", ".join(path for path in kb.absFilePaths)
|
||||
logger.info(infoMsg)
|
||||
|
||||
pagePath = re.search("^/(.*)/", conf.path)
|
||||
for absFilePath in kb.absFilePaths:
|
||||
directories.add(os.path.dirname(absFilePath))
|
||||
else:
|
||||
warnMsg = "unable to retrieve any web server path"
|
||||
logger.warn(warnMsg)
|
||||
|
||||
if kb.docRoot and pagePath:
|
||||
pagePath = pagePath.groups()[0]
|
||||
message = "please provide any additional web server full path to try "
|
||||
message += "to upload the agent [%s]: " % defaultDir
|
||||
inputDirs = readInput(message, default=defaultDir)
|
||||
|
||||
directories.add("%s/%s" % (kb.docRoot, pagePath))
|
||||
if inputDirs:
|
||||
inputDirs = inputDirs.replace(", ", ",")
|
||||
inputDirs = inputDirs.split(",")
|
||||
|
||||
for inputDir in inputDirs:
|
||||
directories.add(inputDir)
|
||||
else:
|
||||
directories.add(defaultDir)
|
||||
|
||||
return directories
|
||||
|
||||
|
||||
def filePathToString(filePath):
|
||||
string = filePath.replace("/", "_").replace("\\", "_")
|
||||
string = string.replace(" ", "_").replace(":", "_")
|
||||
strRepl = filePath.replace("/", "_").replace("\\", "_")
|
||||
strRepl = strRepl.replace(" ", "_").replace(":", "_")
|
||||
|
||||
return string
|
||||
return strRepl
|
||||
|
||||
|
||||
def dataToStdout(data):
|
||||
|
@ -326,18 +344,18 @@ def dataToOutFile(data):
|
|||
return rFilePath
|
||||
|
||||
|
||||
def strToHex(string):
|
||||
def strToHex(inpStr):
|
||||
"""
|
||||
@param string: string to be converted into its hexadecimal value.
|
||||
@type string: C{str}
|
||||
@param inpStr: inpStr to be converted into its hexadecimal value.
|
||||
@type inpStr: C{str}
|
||||
|
||||
@return: the hexadecimal converted string.
|
||||
@return: the hexadecimal converted inpStr.
|
||||
@rtype: C{str}
|
||||
"""
|
||||
|
||||
hexStr = ""
|
||||
|
||||
for character in string:
|
||||
for character in inpStr:
|
||||
if character == "\n":
|
||||
character = " "
|
||||
|
||||
|
@ -457,17 +475,17 @@ def randomStr(length=5, lowercase=False):
|
|||
return rndStr
|
||||
|
||||
|
||||
def sanitizeStr(string):
|
||||
def sanitizeStr(inpStr):
|
||||
"""
|
||||
@param string: string to sanitize: cast to str datatype and replace
|
||||
@param inpStr: inpStr to sanitize: cast to str datatype and replace
|
||||
newlines with one space and strip carriage returns.
|
||||
@type string: C{str}
|
||||
@type inpStr: C{str}
|
||||
|
||||
@return: sanitized string
|
||||
@return: sanitized inpStr
|
||||
@rtype: C{str}
|
||||
"""
|
||||
|
||||
cleanString = str(string)
|
||||
cleanString = str(inpStr)
|
||||
cleanString = cleanString.replace("\n", " ").replace("\r", "")
|
||||
|
||||
return cleanString
|
||||
|
@ -483,8 +501,8 @@ def checkFile(filename):
|
|||
raise sqlmapFilePathException, "unable to read file '%s'" % filename
|
||||
|
||||
|
||||
def replaceNewlineTabs(string):
|
||||
replacedString = string.replace("\n", "__NEWLINE__").replace("\t", "__TAB__")
|
||||
def replaceNewlineTabs(inpStr):
|
||||
replacedString = inpStr.replace("\n", "__NEWLINE__").replace("\t", "__TAB__")
|
||||
replacedString = replacedString.replace(temp.delimiter, "__DEL__")
|
||||
|
||||
return replacedString
|
||||
|
|
|
@ -23,13 +23,8 @@ Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
"""
|
||||
|
||||
|
||||
try:
|
||||
from hashlib import md5
|
||||
from hashlib import sha
|
||||
except ImportError, _:
|
||||
import md5
|
||||
import sha
|
||||
|
||||
import md5
|
||||
import sha
|
||||
import struct
|
||||
import urllib
|
||||
|
||||
|
|
|
@ -24,8 +24,6 @@ Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
|
||||
|
||||
|
||||
import sys
|
||||
|
||||
from lib.core.settings import PLATFORM
|
||||
from lib.core.settings import PYVERSION
|
||||
from lib.core.settings import VERSION
|
||||
|
|
|
@ -31,8 +31,6 @@ import logging
|
|||
import os
|
||||
import re
|
||||
import socket
|
||||
import sys
|
||||
import time
|
||||
import urllib2
|
||||
import urlparse
|
||||
|
||||
|
@ -42,8 +40,6 @@ from lib.core.common import getFileType
|
|||
from lib.core.common import parseTargetUrl
|
||||
from lib.core.common import paths
|
||||
from lib.core.common import randomRange
|
||||
from lib.core.common import randomStr
|
||||
from lib.core.common import readInput
|
||||
from lib.core.common import sanitizeStr
|
||||
from lib.core.data import conf
|
||||
from lib.core.data import kb
|
||||
|
@ -60,8 +56,10 @@ from lib.core.optiondict import optDict
|
|||
from lib.core.settings import MSSQL_ALIASES
|
||||
from lib.core.settings import MYSQL_ALIASES
|
||||
from lib.core.settings import PLATFORM
|
||||
from lib.core.settings import SITE
|
||||
from lib.core.settings import SUPPORTED_DBMS
|
||||
from lib.core.settings import SUPPORTED_OS
|
||||
from lib.core.settings import VERSION_STRING
|
||||
from lib.core.update import update
|
||||
from lib.parse.configfile import configFileParser
|
||||
from lib.parse.queriesfile import queriesParser
|
||||
|
@ -600,9 +598,14 @@ def __defaultHTTPUserAgent():
|
|||
@rtype: C{str}
|
||||
"""
|
||||
|
||||
return "%s (%s)" % (VERSION_STRING, SITE)
|
||||
|
||||
# Firefox 3 running on Ubuntu 9.04 updated at April 2009
|
||||
#return "Mozilla/5.0 (X11; U; Linux i686; en-GB; rv:1.9.0.9) Gecko/2009042113 Ubuntu/9.04 (jaunty) Firefox/3.0.9"
|
||||
|
||||
# Internet Explorer 7.0 running on Windows 2003 Service Pack 2 english
|
||||
# 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():
|
||||
|
|
|
@ -25,7 +25,6 @@ Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
|
||||
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
||||
|
|
|
@ -73,8 +73,8 @@ class CompleterNG(rlcompleter.Completer):
|
|||
matches = []
|
||||
n = len(text)
|
||||
|
||||
for list in [ self.namespace ]:
|
||||
for word in list:
|
||||
for ns in [ self.namespace ]:
|
||||
for word in ns:
|
||||
if word[:n] == text:
|
||||
matches.append(word)
|
||||
|
||||
|
|
|
@ -25,17 +25,14 @@ Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
|
||||
|
||||
import os
|
||||
import re
|
||||
import time
|
||||
|
||||
from lib.core.common import dataToSessionFile
|
||||
from lib.core.common import paramToDict
|
||||
from lib.core.common import parseTargetUrl
|
||||
from lib.core.common import readInput
|
||||
from lib.core.convert import urldecode
|
||||
from lib.core.data import conf
|
||||
from lib.core.data import kb
|
||||
from lib.core.data import logger
|
||||
from lib.core.data import paths
|
||||
from lib.core.dump import dumper
|
||||
from lib.core.exception import sqlmapFilePathException
|
||||
|
|
|
@ -205,7 +205,7 @@ def __createFile(pathname, data):
|
|||
fileFP.close()
|
||||
|
||||
|
||||
def __extractZipFile(tempDir, zipFile, sqlmapNewestVersion):
|
||||
def __extractZipFile(tempDir, zipFile):
|
||||
# Check if the saved binary file is really a ZIP file
|
||||
if zipfile.is_zipfile(zipFile):
|
||||
sqlmapZipFile = zipfile.ZipFile(zipFile)
|
||||
|
@ -285,13 +285,13 @@ def __updateSqlmap():
|
|||
tempDir = tempfile.gettempdir()
|
||||
zipFile = os.path.join(tempDir, "sqlmap-%s.zip" % sqlmapNewestVersion)
|
||||
__createFile(zipFile, sqlmapBinaryString)
|
||||
__extractZipFile(tempDir, zipFile, sqlmapNewestVersion)
|
||||
__extractZipFile(tempDir, zipFile)
|
||||
|
||||
# For each file and directory in the temporary directory copy it
|
||||
# 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, dirs, 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
|
||||
if '.svn' in root:
|
||||
continue
|
||||
|
|
|
@ -29,7 +29,6 @@ import re
|
|||
from xml.sax.handler import ContentHandler
|
||||
|
||||
from lib.core.common import sanitizeStr
|
||||
from lib.core.data import kb
|
||||
|
||||
|
||||
class FingerprintHandler(ContentHandler):
|
||||
|
|
|
@ -24,8 +24,6 @@ Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
|
||||
|
||||
|
||||
import re
|
||||
|
||||
from xml.sax import parse
|
||||
|
||||
from lib.core.common import checkFile
|
||||
|
|
|
@ -28,7 +28,6 @@ import re
|
|||
|
||||
from lib.core.data import conf
|
||||
from lib.core.data import kb
|
||||
from lib.core.data import paths
|
||||
from lib.parse.headers import headersParser
|
||||
from lib.parse.html import htmlParser
|
||||
|
||||
|
@ -73,7 +72,10 @@ def parseResponse(page, headers):
|
|||
# Detect injectable page absolute system path
|
||||
# NOTE: this regular expression works if the remote web application
|
||||
# is written in PHP and debug/error messages are enabled.
|
||||
absFilePaths = re.findall(" in <b>(.*?)</b> on line", page, re.I)
|
||||
absFilePathsRegExp = ( " in <b>(.*?)</b> on line", "([\w]\:[\/\\\\]+)" )
|
||||
|
||||
for absFilePathRegExp in absFilePathsRegExp:
|
||||
absFilePaths = re.findall(absFilePathRegExp, page, re.I)
|
||||
|
||||
for absFilePath in absFilePaths:
|
||||
if absFilePath not in kb.absFilePaths:
|
||||
|
|
|
@ -26,7 +26,6 @@ Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
|
||||
import re
|
||||
|
||||
from lib.core.convert import md5hash
|
||||
from lib.core.data import conf
|
||||
from lib.core.data import logger
|
||||
from lib.core.session import setMatchRatio
|
||||
|
|
|
@ -33,7 +33,6 @@ from lib.core.common import dataToSessionFile
|
|||
from lib.core.common import expandAsteriskForColumns
|
||||
from lib.core.common import parseUnionPage
|
||||
from lib.core.common import readInput
|
||||
from lib.core.common import replaceNewlineTabs
|
||||
from lib.core.data import conf
|
||||
from lib.core.data import kb
|
||||
from lib.core.data import logger
|
||||
|
|
|
@ -29,6 +29,7 @@ from lib.core.data import conf
|
|||
from lib.core.data import kb
|
||||
from lib.core.data import logger
|
||||
from lib.core.dump import dumper
|
||||
from lib.core.exception import sqlmapUnsupportedFeatureException
|
||||
from lib.core.shell import autoCompletion
|
||||
from lib.takeover.udf import UDF
|
||||
from lib.takeover.xp_cmdshell import xp_cmdshell
|
||||
|
|
|
@ -24,11 +24,6 @@ Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
|
||||
|
||||
|
||||
import os
|
||||
|
||||
from lib.core.common import randomStr
|
||||
from lib.core.common import readInput
|
||||
from lib.core.data import conf
|
||||
from lib.core.data import kb
|
||||
from lib.core.data import logger
|
||||
from lib.core.session import setDEP
|
||||
|
|
|
@ -135,14 +135,14 @@ class Metasploit:
|
|||
|
||||
def __skeletonSelection(self, msg, lst=None, maxValue=1, default=1):
|
||||
if kb.os == "Windows":
|
||||
os = "windows"
|
||||
opSys = "windows"
|
||||
else:
|
||||
os = "linux"
|
||||
opSys = "linux"
|
||||
|
||||
message = "which %s do you want to use?" % msg
|
||||
|
||||
if lst:
|
||||
for num, data in lst[os].items():
|
||||
for num, data in lst[opSys].items():
|
||||
description = data[0]
|
||||
|
||||
if num > maxValue:
|
||||
|
@ -174,7 +174,7 @@ class Metasploit:
|
|||
choice = int(choice)
|
||||
|
||||
if lst:
|
||||
choice = lst[os][choice][1]
|
||||
choice = lst[opSys][choice][1]
|
||||
|
||||
return choice
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@ Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
|
||||
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
|
||||
from subprocess import PIPE
|
||||
|
|
|
@ -177,6 +177,7 @@ def __unionTestByNULLBruteforce(comment):
|
|||
def __unionTestByOrderBy(comment):
|
||||
columns = None
|
||||
value = None
|
||||
prevPayload = ""
|
||||
|
||||
for count in range(1, 51):
|
||||
query = agent.prefixQuery(" ORDER BY %d" % count)
|
||||
|
|
|
@ -29,14 +29,11 @@ import time
|
|||
|
||||
from lib.core.agent import agent
|
||||
from lib.core.common import parseUnionPage
|
||||
from lib.core.common import readInput
|
||||
from lib.core.data import conf
|
||||
from lib.core.data import kb
|
||||
from lib.core.data import logger
|
||||
from lib.core.data import queries
|
||||
from lib.core.data import temp
|
||||
from lib.core.exception import sqlmapUnsupportedDBMSException
|
||||
from lib.core.session import setUnion
|
||||
from lib.core.unescaper import unescaper
|
||||
from lib.request.connect import Connect as Request
|
||||
from lib.techniques.inband.union.test import unionTest
|
||||
|
|
|
@ -32,7 +32,6 @@ from lib.core.convert import urlencode
|
|||
from lib.core.data import conf
|
||||
from lib.core.data import kb
|
||||
from lib.core.exception import sqlmapConnectionException
|
||||
from lib.core.exception import sqlmapRegExprException
|
||||
|
||||
|
||||
class Google:
|
||||
|
@ -84,9 +83,9 @@ class Google:
|
|||
|
||||
try:
|
||||
conn = self.opener.open("http://www.google.com/ncr")
|
||||
headers = conn.info()
|
||||
_ = conn.info()
|
||||
except urllib2.HTTPError, e:
|
||||
headers = e.info()
|
||||
_ = e.info()
|
||||
except urllib2.URLError, e:
|
||||
errMsg = "unable to connect to Google"
|
||||
raise sqlmapConnectionException, errMsg
|
||||
|
|
|
@ -28,15 +28,11 @@ import os
|
|||
import time
|
||||
|
||||
from lib.core.agent import agent
|
||||
from lib.core.common import dataToOutFile
|
||||
from lib.core.common import dataToStdout
|
||||
from lib.core.common import formatDBMSfp
|
||||
from lib.core.common import formatFingerprint
|
||||
from lib.core.common import getHtmlErrorFp
|
||||
from lib.core.common import getRange
|
||||
from lib.core.common import randomInt
|
||||
from lib.core.common import randomStr
|
||||
from lib.core.common import readInput
|
||||
from lib.core.convert import urlencode
|
||||
from lib.core.data import conf
|
||||
from lib.core.data import kb
|
||||
|
@ -48,11 +44,9 @@ from lib.core.exception import sqlmapUnsupportedFeatureException
|
|||
from lib.core.session import setDbms
|
||||
from lib.core.settings import MSSQL_ALIASES
|
||||
from lib.core.settings import MSSQL_SYSTEM_DBS
|
||||
from lib.core.shell import autoCompletion
|
||||
from lib.core.unescaper import unescaper
|
||||
from lib.request import inject
|
||||
from lib.request.connect import Connect as Request
|
||||
from lib.techniques.outband.stacked import stackedTest
|
||||
|
||||
from plugins.generic.enumeration import Enumeration
|
||||
from plugins.generic.filesystem import Filesystem
|
||||
|
@ -521,7 +515,7 @@ class MSSQLServerMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeov
|
|||
wFilePointer.close()
|
||||
|
||||
if wFileSize < debugSize:
|
||||
chunkName = self.updateBinChunk(wFileContent, dFile, tmpPath)
|
||||
chunkName = self.updateBinChunk(wFileContent, tmpPath)
|
||||
sFile = "%s\%s" % (tmpPath, dFileName)
|
||||
|
||||
logger.debug("moving binary file %s to %s" % (sFile, dFile))
|
||||
|
|
|
@ -28,7 +28,6 @@ import os
|
|||
import re
|
||||
|
||||
from lib.core.agent import agent
|
||||
from lib.core.common import fileToStr
|
||||
from lib.core.common import formatDBMSfp
|
||||
from lib.core.common import formatFingerprint
|
||||
from lib.core.common import getHtmlErrorFp
|
||||
|
@ -49,7 +48,6 @@ from lib.request import inject
|
|||
from lib.request.connect import Connect as Request
|
||||
from lib.techniques.inband.union.test import unionTest
|
||||
from lib.techniques.inband.union.use import unionUse
|
||||
from lib.techniques.outband.stacked import stackedTest
|
||||
|
||||
from plugins.generic.enumeration import Enumeration
|
||||
from plugins.generic.filesystem import Filesystem
|
||||
|
|
|
@ -34,6 +34,7 @@ from lib.core.data import conf
|
|||
from lib.core.data import kb
|
||||
from lib.core.data import logger
|
||||
from lib.core.exception import sqlmapSyntaxException
|
||||
from lib.core.exception import sqlmapUnsupportedFeatureException
|
||||
from lib.core.session import setDbms
|
||||
from lib.core.settings import ORACLE_ALIASES
|
||||
from lib.core.settings import ORACLE_SYSTEM_DBS
|
||||
|
|
|
@ -48,7 +48,6 @@ from lib.core.settings import PGSQL_SYSTEM_DBS
|
|||
from lib.core.unescaper import unescaper
|
||||
from lib.request import inject
|
||||
from lib.request.connect import Connect as Request
|
||||
from lib.techniques.outband.stacked import stackedTest
|
||||
|
||||
from plugins.generic.enumeration import Enumeration
|
||||
from plugins.generic.filesystem import Filesystem
|
||||
|
@ -302,8 +301,6 @@ class PostgreSQLMap(Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeove
|
|||
|
||||
|
||||
def stackedReadFile(self, rFile):
|
||||
# TODO: write a UDF to retrieve the hexadecimal encoded content of
|
||||
# the requested file
|
||||
warnMsg = "binary file read on PostgreSQL is not yet supported, "
|
||||
warnMsg += "if the requested file is binary, its content will not "
|
||||
warnMsg += "be retrieved"
|
||||
|
|
|
@ -39,7 +39,6 @@ from lib.core.data import temp
|
|||
from lib.core.dump import dumper
|
||||
from lib.core.exception import sqlmapMissingMandatoryOptionException
|
||||
from lib.core.exception import sqlmapNoneDataException
|
||||
from lib.core.exception import sqlmapUndefinedMethod
|
||||
from lib.core.exception import sqlmapUnsupportedFeatureException
|
||||
from lib.core.session import setOs
|
||||
from lib.core.settings import SQL_STATEMENTS
|
||||
|
@ -47,7 +46,6 @@ from lib.core.shell import autoCompletion
|
|||
from lib.core.unescaper import unescaper
|
||||
from lib.parse.banner import bannerParser
|
||||
from lib.request import inject
|
||||
from lib.request.connect import Connect as Request
|
||||
from lib.techniques.inband.union.test import unionTest
|
||||
from lib.techniques.outband.stacked import stackedTest
|
||||
|
||||
|
@ -1098,7 +1096,6 @@ class Enumeration:
|
|||
|
||||
def sqlQuery(self, query):
|
||||
output = None
|
||||
selectQuery = True
|
||||
sqlType = None
|
||||
|
||||
query = urlencode(query, convall=True)
|
||||
|
@ -1108,9 +1105,6 @@ class Enumeration:
|
|||
if query.lower().startswith(sqlStatement):
|
||||
sqlType = sqlTitle
|
||||
|
||||
if sqlTitle != "SQL SELECT statement":
|
||||
selectQuery = False
|
||||
|
||||
break
|
||||
|
||||
message = "do you want to retrieve the SQL statement output? "
|
||||
|
|
|
@ -31,10 +31,8 @@ from lib.core.agent import agent
|
|||
from lib.core.common import dataToOutFile
|
||||
from lib.core.common import randomStr
|
||||
from lib.core.common import readInput
|
||||
from lib.core.data import conf
|
||||
from lib.core.data import kb
|
||||
from lib.core.data import logger
|
||||
from lib.core.exception import sqlmapUnsupportedFeatureException
|
||||
from lib.request import inject
|
||||
from lib.techniques.outband.stacked import stackedTest
|
||||
|
||||
|
@ -215,7 +213,7 @@ class Filesystem:
|
|||
return fcEncodedList
|
||||
|
||||
|
||||
def updateBinChunk(self, binaryData, dFile, tmpPath):
|
||||
def updateBinChunk(self, binaryData, tmpPath):
|
||||
"""
|
||||
Called by Microsoft SQL Server plugin to write a binary file on the
|
||||
back-end DBMS underlying file system
|
||||
|
|
|
@ -33,7 +33,7 @@ class Fingerprint:
|
|||
"""
|
||||
|
||||
@staticmethod
|
||||
def unescape(expression):
|
||||
def unescape(expression, quote=True):
|
||||
errMsg = "'unescape' method must be defined "
|
||||
errMsg += "into the specific DBMS plugin"
|
||||
raise sqlmapUndefinedMethod, errMsg
|
||||
|
|
|
@ -24,12 +24,15 @@ Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
|
||||
|
||||
|
||||
import os
|
||||
import re
|
||||
|
||||
from lib.core.common import getDirectories
|
||||
from lib.core.agent import agent
|
||||
from lib.core.common import fileToStr
|
||||
from lib.core.common import getDirs
|
||||
from lib.core.common import getDocRoot
|
||||
from lib.core.common import randomStr
|
||||
from lib.core.common import readInput
|
||||
from lib.core.convert import urlencode
|
||||
from lib.core.data import conf
|
||||
from lib.core.data import kb
|
||||
from lib.core.data import logger
|
||||
|
@ -59,13 +62,12 @@ class Takeover(Abstraction, DEP, Metasploit, Registry):
|
|||
|
||||
|
||||
def __webBackdoorRunCmd(self, backdoorUrl, cmd):
|
||||
"""
|
||||
TODO: complete review of this code is needed
|
||||
"""
|
||||
|
||||
output = None
|
||||
|
||||
cmdUrl = "%s?cmd=%s" % (backdoorUrl, conf.osCmd)
|
||||
if not cmd:
|
||||
cmd = conf.osCmd
|
||||
|
||||
cmdUrl = "%s?cmd=%s" % (backdoorUrl, cmd)
|
||||
page, _ = Request.getPage(url=cmdUrl, direct=True)
|
||||
output = re.search("<pre>(.+?)</pre>", page, re.I | re.S)
|
||||
|
||||
|
@ -79,8 +81,6 @@ class Takeover(Abstraction, DEP, Metasploit, Registry):
|
|||
|
||||
def __webBackdoorOsShell(self):
|
||||
"""
|
||||
TODO: complete review of this code is needed
|
||||
|
||||
This method is used to write a PHP agent (cmd.php) on a writable
|
||||
remote directory within the web server document root.
|
||||
Such agent is written using the INTO OUTFILE MySQL DBMS
|
||||
|
@ -95,42 +95,10 @@ class Takeover(Abstraction, DEP, Metasploit, Registry):
|
|||
ASP, JSP, CGI (Python, Perl, Ruby, Bash).
|
||||
"""
|
||||
|
||||
infoMsg = "retrieving web application directories"
|
||||
logger.info(infoMsg)
|
||||
self.checkDbmsOs()
|
||||
|
||||
directories = getDirectories()
|
||||
|
||||
if directories:
|
||||
infoMsg = "retrieved web server directories "
|
||||
infoMsg += "'%s'" % ", ".join(d for d in directories)
|
||||
logger.info(infoMsg)
|
||||
|
||||
message = "in addition you can provide a list of directories "
|
||||
message += "absolute path comma separated that you want sqlmap "
|
||||
message += "to try to upload the agent [/var/www/test]: "
|
||||
inputDirs = readInput(message, default="/var/www/test")
|
||||
else:
|
||||
message = "please provide the web server document root [/var/www]: "
|
||||
inputDocRoot = readInput(message, default="/var/www")
|
||||
|
||||
if inputDocRoot:
|
||||
kb.docRoot = inputDocRoot
|
||||
else:
|
||||
kb.docRoot = "/var/www"
|
||||
|
||||
message = "please provide a list of directories absolute path "
|
||||
message += "comma separated that you want sqlmap to try to "
|
||||
message += "upload the agent [/var/www/test]: "
|
||||
inputDirs = readInput(message, default="/var/www/test")
|
||||
|
||||
if inputDirs:
|
||||
inputDirs = inputDirs.replace(", ", ",")
|
||||
inputDirs = inputDirs.split(",")
|
||||
|
||||
for inputDir in inputDirs:
|
||||
directories.add(inputDir)
|
||||
else:
|
||||
directories.add("/var/www/test")
|
||||
kb.docRoot = getDocRoot()
|
||||
directories = getDirs()
|
||||
|
||||
infoMsg = "trying to upload the uploader agent"
|
||||
logger.info(infoMsg)
|
||||
|
@ -139,18 +107,25 @@ class Takeover(Abstraction, DEP, Metasploit, Registry):
|
|||
directories.sort()
|
||||
uploaded = False
|
||||
|
||||
# TODO: backdoor and uploader extensions must be the same as of
|
||||
# the web application language in use
|
||||
backdoorName = "backdoor.php"
|
||||
backdoorPath = "%s/%s" % (paths.SQLMAP_SHELL_PATH, backdoorName)
|
||||
uploaderName = "uploader.php"
|
||||
uploaderStr = fileToStr("%s/%s" % (paths.SQLMAP_SHELL_PATH, uploaderName))
|
||||
|
||||
if kb.os == "Windows":
|
||||
sep = "\\\\"
|
||||
else:
|
||||
sep = "/"
|
||||
|
||||
for directory in directories:
|
||||
if uploaded:
|
||||
break
|
||||
|
||||
# Upload the uploader agent
|
||||
uploaderQuery = uploaderStr.replace("WRITABLE_DIR", directory)
|
||||
query = " LIMIT 1 INTO OUTFILE '%s/%s' " % (directory, uploaderName)
|
||||
query = " LIMIT 1 INTO DUMPFILE '%s%s%s' " % (directory, sep, uploaderName)
|
||||
query += "LINES TERMINATED BY '\\n%s\\n'--" % uploaderQuery
|
||||
|
||||
query = agent.prefixQuery(" %s" % query)
|
||||
|
@ -158,14 +133,13 @@ class Takeover(Abstraction, DEP, Metasploit, Registry):
|
|||
|
||||
payload = agent.payload(newValue=query)
|
||||
page = Request.queryPage(payload)
|
||||
|
||||
if kb.docRoot:
|
||||
requestDir = directory.replace(kb.docRoot, "")
|
||||
else:
|
||||
requestDir = directory
|
||||
requestDir = directory.replace(kb.docRoot, "/").replace("\\", "/")
|
||||
requestDir = os.path.normpath(requestDir)
|
||||
|
||||
baseUrl = "%s://%s:%d%s" % (conf.scheme, conf.hostname, conf.port, requestDir)
|
||||
uploaderUrl = "%s/%s" % (baseUrl, uploaderName)
|
||||
uploaderUrl = os.path.normpath(uploaderUrl)
|
||||
|
||||
page, _ = Request.getPage(url=uploaderUrl, direct=True)
|
||||
|
||||
if "sqlmap backdoor uploader" not in page:
|
||||
|
|
Loading…
Reference in New Issue
Block a user