mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2024-11-22 01:26:42 +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))
|
||||
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()
|
||||
|
||||
|
|
|
@ -252,8 +252,6 @@ optDict = {
|
|||
"forceDns": "boolean",
|
||||
"murphyRate": "integer",
|
||||
"smokeTest": "boolean",
|
||||
"stopFail": "boolean",
|
||||
"runCase": "string",
|
||||
},
|
||||
|
||||
"API": {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue
Block a user