mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2024-11-26 11:33:47 +03:00
Make --live-test Metasploit integration cases work, added more test cases for PostgreSQL and code refactoring (issue #312)
This commit is contained in:
parent
279f6cb9ce
commit
3e2c3851f3
|
@ -10,7 +10,6 @@ import doctest
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import shutil
|
import shutil
|
||||||
import StringIO
|
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
import time
|
import time
|
||||||
|
@ -173,17 +172,19 @@ def liveTest():
|
||||||
cleanCase()
|
cleanCase()
|
||||||
else:
|
else:
|
||||||
errMsg = "test failed "
|
errMsg = "test failed "
|
||||||
if failedItem:
|
if failedTraceBack:
|
||||||
errMsg += " at parsing item: %s - scan folder is %s" % (failedItem, paths.SQLMAP_OUTPUT_PATH)
|
errMsg += "(got a traceback)"
|
||||||
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 = codecs.open("%s%straceback" % (paths.SQLMAP_OUTPUT_PATH, os.sep), "wb", UNICODE_ENCODING)
|
||||||
traceback_fd.write(failedTraceBack)
|
traceback_fd.write(failedTraceBack)
|
||||||
traceback_fd.close()
|
traceback_fd.close()
|
||||||
|
if failedItem:
|
||||||
|
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()
|
||||||
|
|
||||||
|
errMsg += " - scan folder is %s" % paths.SQLMAP_OUTPUT_PATH
|
||||||
logger.error(errMsg)
|
logger.error(errMsg)
|
||||||
beep()
|
beep()
|
||||||
|
|
||||||
|
@ -217,7 +218,6 @@ def initCase(switches=None):
|
||||||
logger.debug("using output directory '%s' for this test case" % paths.SQLMAP_OUTPUT_PATH)
|
logger.debug("using output directory '%s' for this test case" % paths.SQLMAP_OUTPUT_PATH)
|
||||||
|
|
||||||
cmdLineOptions = cmdLineParser()
|
cmdLineOptions = cmdLineParser()
|
||||||
cmdLineOptions.liveTest = cmdLineOptions.smokeTest = False
|
|
||||||
|
|
||||||
if switches:
|
if switches:
|
||||||
for key, value in switches.items():
|
for key, value in switches.items():
|
||||||
|
@ -236,7 +236,7 @@ def runCase(switches=None, parse=None):
|
||||||
|
|
||||||
initCase(switches)
|
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
|
retVal = True
|
||||||
handled_exception = None
|
handled_exception = None
|
||||||
unhandled_exception = None
|
unhandled_exception = None
|
||||||
|
@ -269,8 +269,9 @@ def runCase(switches=None, parse=None):
|
||||||
logger.error("the test did not run")
|
logger.error("the test did not run")
|
||||||
retVal = False
|
retVal = False
|
||||||
|
|
||||||
if parse and retVal:
|
|
||||||
console = getUnicode(console, system=True)
|
console = getUnicode(console, system=True)
|
||||||
|
|
||||||
|
if parse and retVal:
|
||||||
with codecs.open(conf.dumper.getOutputFile(), "rb", UNICODE_ENCODING) as f:
|
with codecs.open(conf.dumper.getOutputFile(), "rb", UNICODE_ENCODING) as f:
|
||||||
content = f.read()
|
content = f.read()
|
||||||
|
|
||||||
|
@ -292,6 +293,7 @@ def runCase(switches=None, parse=None):
|
||||||
failedParseOn = console
|
failedParseOn = console
|
||||||
|
|
||||||
elif retVal is False and tback is not None:
|
elif retVal is False and tback is not None:
|
||||||
|
failedParseOn = console
|
||||||
failedTraceBack = tback
|
failedTraceBack = tback
|
||||||
|
|
||||||
return retVal
|
return retVal
|
||||||
|
|
|
@ -444,6 +444,7 @@ class Metasploit:
|
||||||
|
|
||||||
def _controlMsfCmd(self, proc, func):
|
def _controlMsfCmd(self, proc, func):
|
||||||
stdin_fd = sys.stdin.fileno()
|
stdin_fd = sys.stdin.fileno()
|
||||||
|
initiated_properly = False
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
returncode = proc.poll()
|
returncode = proc.poll()
|
||||||
|
@ -493,6 +494,14 @@ class Metasploit:
|
||||||
out = recv_some(proc, t=.1, e=0)
|
out = recv_some(proc, t=.1, e=0)
|
||||||
blockingWriteToFD(sys.stdout.fileno(), out)
|
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
|
# For --os-pwn and --os-bof
|
||||||
pwnBofCond = self.connectionStr.startswith("reverse")
|
pwnBofCond = self.connectionStr.startswith("reverse")
|
||||||
pwnBofCond &= "Starting the payload handler" in out
|
pwnBofCond &= "Starting the payload handler" in out
|
||||||
|
@ -509,6 +518,9 @@ class Metasploit:
|
||||||
else:
|
else:
|
||||||
send_all(proc, "uname -a ; id\n")
|
send_all(proc, "uname -a ; id\n")
|
||||||
|
|
||||||
|
time.sleep(2)
|
||||||
|
initiated_properly = True
|
||||||
|
|
||||||
metSess = re.search("Meterpreter session ([\d]+) opened", out)
|
metSess = re.search("Meterpreter session ([\d]+) opened", out)
|
||||||
|
|
||||||
if metSess:
|
if metSess:
|
||||||
|
|
|
@ -1242,17 +1242,15 @@
|
||||||
<item value="r'SELECT \* FROM users ORDER BY name \[5\].+1, luther, blissett.+2, fluffy, bunny.+3, wu, ming'"/>
|
<item value="r'SELECT \* FROM users ORDER BY name \[5\].+1, luther, blissett.+2, fluffy, bunny.+3, wu, ming'"/>
|
||||||
</parse>
|
</parse>
|
||||||
</case>
|
</case>
|
||||||
|
|
||||||
|
|
||||||
<case name="PostgreSQL boolean-based multi-threaded custom SQL query enumeration">
|
<case name="PostgreSQL boolean-based multi-threaded custom SQL query enumeration">
|
||||||
<switches>
|
<switches>
|
||||||
<url value="http://debiandev/sqlmap/pgsql/get_int.php?id=1"/>
|
<url value="http://debiandev/sqlmap/pgsql/get_int.php?id=1"/>
|
||||||
<threads value="4"/>
|
<threads value="4"/>
|
||||||
<tech value="B"/>
|
<tech value="B"/>
|
||||||
<query value="SELECT * FROM users LIMIT 0, 2"/>
|
<query value="SELECT * FROM users OFFSET 0 LIMIT 2"/>
|
||||||
</switches>
|
</switches>
|
||||||
<parse>
|
<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>
|
</parse>
|
||||||
</case>
|
</case>
|
||||||
<case name="PostgreSQL error-based multi-threaded custom SQL query enumeration">
|
<case name="PostgreSQL error-based multi-threaded custom SQL query enumeration">
|
||||||
|
@ -1260,10 +1258,10 @@
|
||||||
<url value="http://debiandev/sqlmap/pgsql/get_int.php?id=1"/>
|
<url value="http://debiandev/sqlmap/pgsql/get_int.php?id=1"/>
|
||||||
<threads value="4"/>
|
<threads value="4"/>
|
||||||
<tech value="E"/>
|
<tech value="E"/>
|
||||||
<query value="SELECT * FROM users LIMIT 0, 2"/>
|
<query value="SELECT * FROM users OFFSET 0 LIMIT 2"/>
|
||||||
</switches>
|
</switches>
|
||||||
<parse>
|
<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>
|
</parse>
|
||||||
</case>
|
</case>
|
||||||
<case name="PostgreSQL UNION query multi-threaded custom SQL query enumeration">
|
<case name="PostgreSQL UNION query multi-threaded custom SQL query enumeration">
|
||||||
|
@ -1271,10 +1269,10 @@
|
||||||
<url value="http://debiandev/sqlmap/pgsql/get_int.php?id=1"/>
|
<url value="http://debiandev/sqlmap/pgsql/get_int.php?id=1"/>
|
||||||
<threads value="4"/>
|
<threads value="4"/>
|
||||||
<tech value="U"/>
|
<tech value="U"/>
|
||||||
<query value="SELECT * FROM users LIMIT 0, 2"/>
|
<query value="SELECT * FROM users OFFSET 0 LIMIT 2"/>
|
||||||
</switches>
|
</switches>
|
||||||
<parse>
|
<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>
|
</parse>
|
||||||
</case>
|
</case>
|
||||||
<case name="PostgreSQL boolean-based multi-threaded custom ordered SQL query enumeration">
|
<case name="PostgreSQL boolean-based multi-threaded custom ordered SQL query enumeration">
|
||||||
|
@ -1360,6 +1358,56 @@
|
||||||
<item value="the remote file /tmp/passwd-${random} is larger than the local file /etc/passwd" console_output="True"/>
|
<item value="the remote file /tmp/passwd-${random} is larger than the local file /etc/passwd" console_output="True"/>
|
||||||
</parse>
|
</parse>
|
||||||
</case>
|
</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 -->
|
<!-- End of file system access switches -->
|
||||||
|
|
||||||
<!-- Operating system access switches -->
|
<!-- Operating system access switches -->
|
||||||
|
@ -1374,20 +1422,41 @@
|
||||||
<item value="command standard output: 'uid="/>
|
<item value="command standard output: 'uid="/>
|
||||||
</parse>
|
</parse>
|
||||||
</case>
|
</case>
|
||||||
<!-- TODO: integration with Metasploit cannot be called yet from live testing
|
|
||||||
<case name="MySQL shell via Metasploit integration - command execution">
|
<case name="MySQL shell via Metasploit integration - command execution">
|
||||||
<switches>
|
<switches>
|
||||||
<url value="http://debiandev/sqlmap/mysql/get_int.php?id=1"/>
|
<url value="http://debiandev/sqlmap/mysql/get_int.php?id=1"/>
|
||||||
<tech value="B"/>
|
<tech value="BU"/>
|
||||||
<osPwn value="True"/>
|
<osPwn value="True"/>
|
||||||
<msfPath value="/usr/local/bin/"/>
|
<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>
|
</switches>
|
||||||
<parse>
|
<parse>
|
||||||
<item value="r'Sending stage.+Command shell session.+Linux.+uid='"/>
|
<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.+Linux.+uid=.+postgres'" console_output="True"/>
|
||||||
</parse>
|
</parse>
|
||||||
</case>
|
</case>
|
||||||
-->
|
|
||||||
<!-- End of operating system access switches -->
|
<!-- End of operating system access switches -->
|
||||||
|
|
||||||
<!-- Technique switches and corner cases -->
|
<!-- Technique switches and corner cases -->
|
||||||
|
|
Loading…
Reference in New Issue
Block a user