There have been periodic requests logged in this site’s HTTP access logs that request a PHP page (usually simply index.php) and attempt to pass parameters like “die(md5(34563))” or “die(pi()*42)”. These extra parameters don’t seem to have any effect on the site, but I’m still curious about what the intent of these requests might be.
It seems fairly clear that these are attempts to hack the site. No such request is ever sent as part of serving a legitimate WordPress page – not a post list, nor a single post page, nor a static page or list of categories, tags, or posts by month. And the calls to “md5()”, and “pi()” are simple numerical operations that would be used in back end code, not a parameter for input to a request.
Some of the requests use the POST method, some use GET; some pass a single HTTP named parameter like this:
In other cases, multiple parameters are passed like this:
One request this month had a large number of parameters (the total length was 530 characters comprising 29 calls to “die()”):
/?_=die('z!a'.'x');&q=die('z!a'.'x');&w=die('z!a'.'x');&e=die('z!a'.'x'); ...the rest omitted...
The “die(errorcode)” command in PHP causes a PHP script to exit immediately, returning the error code number that’s passed as an argument. If you run a script like the following, you’ll see that the “after” message doesn’t appear:
$ cat dietest.php
$ php -f dietest.php
$ echo $?
The number passed to die() (42 in this case) is the status that’s returned to the bash shell (found in the “$?” environment variable).
Going to the documentation page for the die() function, I found some pretty simple, straightforward documentation: the sole purpose of “die()” is to terminate a PHP script with an error status.
The “die()” documentation indicates that it is the same as the “exit()” function, both built in to PHP. And scrolling down the exit() function page, some comments (from 2010 and 2003, 8 and 15 years ago!) reveal what the intention of these die() commands might possibly be:
Don’t use the exit() function in the auto prepend file with fastcgi (linux/bsd os).
It has the effect of leaving opened files with for result at least a nice “Too many open files …” error.
Perhaps this is an attempt at a DDOS attack by opening a mounting number of file connections? There really aren’t that many requests being made, just a few, and there can theoretically be thousands of file connections open at once.
Note, that using exit() will explicitly cause Roxen webserver to die, if PHP is used as Roxen SAPI module. There is no known workaround for that, except not to use exit(). CGI versions of PHP are not affected.
Roxen is a CMS that also offers an optional open source web server. Originally developed in 1997, the Roxen CMS is still being marketed today. But the post about the Roxen server is 15 years old; I would think that any such vulnerability would have been found and fixed by now.
Looking at the request parameters more closely, it’s clear that the “die()” commands are being passed as the values of named parameters. For any of these attacks to work, the “die()” code shown up above has to be executed somehow, and since named parameters are simply strings, the code could only be executed by something like a call to eval(). A quick check of the current WordPress code shows no place where eval is used to execute code. But it’s possible that some plugin or theme may use eval() a named parameter somewhere in its code, and so would be vulnerable to this kind of attack.
I’m not clear to me what the significance is of passing a large number as a parameter, like values returned from the “md5()” or “pi()” functions. These don’t seem to be particularly large numbers that could cause problems:
php > $val=md5(34563);
php > print $val;
php > $val=pi();
php > print $val;
So it looks like these kinds of attacks that pass “die()” commands as GET or POST parameters are attempting to find a vulnerability in PHP code that evaluates the parameters’ value as code. It’s good programming practice to avoid using “eval()” to execute any data from an external source in any case, and these requests demonstrate why this is so.
Where multiple parameters with “die()” command strings were passed, each of the parameters has a different, simple name: it seems that different parameters are being tried, attempting to find one that’s being used somewhere in the running instance of WordPress (either the core code, or in a plugin or theme).
The effect of getting a die() command to execute would be local to the request, so it’s not clear how someone could use this to their advantage. The attacks don’t seem to be frequent enough to leave enough connections open that any damage would be done.