Tales from the hunt: A "fun" SQL Injection without sqlmap

On the weekend, I came across an interesting SQL injection vulnerability whilst researching on a financing related website.

I expected the website to have vulnerabilities, as I'd earlier found an IDOR that allowed for the read/write of contacts who'd receive emails across accounts, but I was surprised SQL injection was possible since it was utilizing Microsoft URL Scan – I'd wrongly assumed it'd stop everything.

I managed to find an injection point in a POST request inside JSON, but with sqlmap I was unable to retrieve data from the table, but I was at least able to prove that time-based injection was possible. Unfortunately for me, Synack Red Team focuses on impact so I had to prove I could do more than do a sleep – but I at least had a working payload:

'); WAITFOR DELAY '0:0:5' --

I did some investigation using the absolutely fantastic tool db<>fiddle to see what my options were to extract some data, and after some trial and error, I was able to get the following to work to at least show me the length of the current username:

IF (LEN(USER)>1) WAITFOR DELAY '00:00:5' --

With trial and error, I then scripted something to iterate with like to give me the current username:

IF (USER like '<CHAR>%') WAITFOR DELAY '0:0:5' --

By iterating through each character with like and using the %, I was able to determine the username – slightly more exciting.

I was able to then verify the name by doing the following:

IF (USER = '<STRING>') WAITFOR DELAY '0:0:5' --

I then repeated this with HOST_NAME, @@VERSION, and DB_NAME and I had enough to submit a report.

In Synack terms, this is a partial SQLi as I did not retrieve data from inside the tables, but at this point I just wanted to put it in before the target went offline or someone beat me to reporting it.

An interesting find that has definitely piqued my interest in manual injection again! Certainly not the most difficult, but it definitely gave a great deal of satisfaction!