PHP / Security

PHP Security: disable error_reporting() NOW

by , , revisited on


Amazing malware

On one of the servers which I’ve been investigating for malware scripts, an amazing backdoor was found:

<?php error_reporting(0); ${"\x47L\x4fB\x41\x4c\x53"}["\x72\x6d\x63vfy"]="b\x6f\x74\x5f\x75\x73ers";${"\x47\x4c\x4fB\x41\x4c\x53"}["\x67\x74l\x76\x68\x75\x6e"]="\x62\x6ft_i\x70s";${"\x47\x4c\x4fB\x41\x4c\x53"}... lots of obfuscated code follows..

Why was this undetected by malware scanners and how can we detect this kind of malware ourselves?

I won’t go into much details what the actual code does. It allows hackers to run commands on the servers.
The code is highly obfuscated and there were dozens of similar scripts implanted in multiple directories of the website in question.

Take note at the beginning of it: error_reporting(0). This just turns off any errors from being written to PHP error log or displayed to browsers.

Surely enough, if hackers want to use your server as a tool, they want to keep their profile low. This is especially true for cryptojackers who want to leverage the power of your server to mine Monero. They want to do it as long as possible and stay undetected for as long as possible.

And the error_reporting PHP function is just there for their benefit. No matter what configuration PHP has on the server level, the error_reporting(0) can override it and completely silence errors in affected scripts.

I can’t think of a good use for error_reporting function at all!. Apart from the mentioned malicious intent, error_reporting(0) is also a darling of bad coders trying to silence their code from emitting errors and warnings. This just makes things hard to troubleshoot on live servers.

If you know how to configure servers properly and have already specified the necessary logging level via error_reporting php.ini configuration directive, then you don’t need error_reporting(...) function at all.

Disable error_reporting(…)

Unfortunately, any script can override the configured error level, by just calling error_reporting(0). The only way to stop this, is to disable the function altogether.

Make sure that your php.ini is configured with:

disable_functions=error_reporting

This will emit a security warning for scripts that use the function (they won’t fail). There, one change got us 2 things:

  • The malware can’t hide so easily as we have raised the chances of it exposing itself via PHP error log
  • We know who’s only trying to appear as a good coder by having PHP run with mouth shut about their unfixed bugs

But WordPress…

WordPress is trying to outsmart us and their developers think that we don’t know how to configure our servers. Even with default configuration (with WP_DEBUG off), you’d notice:

error_reporting() has been disabled for security reasons in wp-load.php on line 24
error_reporting() has been disabled for security reasons in load.php on line 333

You can’t do much about this: ignore the warnings or comment out those lines with ‘//’ to keep your logs clean (and also make things a little faster by running 2 less lines of PHP. Micro optimization maniac detectado 🙂

@ Not so fast @

PHP has one built-in error handling operator which is @. If you prepend anything to a code with this sign, the error will be silenced.

There are basically 2 solutions to unsilence all pieces of code that make use of it.

First, is PHP based. In your bootstrap PHP file, set a custom PHP error handler ( via set_error_handler() ).

Second, is to install and configure scream PHP extension. After the extension is installed, configure it in php.ini:

scream.enabled = On

Leave a Reply