diff --git a/tamper/ifnull2casewhenisnull.py b/tamper/ifnull2casewhenisnull.py new file mode 100644 index 000000000..cabea4cc8 --- /dev/null +++ b/tamper/ifnull2casewhenisnull.py @@ -0,0 +1,65 @@ +#!/usr/bin/env python + +""" +Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/) +See the file 'doc/COPYING' for copying permission +""" + +from lib.core.enums import PRIORITY + +__priority__ = PRIORITY.HIGHEST + +def dependencies(): + pass + +def tamper(payload, **kwargs): + """ + Replaces instances like 'IFNULL(A, B)' with 'CASE WHEN ISNULL(A) THEN (B) ELSE (A) END' + + Requirement: + * MySQL + * SQLite (possibly) + * SAP MaxDB (possibly) + + Tested against: + * MySQL 5.0 and 5.5 + + Notes: + * Useful to bypass very weak and bespoke web application firewalls + that filter the IFNULL() and IF() functions + + >>> tamper('IFNULL(1, 2)') + 'CASE WHEN ISNULL(1) THEN (2) ELSE (1) END' + """ + + if payload and payload.find("IFNULL") > -1: + while payload.find("IFNULL(") > -1: + index = payload.find("IFNULL(") + depth = 1 + comma, end = None, None + + for i in xrange(index + len("IFNULL("), len(payload)): + if depth == 1 and payload[i] == ',': + comma = i + + elif depth == 1 and payload[i] == ')': + end = i + break + + elif payload[i] == '(': + depth += 1 + + elif payload[i] == ')': + depth -= 1 + + if comma and end: + _ = payload[index + len("IFNULL("):comma] + __ = payload[comma + 1:end].lstrip() + newVal = "CASE WHEN ISNULL(%s) THEN (%s) ELSE (%s) END" % (_, __, _) + payload = payload[:index] + newVal + payload[end + 1:] + else: + break + + return payload + +