<commit_before>#!/usr/bin/env python

"""
$Id$

Copyright (c) 2006-2010 sqlmap developers (http://sqlmap.sourceforge.net/)
See the file 'doc/COPYING' for copying permission
"""

import re
import socket
import time

from difflib import SequenceMatcher

from lib.core.agent import agent
from lib.core.common import beep
from lib.core.common import getUnicode
from lib.core.common import randomInt
from lib.core.common import randomStr
from lib.core.common import readInput
from lib.core.common import showStaticWords
from lib.core.common import wasLastRequestError
from lib.core.common import DynamicContentItem
from lib.core.data import conf
from lib.core.data import kb
from lib.core.data import logger
from lib.core.data import paths
from lib.core.enums import HTTPMETHOD
from lib.core.enums import NULLCONNECTION
from lib.core.exception import sqlmapConnectionException
from lib.core.exception import sqlmapGenericException
from lib.core.exception import sqlmapNoneDataException
from lib.core.exception import sqlmapUserQuitException
from lib.core.exception import sqlmapSilentQuitException
from lib.core.session import setString
from lib.core.session import setRegexp
from lib.request.connect import Connect as Request

def checkSqlInjection(place, parameter, value, parenthesis):
    """
    This function checks if the GET, POST, Cookie, User-Agent
    parameters are affected by a SQL injection vulnerability and
    identifies the type of SQL injection:

      * Unescaped numeric injection
      * Single quoted string injection
      * Double quoted string injection
    """

    logic = conf.logic
    randInt = randomInt()
    randStr = randomStr()
    prefix = ""
    postfix = ""
    retVal = None

    if conf.prefix or conf.postfix:
        if conf.prefix:
            prefix = conf.prefix

        if conf.postfix:
            postfix = conf.postfix

    for case in kb.injections.root.case:
        positive = case.test.positive
        negative = case.test.negative

        if not prefix and not postfix and case.name == "custom":
            continue

        infoMsg  = "testing %s (%s) injection " % (case.desc, logic)
        infoMsg += "on %s parameter '%s'" % (place, parameter)
        logger.info(infoMsg)

        payload = agent.payload(place, parameter, value, positive.format % eval(positive.params))
        trueResult = Request.queryPage(payload, place)

        if trueResult:
            payload = agent.payload(place, parameter, value, negative.format % eval(negative.params))

            falseResult = Request.queryPage(payload, place)

            if not falseResult:
                infoMsg  = "%s parameter '%s' is %s (%s) injectable " % (place, parameter, case.desc, logic)
                infoMsg += "with %d parenthesis" % parenthesis
                logger.info(infoMsg)

                if conf.beep:
                    beep()

                retVal = case.name
                break

    kb.paramMatchRatio[(place, parameter)] = conf.matchRatio

    return retVal

def heuristicCheckSqlInjection(place, parameter, value):
    if kb.nullConnection:
        debugMsg  = "heuristic checking skipped "
        debugMsg += "because NULL connection used"
        logger.debug(debugMsg)
        return

    prefix = ""
    postfix = ""

    if conf.prefix or conf.postfix:
        if conf.prefix:
            prefix = conf.prefix

        if conf.postfix:
            postfix = conf.postfix

    payload = "%s%s%s" % (prefix, randomStr(length=10, alphabet=['"', '\'', ')', '(']), postfix)
    payload = agent.payload(place, parameter, value, payload)
    Request.queryPage(payload, place, raise404=False)
    result = wasLastRequestError()

    infoMsg  = "(error based) heuristics shows that %s " % place
    infoMsg += "parameter '%s' is " % parameter

    if result:
        infoMsg += "injectable (possible DBMS: %s)" % kb.htmlFp[-1]
        logger.info(infoMsg)
    else:
        infoMsg += "not injectable"
        logger.warning(infoMsg)

def checkDynParam(place, parameter, value):
    """
    This function checks if the url parameter is dynamic. If it is
    dynamic, the content of the page differs, otherwise the
    dynamicity might depend on another parameter.
    """

    infoMsg = "testing if %s parameter '%s' is dynamic" % (place, parameter)
    logger.info(infoMsg)

    randInt = randomInt()
    payload = agent.payload(place, parameter, value, getUnicode(randInt))
    dynResult = Request.queryPage(payload, place)

    if True == dynResult:
        return False<commit_msg>tuning detection engine (None results from queryPage/comparison should not be treated as False in checkSqlInjection routine - None is returned when error is detected)<commit_after>#!/usr/bin/env python

"""
$Id$

Copyright (c) 2006-2010 sqlmap developers (http://sqlmap.sourceforge.net/)
See the file 'doc/COPYING' for copying permission
"""

import re
import socket
import time

from difflib import SequenceMatcher

from lib.core.agent import agent
from lib.core.common import beep
from lib.core.common import getUnicode
from lib.core.common import randomInt
from lib.core.common import randomStr
from lib.core.common import readInput
from lib.core.common import showStaticWords
from lib.core.common import wasLastRequestError
from lib.core.common import DynamicContentItem
from lib.core.data import conf
from lib.core.data import kb
from lib.core.data import logger
from lib.core.data import paths
from lib.core.enums import HTTPMETHOD
from lib.core.enums import NULLCONNECTION
from lib.core.exception import sqlmapConnectionException
from lib.core.exception import sqlmapGenericException
from lib.core.exception import sqlmapNoneDataException
from lib.core.exception import sqlmapUserQuitException
from lib.core.exception import sqlmapSilentQuitException
from lib.core.session import setString
from lib.core.session import setRegexp
from lib.request.connect import Connect as Request

def checkSqlInjection(place, parameter, value, parenthesis):
    """
    This function checks if the GET, POST, Cookie, User-Agent
    parameters are affected by a SQL injection vulnerability and
    identifies the type of SQL injection:

      * Unescaped numeric injection
      * Single quoted string injection
      * Double quoted string injection
    """

    logic = conf.logic
    randInt = randomInt()
    randStr = randomStr()
    prefix = ""
    postfix = ""
    retVal = None

    if conf.prefix or conf.postfix:
        if conf.prefix:
            prefix = conf.prefix

        if conf.postfix:
            postfix = conf.postfix

    for case in kb.injections.root.case:
        positive = case.test.positive
        negative = case.test.negative

        if not prefix and not postfix and case.name == "custom":
            continue

        infoMsg  = "testing %s (%s) injection " % (case.desc, logic)
        infoMsg += "on %s parameter '%s'" % (place, parameter)
        logger.info(infoMsg)

        payload = agent.payload(place, parameter, value, positive.format % eval(positive.params))
        trueResult = Request.queryPage(payload, place)

        if trueResult == True:
            payload = agent.payload(place, parameter, value, negative.format % eval(negative.params))

            falseResult = Request.queryPage(payload, place)

            if falseResult == False:
                infoMsg  = "%s parameter '%s' is %s (%s) injectable " % (place, parameter, case.desc, logic)
                infoMsg += "with %d parenthesis" % parenthesis
                logger.info(infoMsg)

                if conf.beep:
                    beep()

                retVal = case.name
                break

    kb.paramMatchRatio[(place, parameter)] = conf.matchRatio

    return retVal

def heuristicCheckSqlInjection(place, parameter, value):
    if kb.nullConnection:
        debugMsg  = "heuristic checking skipped "
        debugMsg += "because NULL connection used"
        logger.debug(debugMsg)
        return

    prefix = ""
    postfix = ""

    if conf.prefix or conf.postfix:
        if conf.prefix:
            prefix = conf.prefix

        if conf.postfix:
            postfix = conf.postfix

    payload = "%s%s%s" % (prefix, randomStr(length=10, alphabet=['"', '\'', ')', '(']), postfix)
    payload = agent.payload(place, parameter, value, payload)
    Request.queryPage(payload, place, raise404=False)
    result = wasLastRequestError()

    infoMsg  = "(error based) heuristics shows that %s " % place
    infoMsg += "parameter '%s' is " % parameter

    if result:
        infoMsg += "injectable (possible DBMS: %s)" % (kb.htmlFp[-1] if kb.htmlFp else 'Unknown')
        logger.info(infoMsg)
    else:
        infoMsg += "not injectable"
        logger.warning(infoMsg)

def checkDynParam(place, parameter, value):
    """
    This function checks if the url parameter is dynamic. If it is
    dynamic, the content of the page differs, otherwise the
    dynamicity might depend on another parameter.
    """

    infoMsg = "testing if %s parameter '%s' is dynamic" % (place, parameter)
    logger.info(infoMsg)

    randInt = randomInt()
    payload = agent.payload(place, parameter, value, getUnicode(randInt))
    dynResult = Request.queryPage(payload, place)

    if True == dynResult:
        return False
{'fraction_non_alphanumeric': 0.09091889559965488, 'fraction_numerical': 0.0030198446937014668, 'mean_word_length': 2.9060657118786857, 'pattern_counts': {'":': 2, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4705282', 'n_tokens_mistral': 2626, 'n_tokens_neox': 2499, 'n_words': 822}