Add the --chunk option to send requests in chunks

This commit is contained in:
boy-hack 2019-03-16 12:03:19 +08:00
parent e7ffc8f9b1
commit 0ca7502000
4 changed files with 64 additions and 2 deletions

View File

@ -4895,3 +4895,50 @@ def firstNotNone(*args):
break
return retVal
def generateChunkDdata(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
"""
dl = len(data)
ret = ""
keywords = CHUNK_KEYWORDS
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

View File

@ -794,6 +794,9 @@ 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']
# CSS style used in HTML dump format
HTML_DUMP_CSS_STYLE = """<style>
table{

View File

@ -220,6 +220,8 @@ def cmdLineParser(argv=None):
request.add_option("--eval", dest="evalCode",
help="Evaluate provided Python code before the request (e.g. \"import hashlib;id2=hashlib.md5(id).hexdigest()\")")
request.add_option("--chunk", dest="chunk", action="store_true", help="all requests will be added headers with 'Transfer-Encoding: Chunked' and sent by transcoding")
# Optimization options
optimization = OptionGroup(parser, "Optimization", "These options can be used to optimize the performance of sqlmap")

View File

@ -61,6 +61,7 @@ from lib.core.common import unicodeencode
from lib.core.common import unsafeVariableNaming
from lib.core.common import urldecode
from lib.core.common import urlencode
from lib.core.common import generateChunkDdata
from lib.core.data import conf
from lib.core.data import kb
from lib.core.data import logger
@ -271,9 +272,12 @@ class Connect(object):
checking = kwargs.get("checking", False)
skipRead = kwargs.get("skipRead", False)
finalCode = kwargs.get("finalCode", False)
chunked = conf.chunk
if multipart:
post = multipart
if chunked:
post = generateChunkDdata(post)
websocket_ = url.lower().startswith("ws")
@ -396,6 +400,9 @@ class Connect(object):
if conf.keepAlive:
headers[HTTP_HEADER.CONNECTION] = "keep-alive"
if chunked:
headers[HTTP_HEADER.TRANSFER_ENCODING] = "Chunked"
if auxHeaders:
headers = forgeHeaders(auxHeaders, headers)
@ -455,7 +462,7 @@ class Connect(object):
requestHeaders += "\r\n%s" % ("Cookie: %s" % ";".join("%s=%s" % (getUnicode(cookie.name), getUnicode(cookie.value)) for cookie in cookies))
if post is not None:
if not getRequestHeader(req, HTTP_HEADER.CONTENT_LENGTH):
if not getRequestHeader(req, HTTP_HEADER.CONTENT_LENGTH) and not chunked:
requestHeaders += "\r\n%s: %d" % (string.capwords(HTTP_HEADER.CONTENT_LENGTH), len(post))
if not getRequestHeader(req, HTTP_HEADER.CONNECTION):
@ -464,7 +471,10 @@ class Connect(object):
requestMsg += "\r\n%s" % requestHeaders
if post is not None:
requestMsg += "\r\n\r\n%s" % getUnicode(post)
if chunked:
requestMsg += getUnicode(post)
else:
requestMsg += "\r\n\r\n%s" % getUnicode(post)
requestMsg += "\r\n"