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

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

View File

@@ -54,11 +54,11 @@ class MultipartPostHandler(urllib2.BaseHandler):
v_files = []
v_vars = []
try:
for(key, value) in data.items():
if type(value) == file:
v_files.append((key, value))
else:
v_vars.append((key, value))
for(key, value) in data.items():
if type(value) == file:
v_files.append((key, value))
else:
v_vars.append((key, value))
except TypeError:
systype, value, traceback = sys.exc_info()
raise sqlmapDataException, "not a valid non-string sequence or mapping object", traceback

View File

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

View File

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

View File

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

View File

@@ -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/"
for absFilePath in kb.absFilePaths:
if conf.path in absFilePath:
index = absFilePath.index(conf.path)
docRoot = absFilePath[:index]
break
if kb.absFilePaths:
for absFilePath in kb.absFilePaths:
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

View File

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

View File

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

View File

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

View File

@@ -25,7 +25,6 @@ Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
import logging
import os
import sys

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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,8 +72,11 @@ 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 absFilePath in absFilePaths:
if absFilePath not in kb.absFilePaths:
kb.absFilePaths.add(absFilePath)
for absFilePathRegExp in absFilePathsRegExp:
absFilePaths = re.findall(absFilePathRegExp, page, re.I)
for absFilePath in absFilePaths:
if absFilePath not in kb.absFilePaths:
kb.absFilePaths.add(absFilePath)

View File

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

View File

@@ -93,11 +93,11 @@ class Connect:
requestMsg += "?%s" % params
elif multipart:
multipartOpener = urllib2.build_opener(multipartpost.MultipartPostHandler)
conn = multipartOpener.open(url, multipart)
page = conn.read()
multipartOpener = urllib2.build_opener(multipartpost.MultipartPostHandler)
conn = multipartOpener.open(url, multipart)
page = conn.read()
return page
return page
else:
if conf.parameters.has_key("GET") and not get:

View File

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

View File

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

View File

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

View File

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

View File

@@ -25,7 +25,6 @@ Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
import os
import sys
import time
from subprocess import PIPE

View File

@@ -175,8 +175,9 @@ def __unionTestByNULLBruteforce(comment):
def __unionTestByOrderBy(comment):
columns = None
value = None
columns = None
value = None
prevPayload = ""
for count in range(1, 51):
query = agent.prefixQuery(" ORDER BY %d" % count)

View File

@@ -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
@@ -202,7 +199,7 @@ def unionUse(expression, direct=False, unescape=True, resetCounter=False, nullCh
field = expressionFieldsList[0]
elif kb.dbms == "Oracle":
field = expressionFieldsList
field = expressionFieldsList
else:
field = None

View File

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