mirror of
				https://github.com/sqlmapproject/sqlmap.git
				synced 2025-11-04 01:47:37 +03:00 
			
		
		
		
	Some testing stuff
This commit is contained in:
		
							parent
							
								
									57f17794c4
								
							
						
					
					
						commit
						0e9dd9b0be
					
				| 
						 | 
					@ -191,7 +191,7 @@ class ReqHandler(BaseHTTPRequestHandler):
 | 
				
			||||||
        length = int(self.headers.get("Content-length", 0))
 | 
					        length = int(self.headers.get("Content-length", 0))
 | 
				
			||||||
        if length:
 | 
					        if length:
 | 
				
			||||||
            data = self.rfile.read(length)
 | 
					            data = self.rfile.read(length)
 | 
				
			||||||
            data = unquote_plus(data.decode(UNICODE_ENCODING))
 | 
					            data = unquote_plus(data.decode(UNICODE_ENCODING, "ignore"))
 | 
				
			||||||
            self.data = data
 | 
					            self.data = data
 | 
				
			||||||
        self.do_REQUEST()
 | 
					        self.do_REQUEST()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -252,8 +252,6 @@ optDict = {
 | 
				
			||||||
        "forceDns": "boolean",
 | 
					        "forceDns": "boolean",
 | 
				
			||||||
        "murphyRate": "integer",
 | 
					        "murphyRate": "integer",
 | 
				
			||||||
        "smokeTest": "boolean",
 | 
					        "smokeTest": "boolean",
 | 
				
			||||||
        "stopFail": "boolean",
 | 
					 | 
				
			||||||
        "runCase": "string",
 | 
					 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    "API": {
 | 
					    "API": {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,7 +18,7 @@ from lib.core.enums import OS
 | 
				
			||||||
from thirdparty.six import unichr as _unichr
 | 
					from thirdparty.six import unichr as _unichr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
 | 
					# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
 | 
				
			||||||
VERSION = "1.4.1.11"
 | 
					VERSION = "1.4.1.12"
 | 
				
			||||||
TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable"
 | 
					TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable"
 | 
				
			||||||
TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34}
 | 
					TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34}
 | 
				
			||||||
VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE)
 | 
					VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,51 +7,33 @@ See the file 'LICENSE' for copying permission
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from __future__ import division
 | 
					from __future__ import division
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import codecs
 | 
					 | 
				
			||||||
import doctest
 | 
					import doctest
 | 
				
			||||||
import logging
 | 
					import logging
 | 
				
			||||||
import os
 | 
					import os
 | 
				
			||||||
import random
 | 
					import random
 | 
				
			||||||
import re
 | 
					import re
 | 
				
			||||||
import shutil
 | 
					 | 
				
			||||||
import socket
 | 
					import socket
 | 
				
			||||||
import sqlite3
 | 
					import sqlite3
 | 
				
			||||||
import sys
 | 
					import sys
 | 
				
			||||||
import tempfile
 | 
					import tempfile
 | 
				
			||||||
import threading
 | 
					import threading
 | 
				
			||||||
import time
 | 
					import time
 | 
				
			||||||
import traceback
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
from extra.vulnserver import vulnserver
 | 
					from extra.vulnserver import vulnserver
 | 
				
			||||||
from lib.controller.controller import start
 | 
					 | 
				
			||||||
from lib.core.common import clearColors
 | 
					from lib.core.common import clearColors
 | 
				
			||||||
from lib.core.common import clearConsoleLine
 | 
					from lib.core.common import clearConsoleLine
 | 
				
			||||||
from lib.core.common import dataToStdout
 | 
					from lib.core.common import dataToStdout
 | 
				
			||||||
 | 
					from lib.core.common import randomInt
 | 
				
			||||||
 | 
					from lib.core.common import randomStr
 | 
				
			||||||
from lib.core.common import shellExec
 | 
					from lib.core.common import shellExec
 | 
				
			||||||
from lib.core.compat import round
 | 
					from lib.core.compat import round
 | 
				
			||||||
from lib.core.compat import xrange
 | 
					from lib.core.compat import xrange
 | 
				
			||||||
from lib.core.convert import encodeBase64
 | 
					from lib.core.convert import encodeBase64
 | 
				
			||||||
from lib.core.convert import getUnicode
 | 
					 | 
				
			||||||
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
 | 
				
			||||||
from lib.core.data import paths
 | 
					from lib.core.data import paths
 | 
				
			||||||
from lib.core.data import queries
 | 
					from lib.core.data import queries
 | 
				
			||||||
from lib.core.enums import MKSTEMP_PREFIX
 | 
					 | 
				
			||||||
from lib.core.exception import SqlmapBaseException
 | 
					 | 
				
			||||||
from lib.core.log import LOGGER_HANDLER
 | 
					 | 
				
			||||||
from lib.core.option import init
 | 
					 | 
				
			||||||
from lib.core.option import initOptions
 | 
					 | 
				
			||||||
from lib.core.optiondict import optDict
 | 
					 | 
				
			||||||
from lib.core.settings import UNICODE_ENCODING
 | 
					 | 
				
			||||||
from lib.parse.cmdline import cmdLineParser
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Failures(object):
 | 
					 | 
				
			||||||
    failedItems = None
 | 
					 | 
				
			||||||
    failedParseOn = None
 | 
					 | 
				
			||||||
    failedTraceBack = None
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
_failures = Failures()
 | 
					 | 
				
			||||||
_rand = 0
 | 
					_rand = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def vulnTest():
 | 
					def vulnTest():
 | 
				
			||||||
| 
						 | 
					@ -154,6 +136,63 @@ def vulnTest():
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return retVal
 | 
					    return retVal
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def fuzzTest():
 | 
				
			||||||
 | 
					    count = 0
 | 
				
			||||||
 | 
					    address, port = "127.0.0.10", random.randint(1025, 65535)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def _thread():
 | 
				
			||||||
 | 
					        vulnserver.init(quiet=True)
 | 
				
			||||||
 | 
					        vulnserver.run(address=address, port=port)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    thread = threading.Thread(target=_thread)
 | 
				
			||||||
 | 
					    thread.daemon = True
 | 
				
			||||||
 | 
					    thread.start()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while True:
 | 
				
			||||||
 | 
					        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            s.connect((address, port))
 | 
				
			||||||
 | 
					            break
 | 
				
			||||||
 | 
					        except:
 | 
				
			||||||
 | 
					            time.sleep(1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    handle, config = tempfile.mkstemp(suffix=".conf")
 | 
				
			||||||
 | 
					    os.close(handle)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    url = "http://%s:%d/?id=1" % (address, port)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    content = open(os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "sqlmap.conf"))).read().replace("url =", "url = %s" % url)
 | 
				
			||||||
 | 
					    open(config, "w+").write(content)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while True:
 | 
				
			||||||
 | 
					        lines = content.split("\n")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for i in xrange(20):
 | 
				
			||||||
 | 
					            j = random.randint(0, len(lines) - 1)
 | 
				
			||||||
 | 
					            if lines[j].strip().endswith('='):
 | 
				
			||||||
 | 
					                lines[j] += random.sample(("True", "False", randomStr(), str(randomInt())), 1)[0]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            k = random.randint(0, len(lines) - 1)
 | 
				
			||||||
 | 
					            if '=' in lines[k]:
 | 
				
			||||||
 | 
					                lines[k] += chr(random.randint(0, 255))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        open(config, "w+").write("\n".join(lines))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        cmd = "%s %s -c %s --batch --flush-session --technique=%s --banner" % (sys.executable, os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "sqlmap.py")), config, random.sample("BEUQ", 1)[0])
 | 
				
			||||||
 | 
					        output = shellExec(cmd)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if "Traceback" in output:
 | 
				
			||||||
 | 
					            dataToStdout("---\n\n$ %s\n" % cmd)
 | 
				
			||||||
 | 
					            dataToStdout("%s---\n" % clearColors(output))
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            handle, config = tempfile.mkstemp(prefix="sqlmapcrash", suffix=".conf")
 | 
				
			||||||
 | 
					            os.close(handle)
 | 
				
			||||||
 | 
					            open(config, "w+").write("\n".join(lines))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            dataToStdout("\r%d\r" % count)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        count += 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def dirtyPatchRandom():
 | 
					def dirtyPatchRandom():
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Unifying random generated data across different Python versions
 | 
					    Unifying random generated data across different Python versions
 | 
				
			||||||
| 
						 | 
					@ -274,109 +313,3 @@ def smokeTest():
 | 
				
			||||||
        logger.error("smoke test final result: FAILED")
 | 
					        logger.error("smoke test final result: FAILED")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return retVal
 | 
					    return retVal
 | 
				
			||||||
 | 
					 | 
				
			||||||
def adjustValueType(tagName, value):
 | 
					 | 
				
			||||||
    for family in optDict:
 | 
					 | 
				
			||||||
        for name, type_ in optDict[family].items():
 | 
					 | 
				
			||||||
            if type(type_) == tuple:
 | 
					 | 
				
			||||||
                type_ = type_[0]
 | 
					 | 
				
			||||||
            if tagName == name:
 | 
					 | 
				
			||||||
                if type_ == "boolean":
 | 
					 | 
				
			||||||
                    value = (value == "True")
 | 
					 | 
				
			||||||
                elif type_ == "integer":
 | 
					 | 
				
			||||||
                    value = int(value)
 | 
					 | 
				
			||||||
                elif type_ == "float":
 | 
					 | 
				
			||||||
                    value = float(value)
 | 
					 | 
				
			||||||
                break
 | 
					 | 
				
			||||||
    return value
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def initCase(switches, count):
 | 
					 | 
				
			||||||
    _failures.failedItems = []
 | 
					 | 
				
			||||||
    _failures.failedParseOn = None
 | 
					 | 
				
			||||||
    _failures.failedTraceBack = None
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    paths.SQLMAP_OUTPUT_PATH = tempfile.mkdtemp(prefix="%s%d-" % (MKSTEMP_PREFIX.TESTING, count))
 | 
					 | 
				
			||||||
    paths.SQLMAP_DUMP_PATH = os.path.join(paths.SQLMAP_OUTPUT_PATH, "%s", "dump")
 | 
					 | 
				
			||||||
    paths.SQLMAP_FILES_PATH = os.path.join(paths.SQLMAP_OUTPUT_PATH, "%s", "files")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    logger.debug("using output directory '%s' for this test case" % paths.SQLMAP_OUTPUT_PATH)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    LOGGER_HANDLER.stream = sys.stdout = tempfile.SpooledTemporaryFile(max_size=0, mode="w+b", prefix="sqlmapstdout-")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    cmdLineOptions = cmdLineParser()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if switches:
 | 
					 | 
				
			||||||
        for key, value in switches.items():
 | 
					 | 
				
			||||||
            if key in cmdLineOptions.__dict__:
 | 
					 | 
				
			||||||
                cmdLineOptions.__dict__[key] = value
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    initOptions(cmdLineOptions, True)
 | 
					 | 
				
			||||||
    init()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def cleanCase():
 | 
					 | 
				
			||||||
    shutil.rmtree(paths.SQLMAP_OUTPUT_PATH, True)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def runCase(parse):
 | 
					 | 
				
			||||||
    retVal = True
 | 
					 | 
				
			||||||
    handled_exception = None
 | 
					 | 
				
			||||||
    unhandled_exception = None
 | 
					 | 
				
			||||||
    result = False
 | 
					 | 
				
			||||||
    console = ""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    try:
 | 
					 | 
				
			||||||
        result = start()
 | 
					 | 
				
			||||||
    except KeyboardInterrupt:
 | 
					 | 
				
			||||||
        pass
 | 
					 | 
				
			||||||
    except SqlmapBaseException as ex:
 | 
					 | 
				
			||||||
        handled_exception = ex
 | 
					 | 
				
			||||||
    except Exception as ex:
 | 
					 | 
				
			||||||
        unhandled_exception = ex
 | 
					 | 
				
			||||||
    finally:
 | 
					 | 
				
			||||||
        sys.stdout.seek(0)
 | 
					 | 
				
			||||||
        console = sys.stdout.read()
 | 
					 | 
				
			||||||
        LOGGER_HANDLER.stream = sys.stdout = sys.__stdout__
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if unhandled_exception:
 | 
					 | 
				
			||||||
        _failures.failedTraceBack = "unhandled exception: %s" % str(traceback.format_exc())
 | 
					 | 
				
			||||||
        retVal = None
 | 
					 | 
				
			||||||
    elif handled_exception:
 | 
					 | 
				
			||||||
        _failures.failedTraceBack = "handled exception: %s" % str(traceback.format_exc())
 | 
					 | 
				
			||||||
        retVal = None
 | 
					 | 
				
			||||||
    elif result is False:  # this means no SQL injection has been detected - if None, ignore
 | 
					 | 
				
			||||||
        retVal = False
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    console = getUnicode(console, encoding=sys.stdin.encoding)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if parse and retVal:
 | 
					 | 
				
			||||||
        with codecs.open(conf.dumper.getOutputFile(), "rb", UNICODE_ENCODING) as f:
 | 
					 | 
				
			||||||
            content = f.read()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        for item, parse_from_console_output in parse:
 | 
					 | 
				
			||||||
            parse_on = console if parse_from_console_output else content
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if item.startswith("r'") and item.endswith("'"):
 | 
					 | 
				
			||||||
                if not re.search(item[2:-1], parse_on, re.DOTALL):
 | 
					 | 
				
			||||||
                    retVal = None
 | 
					 | 
				
			||||||
                    _failures.failedItems.append(item)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            elif item not in parse_on:
 | 
					 | 
				
			||||||
                retVal = None
 | 
					 | 
				
			||||||
                _failures.failedItems.append(item)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if _failures.failedItems:
 | 
					 | 
				
			||||||
            _failures.failedParseOn = console
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    elif retVal is False:
 | 
					 | 
				
			||||||
        _failures.failedParseOn = console
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return retVal
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def replaceVars(item, vars_):
 | 
					 | 
				
			||||||
    retVal = item
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if item and vars_:
 | 
					 | 
				
			||||||
        for var in re.findall(r"\$\{([^}]+)\}", item):
 | 
					 | 
				
			||||||
            if var in vars_:
 | 
					 | 
				
			||||||
                retVal = retVal.replace("${%s}" % var, vars_[var])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return retVal
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -790,10 +790,7 @@ def cmdLineParser(argv=None):
 | 
				
			||||||
        parser.add_argument("--vuln-test", dest="vulnTest", action="store_true",
 | 
					        parser.add_argument("--vuln-test", dest="vulnTest", action="store_true",
 | 
				
			||||||
            help=SUPPRESS)
 | 
					            help=SUPPRESS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        parser.add_argument("--stop-fail", dest="stopFail", action="store_true",
 | 
					        parser.add_argument("--fuzz-test", dest="fuzzTest", action="store_true",
 | 
				
			||||||
            help=SUPPRESS)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        parser.add_argument("--run-case", dest="runCase",
 | 
					 | 
				
			||||||
            help=SUPPRESS)
 | 
					            help=SUPPRESS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # API options
 | 
					        # API options
 | 
				
			||||||
| 
						 | 
					@ -1002,7 +999,7 @@ def cmdLineParser(argv=None):
 | 
				
			||||||
        if args.dummy:
 | 
					        if args.dummy:
 | 
				
			||||||
            args.url = args.url or DUMMY_URL
 | 
					            args.url = args.url or DUMMY_URL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if not any((args.direct, args.url, args.logFile, args.bulkFile, args.googleDork, args.configFile, args.requestFile, args.updateAll, args.smokeTest, args.vulnTest, args.wizard, args.dependencies, args.purge, args.listTampers, args.hashFile)):
 | 
					        if not any((args.direct, args.url, args.logFile, args.bulkFile, args.googleDork, args.configFile, args.requestFile, args.updateAll, args.smokeTest, args.vulnTest, args.fuzzTest, args.wizard, args.dependencies, args.purge, args.listTampers, args.hashFile)):
 | 
				
			||||||
            errMsg = "missing a mandatory option (-d, -u, -l, -m, -r, -g, -c, --list-tampers, --wizard, --update, --purge or --dependencies). "
 | 
					            errMsg = "missing a mandatory option (-d, -u, -l, -m, -r, -g, -c, --list-tampers, --wizard, --update, --purge or --dependencies). "
 | 
				
			||||||
            errMsg += "Use -h for basic and -hh for advanced help\n"
 | 
					            errMsg += "Use -h for basic and -hh for advanced help\n"
 | 
				
			||||||
            parser.error(errMsg)
 | 
					            parser.error(errMsg)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -173,6 +173,9 @@ def main():
 | 
				
			||||||
            elif conf.vulnTest:
 | 
					            elif conf.vulnTest:
 | 
				
			||||||
                from lib.core.testing import vulnTest
 | 
					                from lib.core.testing import vulnTest
 | 
				
			||||||
                os._exitcode = 1 - (vulnTest() or 0)
 | 
					                os._exitcode = 1 - (vulnTest() or 0)
 | 
				
			||||||
 | 
					            elif conf.fuzzTest:
 | 
				
			||||||
 | 
					                from lib.core.testing import fuzzTest
 | 
				
			||||||
 | 
					                fuzzTest()
 | 
				
			||||||
            else:
 | 
					            else:
 | 
				
			||||||
                from lib.controller.controller import start
 | 
					                from lib.controller.controller import start
 | 
				
			||||||
                if conf.profile and six.PY2:
 | 
					                if conf.profile and six.PY2:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user