commit of all sorts (bug fix for heuristics and URI injections, fine tunning of tampering modules with SQL keywords,...)

This commit is contained in:
Miroslav Stampar 2010-10-14 11:06:28 +00:00
parent cf73d9c799
commit 162d01abed
8 changed files with 328 additions and 23 deletions

View File

@ -38,6 +38,7 @@ from lib.core.common import readInput
from lib.core.common import showStaticWords
from lib.core.common import DynamicContentItem
from lib.core.convert import md5hash
from lib.core.convert import urlencode
from lib.core.data import conf
from lib.core.data import kb
from lib.core.data import logger
@ -105,9 +106,6 @@ def heuristicCheckSqlInjection(place, parameter, value):
prefix = ""
postfix = ""
if place == "URI":
return
if conf.prefix or conf.postfix:
if conf.prefix:
prefix = conf.prefix
@ -116,9 +114,11 @@ def heuristicCheckSqlInjection(place, parameter, value):
postfix = conf.postfix
payload = "%s%s%s" % (prefix, randomStr(length=10, alphabet=['"', '\'', ')', '(']), postfix)
if place == "URI":
payload = conf.paramDict[place][parameter].replace('*', payload)
Request.queryPage(payload, place)
result = kb.lastErrorPage and kb.lastErrorPage[0]==kb.lastRequestUID
infoMsg = "heuristics show that %s parameter '%s' is " % (place, parameter)
infoMsg = "(error based) heuristics show that %s parameter '%s' is " % (place, parameter)
if result:
infoMsg += "injectable"
logger.info(infoMsg)

View File

@ -663,6 +663,7 @@ def setPaths():
paths.SQLMAP_CONFIG = os.path.join(paths.SQLMAP_ROOT_PATH, "sqlmap-%s.conf" % randomStr())
paths.COMMON_OUTPUTS = os.path.join(paths.SQLMAP_TXT_PATH, 'common-outputs.txt')
paths.COMMON_TABLES = os.path.join(paths.SQLMAP_TXT_PATH, "common-tables.txt")
paths.SQLKEYWORDS = os.path.join(paths.SQLMAP_TXT_PATH, "keywords.txt")
paths.FUZZ_VECTORS = os.path.join(paths.SQLMAP_TXT_PATH, "fuzz_vectors.txt")
paths.DETECTION_RULES_XML = os.path.join(paths.SQLMAP_XML_PATH, "detection.xml")
paths.ERRORS_XML = os.path.join(paths.SQLMAP_XML_PATH, "errors.xml")

View File

@ -36,6 +36,7 @@ import urlparse
from extra.keepalive import keepalive
from extra.xmlobject import xmlobject
from lib.core.common import getConsoleWidth
from lib.core.common import getFileItems
from lib.core.common import getFileType
from lib.core.common import normalizePath
from lib.core.common import ntToPosixSlashes
@ -1057,12 +1058,13 @@ def __setKnowledgeBaseAttributes():
kb.lastErrorPage = None
kb.headersCount = 0
kb.headersFp = {}
kb.hintValue = None
kb.htmlFp = []
kb.injParameter = None
kb.injPlace = None
kb.injType = None
kb.injections = xmlobject.XMLFile(path=paths.INJECTIONS_XML)
kb.hintValue = None
kb.keywords = getFileItems(paths.SQLKEYWORDS)
kb.nullConnection = None
# Back-end DBMS underlying operating system fingerprint via banner (-b)

View File

@ -307,13 +307,13 @@ class Connect:
if not place:
place = kb.injPlace
if kb.tamperFunctions:
for function in kb.tamperFunctions:
value = function(place, value)
if "GET" in conf.parameters:
get = conf.parameters["GET"] if place != "GET" or not value else value
get = conf.parameters["GET"] if place != "GET" or not value else value
if "POST" in conf.parameters:
post = conf.parameters["POST"] if place != "POST" or not value else value

View File

@ -2,12 +2,32 @@ import re
import string
from lib.core.common import randomRange
from lib.core.exception import sqlmapUnsupportedFeatureException
from lib.core.convert import urldecode
from lib.core.convert import urlencode
from lib.core.data import kb
"""
value -> value with inserted random blanks (e.g., INSERT->IN/**/S/**/ERT)
"""
#TODO: all
#TODO: only do it for deepness = 0 regarding '"
def tamper(place, value):
return value
retVal = value
if value:
if place != "URI":
retVal = urldecode(retVal)
for match in re.finditer(r"[A-Za-z_]+", retVal):
word = match.group()
if len(word) < 2:
continue
if word.upper() in kb.keywords:
newWord = word[0]
for i in xrange(1, len(word) - 1):
newWord += "%s%s" % ("/**/" if randomRange(0,1) else "", word[i])
newWord += word[-1]
retVal = retVal.replace(word, newWord)
if place != "URI":
retVal = urlencode(retVal)
return retVal

View File

@ -2,19 +2,28 @@ import re
import string
from lib.core.common import randomRange
from lib.core.exception import sqlmapUnsupportedFeatureException
from lib.core.convert import urldecode
from lib.core.convert import urlencode
from lib.core.data import kb
"""
value -> chars from value with random case (e.g., INSERT->InsERt)
"""
#TODO: only do it for deepness = 0 regarding '"
def tamper(place, value):
retVal = value
if value:
retVal = ""
for i in xrange(len(value)):
if value[i].isalpha():
retVal += value[i].upper() if randomRange(0,1) else value[i].lower()
else:
retVal += value[i]
if place != "URI":
retVal = urldecode(retVal)
for match in re.finditer(r"[A-Za-z_]+", retVal):
word = match.group()
if word.upper() in kb.keywords:
newWord = str()
for i in xrange(len(word)):
newWord += word[i].upper() if randomRange(0,1) else word[i].lower()
retVal = retVal.replace(word, newWord)
if place != "URI":
retVal = urlencode(retVal)
return retVal

View File

@ -6,12 +6,28 @@ from lib.core.convert import urlencode
"""
' ' -> /**/ (e.g., SELECT id FROM users->SELECT/**/id/**/FROM users)
"""
#TODO: only do it for deepness = 0 regarding '"
def tamper(place, value):
retVal = value
if value:
if place != "URI":
value = urldecode(value)
value = value.replace(" ", "/**/")
retVal = ""
qoute, doublequote, firstspace = False, False, False
for i in xrange(len(value)):
if not firstspace:
firstspace = value[i].isspace()
elif value[i] == '\'':
qoute = not qoute
elif value[i] == '"':
doublequote = not doublequote
elif value[i]==" " and not doublequote and not qoute:
retVal += "/**/"
continue
retVal += value[i]
if place != "URI":
value = urlencode(value)
return value
retVal = urlencode(retVal)
return retVal

257
txt/keywords.txt Normal file
View File

@ -0,0 +1,257 @@
#SQL-92 keywords (reference: http://developer.mimer.com/validator/sql-reserved-words.tml)
ABSOLUTE
ACTION
ADD
ALL
ALLOCATE
ALTER
AND
ANY
ARE 
AS
ASC
ASSERTION
AT
AUTHORIZATION
AVG
BEGIN
BETWEEN
BIT
BIT_LENGTH
BOTH
BY
CALL
CASCADE
CASCADED
CASE
CAST
CATALOG
CHAR
CHAR_LENGTH
CHARACTER
CHARACTER_LENGTH
CHECK
CLOSE
COALESCE
COLLATE
COLLATION
COLUMN
COMMIT
CONDITION
CONNECT
CONNECTION
CONSTRAINT
CONSTRAINTS
CONTAINS
CONTINUE
CONVERT
CORRESPONDING
COUNT
CREATE
CROSS
CURRENT
CURRENT_DATE
CURRENT_PATH
CURRENT_TIME
CURRENT_TIMESTAMP
CURRENT_USER
CURSOR
DATE
DAY
DEALLOCATE
DEC
DECIMAL
DECLARE
DEFAULT
DEFERRABLE
DEFERRED
DELETE
DESC
DESCRIBE
DESCRIPTOR
DETERMINISTIC
DIAGNOSTICS
DISCONNECT
DISTINCT
DO
DOMAIN
DOUBLE
DROP
ELSE
ELSEIF
END
ESCAPE
EXCEPT
EXCEPTION
EXEC
EXECUTE
EXISTS
EXIT
EXTERNAL
EXTRACT
FALSE
FETCH
FIRST
FLOAT
FOR
FOREIGN
FOUND
FROM
FULL
FUNCTION
GET
GLOBAL
GO
GOTO
GRANT
GROUP
HANDLER
HAVING
HOUR
IDENTITY
IF
IMMEDIATE
IN
INDICATOR
INITIALLY
INNER
INOUT
INPUT
INSENSITIVE
INSERT
INT
INTEGER
INTERSECT
INTERVAL
INTO
IS
ISOLATION
JOIN
KEY
LANGUAGE
LAST
LEADING
LEAVE
LEFT
LEVEL
LIKE
LOCAL
LOOP
LOWER
MATCH
MAX
MIN
MINUTE
MODULE
MONTH
NAMES
NATIONAL
NATURAL
NCHAR
NEXT
NO
NOT
NULL
NULLIF
NUMERIC
OCTET_LENGTH
OF
ON
ONLY
OPEN
OPTION
OR
ORDER
OUT
OUTER
OUTPUT
OVERLAPS
PAD
PARAMETER
PARTIAL
PATH
POSITION
PRECISION
PREPARE
PRESERVE
PRIMARY
PRIOR
PRIVILEGES
PROCEDURE
PUBLIC
READ
REAL
REFERENCES
RELATIVE
REPEAT
RESIGNAL
RESTRICT
RETURN
RETURNS
REVOKE
RIGHT
ROLLBACK
ROUTINE
ROWS
SCHEMA
SCROLL
SECOND
SECTION
SELECT
SESSION
SESSION_USER
SET
SIGNAL
SIZE
SMALLINT
SOME
SPACE
SPECIFIC
SQL
SQLCODE
SQLERROR
SQLEXCEPTION
SQLSTATE
SQLWARNING
SUBSTRING
SUM
SYSTEM_USER
TABLE
TEMPORARY
THEN
TIME
TIMESTAMP
TIMEZONE_HOUR
TIMEZONE_MINUTE
TO
TRAILING
TRANSACTION
TRANSLATE
TRANSLATION
TRIM
TRUE
UNDO
UNION
UNIQUE
UNKNOWN
UNTIL
UPDATE
UPPER
USAGE
USER
USING
VALUE
VALUES
VARCHAR
VARYING
VIEW
WHEN
WHENEVER
WHERE
WHILE
WITH
WORK
WRITE
YEAR
ZONE