OverTheWire Natas Level 22 → 23 tutorial!!
Published on 04 Jan 2024
Login
URL: http://natas23.natas.labs.overthewire.org
Credentials: natas23:dIUQcI3uSus1JEOSSWRAEXBG8KbR8tRs
# Using curl (optional):
curl -u natas23:dIUQcI3uSus1JEOSSWRAEXBG8KbR8tRs
-d 'passwd=123iloveyou'
http://natas23.natas.labs.overthewire.org/
Task
Source:
if (array_key_exists("passwd", $_REQUEST)) {
if (strstr($_REQUEST["passwd"], "iloveyou") && ($_REQUEST["passwd"] > 10)) {
echo "<br>The credentials for the next level are:<br>";
echo "<pre>Username: natas24 Password: <censored></pre>";
} else {
echo "<br>Wrong!<br>";
}
}
We need two conditions:
passwd
containsiloveyou
(strstr()
just checks substring).passwd > 10
— here’s the catch: in PHP, when you compare a string to a number, PHP converts the string to a number.
- If the string starts with digits, those digits become the number.
- If it doesn’t start with digits, it becomes
0
.
So a value like 123iloveyou
converts to the number 123
, and 123 > 10
is true.
Solution
Just post a password that starts with a number and contains iloveyou
, e.g.:
123iloveyou
With Python (optional)
import requests
auth = ("natas23", "dIUQcI3uSus1JEOSSWRAEXBG8KbR8tRs")
data = {"passwd": "123iloveyou"}
r = requests.post("http://natas23.natas.labs.overthewire.org/", auth=auth, data=data)
print(r.text)
Password
MeuqmfJ8DDKuTr5pcvzFKSwlxedZYEWd
Why it works
This is classic PHP type juggling:
strstr()
doesn’t require equality, only substring.$_REQUEST["passwd"] > 10
coerces the string to a number, so prefixing digits satisfies the numeric comparison.
Troubleshooting
- Still “Wrong!”? → Ensure your value starts with digits and contains
iloveyou
. - Spaces before digits? → Leading spaces turn into
0
in numeric context. Avoid them. - URL-encoding? → If you send via GET, make sure it’s properly encoded; POST is simpler.
Nice job 🎉 You just beat a sneaky substring + type-juggling combo. On to natas24!
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