Time Based SQL Injection (HSCTF) big-blind writeup

INTRODUCTION

Musyoka Ian
10 min readJun 19, 2021

Hello guys back again with another walkthrough. This time we will be tackling big-blind challenge from HSCTF. According to my opinion the challenge was a bit technical but nothing hard if you took a good look at the challenge. Am actually a part of a Kenyan team and i was asked by one of the members to try out this challenge since it was a blind SQL Injection and i decided to try it that evening after work. I Exploited the challenge and the leaked password which turned out to be the flag for the challenge.

The challenge had dynamic scoring(i think) and during the time of writing this article the points were 444

The challenge had no description but it provided a link. The first step was opening it using a web browser in my case i used Mozilla. The challenge consisted of a login page

I tried credentials like

admin:admin
admin:password
guest:guest

Since it isn’t rare to find some website still using weak credentials. But it didn’t work. I got an error message saying

TODO: Do something here.

Next i decided to run background common enumeration like diresctory brute forcing. Gobuster is a Directory/file & DNS busting tool written in Go. Gobuster is used to brute-force URIs including directories and files as well as DNS subdomains

Next i ran nikto a web server security scanner on the web server. nikto is a pluggable web server and CGI scanner written in Perl, using rfp’s LibWhisker to perform fast security or informational checks.

Once enumerations were running in the background, i decided to pork at the web application manually. There is a login page and this gives us a number of possible tests we can run

  1. We can test for either SQL Injections or NoSQL Injections attacks
  2. We can probably guess that the username is admin and using hydra or burpsuite brute force for a password using using rockyou as our wordlist

But for both of these to happen we have to intercept the request. Burpsuite is my go to web application proxy framework or request interceptor. Next i configured my proxy(foxy proxy) and intercepted the login request with burpsuite

Looking at the request it look basic and it even lacks some security feature like a cross site request forgery token which make it to be vulnerable to a cross site request forgery attack and also it make the login page easily brute forced. cross site request forgery token is a randomized string that is generated by the web application every time we make a login request to the web application. With an invalid cross site request forgery token submitted during the login process, the login process is terminated by the web application. It make brute forcing with automated tools like hydra a pain but you can cook up a simple python script to brute force the login easily (look at my previous articles I’ve done a piece on it).

Enough of that. I decided to avoid a brute force attack for the time being since i didn’t even have an idea about the account lockout policy that the web application had. We might brute force the login and end up locking accounts and that is never good. Next i decide to test for SQL Injection attacks

Adding a double quote to the username field we see from the screenshot below that the web application doesn’t error out

On adding a single quote we get an internal server error. Status code 500

This means that the web application is probably using single quotes to enclose users input

The query structure is probably looking something like

select * FROM (table_name) where user='(our_supplied username)' AND pass='(our_supplied_password)'

On adding a single quote causes unbalanced number of quote and therefore causing the web application to error out with a status code of 500

On adding a comment at the end we see that the web application stops erroring out because we invalidate the end single quote that the web application automatically adds

Now that we are certain that the web application is vulnerable to a SQL Injection attack i saved the login request and ran SQLMap which detects and take advantage of SQL injection vulnerabilities in web applications. Once it detects one or more SQL injections on the target host, the user can choose among a variety of options to perform an extensive back-end database management system fingerprint, retrieve DBMS session user and database, enumerate users, password hashes, privileges, databases, dump entire or user’s specific DBMS tables/columns, run his own SQL statement, read specific files on the file system and more.

Next i decided to try and exploit the SQL Injection manual. I prefer knowing what’s happening under the hood when exploiting a vulnerability rather that just using an automated tool and utilizing the result it found. Also sometimes automated tools miss vulnerability which otherwise you could have found if you could have exploited the vulnerability manually

Looking at the request again we see that we probably can’t use UNION injection to leak the database since the web application errors out with the same error every time. Making the vulnerability a blind SQL Injection which is a bit technical compared to UNION Injection. Next i decided to test for a Time-based Blind SQLi

Basically we use time delays to determine where an injection returned a valid result or not.

In my case an gonna show how i used the time delay to determine where the username i used was valid or now using AND

The payload that i sent to the server was

admin' AND sleep(10);-- -

N/B remember to perform a URL encode

Let me explain the payload

  1. First it will check is the user admin is True:
  2. If the user admin is valid it will then sleep for a period of 10 seconds and return the page back to us

The user condition must be True or Valid for the page to take at least 10 seconds to load

And looking at the screenshot the page took a total of 12 seconds to load

If we change the user name to be something that totally doesn’t exists we see that the page take way less time load the request

Using the comments we can also assume that the server is probably using MySQL as a database management system.

So by using the time delay we can leak the database content one character at a time. How?????

If the query is valid the request will sleep for the amount of time specified and if the query is not valid the script will will return immediately. Using a payload from payloadallthethings we can started leaking the contents from the database

The payload below will leak the database name the web application is using

(select sleep(10) from dual where database() like '%')

The query above will sleep for 10 seconds of the database is like…..

The % in My SQL acts as a wildcard meaning if we read the query again is simply say, sleep 10 second is the database string is anything. This Query should always sleep for 10 seconds

Now to build on our query we will starting brute forcing characters on the left of the wild card. Example:

admin' AND (select sleep(10) from dual where database() like 'a%');-- -

This Query will sleep for a period of 10 second if the database letter starts with a and any other characters in front (remember % == wildcard)

If its true then we start brute forcing the second character

admin' AND (select sleep(10) from dual where database() like 'ab%');-- -

This Query will sleep for a period of 10 second if the database letter starts with a followed by b and any other characters in front

So we will loop through the entire alphabet and digits and special characters and when the request sleep by 10 seconds we’ll believe that the character we were brute forcing at the period of time is probably the correct character. To make the process a little less tedious we are going to create a python script that automates the process of brute forcing characters

Before starting i went back to my recon i had done before and SQLMap had not found the vulnerability

Nikto had found the misconfiguration that are normally found on CTF web applications

And gobuster had absolutely not found anything

Let’s begin creating the python script

First i begun by importing the necessary modules and use the string library to create the entire character set that i was going to use

Sweet now to make the script a little bit cleaner i decided to create the exploit inside a function

Instead of explaining the script after every line of code i wrote i decided to write the entire script and explain once it once done. It’s much simpler that way

So the script will loop the character set and whenever the request take at least 5 seconds to return a result it will consider that request valid

Sorry changed the script sleep time because 10 seconds was too long

Then it will build up the database name in the admin_password variable

Sorry again for the horrible naming

Let’s run the script and see what comes up

After some few trial i found that % sign was a bad char and therefore i added a condition that told the script that % signs were a false positive

And we will be ignoring the last letter since the script will always loop infinitely

Bad code ;)

After getting db the scripts starts looping infinitely without adding any more characters meaning that probably the database is called db

next i tried to leak the MySQL version. I added changed the code just a little bit and also made the queries to be case-sensitive by adding the BINARY word

And ran the script again and looking at the screenshot below we successfully leak the MySQL version that was running in the box

And now using the MySQL version we believe that the underlying operating system is Debian. Remember i blurred the last character because the script doesn’t exit successfully upon completion

I assumed that the table had probably a user column and a pass column. It was a wild guess used from the post parameter variable used to login

So i changed the python code to be as seen in the screenshot below

Ran the script again. Looking at the screenshot below we leak the password using a time based blind SQL Injection

And after the script finished looping the characters we get that the password is

flag_any_info_is_good_info_

But it didn’t look like the flag at first glance since the flag format was

flag{.*}

But i changed the leaked password to be

flag{any_info_is_good_info}

And tried submitting it and voila it worked i had solved the challenge successfully. It was considered a hard challenge but am sure though the walkthrough you’ve seen it was an easy one. Thanks so much for reading the writeup if you liked it don’t forget to clap down below and be sure to follow me so that you won’t miss any upcoming articles

A link to my GitHub page where I’ve uploaded the exploit script is down below

Exploit

--

--