mirror of
				https://github.com/sqlmapproject/sqlmap.git
				synced 2025-10-31 07:57:47 +03:00 
			
		
		
		
	Merge branch 'master' of github.com:sqlmapproject/sqlmap
This commit is contained in:
		
						commit
						a0b9e0f1c5
					
				|  | @ -22,6 +22,7 @@ from lib.core.common import extractTextTagContent | |||
| from lib.core.common import findDynamicContent | ||||
| from lib.core.common import Format | ||||
| from lib.core.common import getLastRequestHTTPError | ||||
| from lib.core.common import getPublicTypeMembers | ||||
| from lib.core.common import getSortedInjectionTests | ||||
| from lib.core.common import getUnicode | ||||
| from lib.core.common import intersect | ||||
|  | @ -42,6 +43,8 @@ from lib.core.data import kb | |||
| from lib.core.data import logger | ||||
| from lib.core.datatype import AttribDict | ||||
| from lib.core.datatype import InjectionDict | ||||
| from lib.core.dicts import FROM_DUMMY_TABLE | ||||
| from lib.core.enums import DBMS | ||||
| from lib.core.enums import HEURISTIC_TEST | ||||
| from lib.core.enums import HTTPHEADER | ||||
| from lib.core.enums import HTTPMETHOD | ||||
|  | @ -55,7 +58,7 @@ from lib.core.exception import SqlmapUserQuitException | |||
| from lib.core.settings import FORMAT_EXCEPTION_STRINGS | ||||
| from lib.core.settings import HEURISTIC_CHECK_ALPHABET | ||||
| from lib.core.settings import SUHOSIN_MAX_VALUE_LENGTH | ||||
| from lib.core.settings import UNKNOWN_DBMS_VERSION | ||||
| from lib.core.settings import UNKNOWN_DBMS | ||||
| from lib.core.settings import LOWER_RATIO_BOUND | ||||
| from lib.core.settings import UPPER_RATIO_BOUND | ||||
| from lib.core.settings import IDS_WAF_CHECK_PAYLOAD | ||||
|  | @ -441,11 +444,17 @@ def checkSqlInjection(place, parameter, value): | |||
|                             configUnion(test.request.char, test.request.columns) | ||||
| 
 | ||||
|                             if not Backend.getIdentifiedDbms(): | ||||
|                                 if not kb.heuristicDbms: | ||||
|                                     kb.heuristicDbms = heuristicCheckDbms(injection) or UNKNOWN_DBMS | ||||
| 
 | ||||
|                                 if kb.heuristicDbms == UNKNOWN_DBMS: | ||||
|                                     warnMsg = "using unescaped version of the test " | ||||
|                                     warnMsg += "because of zero knowledge of the " | ||||
|                                     warnMsg += "back-end DBMS. You can try to " | ||||
|                                     warnMsg += "explicitly set it using option '--dbms'" | ||||
|                                     singleTimeWarnMessage(warnMsg) | ||||
|                                 else: | ||||
|                                     Backend.forceDbms(kb.heuristicDbms) | ||||
| 
 | ||||
|                             if unionExtended: | ||||
|                                 infoMsg = "automatically extending ranges " | ||||
|  | @ -582,6 +591,32 @@ def checkSqlInjection(place, parameter, value): | |||
| 
 | ||||
|     return injection | ||||
| 
 | ||||
| def heuristicCheckDbms(injection): | ||||
|     retVal = None | ||||
| 
 | ||||
|     if not Backend.getIdentifiedDbms() and len(injection.data) == 1 and PAYLOAD.TECHNIQUE.BOOLEAN in injection.data: | ||||
|         pushValue(kb.injection) | ||||
|         kb.injection = injection | ||||
|         randStr1, randStr2 = randomStr(), randomStr() | ||||
| 
 | ||||
|         for dbms in getPublicTypeMembers(DBMS, True): | ||||
|             Backend.forceDbms(dbms) | ||||
| 
 | ||||
|             if checkBooleanExpression("(SELECT '%s'%s)='%s'" % (randStr1, FROM_DUMMY_TABLE.get(dbms, ""), randStr1)): | ||||
|                 if not checkBooleanExpression("(SELECT '%s'%s)='%s'" % (randStr1, FROM_DUMMY_TABLE.get(dbms, ""), randStr2)): | ||||
|                     retVal = dbms | ||||
|                     break | ||||
| 
 | ||||
|         Backend.flushForcedDbms() | ||||
|         kb.injection = popValue() | ||||
| 
 | ||||
|     if retVal: | ||||
|         infoMsg = "heuristic test showed that the back-end DBMS " | ||||
|         infoMsg += "could be '%s' " % retVal | ||||
|         logger.info(infoMsg) | ||||
| 
 | ||||
|     return retVal | ||||
| 
 | ||||
| def checkFalsePositives(injection): | ||||
|     """ | ||||
|     Checks for false positives (only in single special cases) | ||||
|  | @ -723,7 +758,7 @@ def heuristicCheckSqlInjection(place, parameter): | |||
|             kb.ignoreCasted = readInput(message, default='Y' if conf.multipleTargets else 'N').upper() != 'N' | ||||
| 
 | ||||
|     elif result: | ||||
|         infoMsg += "be injectable (possible DBMS: %s)" % (Format.getErrorParsedDBMSes() or UNKNOWN_DBMS_VERSION) | ||||
|         infoMsg += "be injectable (possible DBMS: %s)" % (Format.getErrorParsedDBMSes() or UNKNOWN_DBMS) | ||||
|         logger.info(infoMsg) | ||||
| 
 | ||||
|     else: | ||||
|  |  | |||
|  | @ -122,6 +122,7 @@ from lib.core.settings import SUPPORTED_DBMS | |||
| from lib.core.settings import TEXT_TAG_REGEX | ||||
| from lib.core.settings import TIME_STDEV_COEFF | ||||
| from lib.core.settings import UNICODE_ENCODING | ||||
| from lib.core.settings import UNKNOWN_DBMS | ||||
| from lib.core.settings import UNKNOWN_DBMS_VERSION | ||||
| from lib.core.settings import URI_QUESTION_MARKER | ||||
| from lib.core.settings import URLENCODE_CHAR_LIMIT | ||||
|  |  | |||
|  | @ -1526,6 +1526,7 @@ def _setKnowledgeBaseAttributes(flushAll=True): | |||
|     kb.fileReadMode = False | ||||
|     kb.forcedDbms = None | ||||
|     kb.headersFp = {} | ||||
|     kb.heuristicDbms = None | ||||
|     kb.heuristicTest = None | ||||
|     kb.hintValue = None | ||||
|     kb.htmlFp = [] | ||||
|  |  | |||
|  | @ -36,7 +36,8 @@ UPPER_RATIO_BOUND = 0.98 | |||
| # Markers for special cases when parameter values contain html encoded characters | ||||
| PARAMETER_AMP_MARKER = "__AMP__" | ||||
| PARAMETER_SEMICOLON_MARKER = "__SEMICOLON__" | ||||
| PARTIAL_VALUE_MARKER = "__PARTIAL__" | ||||
| PARTIAL_VALUE_MARKER = "__PARTIAL_VALUE__" | ||||
| PARTIAL_HEX_VALUE_MARKER = "__PARTIAL_HEX_VALUE__" | ||||
| URI_QUESTION_MARKER = "__QUESTION_MARK__" | ||||
| ASTERISK_MARKER = "__ASTERISK_MARK__" | ||||
| 
 | ||||
|  | @ -111,6 +112,9 @@ INFERENCE_EQUALS_CHAR = "=" | |||
| # Character used for operation "not-equals" in inference | ||||
| INFERENCE_NOT_EQUALS_CHAR = "!=" | ||||
| 
 | ||||
| # String used for representation of unknown dbms | ||||
| UNKNOWN_DBMS = "Unknown" | ||||
| 
 | ||||
| # String used for representation of unknown dbms version | ||||
| UNKNOWN_DBMS_VERSION = "Unknown" | ||||
| 
 | ||||
|  | @ -459,7 +463,7 @@ VALID_TIME_CHARS_RUN_THRESHOLD = 100 | |||
| CHECK_ZERO_COLUMNS_THRESHOLD = 10 | ||||
| 
 | ||||
| # Boldify all logger messages containing these "patterns" | ||||
| BOLD_PATTERNS = ("' injectable", "might be injectable", "' is vulnerable", "is not injectable", "test failed", "test passed", "live test final result") | ||||
| BOLD_PATTERNS = ("' injectable", "might be injectable", "' is vulnerable", "is not injectable", "test failed", "test passed", "live test final result", "heuristic test showed") | ||||
| 
 | ||||
| # Generic www root directory names | ||||
| GENERIC_DOC_ROOT_DIRECTORY_NAMES = ("htdocs", "wwwroot", "www") | ||||
|  |  | |||
|  | @ -687,7 +687,7 @@ class Connect(object): | |||
|         else: | ||||
|             uri = conf.url | ||||
| 
 | ||||
|         if place == PLACE.CUSTOM_HEADER: | ||||
|         if value and place == PLACE.CUSTOM_HEADER: | ||||
|             if not auxHeaders: | ||||
|                 auxHeaders = {} | ||||
|             auxHeaders[value.split(',')[0]] = value.split(',', 1)[1] | ||||
|  |  | |||
|  | @ -42,6 +42,7 @@ from lib.core.settings import INFERENCE_GREATER_CHAR | |||
| from lib.core.settings import INFERENCE_EQUALS_CHAR | ||||
| from lib.core.settings import INFERENCE_NOT_EQUALS_CHAR | ||||
| from lib.core.settings import MAX_TIME_REVALIDATION_STEPS | ||||
| from lib.core.settings import PARTIAL_HEX_VALUE_MARKER | ||||
| from lib.core.settings import PARTIAL_VALUE_MARKER | ||||
| from lib.core.settings import VALID_TIME_CHARS_RUN_THRESHOLD | ||||
| from lib.core.threads import getCurrentThreadData | ||||
|  | @ -65,10 +66,17 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None | |||
|     retVal = hashDBRetrieve(expression, checkConf=True) | ||||
| 
 | ||||
|     if retVal: | ||||
|         if PARTIAL_VALUE_MARKER in retVal: | ||||
|         if PARTIAL_HEX_VALUE_MARKER in retVal: | ||||
|             retVal = retVal.replace(PARTIAL_HEX_VALUE_MARKER, "") | ||||
| 
 | ||||
|             if retVal and conf.hexConvert: | ||||
|                 partialValue = retVal | ||||
|                 infoMsg = "resuming partial value: %s" % safecharencode(partialValue) | ||||
|                 logger.info(infoMsg) | ||||
|         elif PARTIAL_VALUE_MARKER in retVal: | ||||
|             retVal = retVal.replace(PARTIAL_VALUE_MARKER, "") | ||||
| 
 | ||||
|             if retVal: | ||||
|             if retVal and not conf.hexConvert: | ||||
|                 partialValue = retVal | ||||
|                 infoMsg = "resuming partial value: %s" % safecharencode(partialValue) | ||||
|                 logger.info(infoMsg) | ||||
|  | @ -545,7 +553,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None | |||
|             finalValue = decodeHexValue(finalValue) if conf.hexConvert else finalValue | ||||
|             hashDBWrite(expression, finalValue) | ||||
|         elif partialValue: | ||||
|             hashDBWrite(expression, "%s%s" % (PARTIAL_VALUE_MARKER, partialValue)) | ||||
|             hashDBWrite(expression, "%s%s" % (PARTIAL_VALUE_MARKER if not conf.hexConvert else PARTIAL_HEX_VALUE_MARKER, partialValue)) | ||||
| 
 | ||||
|     if conf.hexConvert and not abortedFlag: | ||||
|         infoMsg = "\r[%s] [INFO] retrieved: %s  %s\n" % (time.strftime("%X"), filterControlChars(finalValue), " " * retrievedLength) | ||||
|  |  | |||
|  | @ -3354,6 +3354,41 @@ | |||
|             <item value="r'performed 112 queries'" console_output="True"/> | ||||
|         </parse> | ||||
|     </case> | ||||
|     <case name="Custom GET parameter injection mark"> | ||||
|         <switches> | ||||
|             <verbose value="2"/> | ||||
|             <url value="http://debiandev/sqlmap/mysql/get_int.php?id=1*"/> | ||||
|             <tech value="B"/> | ||||
|             <getBanner value="True"/> | ||||
|         </switches> | ||||
|         <parse> | ||||
|             <item value="banner:    '5.1.66-0+squeeze1'"/> | ||||
|         </parse> | ||||
|     </case> | ||||
|     <case name="Custom POST data injection mark"> | ||||
|         <switches> | ||||
|             <verbose value="2"/> | ||||
|             <url value="http://debiandev/sqlmap/mysql/post_int.php"/> | ||||
|             <data value="id=1*"/> | ||||
|             <tech value="E"/> | ||||
|             <getBanner value="True"/> | ||||
|         </switches> | ||||
|         <parse> | ||||
|             <item value="banner:    '5.1.66-0+squeeze1'"/> | ||||
|         </parse> | ||||
|     </case> | ||||
|     <case name="Custom HTTP header (UA) injection mark"> | ||||
|         <switches> | ||||
|             <verbose value="2"/> | ||||
|             <url value="http://debiandev/sqlmap/mysql/header_str.php"/> | ||||
|             <headers value="User-Agent: 1*"/> | ||||
|             <tech value="U"/> | ||||
|             <getBanner value="True"/> | ||||
|         </switches> | ||||
|         <parse> | ||||
|             <item value="banner:    '5.1.66-0+squeeze1'"/> | ||||
|         </parse> | ||||
|     </case> | ||||
|     <case name="Estimated time of arrival"> | ||||
|         <switches> | ||||
|             <verbose value="2"/> | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user