From d65d9e25cd57925d0a8ed61bacb1d0852e39e284 Mon Sep 17 00:00:00 2001 From: Miroslav Stampar Date: Fri, 19 Oct 2012 11:02:14 +0200 Subject: [PATCH] Implementation for an Issue #2 --- lib/controller/controller.py | 3 ++- lib/core/settings.py | 12 +++++++++--- lib/request/basic.py | 10 ++++++++++ 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/lib/controller/controller.py b/lib/controller/controller.py index b503a7701..b1e8c80db 100644 --- a/lib/controller/controller.py +++ b/lib/controller/controller.py @@ -47,6 +47,7 @@ from lib.core.exception import sqlmapNotVulnerableException from lib.core.exception import sqlmapSilentQuitException from lib.core.exception import sqlmapValueException from lib.core.exception import sqlmapUserQuitException +from lib.core.settings import ASP_NET_CONTROL_REGEX from lib.core.settings import DEFAULT_COOKIE_DELIMITER from lib.core.settings import DEFAULT_GET_POST_DELIMITER from lib.core.settings import EMPTY_FORM_FIELDS_REGEX @@ -166,7 +167,7 @@ def __randomFillBlankFields(value): if not test or test[0] in ("y", "Y"): for match in re.finditer(EMPTY_FORM_FIELDS_REGEX, retVal): item = match.group("result") - if not any(_ in item for _ in IGNORE_PARAMETERS): + if not any(_ in item for _ in IGNORE_PARAMETERS) and not re.search(ASP_NET_CONTROL_REGEX, item): if item[-1] == DEFAULT_GET_POST_DELIMITER: retVal = retVal.replace(item, "%s%s%s" % (item[:-1], randomStr(), DEFAULT_GET_POST_DELIMITER)) else: diff --git a/lib/core/settings.py b/lib/core/settings.py index e11ca9f60..f4f76278f 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -229,7 +229,7 @@ META_CHARSET_REGEX = r']+charset=(?P META_REFRESH_REGEX = r']+content="?[^">]+url=(?P[^">]+)' # Regular expression used for parsing empty fields in tested form data -EMPTY_FORM_FIELDS_REGEX = r'(?P[^=]+=(&|\Z))' +EMPTY_FORM_FIELDS_REGEX = r'(&|\A)(?P[^=]+=(&|\Z))' # Reference: http://www.cs.ru.nl/bachelorscripties/2010/Martin_Devillers___0437999___Analyzing_password_strength.pdf COMMON_PASSWORD_SUFFIXES = ("1", "123", "2", "12", "3", "13", "7", "11", "5", "22", "23", "01", "4", "07", "21", "14", "10", "06", "08", "8", "15", "69", "16", "6", "18") @@ -309,6 +309,9 @@ MAX_INT = sys.maxint # Parameters to be ignored in detection phase (upper case) IGNORE_PARAMETERS = ("__VIEWSTATE", "__VIEWSTATEENCRYPTED", "__EVENTARGUMENT", "__EVENTTARGET", "__EVENTVALIDATION", "ASPSESSIONID", "ASP.NET_SESSIONID", "JSESSIONID", "CFID", "CFTOKEN") +# Regular expression used for recognition of ASP.NET control parameters +ASP_NET_CONTROL_REGEX = r"(?i)\Actl\d+\$" + # Turn off resume console info to avoid potential slowdowns TURN_OFF_RESUME_INFO_LIMIT = 20 @@ -462,8 +465,11 @@ MAX_HELP_OPTION_LENGTH = 18 # Strings for detecting formatting errors FORMAT_EXCEPTION_STRINGS = ("Type mismatch", "Error converting", "Failed to convert", "System.FormatException", "java.lang.NumberFormatException") -# Regular expression used for extracting ASP.NET View State values -VIEWSTATE_REGEX = r'(?P__VIEWSTATE[^"]*)[^>]+value="(?P[^"]+)' +# Regular expression used for extracting ASP.NET view state values +VIEWSTATE_REGEX = r'(?P__VIEWSTATE[^"]*)[^>]+value="(?P[^"]+)' + +# Regular expression used for extracting ASP.NET event validation values +EVENTVALIDATION_REGEX = r'(?P__EVENTVALIDATION[^"]*)[^>]+value="(?P[^"]+)' # Number of rows to generate inside the full union test for limited output (mustn't be too large to prevent payload length problems) LIMITED_ROWS_TEST_NUMBER = 15 diff --git a/lib/request/basic.py b/lib/request/basic.py index 7ff5833ec..664cd78e7 100644 --- a/lib/request/basic.py +++ b/lib/request/basic.py @@ -28,10 +28,12 @@ from lib.core.enums import PLACE from lib.core.exception import sqlmapCompressionException from lib.core.htmlentities import htmlEntities from lib.core.settings import DEFAULT_COOKIE_DELIMITER +from lib.core.settings import EVENTVALIDATION_REGEX from lib.core.settings import MAX_CONNECTION_TOTAL_SIZE from lib.core.settings import ML from lib.core.settings import META_CHARSET_REGEX from lib.core.settings import PARSE_HEADERS_LIMIT +from lib.core.settings import VIEWSTATE_REGEX from lib.parse.headers import headersParser from lib.parse.html import htmlParser from thirdparty.chardet import detect @@ -260,3 +262,11 @@ def processResponse(page, responseHeaders): if msg: logger.info("parsed error message: '%s'" % msg) + + for regex in (EVENTVALIDATION_REGEX, VIEWSTATE_REGEX): + match = re.search(regex, page) + if match and PLACE.POST in conf.parameters: + name, value = match.groups() + conf.parameters[PLACE.POST] = re.sub("(%s=)[^&]+" % name, r"\g<1>%s" % value, conf.parameters[PLACE.POST]) + if PLACE.POST in conf.paramDict and name in conf.paramDict[PLACE.POST]: + conf.paramDict[PLACE.POST][name] = value