mirror of
				https://github.com/sqlmapproject/sqlmap.git
				synced 2025-11-04 09:57:38 +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
 | 
				
			||||||
| 
						 | 
					@ -172,18 +171,20 @@ def liveTest():
 | 
				
			||||||
            logger.info("test passed")
 | 
					            logger.info("test passed")
 | 
				
			||||||
            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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    console = getUnicode(console, system=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if parse and retVal:
 | 
					    if parse and retVal:
 | 
				
			||||||
        console = getUnicode(console, system=True)
 | 
					 | 
				
			||||||
        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