OverTheWire Natas 10-19

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

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 )

Google photo

You are commenting using your Google 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 )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Create a website or blog at WordPress.com

Up ↑

%d bloggers like this: