Skip to content

Commit

Permalink
Make --live-test Metasploit integration cases work, added more test c…
Browse files Browse the repository at this point in the history
…ases for PostgreSQL and code refactoring (issue #312)
  • Loading branch information
bdamele committed Jan 14, 2013
1 parent 279f6cb commit 3e2c385
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 24 deletions.
24 changes: 13 additions & 11 deletions lib/core/testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import os
import re
import shutil
import StringIO
import sys
import tempfile
import time
Expand Down Expand Up @@ -172,18 +171,20 @@ def liveTest():
logger.info("test passed")
cleanCase()
else:
errMsg = "test failed"
errMsg = "test failed "
if failedTraceBack:
errMsg += "(got a traceback)"
traceback_fd = codecs.open("%s%straceback" % (paths.SQLMAP_OUTPUT_PATH, os.sep), "wb", UNICODE_ENCODING)
traceback_fd.write(failedTraceBack)
traceback_fd.close()
if failedItem:
errMsg += " at parsing item: %s - scan folder is %s" % (failedItem, paths.SQLMAP_OUTPUT_PATH)
errMsg += "at parsing item: %s" % failedItem
if failedParseOn:
console_output_fd = codecs.open("%s%sconsole_output" % (paths.SQLMAP_OUTPUT_PATH, os.sep), "wb", UNICODE_ENCODING)
console_output_fd.write(failedParseOn)
console_output_fd.close()
elif failedTraceBack:
errMsg += ": got a traceback - scan folder is %s" % paths.SQLMAP_OUTPUT_PATH
traceback_fd = codecs.open("%s%straceback" % (paths.SQLMAP_OUTPUT_PATH, os.sep), "wb", UNICODE_ENCODING)
traceback_fd.write(failedTraceBack)
traceback_fd.close()

errMsg += " - scan folder is %s" % paths.SQLMAP_OUTPUT_PATH
logger.error(errMsg)
beep()

Expand Down Expand Up @@ -217,7 +218,6 @@ def initCase(switches=None):
logger.debug("using output directory '%s' for this test case" % paths.SQLMAP_OUTPUT_PATH)

cmdLineOptions = cmdLineParser()
cmdLineOptions.liveTest = cmdLineOptions.smokeTest = False

if switches:
for key, value in switches.items():
Expand All @@ -236,7 +236,7 @@ def runCase(switches=None, parse=None):

initCase(switches)

LOGGER_HANDLER.stream = sys.stdout = StringIO.StringIO()
LOGGER_HANDLER.stream = sys.stdout = tempfile.SpooledTemporaryFile(max_size=0, mode="w+b", prefix="sqlmapstdout-")
retVal = True
handled_exception = None
unhandled_exception = None
Expand Down Expand Up @@ -269,8 +269,9 @@ def runCase(switches=None, parse=None):
logger.error("the test did not run")
retVal = False

console = getUnicode(console, system=True)

if parse and retVal:
console = getUnicode(console, system=True)
with codecs.open(conf.dumper.getOutputFile(), "rb", UNICODE_ENCODING) as f:
content = f.read()

Expand All @@ -292,6 +293,7 @@ def runCase(switches=None, parse=None):
failedParseOn = console

elif retVal is False and tback is not None:
failedParseOn = console
failedTraceBack = tback

return retVal
Expand Down
12 changes: 12 additions & 0 deletions lib/takeover/metasploit.py
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,7 @@ def _loadMetExtensions(self, proc, metSess):

def _controlMsfCmd(self, proc, func):
stdin_fd = sys.stdin.fileno()
initiated_properly = False

while True:
returncode = proc.poll()
Expand Down Expand Up @@ -493,6 +494,14 @@ def _controlMsfCmd(self, proc, func):
out = recv_some(proc, t=.1, e=0)
blockingWriteToFD(sys.stdout.fileno(), out)

# Dirty hack to allow Metasploit integration to be tested
# in --live-test mode
if initiated_properly and conf.liveTest:
try:
send_all(proc, "exit\n")
except TypeError:
continue

# For --os-pwn and --os-bof
pwnBofCond = self.connectionStr.startswith("reverse")
pwnBofCond &= "Starting the payload handler" in out
Expand All @@ -509,6 +518,9 @@ def _controlMsfCmd(self, proc, func):
else:
send_all(proc, "uname -a ; id\n")

time.sleep(2)
initiated_properly = True

metSess = re.search("Meterpreter session ([\d]+) opened", out)

if metSess:
Expand Down
95 changes: 82 additions & 13 deletions xml/livetests.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1242,39 +1242,37 @@
<item value="r'SELECT \* FROM users ORDER BY name \[5\].+1, luther, blissett.+2, fluffy, bunny.+3, wu, ming'"/>
</parse>
</case>


<case name="PostgreSQL boolean-based multi-threaded custom SQL query enumeration">
<switches>
<url value="http://debiandev/sqlmap/pgsql/get_int.php?id=1"/>
<threads value="4"/>
<tech value="B"/>
<query value="SELECT * FROM users LIMIT 0, 2"/>
<query value="SELECT * FROM users OFFSET 0 LIMIT 2"/>
</switches>
<parse>
<item value="r'SELECT \* FROM users LIMIT 0, 2 \[2\].+1, luther, blissett.+2, fluffy, bunny'"/>
<item value="r'SELECT \* FROM users OFFSET 0 LIMIT 2 \[2\].+1, luther, blissett.+2, fluffy, bunny'"/>
</parse>
</case>
<case name="PostgreSQL error-based multi-threaded custom SQL query enumeration">
<switches>
<url value="http://debiandev/sqlmap/pgsql/get_int.php?id=1"/>
<threads value="4"/>
<tech value="E"/>
<query value="SELECT * FROM users LIMIT 0, 2"/>
<query value="SELECT * FROM users OFFSET 0 LIMIT 2"/>
</switches>
<parse>
<item value="r'SELECT \* FROM users LIMIT 0, 2 \[2\].+1, luther, blissett.+2, fluffy, bunny'"/>
<item value="r'SELECT \* FROM users OFFSET 0 LIMIT 2 \[2\].+1, luther, blissett.+2, fluffy, bunny'"/>
</parse>
</case>
<case name="PostgreSQL UNION query multi-threaded custom SQL query enumeration">
<switches>
<url value="http://debiandev/sqlmap/pgsql/get_int.php?id=1"/>
<threads value="4"/>
<tech value="U"/>
<query value="SELECT * FROM users LIMIT 0, 2"/>
<query value="SELECT * FROM users OFFSET 0 LIMIT 2"/>
</switches>
<parse>
<item value="r'SELECT \* FROM users LIMIT 0, 2 \[2\].+1, luther, blissett.+2, fluffy, bunny'"/>
<item value="r'SELECT \* FROM users OFFSET 0 LIMIT 2 \[2\].+1, luther, blissett.+2, fluffy, bunny'"/>
</parse>
</case>
<case name="PostgreSQL boolean-based multi-threaded custom ordered SQL query enumeration">
Expand Down Expand Up @@ -1360,6 +1358,56 @@
<item value="the remote file /tmp/passwd-${random} is larger than the local file /etc/passwd" console_output="True"/>
</parse>
</case>
<case name="PostgreSQL boolean-based multi-threaded file read">
<switches>
<url value="http://debiandev/sqlmap/pgsql/get_int.php?id=1"/>
<threads value="4"/>
<tech value="BS"/>
<timeSec value="2"/>
<rFile value="/etc/hosts,/tmp/invalidfile"/>
<answers value="do you want to overwrite it=Y"/>
</switches>
<parse>
<item value="r'files saved to.+files/_etc_hosts \(same file\)'"/>
</parse>
</case>
<case name="PostgreSQL error-based multi-threaded file read">
<switches>
<url value="http://debiandev/sqlmap/pgsql/get_int.php?id=1"/>
<threads value="4"/>
<tech value="ES"/>
<rFile value="/etc/hosts,/tmp/invalidfile"/>
<answers value="do you want to overwrite it=Y"/>
</switches>
<parse>
<item value="r'files saved to.+files/_etc_hosts \(same file\)'"/>
</parse>
</case>
<case name="PostgreSQL UNION query multi-threaded file read">
<switches>
<url value="http://debiandev/sqlmap/pgsql/get_int.php?id=1"/>
<threads value="4"/>
<tech value="US"/>
<rFile value="/etc/hosts,/tmp/invalidfile"/>
<answers value="do you want to overwrite it=Y"/>
</switches>
<parse>
<item value="r'files saved to.+files/_etc_hosts \(same file\)'"/>
</parse>
</case>
<case name="PostgreSQL multi-threaded file write">
<switches>
<verbose value="2"/>
<url value="http://debiandev/sqlmap/pgsql/get_int.php?id=1"/>
<threads value="4"/>
<wFile value="/etc/passwd"/>
<dFile value="/tmp/passwd-${random}"/>
<answers value="do you want to overwrite it=Y"/>
</switches>
<parse>
<item value="the local file /etc/passwd and the remote file /tmp/passwd-${random} have the same size" console_output="True"/>
</parse>
</case>
<!-- End of file system access switches -->

<!-- Operating system access switches -->
Expand All @@ -1374,20 +1422,41 @@
<item value="command standard output: 'uid="/>
</parse>
</case>
<!-- TODO: integration with Metasploit cannot be called yet from live testing
<case name="MySQL shell via Metasploit integration - command execution">
<switches>
<url value="http://debiandev/sqlmap/mysql/get_int.php?id=1"/>
<tech value="B"/>
<tech value="BU"/>
<osPwn value="True"/>
<msfPath value="/usr/local/bin/"/>
<answers value="please provide any additional web server=/var/www/test"/>
<answers value="please provide any additional web server=/var/www/test,do you want to overwrite it=Y"/>
</switches>
<parse>
<item value="r'Sending stage.+Linux.+uid=.+www-data'" console_output="True"/>
</parse>
</case>
<case name="PostgreSQL User-Defined Function (UDF) injection - command execution">
<switches>
<url value="http://debiandev/sqlmap/pgsql/get_int.php?id=1"/>
<tech value="US"/>
<osCmd value="id"/>
<answers value="do you want to overwrite it=Y"/>
</switches>
<parse>
<item value="command standard output: 'uid="/>
</parse>
</case>
<case name="PostgreSQL shell via Metasploit integration - command execution">
<switches>
<url value="http://debiandev/sqlmap/pgsql/get_int.php?id=1"/>
<tech value="US"/>
<osPwn value="True"/>
<msfPath value="/usr/local/bin/"/>
<answers value="do you want to overwrite it=Y"/>
</switches>
<parse>
<item value="r'Sending stage.+Command shell session.+Linux.+uid='"/>
<item value="r'Sending stage.+Linux.+uid=.+postgres'" console_output="True"/>
</parse>
</case>
-->
<!-- End of operating system access switches -->

<!-- Technique switches and corner cases -->
Expand Down

0 comments on commit 3e2c385

Please sign in to comment.