HTB Falafel (Hard) - Writeup
Difficulty: Hard
Initial access combined SQL injection with PHP type juggling to bypass login, gaining admin web access.
A filename length trick bypassed upload restrictions, enabling remote code execution with a PHP reverse shell.
Privilege escalation involved extracting framebuffer data via video group access to find credentials, then using disk group permissions with debugfs for further escalation.
Nmap
The nmap scan revealed two open ports:
Port 80 - Website
First I’ll add falafel.htb to /etc/hosts.
Next, I checked the robots.txt file, but it was empty.
There is a login page:
I tried some basic sql injection and default credentials but it didn’t work.
Now we can look for exposed directories using Feroxbuster.
I’ll use a list from Seclists first:
We’ve successfully found two files:
cyberlaw.txt and Connection.php
Let’s take a look at cyberlaw.txt:
It contains new user “chris” and a hint that we will be able to login without a password.
Login Page
Now we will move to the login page and try to bypass authentication somehow.
My first idea was to run sqlmap against it.
For it to work we will open Burpsuite turn intercept on and catch login request.
Copy the request to a file and save it.
Now we can run sqlmap.
sqlmap -r chris.req
Unfortunately it didn’t work.
Observing the login page’s behavior, we notice it responds with “Try again” when the username doesn’t exist, but returns “Wrong identification: admin” when the username is valid.
Meaning we can try blind sql injection. In order to do that we can use –string parameter.
sqlmap -r chris.req --string "Wrong identification"
Now all we need to do is add –dump parameter and wait.
sqlmap -r chris.req --string "Wrong identification" --dump
Copy those two passwords into a file and save.
Then proceed with hashcat module 0 - which is md5.
After waiting for some time we get a result.
Elevate from chris to admin
We can log in using the credentials chris:juggling.
Chris’s profile description heavily hints at a PHP type juggling vulnerability.
The admin’s password hash starts with 0e, which PHP interprets as scientific notation for zero when using loose comparison (==).
In the code, authentication likely uses a loose comparison like:
if ($password_hash == $stored_hash) { ... }
Because the hash starts with 0e, PHP treats it as 0. If we supply a password that when hashed also evaluates to 0 under loose comparison the comparison becomes:
0 == 0
which evaluates to true, allowing us to bypass authentication and gain admin access.
We can use this post as a resource:
https://web.archive.org/web/20220118182443/https://www.whitehatsec.com/blog/magic-hashes/
There is a magic number that when hashed will start with 0e.
We can verify that:
Now if we use this as a password it will evaluate to 0, leading to authentication bypass.
File Upload to shell access
Let’s login with admin:240610708
We have ability to upload an image from the URL that we can specify.
First test a normal .png file:
Output:
It discloses two important information:
- File upload location
- We’re using wget to upload a file
Let’s check if we can reach this file:
We can reach this file, meaning now we have to bypass filter to upload php file containing a reverse shell.
First thing I tried was uploading test.php%00.png, but it gave an error.
We can try other methods to bypass filters but they didn’t work.
The admin’s profile description hints at “Limits,” specifically referring to wget’s filename character length limit.
Linux character limit for a filename is 255, but wget will shorten filename to 236 characters which can be abused to bypass extension filter.
Let’s first check it by uploading a file with 255 character long filename:
251 characters of A’s and 4 characters for .png, resulting in 255 characters total.
Now upload it with python server to the site.
We can copy the truncated filename and use the wc -c command to count its length in characters.
How to exploit it?
Wget truncates filenames longer than 236 characters. By naming a file with 232 “A” characters + .php.png (240 chars total), the last 4 .png get cut off, leaving .php and bypassing upload filters.
Contents of this file in our case will be pentest monkey reverse shell.
https://github.com/pentestmonkey/php-reverse-shell
After we upload our reverse shell we will be able to curl it (notice that we specify previously discovered file location):
Resulting in a shell access:
Privesc to Moshe
We have shell access as www-data, meaning the first thing I will do is enumerating web root directory.
Connection.php exposed credentials.
moshe:falafelIsReallyTasty
Now we can switch user.
We can retrieve a flag:
Privesc to Yossi
Moshe is a part of video group:
I used this article as reference:
https://steflan-security.com/linux-privilege-escalation-exploiting-user-groups/#video
We will copy /dev/fb0 to /tmp, fb0 is framebuffer device.
In order to view this file we’re also going to need the screen resolution:
Screen resolution is:
1176x885
We have ssh access meaning we can transfer this file with scp utility.
I’ll use perl script from previous article.
#!/usr/bin/perl -w
$w = shift || 240;
$h = shift || 320;
$pixels = $w * $h;
open OUT, "|pnmtopng" or die "Can't pipe pnmtopng: $!\n";
printf OUT "P6%d %d\n255\n", $w, $h;
while ((read STDIN, $raw, 2) and $pixels--) {
$short = unpack('S', $raw);
print OUT pack("C3",
($short & 0xf800) >> 8,
($short & 0x7e0) >> 3,
($short & 0x1f) << 3);
}
close OUT;
This script will convert .raw file to .png:
Now we can view it:
It discloses a password:
yossi:MoshePlzStopHackingMe!
Privesc to root
We’ll login via ssh as yossi:
We’re in disk group which can be abused.
First we’ll check mounted filesystems:
Ideally we want a filesystem with / directory mounted.
We’ll now use debugfs to enter this filesystem:
We can also get root’s ssh key:
Lastly save it to a file on kali and login: