This commit is contained in:
Miroslav Stampar
2019-03-19 14:07:39 +01:00
parent 340e250fb1
commit 87237c82d3
9 changed files with 72 additions and 79 deletions

View File

@@ -98,7 +98,7 @@ from lib.core.exception import SqlmapUserQuitException
from lib.core.exception import SqlmapValueException
from lib.core.log import LOGGER_HANDLER
from lib.core.optiondict import optDict
from lib.core.settings import BANNER, CHUNKED_KEYWORDS
from lib.core.settings import BANNER
from lib.core.settings import BOLD_PATTERNS
from lib.core.settings import BOUNDED_INJECTION_MARKER
from lib.core.settings import BRUTE_DOC_ROOT_PREFIXES
@@ -126,6 +126,7 @@ from lib.core.settings import GITHUB_REPORT_OAUTH_TOKEN
from lib.core.settings import GOOGLE_ANALYTICS_COOKIE_PREFIX
from lib.core.settings import HASHDB_MILESTONE_VALUE
from lib.core.settings import HOST_ALIASES
from lib.core.settings import HTTP_CHUNKED_SPLIT_KEYWORDS
from lib.core.settings import IGNORE_SAVE_OPTIONS
from lib.core.settings import INFERENCE_UNKNOWN_CHAR
from lib.core.settings import INVALID_UNICODE_CHAR_FORMAT
@@ -4896,49 +4897,35 @@ def firstNotNone(*args):
return retVal
def generateChunkDdata(data):
def chunkSplitPostData(data):
"""
Convert post data to chunked format data. If the keyword is in a block, the keyword will be cut.
>>> generateChunkDdata('select 1,2,3,4 from admin')
4;AZdYz
sele
2;fJS4D
ct
5;qbCOT
1,2,
7;KItpi
3,4 fro
2;pFu1R
m
5;uRoYZ
admin
0
Convert POST data to chunked transfer-encoded data (Note: splitting done by SQL keywords)
"""
dl = len(data)
ret = ""
keywords = CHUNKED_KEYWORDS
length = len(data)
retVal = ""
index = 0
while index < dl:
chunk_size = random.randint(1, 9)
if index + chunk_size >= dl:
chunk_size = dl - index
salt = ''.join(random.sample(string.ascii_letters + string.digits, 5))
while 1:
tmp_chunk = data[index:index + chunk_size]
tmp_bool = True
for k in keywords:
if k in tmp_chunk:
chunk_size -= 1
tmp_bool = False
break
if tmp_bool:
break
index += chunk_size
ret += "%s;%s\r\n" % (hex(chunk_size)[2:], salt)
ret += "%s\r\n" % tmp_chunk
ret += "0\r\n\r\n"
return ret
while index < length:
chunkSize = randomInt(1)
if index + chunkSize >= length:
chunkSize = length - index
salt = randomStr(5, alphabet=string.ascii_letters + string.digits)
while chunkSize:
candidate = data[index:index + chunkSize]
if re.search(r"\b%s\b" % '|'.join(HTTP_CHUNKED_SPLIT_KEYWORDS), candidate, re.I):
chunkSize -= 1
else:
break
index += chunkSize
retVal += "%x;%s\r\n" % (chunkSize, salt)
retVal += "%s\r\n" % candidate
retVal += "0\r\n\r\n"
return retVal

View File

@@ -140,7 +140,7 @@ from lib.request.basic import checkCharEncoding
from lib.request.connect import Connect as Request
from lib.request.dns import DNSServer
from lib.request.basicauthhandler import SmartHTTPBasicAuthHandler
from lib.request.httphandler import HTTPHandler
from lib.request.chunkedhandler import ChunkedHandler
from lib.request.httpshandler import HTTPSHandler
from lib.request.pkihandler import HTTPSPKIAuthHandler
from lib.request.rangehandler import HTTPRangeHandler
@@ -158,7 +158,7 @@ from thirdparty.socks import socks
from xml.etree.ElementTree import ElementTree
authHandler = urllib2.BaseHandler()
httpHandler = HTTPHandler()
chunkedHandler = ChunkedHandler()
httpsHandler = HTTPSHandler()
keepAliveHandler = keepalive.HTTPHandler()
proxyHandler = urllib2.ProxyHandler()
@@ -1109,7 +1109,7 @@ def _setHTTPHandlers():
debugMsg = "creating HTTP requests opener object"
logger.debug(debugMsg)
handlers = filter(None, [multipartPostHandler, proxyHandler if proxyHandler.proxies else None, authHandler, redirectHandler, rangeHandler, httpHandler, httpsHandler])
handlers = filter(None, [multipartPostHandler, proxyHandler if proxyHandler.proxies else None, authHandler, redirectHandler, rangeHandler, chunkedHandler if conf.chunked else None, httpsHandler])
if not conf.dropSetCookie:
if not conf.loadCookies:
@@ -2314,6 +2314,10 @@ def _setTorSocksProxySettings():
socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5 if conf.torType == PROXY_TYPE.SOCKS5 else socks.PROXY_TYPE_SOCKS4, LOCALHOST, port)
socks.wrapmodule(urllib2)
def _setHttpChunked():
if conf.chunked and conf.data:
httplib.HTTPConnection._set_content_length = lambda self, a, b: None
def _checkWebSocket():
if conf.url and (conf.url.startswith("ws:/") or conf.url.startswith("wss:/")):
try:
@@ -2401,6 +2405,10 @@ def _basicOptionValidation():
errMsg = "switch '--dump' is incompatible with switch '--search'"
raise SqlmapSyntaxException(errMsg)
if conf.chunked and not any((conf.data, conf.requestFile)):
errMsg = "switch '--chunked' requires usage of option '--data' or '-r'"
raise SqlmapSyntaxException(errMsg)
if conf.api and not conf.configFile:
errMsg = "switch '--api' requires usage of option '-c'"
raise SqlmapSyntaxException(errMsg)
@@ -2605,15 +2613,6 @@ def initOptions(inputOptions=AttribDict(), overrideOptions=False):
_setKnowledgeBaseAttributes()
_mergeOptions(inputOptions, overrideOptions)
def _setHttpChunked():
conf.chunk = conf.chunk and conf.data
if conf.chunk:
def hook(self, a, b):
pass
httplib.HTTPConnection._set_content_length = hook
def init():
"""
Set attributes into both configuration and knowledge base singletons
@@ -2639,11 +2638,11 @@ def init():
_listTamperingFunctions()
_setTamperingFunctions()
_setPreprocessFunctions()
_setHttpChunked()
_setWafFunctions()
_setTrafficOutputFP()
_setupHTTPCollector()
_resolveCrossReferences()
_setHttpChunked()
_checkWebSocket()
parseTargetDirect()

View File

@@ -61,6 +61,7 @@ optDict = {
"csrfToken": "string",
"csrfUrl": "string",
"forceSSL": "boolean",
"chunked": "boolean",
"hpp": "boolean",
"evalCode": "string",
},

View File

@@ -19,7 +19,7 @@ from lib.core.enums import DBMS_DIRECTORY_NAME
from lib.core.enums import OS
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
VERSION = "1.3.3.31"
VERSION = "1.3.3.32"
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)
@@ -794,8 +794,8 @@ KB_CHARS_BOUNDARY_CHAR = 'q'
# Letters of lower frequency used in kb.chars
KB_CHARS_LOW_FREQUENCY_ALPHABET = "zqxjkvbp"
# Keywords that need to be cut in the chunked
CHUNKED_KEYWORDS = ['select', 'update', 'insert', 'from', 'load_file', 'sysdatabases', 'msysaccessobjects', 'msysqueries', 'sysmodules', 'information_schema', 'union']
# SQL keywords used for splitting in HTTP Chunked encoding (switch --chunk)
HTTP_CHUNKED_SPLIT_KEYWORDS = ("SELECT", "UPDATE", "INSERT", "FROM", "LOAD_FILE", "UNION", "information_schema", "sysdatabases", "msysaccessobjects", "msysqueries", "sysmodules")
# CSS style used in HTML dump format
HTML_DUMP_CSS_STYLE = """<style>