Levels 0-9 can be found at https://cramhack.com/2019/02/11/overthewire-natas-0-10/
Level 10
User: natas10
Pass: nOpp1igQAkUzaI1GUUjzn1bFVj7xCNzu
Here we see that our input will be sent as a parameter in the command ‘grep -i $key dictionary.txt’ using the form to input ‘. /etc/natas_webpass/natas11’ will become ‘grep -i . /etc/natas_webpass/natas11 dictionary.txt’ What this is doing is searching for lines containing any character because the ‘.’ symbolizes any characters for this command. The -i flag ignores case sensitivity and grep can take in multiple files to search so for our case we are searching both the file containing the password and the dictionary.txt file.
Level 11
User: natas11
Pass: U82q5TCMMQ9xuFoI3dYX61s7OZD9JKoK
Once on the page we see the option to view the source code for the input form. In the php we see a function for xor encryption, a function to load data, save data, and a conditional statement.
The function saveData tells us that they are saving the data as a cookie with the key name ‘data’. Here we also see the encryption and encoding methods.
Original cookie: ClVLIh4ASCsCBE8lAxMacFMZV2hdVVotEhhUJQNVAmhSEV4sFxFeaAw%3D
Take note that the cookie is url encoded depending on the tool we use to grab the cookie. Be sure to convert %3D to ‘=’. We know the original cookie correlates to the default $data which is
$defaultdata = array( “showpassword”=>”no”, “bgcolor”=>”#ffffff”);
Taking the info we have found we must attempt to find the $key used for the xor_encypt function as it is censored in the source code. Xor encryption though generally secure has one major weakness. Xor encryption utilizes a plaintext string, a cipher string, and a key. Once two of the three values are known the encryption method is no longer secure. We have the cipher string and we also have the plaintext string and now we can use these two to discover the key so that we can use the same xor_encryption for a new json array to send via the form.
Let’s first consider what we do have; the cookie which is base64 encoded, the defaultdata array which needs to be json_encoded, and the understanding of xor encryption. Let’s make a php script to do this for us and make things quicker.
To reverse the xor encryption we will place the plain text (defaultarray) as the key and the cookie as the key but, remember that defaultarray needs to be json_encoded before going through the xor encryption.
Using an online php sandbox we can execute php code, I used http://sandbox.onlinephpfunctions.com/
In our output we can see the string ‘qw8J’ which is a sign of a weak encryption key. For xor encryption it is best to have a key longer than the text you plan on encrypting. In this case the key is only 4 characters long. Using this key we can now create our own cookie with a data array telling the server to show us the password.
Here we have it, go to your web browser and use whatever tool you like to change your cookie value for ‘data’ and you will receive the password.
Level 12
User: natas12
Pass: EDXp0pS26wLKHZy1rDBPUZk0RKfLGIR3
First thing we see is that you can choose a file and upload a file. In the sourcecode we can see <input type=”hidden” name=”filename” value=”<? print genRandomString(); ?>.jpg” />
When uploading a file it will be saved with a random string as its name an a .jpg extension. Being that the .jpg is part of the html of the site we can simply change this to .php as there is no verification of file type or extensions in this code. Using PHP we can use a system call to cat the password for the next level.
<?php
$output = shell_exec(‘cat /etc/natas_webpass/natas13’);
echo “<pre>$output</pre>”;
?>
Saving this as a php file and changing the html to change the new file as a .php instead of a .jpg we can upload the file and go to the directory which will reveal the password.
Level 13
User: Natas13
Pass: jmLTY0qiPZBbaKc9341cqPQZBJv7MQbY
else if (! exif_imagetype($_FILES[‘uploadedfile’][‘tmp_name’])) {
echo “File is not an image”;
Looking at the source code we can see that it is using exif_imagetype to determine if the file is a jpg. All this function does is check the magic bytes (initial bytes that specify the filetype) of the file. To trick this function we can use a hex editor to add the magic bytes for a jpg (FF D8 FF DB)or you can just copy the symbols the hex creates in the following php file text.
ÿØÿÛ
<?php
$output = shell_exec(‘cat /etc/natas_webpass/natas14’);
echo “<pre>$output</pre>”;
?>
Same as last time we must edit the html so that the extension for the uploaded file is .php instead of .jpg and by doing so we can upload our payload and receive the password.
Level 14
User: natas14
Pass: Lg96M10TdfaPyVBkJdjymbllQ5L6qdl1
For this level we are given a username field and a password field. Looking at the source code we can see what exactly this input is being used for.
$query = “SELECT * from users where username=\””.$_REQUEST[“username”].”\” and password=\””.$_REQUEST[“password”].”\””;
So our username input and password input are being placed into the following query. There is no input checks or filtering so this challenge is quite easy. In order to output the password all we must do is have the query return something as the conditional statement is:
if(mysql_num_rows(mysql_query($query, $link)) > 0) {
So there are many ways to solve this challenge but I recommend using the ‘hello world’ version of sql injections and use the following:
“ OR “1” = “1” #
This will search all columns of the table ‘users’ for a username we could have entered and then return what the query finds or if 1 = 1 it will print everything. Since 1 = 1 is indeed true the query will print out the discovered info. However since the conditional statement only checks if something will be returned and doesn’t actually return it, we will not see this info. What we will see is the password for the next level.
Level 15
User: natas15
Pass: AwWj0w5cvxrZiONgZ9J5stNVkmxdk39J
The following script can certainly sped up if we just split the two operations of finding the correct characters and finding the correct order. Being that it is a 32 char password and the time to find the password is merely a minute or two I didn’t feel like expanding the two functions.
Level 16:
User: natas16
Pass: WaIHEacj63wnNIBROHeqi3p9t0m5nhmh
This level is very similar to the last however we will be using a blind command injection. Viewing the characters that are filtered we can discover that we can use $(command) to execute commands as it is not filtered by the code. Now let’s try to execute a command such as echo. If we enter ‘$(echo test)’ the response will be all dictionary words including ‘test’ because it is simply echoing this word to the server’s query. If we do something like ‘test$(cat /etc/natas_webpass/natas17)’ we will receive nothing in return. I would have originally expected this to return the results for ‘test’ but it did not. Interestingly enough if we do
‘test$(grep what /etc/web_pass/natas17)’
The response will be the dictionary results for ‘test’ as expected. So likely what is happening is that when the second command contains an output it overrides the original command but does not display it to the webpage. Similarly to the last challenge we can make a script that does a grep command for a char and if the char exists in the password than it should return nothing. If the char is not in the password it should return the results for whatever we put in the search before the command.
Just like the last challenge this script can be much more efficient if we split the two main tasks. Given the simplicity of the challenge I felt no need.
Level 17:
User: natas17
Pass: 8Ps3H0GWbn5rd9S7GmAdgQNdkhPkq9cw
This challenge is very much like level 15 -> 16. The difference here is that we do not recieve any response no matter the input. What can we do with an SQL injection that will help us determine the password? Luckily, there is a sleep operation that we can use with the where clause. Sleep(x) will pause the query for x amount of seconds. So what we will do is add a few second pause if the query finds a match.
As you can probably guess this program would take quite a while to run if we used the same single function program as the past few levels. That being said I have separated the two tasks of finding the correct characters and finding the actual password using the discovered characters.
Level 18:
User: natas18
Pass: xvKIqDjy4OPv7wCRgDlmj0pFsCsDjhdP
Going through the source code you may notice
if(array_key_exists(“username”, $_REQUEST) && array_key_exists(“password”, $_REQUEST)) {
session_id(createID($_REQUEST[“username”]));
The line that is really important in the above code is the ‘session_id(createID(…))’. In order to become admin we need to obtain the session_id for the admin. The function for createID is:
function createID($user) { /* {{{ */
global $maxid;
return rand(1, $maxid);
}
Which is just assigning a value between 1 and 640 as the sessionid for each session. Therefore, we can easily bruteforce this and obtain admin access. We will once again use a python script to do this.
Level 19:
User: natas19
Pass: 4IwIrekcuZlA9OsjOkoUtwU6lhokCPYs
For the first time we are not given source code to view. What we do get is a little hint “This page uses mostly the same code as the previous level, but session IDs are no longer sequential…” which is a bit difficult to understand. It is really unnecessary, just know that most of the code is the same as the previous level. Let’s click login to create a session and see what kind of sessID cookie we receive.
7 digits followed by d
‘3438342’ ‘d’
Now sign in with a user of ‘1’
7 digits followed by d followed by 2 digits
‘3334382’
And ‘12’
7 digits followed by d followed by 4 digits
‘3334382’ ‘d’ ‘3132’
And ‘21’
7 digits followed by d followed by 4 characters
‘3334392’ ‘d’ ‘3231’
And ‘A’
7 digits followed by d followed by 41
Looking at the pattern I first realized that the values after ‘d’ were the hex representation of my input. So we now know it’s 7 characters followed by ‘d’ which is followed by our input in hex. Hex is usually in groups of 2 values so maybe it’s not 7 digits after all? What if it is 6 and then ‘2d’ which when we translate becomes ‘-’. So now we have 6 digits followed by ‘-’ which is followed by our input in hex. Looking at the values of the first 6 digits I do not seem any specific pattern but I have noticed that the highest value these 6 hex values created has been 484. We may not totally understand the pattern here but we do likely have enough info to bruteforce the sessid just as we did in the previous challenge.
Leave a Reply