Skip to content

Commit c2b9e53

Browse files
committed
Update for #4351
1 parent 3d8eb62 commit c2b9e53

File tree

7 files changed

+107
-13
lines changed

7 files changed

+107
-13
lines changed

lib/core/option.py

Lines changed: 84 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -825,7 +825,7 @@ def _setTamperingFunctions():
825825

826826
def _setPreprocessFunctions():
827827
"""
828-
Loads preprocess functions from given script(s)
828+
Loads preprocess function(s) from given script(s)
829829
"""
830830

831831
if conf.preprocess:
@@ -870,7 +870,7 @@ def _setPreprocessFunctions():
870870
raise SqlmapSyntaxException("cannot import preprocess module '%s' (%s)" % (getUnicode(filename[:-3]), getSafeExString(ex)))
871871

872872
for name, function in inspect.getmembers(module, inspect.isfunction):
873-
if name == "preprocess" and inspect.getargspec(function).args and all(_ in inspect.getargspec(function).args for _ in ("page", "headers", "code")):
873+
if name == "preprocess" and inspect.getargspec(function).args and all(_ in inspect.getargspec(function).args for _ in ("req",)):
874874
found = True
875875

876876
kb.preprocessFunctions.append(function)
@@ -879,21 +879,96 @@ def _setPreprocessFunctions():
879879
break
880880

881881
if not found:
882-
errMsg = "missing function 'preprocess(page, headers=None, code=None)' "
882+
errMsg = "missing function 'preprocess(req)' "
883883
errMsg += "in preprocess script '%s'" % script
884884
raise SqlmapGenericException(errMsg)
885885
else:
886886
try:
887-
_, _, _ = function("", {}, None)
887+
function(_urllib.request.Request("http://localhost"))
888888
except:
889889
handle, filename = tempfile.mkstemp(prefix=MKSTEMP_PREFIX.PREPROCESS, suffix=".py")
890890
os.close(handle)
891891

892-
open(filename, "w+b").write("#!/usr/bin/env\n\ndef preprocess(page, headers=None, code=None):\n return page, headers, code\n")
893-
open(os.path.join(os.path.dirname(filename), "__init__.py"), "w+b").write("pass")
892+
openFile(filename, "w+b").write("#!/usr/bin/env\n\ndef preprocess(req):\n pass\n")
893+
openFile(os.path.join(os.path.dirname(filename), "__init__.py"), "w+b").write("pass")
894894

895-
errMsg = "function 'preprocess(page, headers=None, code=None)' "
895+
errMsg = "function 'preprocess(req)' "
896896
errMsg += "in preprocess script '%s' " % script
897+
errMsg += "appears to be invalid "
898+
errMsg += "(Note: find template script at '%s')" % filename
899+
raise SqlmapGenericException(errMsg)
900+
901+
def _setPostprocessFunctions():
902+
"""
903+
Loads postprocess function(s) from given script(s)
904+
"""
905+
906+
if conf.postprocess:
907+
for script in re.split(PARAMETER_SPLITTING_REGEX, conf.postprocess):
908+
found = False
909+
function = None
910+
911+
script = safeFilepathEncode(script.strip())
912+
913+
try:
914+
if not script:
915+
continue
916+
917+
if not os.path.exists(script):
918+
errMsg = "postprocess script '%s' does not exist" % script
919+
raise SqlmapFilePathException(errMsg)
920+
921+
elif not script.endswith(".py"):
922+
errMsg = "postprocess script '%s' should have an extension '.py'" % script
923+
raise SqlmapSyntaxException(errMsg)
924+
except UnicodeDecodeError:
925+
errMsg = "invalid character provided in option '--postprocess'"
926+
raise SqlmapSyntaxException(errMsg)
927+
928+
dirname, filename = os.path.split(script)
929+
dirname = os.path.abspath(dirname)
930+
931+
infoMsg = "loading postprocess module '%s'" % filename[:-3]
932+
logger.info(infoMsg)
933+
934+
if not os.path.exists(os.path.join(dirname, "__init__.py")):
935+
errMsg = "make sure that there is an empty file '__init__.py' "
936+
errMsg += "inside of postprocess scripts directory '%s'" % dirname
937+
raise SqlmapGenericException(errMsg)
938+
939+
if dirname not in sys.path:
940+
sys.path.insert(0, dirname)
941+
942+
try:
943+
module = __import__(safeFilepathEncode(filename[:-3]))
944+
except Exception as ex:
945+
raise SqlmapSyntaxException("cannot import postprocess module '%s' (%s)" % (getUnicode(filename[:-3]), getSafeExString(ex)))
946+
947+
for name, function in inspect.getmembers(module, inspect.isfunction):
948+
if name == "postprocess" and inspect.getargspec(function).args and all(_ in inspect.getargspec(function).args for _ in ("page", "headers", "code")):
949+
found = True
950+
951+
kb.postprocessFunctions.append(function)
952+
function.__name__ = module.__name__
953+
954+
break
955+
956+
if not found:
957+
errMsg = "missing function 'postprocess(page, headers=None, code=None)' "
958+
errMsg += "in postprocess script '%s'" % script
959+
raise SqlmapGenericException(errMsg)
960+
else:
961+
try:
962+
_, _, _ = function("", {}, None)
963+
except:
964+
handle, filename = tempfile.mkstemp(prefix=MKSTEMP_PREFIX.PREPROCESS, suffix=".py")
965+
os.close(handle)
966+
967+
openFile(filename, "w+b").write("#!/usr/bin/env\n\ndef postprocess(page, headers=None, code=None):\n return page, headers, code\n")
968+
openFile(os.path.join(os.path.dirname(filename), "__init__.py"), "w+b").write("pass")
969+
970+
errMsg = "function 'postprocess(page, headers=None, code=None)' "
971+
errMsg += "in postprocess script '%s' " % script
897972
errMsg += "should return a tuple '(page, headers, code)' "
898973
errMsg += "(Note: find template script at '%s')" % filename
899974
raise SqlmapGenericException(errMsg)
@@ -2038,6 +2113,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
20382113
kb.keywords = set(getFileItems(paths.SQL_KEYWORDS))
20392114
kb.normalizeCrawlingChoice = None
20402115
kb.passwordMgr = None
2116+
kb.postprocessFunctions = []
20412117
kb.preprocessFunctions = []
20422118
kb.skipVulnHost = None
20432119
kb.storeCrawlingChoice = None
@@ -2684,6 +2760,7 @@ def init():
26842760
_listTamperingFunctions()
26852761
_setTamperingFunctions()
26862762
_setPreprocessFunctions()
2763+
_setPostprocessFunctions()
26872764
_setTrafficOutputFP()
26882765
_setupHTTPCollector()
26892766
_setHttpChunked()

lib/core/optiondict.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@
222222
"hexConvert": "boolean",
223223
"outputDir": "string",
224224
"parseErrors": "boolean",
225+
"postprocess": "string",
225226
"preprocess": "string",
226227
"repair": "boolean",
227228
"saveConfig": "string",

lib/core/settings.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
from thirdparty.six import unichr as _unichr
1919

2020
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
21-
VERSION = "1.4.9.15"
21+
VERSION = "1.4.9.16"
2222
TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable"
2323
TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34}
2424
VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE)

lib/parse/cmdline.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -683,7 +683,10 @@ def cmdLineParser(argv=None):
683683
help="Parse and display DBMS error messages from responses")
684684

685685
general.add_argument("--preprocess", dest="preprocess",
686-
help="Use given script(s) for preprocessing of response data")
686+
help="Use given script(s) for preprocessing (request data)")
687+
688+
general.add_argument("--postprocess", dest="postprocess",
689+
help="Use given script(s) for postprocessing (response data)")
687690

688691
general.add_argument("--repair", dest="repair", action="store_true",
689692
help="Redump entries having unknown character marker (%s)" % INFERENCE_UNKNOWN_CHAR)

lib/request/connect.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -501,6 +501,16 @@ class _(dict):
501501
else:
502502
return None, None, None
503503

504+
for function in kb.preprocessFunctions:
505+
try:
506+
function(req)
507+
except Exception as ex:
508+
errMsg = "error occurred while running preprocess "
509+
errMsg += "function '%s' ('%s')" % (function.__name__, getSafeExString(ex))
510+
raise SqlmapGenericException(errMsg)
511+
else:
512+
post, headers = req.data, req.headers
513+
504514
requestHeaders += "\r\n".join(["%s: %s" % (getUnicode(key.capitalize() if hasattr(key, "capitalize") else key), getUnicode(value)) for (key, value) in req.header_items()])
505515

506516
if not getRequestHeader(req, HTTP_HEADER.COOKIE) and conf.cj:
@@ -815,11 +825,11 @@ class _(dict):
815825
else:
816826
page = getUnicode(page)
817827

818-
for function in kb.preprocessFunctions:
828+
for function in kb.postprocessFunctions:
819829
try:
820830
page, responseHeaders, code = function(page, responseHeaders, code)
821831
except Exception as ex:
822-
errMsg = "error occurred while running preprocess "
832+
errMsg = "error occurred while running postprocess "
823833
errMsg += "function '%s' ('%s')" % (function.__name__, getSafeExString(ex))
824834
raise SqlmapGenericException(errMsg)
825835

sqlmap.conf

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -769,9 +769,12 @@ outputDir =
769769
# Valid: True or False
770770
parseErrors = False
771771

772-
# Use given script(s) for preprocessing of response data.
772+
# Use given script(s) for preprocessing of request.
773773
preprocess =
774774

775+
# Use given script(s) for postprocessing of response data.
776+
postprocess =
777+
775778
# Redump entries having unknown character marker (?).
776779
# Valid: True or False
777780
repair = False

tamper/schemasplit.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ def dependencies():
1616

1717
def tamper(payload, **kwargs):
1818
"""
19-
Replaces instances of <int> UNION with <int>e0UNION
19+
Splits FROM schema identifiers (e.g. 'testdb.users') with whitespace (e.g. 'testdb 9.e.users')
2020
2121
Requirement:
2222
* MySQL

0 commit comments

Comments
 (0)