Some testing stuff

This commit is contained in:
Miroslav Stampar 2020-01-07 23:49:45 +01:00
parent 57f17794c4
commit 0e9dd9b0be
6 changed files with 66 additions and 135 deletions

View File

@ -191,7 +191,7 @@ class ReqHandler(BaseHTTPRequestHandler):
length = int(self.headers.get("Content-length", 0))
if 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.do_REQUEST()

View File

@ -252,8 +252,6 @@ optDict = {
"forceDns": "boolean",
"murphyRate": "integer",
"smokeTest": "boolean",
"stopFail": "boolean",
"runCase": "string",
},
"API": {

View File

@ -18,7 +18,7 @@ from lib.core.enums import OS
from thirdparty.six import unichr as _unichr
# 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_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)

View File

@ -7,51 +7,33 @@ See the file 'LICENSE' for copying permission
from __future__ import division
import codecs
import doctest
import logging
import os
import random
import re
import shutil
import socket
import sqlite3
import sys
import tempfile
import threading
import time
import traceback
from extra.vulnserver import vulnserver
from lib.controller.controller import start
from lib.core.common import clearColors
from lib.core.common import clearConsoleLine
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.compat import round
from lib.core.compat import xrange
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 logger
from lib.core.data import paths
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
def vulnTest():
@ -154,6 +136,63 @@ def vulnTest():
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():
"""
Unifying random generated data across different Python versions
@ -274,109 +313,3 @@ def smokeTest():
logger.error("smoke test final result: FAILED")
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

View File

@ -790,10 +790,7 @@ def cmdLineParser(argv=None):
parser.add_argument("--vuln-test", dest="vulnTest", action="store_true",
help=SUPPRESS)
parser.add_argument("--stop-fail", dest="stopFail", action="store_true",
help=SUPPRESS)
parser.add_argument("--run-case", dest="runCase",
parser.add_argument("--fuzz-test", dest="fuzzTest", action="store_true",
help=SUPPRESS)
# API options
@ -1002,7 +999,7 @@ def cmdLineParser(argv=None):
if args.dummy:
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 += "Use -h for basic and -hh for advanced help\n"
parser.error(errMsg)

View File

@ -173,6 +173,9 @@ def main():
elif conf.vulnTest:
from lib.core.testing import vulnTest
os._exitcode = 1 - (vulnTest() or 0)
elif conf.fuzzTest:
from lib.core.testing import fuzzTest
fuzzTest()
else:
from lib.controller.controller import start
if conf.profile and six.PY2: