implemented mechanism for merging cookies by request

This commit is contained in:
Miroslav Stampar 2012-01-11 14:28:08 +00:00
parent f1147035cf
commit 1d0b43b1a2
5 changed files with 42 additions and 54 deletions

View File

@ -49,6 +49,7 @@ from lib.core.exception import sqlmapSilentQuitException
from lib.core.exception import sqlmapValueException from lib.core.exception import sqlmapValueException
from lib.core.exception import sqlmapUserQuitException from lib.core.exception import sqlmapUserQuitException
from lib.core.session import setInjection from lib.core.session import setInjection
from lib.core.settings import DEFAULT_COOKIE_DELIMITER
from lib.core.settings import DEFAULT_GET_POST_DELIMITER from lib.core.settings import DEFAULT_GET_POST_DELIMITER
from lib.core.settings import EMPTY_FORM_FIELDS_REGEX from lib.core.settings import EMPTY_FORM_FIELDS_REGEX
from lib.core.settings import IGNORE_PARAMETERS from lib.core.settings import IGNORE_PARAMETERS
@ -241,7 +242,6 @@ def start():
hostCount = 0 hostCount = 0
cookieStr = "" cookieStr = ""
setCookieAsInjectable = True
for targetUrl, targetMethod, targetData, targetCookie in kb.targetUrls: for targetUrl, targetMethod, targetData, targetCookie in kb.targetUrls:
try: try:
@ -345,31 +345,6 @@ def start():
if conf.nullConnection: if conf.nullConnection:
checkNullConnection() checkNullConnection()
if not conf.dropSetCookie and conf.cj:
cookieStr = ";".join("%s=%s" % (getUnicode(cookie.name), getUnicode(cookie.value)) for _, cookie in enumerate(conf.cj))
if cookieStr:
if PLACE.COOKIE in conf.parameters:
message = "you provided an HTTP Cookie header value. "
message += "The target url provided its own Cookie within "
message += "the HTTP Set-Cookie header. Do you want to "
message += "continue using the HTTP Cookie values that "
message += "you provided? [Y/n] "
test = readInput(message, default="Y")
if not test or test[0] in ("y", "Y"):
setCookieAsInjectable = False
if setCookieAsInjectable:
conf.httpHeaders.append((HTTPHEADER.COOKIE, cookieStr))
conf.parameters[PLACE.COOKIE] = cookieStr
__paramDict = paramToDict(PLACE.COOKIE, cookieStr)
if __paramDict:
conf.paramDict[PLACE.COOKIE] = __paramDict
# TODO: consider the following line in __setRequestParams()
# __testableParameters = True
if (len(kb.injections) == 0 or (len(kb.injections) == 1 and kb.injections[0].place is None)) \ if (len(kb.injections) == 0 or (len(kb.injections) == 1 and kb.injections[0].place is None)) \
and (kb.injection.place is None or kb.injection.parameter is None): and (kb.injection.place is None or kb.injection.parameter is None):

View File

@ -109,6 +109,7 @@ class HTTPHEADER:
CONTENT_RANGE = "Content-Range" CONTENT_RANGE = "Content-Range"
CONTENT_TYPE = "Content-Type" CONTENT_TYPE = "Content-Type"
COOKIE = "Cookie" COOKIE = "Cookie"
SET_COOKIE = "Set-Cookie"
HOST = "Host" HOST = "Host"
PRAGMA = "Pragma" PRAGMA = "Pragma"
PROXY_AUTHORIZATION = "Proxy-Authorization" PROXY_AUTHORIZATION = "Proxy-Authorization"

View File

@ -1442,6 +1442,7 @@ def __setKnowledgeBaseAttributes(flushAll=True):
kb.locks[_] = threading.Lock() kb.locks[_] = threading.Lock()
kb.matchRatio = None kb.matchRatio = None
kb.mergeCookies = None
kb.multiThreadMode = False kb.multiThreadMode = False
kb.nullConnection = None kb.nullConnection = None
kb.pageTemplate = None kb.pageTemplate = None

View File

@ -21,13 +21,16 @@ from lib.core.common import extractRegexResult
from lib.core.common import getUnicode from lib.core.common import getUnicode
from lib.core.common import isWindowsDriveLetterPath from lib.core.common import isWindowsDriveLetterPath
from lib.core.common import posixToNtSlashes from lib.core.common import posixToNtSlashes
from lib.core.common import readInput
from lib.core.common import sanitizeAsciiString from lib.core.common import sanitizeAsciiString
from lib.core.common import singleTimeLogMessage from lib.core.common import singleTimeLogMessage
from lib.core.data import conf from lib.core.data import conf
from lib.core.data import kb from lib.core.data import kb
from lib.core.data import logger from lib.core.data import logger
from lib.core.enums import HTTPHEADER from lib.core.enums import HTTPHEADER
from lib.core.enums import PLACE
from lib.core.exception import sqlmapDataException from lib.core.exception import sqlmapDataException
from lib.core.settings import DEFAULT_COOKIE_DELIMITER
from lib.core.settings import ML from lib.core.settings import ML
from lib.core.settings import META_CHARSET_REGEX from lib.core.settings import META_CHARSET_REGEX
from lib.core.settings import PARSE_HEADERS_LIMIT from lib.core.settings import PARSE_HEADERS_LIMIT
@ -35,27 +38,48 @@ from lib.core.settings import UNICODE_ENCODING
from lib.parse.headers import headersParser from lib.parse.headers import headersParser
from lib.parse.html import htmlParser from lib.parse.html import htmlParser
def forgeHeaders(cookie, ua, referer): def forgeHeaders(items=None):
""" """
Prepare HTTP Cookie, HTTP User-Agent and HTTP Referer headers to use when performing Prepare HTTP Cookie, HTTP User-Agent and HTTP Referer headers to use when performing
the HTTP requests the HTTP requests
""" """
headers = {} headers = dict(conf.httpHeaders)
headers.update(items or {})
for header, value in conf.httpHeaders: for _ in headers.keys():
if cookie and header == HTTPHEADER.COOKIE: if headers[_] is None:
headers[header] = cookie del headers[_]
elif ua and header == HTTPHEADER.USER_AGENT:
headers[header] = ua if conf.cj:
elif referer and header == HTTPHEADER.REFERER: if HTTPHEADER.COOKIE in headers:
headers[header] = referer for cookie in conf.cj:
else: if ("%s=" % cookie.name) in headers[HTTPHEADER.COOKIE]:
headers[header] = value if kb.mergeCookies is None:
message = "you provided a HTTP %s header value. " % HTTPHEADER.COOKIE
message += "The target url provided it's own cookies within "
message += "the HTTP %s header which intersect with yours. " % HTTPHEADER.SET_COOKIE
message += "Do you want to merge them in futher requests? [Y/n] "
test = readInput(message, default="Y")
kb.mergeCookies = not test or test[0] in ("y", "Y")
if kb.mergeCookies:
_ = lambda x: re.sub("%s=[^%s]+" % (cookie.name, DEFAULT_COOKIE_DELIMITER), "%s=%s" % (cookie.name, cookie.value), x, re.I)
headers[HTTPHEADER.COOKIE] = _(headers[HTTPHEADER.COOKIE])
if PLACE.COOKIE in conf.parameters:
conf.parameters[PLACE.COOKIE] = _(conf.parameters[PLACE.COOKIE])
conf.httpHeaders = [(item[0], item[1] if item[0] != HTTPHEADER.COOKIE else _(item[1])) for item in conf.httpHeaders]
elif not kb.testMode:
headers[HTTPHEADER.COOKIE] += "%s %s=%s" % (DEFAULT_COOKIE_DELIMITER, cookie.name, cookie.value)
if kb.testMode:
conf.cj.clear()
if kb.redirectSetCookie and not conf.dropSetCookie: if kb.redirectSetCookie and not conf.dropSetCookie:
if HTTPHEADER.COOKIE in headers: if HTTPHEADER.COOKIE in headers:
headers[HTTPHEADER.COOKIE] = "%s; %s" % (headers[HTTPHEADER.COOKIE], kb.redirectSetCookie) headers[HTTPHEADER.COOKIE] += "%s %s" % (DEFAULT_COOKIE_DELIMITER, kb.redirectSetCookie)
else: else:
headers[HTTPHEADER.COOKIE] = kb.redirectSetCookie headers[HTTPHEADER.COOKIE] = kb.redirectSetCookie

View File

@ -240,7 +240,7 @@ class Connect:
requestMsg += " %s" % httplib.HTTPConnection._http_vsn_str requestMsg += " %s" % httplib.HTTPConnection._http_vsn_str
# Prepare HTTP headers # Prepare HTTP headers
headers = forgeHeaders(cookie, ua, referer) headers = forgeHeaders({ HTTPHEADER.COOKIE: cookie, HTTPHEADER.USER_AGENT: ua, HTTPHEADER.REFERER: referer })
if conf.realTest: if conf.realTest:
headers[HTTPHEADER.REFERER] = "%s://%s" % (conf.scheme, conf.hostname) headers[HTTPHEADER.REFERER] = "%s://%s" % (conf.scheme, conf.hostname)
@ -271,23 +271,13 @@ class Connect:
else: else:
req = urllib2.Request(url, post, headers) req = urllib2.Request(url, post, headers)
if not conf.dropSetCookie and conf.cj:
for _, cookie in enumerate(conf.cj):
if not cookieStr:
cookieStr = "Cookie: "
cookie = getUnicode(cookie)
index = cookie.index(" for ")
cookieStr += "%s; " % cookie[8:index]
if not req.has_header(HTTPHEADER.ACCEPT_ENCODING): if not req.has_header(HTTPHEADER.ACCEPT_ENCODING):
requestHeaders += "%s: identity\n" % HTTPHEADER.ACCEPT_ENCODING requestHeaders += "%s: identity\n" % HTTPHEADER.ACCEPT_ENCODING
requestHeaders += "\n".join("%s: %s" % (key.capitalize() if isinstance(key, basestring) else key, getUnicode(value)) for (key, value) in req.header_items()) requestHeaders += "\n".join("%s: %s" % (key.capitalize() if isinstance(key, basestring) else key, getUnicode(value)) for (key, value) in req.header_items())
if not req.has_header(HTTPHEADER.COOKIE) and cookieStr: if not req.has_header(HTTPHEADER.COOKIE) and conf.cj:
requestHeaders += "\n%s" % cookieStr[:-2] requestHeaders += "\n%s" % ("Cookie: %s" % ";".join("%s=%s" % (getUnicode(cookie.name), getUnicode(cookie.value)) for cookie in conf.cj))
if not req.has_header(HTTPHEADER.CONNECTION): if not req.has_header(HTTPHEADER.CONNECTION):
requestHeaders += "\n%s: close" % HTTPHEADER.CONNECTION requestHeaders += "\n%s: close" % HTTPHEADER.CONNECTION
@ -728,9 +718,6 @@ class Connect:
if kb.testMode: if kb.testMode:
kb.testQueryCount += 1 kb.testQueryCount += 1
if conf.cj:
conf.cj.clear()
if timeBasedCompare: if timeBasedCompare:
return wasLastRequestDelayed() return wasLastRequestDelayed()
elif noteResponseTime: elif noteResponseTime: