Use POSIX file capabilities and PHP to create a backdoor that opens a root back-channel to the attacker’s PC on port TCP 53 when a PHP page is called with a special url.
by Emeric Nasi
Also the author suppose the reader have a good base about GNU Linux and security.
License : Copyright Emeric Nasi, some rights reserved
This work is licensed under a Creative Commons Attribution 4.0 International License.
I wrote an example of a tiny backdoor exploiting capabilities in my article
POSIX file capabilities, the dark side.
This backdoor was only a local backdoor that needed a local access shell to be launched.
I decided to create a more dangerous one that can be activated by a distant attacker via the Internet.
I decided this backdoor target would be web-servers.
The goal is to create a backdoor that opens a root back-channel to the attacker’s PC on port TCP 53 when a PHP page is called with a special URL.
I choose the port 53 because distant connexion to DNS servers are generally authorized by firewalls.
The backdoor binary will be hidden among the website images and unless the admin monitors the file-system
for suspect file capabilities, it will be very difficult to detect the backdoor.
I Create the backdoor
Now we imagine that we gained root access on a Linux web-server (I used Debian5 to run my tests).
How do you know the victim OS is vulnerable ?
grep -x "CONFIG_SECURITY_FILE_CAPABILITIES=y" /boot/config-<span class="base64" title="PGNvZGUgY2xhc3M9InNwaXBfY29kZSBzcGlwX2NvZGVfaW5saW5lIiBkaXI9Imx0ciI+Y2F0IC9wcm9jL3ZlcnNpb24gfCBjdXQgLWQgJnF1b3Q7ICZxdW90OyAtZiAzPC9jb2RlPg=="></span>
Should return : "CONFIG_SECURITY_FILE_CAPABILITIES=y"
OK we can now create the backdoor.
I.1 The binary
Our binary will be the smallest possible and do two things :
- Escalate privileges to become root
- Use netcat to create a back-channel
Create a file called backdoor.c and paste next code :
Compile the backdoor and name it "02.png" :
gcc backdoor.c -o 02.png
Copy or compile the backdoor on the victim server. In our case we place it in the folder /var/www/ex/IMG.
Give execute permission to others (so that Apache can execute the backdoor) :
chmod 755 02.png
The user running apache under Debian is www_data. He will be the owner of the process and won’t be able to do the setuid(0) part...
Unless we use POSIX file capabilities! The particular capability we need here is the same as in the local backdoor described in the article
POSIX file capabilities, the dark side , the cap_setuid capability. A binary with this capability will be
able to run the setuid(0) function, thus any user running the binary can become a superuser (root with all capabilities enabled).
If libcap2-bin is installed on the web-server we can use setcap :
setcap cap_setuid=ep 02.png
If not (like in my case) you can upload the setcap binary from your system and it should work (Remember to remove the setcap binary after you used it).
I.2 The PHP code
We will use the PHP exec() function to call the backdoor. The next code can be hidden in any PHP file already existing on the web-server.
In our case we will place it at the beginning of the file /var/www/ex/test2.php.
I.3 The remote channel server
On the attacker machine, we need to open a server listening on the port 53.
For more simplicity we will use (again!) netcat.
Open a file called nc53.sh and paste next code :
This little script keeps spawning netcat sessions listening on port 53. If you run this script, you will have to kill the nc53.sh and all nc process
to terminate it. If the attacker is using a Microsoft Windows system, a simple nc -L -p 53 command should be enough.
II Test the backdoor
I run my tests using VirtualBox. In my test, the attacker IP is 192.168.56.11, the victim web-server IP address is 192.168.56.4.
First, run the netcat server. On the attacker’s machine do :
The machine is now listening on port 53.
Next we call the backdoor. Just open Firefox and paste the next URL :
If the backdoor install was successful, you should see the page indefinitely loading.
That is because of the PHP exec() function that won’t return before the binary has finished running. We do not care about it anymore, the connection is already done. Close Firefox.
Go back to the terminal where you ran the nc53.sh script.
Type the next command :
We gained a root shell on the web-server!!
Now we can do whatever we want.
For example, verify the latest apache logs :
... 192.168.56.11 - - [18/Jun/2010:22:19:22 +1000] "GET /ex/test2.php?polite=please HTTP/1.1" ...
This is our connection log (it can be deleted using sed)
We have others logs to check :
... Jun 18 22:39:01 debian-apache CRON: pam_unix(cron:session): session opened for user root by (uid=0)
Detect the backdoor
The backdoor is a back-channel, that means that no server are listening on the victim machine.
Detecting the backdoor via opened sockets is only possible when
it is handled by the attacker. When it is the case you can detect the connection by doing :
We can see here that a process called sh and run by root is connected to 192.168.56.11 on port 53.
After the attacker typed "exit" in his shell, the connection is closed and there is no way to find the backdoor using port scanners or netstat/lsof.
To detect the backdoor the admin has to monitor the logs (providing that they weren’t erase). A better solution is to scan the file-system for dangerous file capabilities.
This backdoor is a proof of concept that could be improved (ssh back-channel, log cleaning, distant command, bot behavior, etc).
We showed that with a few lines of C and PHP code and the help of file capabilities, we can create a simple backdoor triggered via HTTP
that is very difficult to detect because it is hidden among the website’s common files.
Prevent that kind of backdoor is however very simple. Be sure you have the getcap tool on your server then download and install
Glyptodon to run regular file-system scans (including file capabilities scans).