Many rootkits work in the roughly same way, they find out where the operating system handles the communication between the kernel and the user, and inject code that will act as a proxy between the two spaces, giving it the ability to read and modify all the data that passes through.

In software development, this process is also referred to as 'hooking' and has many legitimate uses too (like monkey-patching code by other developers as a temporary workaround).

Example of how rootkits can intercept function calls

Why write a rootkit as a PHP module?

So why would anyone write a rootkit for PHP, of all languages? Well, there are quite a few reasons, the most important being:

PHP is one of the most popular programming languages used on the web.

But this still doesn’t explain why you wouldn’t just go and write a kernel rootkit and intercept function calls from there. The reasons can be summed up as follows:

Accessibility

The first and very obvious reason why you would write a rootkit as a PHP module is accessibility. In my experience, learning how to use the Zend Engine (the framework the entire PHP language is built with) is a lot easier than learning how to write kernel modules, simply because the code base itself is smaller, better documented and a lot less complex.

Even without good documentation or tutorials, I managed to learn the basics of writing a PHP module within a day. If I (a novice C developer) can do it, the bad guys definitely can.

Stability

Since traditional rootkits are designed to run in kernel space, the chance of a poorly written rootkit crashing the entire system is very high. PHP rootkits don’t have this problem. While a poorly written PHP rootkit can certainly cause some damage, it can’t crash the entire underlying system.

In the worst-case scenario, a rootkit will cause a segmentation fault and just interrupt the current request (note: most web servers report this in their error log, so this could raise suspicion).

Detectability

Let’s be realistic, when is the last time you actually checked the file integrity of your PHP modules? If I were to name my module something deceptive like 'curl.so’, would you be paranoid enough to check if it’s actually the curl extension for PHP?

This, as well as the fact it’s custom code (meaning no antivirus signatures exist), no network-based IDS systems get triggered (since networking is managed by the web server and is expected) and the fact there are many inexperienced developers that only just know how to install PHP, leaves you with the perfect conditions for stealth.

Furthermore, kernel rootkits require you to hook system calls for every process rather than just one, this slows down your machine drastically, which might lead to more suspicion.

Portability

Not only do you get to enjoy the benefits of writing code in the user space, your rootkit also just became a cross-platform rootkit! This is because PHP is (in most cases) platform-independent. Code written for one platform can easily be compiled to be run on another platform (eg: modules written for Linux can often be compiled for Windows).

Proof of concept

Now comes the most exciting part, actually getting to show off how dangerous a malicious extension can be. In my examples, it will be totally obvious to the user that they’re being spied on, but with a few tiny tweaks this becomes essentially invisible to a system administrator.

Hooking cryptography methods

The two most important parts of writing a PHP rootkit are registering the actual rootkit itself, and hooking the target functions. The following screenshots are the actual code I used to achieve all of the required functionality, which came in at only 80 lines of code (including comment blocks).

Registering the module in the Zend Engine

Here you can see how a basic PHP extension is registered with the Zend Engine (the underlying framework of PHP). Notice the two strange lines of code in the PHP_MINIT_FUNCTION method?