We covered a scenario of blind SQL Injection where the web application accepts user input without sanitization or filtering. We used a blind SQL query to guess the password by guessing the characters and their order. We finally wrapped this up with a simple python script that does the job.. This was part of OverTheWire War Games Natas Level 15

Challenge Overview

The challenge presents a username input box to check if a username exists. Examining the source code reveals a table named users with usernames and passwords columns, both with a maximum of 64 characters. The password for each challenge is typically a maximum of 32 characters. The username input is taken as a GET request and passed directly into an SQL query without filtering. The query is select from users where username = '[user_input]'. A debug parameter in the URL can reveal the executed query. My goal is to find the password for the user natas16. This is a blind SQL injection because there’s no direct way to see the password; I can only check if a username exists.

Exploitation Strategy – Using the LIKE statement

I will use the SQL LIKE statement to guess the password character by character. The LIKE statement helps determine if a character exists within a column. For example:

  • database LIKE 'S%' checks if the database name starts with ‘S’.
  • table_name LIKE '%A' checks if the table name ends with ‘A’.

Manually guessing each character is tedious, so I will use a Python script.

Python Script Breakdown

  1. Initialization:
    • I define authentication parameters (username and password for the previous level).
    • I generate a character set including letters and digits, as passwords can contain uppercase, lowercase, and numbers.
    • I initialize an empty dictionary to store valid password characters.
    • I define a string user_exists_string = "This user exists." to check against the application’s response.
  2. Finding Valid Characters:
    • The script sends an SQL query like: username=natas16" AND password LIKE BINARY "%<char>%" --
      • natas16": Closes the initial double quote and specifies the target user.
      • AND password LIKE BINARY "%<char>%": Checks if the character <char> exists anywhere in the password. BINARY is used because the column’s collation is unknown.
      • The two percentage signs (%) mean the character can be anywhere in the password.
    • If the application responds with “This user exists,” it means the character is part of the password.
    • The script iterates through the generated character set, and if a character is valid, it’s added to the password_dictionary.
  3. Determining Character Order:
    • I initialize an empty list for the ordered password.
    • I iterate 32 times (assuming max password length).
    • For each position, I try appending each valid character (from password_dictionary) to the currently known part of the password.
    • The query will be like: username=natas16" AND password LIKE BINARY "<known_password_part><test_char>%" --
      • This checks if the password starts with the known_password_part followed by the test_char.
    • If “This user exists” is returned, the test_char is correct for the current position, and it’s added to the password being built.
    • The script prints its attempts, showing how it builds the password character by character.

Manual Example

I can manually test this by inputting a query like: natas16" AND password LIKE BINARY "%t%" --. If this returns “This user exists,” then ‘t’ is in the password. To check if the password ends with ‘t’, the query would be: natas16" AND password LIKE BINARY "%t" --.

Result

The script successfully retrieves the password for Natas Level 16.

Natas Level 16 Password:

TRD7iZrd5gATjj9OkPEuaOlfEjHqj32V

Technical Commands/Queries

While there are no traditional “terminal commands” in this video, the following SQL injection payloads were used or discussed:

  • SQL query structure shown in source code:SQLselect from users where username = "[user_input]"
  • Example of LIKE statement for database name:SQLdatabase LIKE 'S%'
  • Example of LIKE statement for table name:SQLtable_name LIKE 'A'
  • Python script’s SQL query to find valid characters:SQLusername=natas16" AND password LIKE BINARY "%<char>%" --
  • Python script’s SQL query to determine character order:SQLusername=natas16" AND password LIKE BINARY "<known_password_part><test_char>%" --
  • Manual test query example from the video:SQLnatas16" AND password LIKE BINARY "%t" --

The video also mentions using the ?debug parameter in the URL to view the SQL query.

Video Walkthrough

About the Author

Mastermind Study Notes is a group of talented authors and writers who are experienced and well-versed across different fields. The group is led by, Motasem Hamdan, who is a Cybersecurity content creator and YouTuber.

View Articles