Improving web shells with asymmetric encryption

You're out surfing the world wide web having a great time, then suddenly, you find a security vulnerability. What do you do? Report it? Hmm, ok. Well some people might go the other way and upload a web shell1 to own the server. However, current state-ot-the-art web shells are lacking in my opinion and in this post I want to present a possible improvement, together with defensive methods.

If you're just interested in the challenge, and the possibility to win some Monero (XMR), you can jump to the challenge section.

Web shells

First of all, what is a web shell? In short, you can think of it as a web page that allows you to run commands on the remote server. A shell2 on the web so to say. From there, it is usually easy for an attacker to do whatever they want, e.g. exfiltrate data, modify data, steal computing resources, etc. The image below shows what such a web shell might look like.

Screenshot of a classic C99 shell
Screenshot of a classic C99 shell (Chingyanyho, Wikimedia Commons).

So where is the need for improvement you might wonder. The problem is that using digital forensics together with a network log, it is trivial to see what commands the attackers used and what data they got away with. Let's quickly define the model and the problem we want to solve.

Defence model

Goal: Confidentially run commands and extract data from server. I.e. the defender should not be able to tell which commands where issued.

  1. The defender logs all network traffic and is capable of decrypting their own TLS.
  2. The defender knows the clean (deobfuscated) source code of the shell.

Based on this model we can draw some conclusions. First, to achieve confidentiality we need encryption. Some shells do this, more about that in the next section. Second, since all traffic is logged, the attacker cannot send the keys using HTTP(S). The most important thing is that we cannot hide the key inside the shell. I cannot stress this enough. No matter the amount of obfuscation and sleight-of-code, the key cannot be inside the shell. While not a web shell but rather a ransomware, PowerWare made this mistake.

Luckily, PowerWare is nowhere near as strong as the ransomware programs it impersonates. It uses the AES-128 encryption algorithm, but with a hard-coded key4
Not only criminals make this mistake. Atlassian thought they could put a key inside the application, they got owned for it3.

Based on this, the only possibility I see is that the web shell must generate it's own key. This is the at the core of asymmetric encryption, which isn't particularly new. Yet I haven't seen any web shells use it. To be fair, most ransomware actually do use it.

Short survey of web shells

Before I present my solution, I think we should that a look at the history and current state-of-the-art.

C99 is a classic web shell with a lot of features. In terms of security it has password protection for access. This mainly stops other attackers from using the same shell. Using the network log, an administrator can easily see the password.

encrypted-web-shell.php is a packer for web shells that uses strong encryption to encrypt the shell code before uploading it. This is clearly an improvement over a plain C99 shell. However, as soon as the attacker submits the encryption key, either through the cookie or a post request, the defender will be able to decrypt the file.

CCCPShell is the only shell I found that actually encrypts the communication. Even they themselves seem surprised over this, judging from the README, "Encrypted comunication (first phpshell in the world???)". While an improvement, it still fails because the key used for encryption is hard coded in the shell, as well as, sent over POST by the attacker.

I think the FRA shell from FRA Challenge 2019-1 deserves an honorable mention as it uses different keys for each message and no hard coded keys. Impressive for being just a toy example of a vulnerable shell.

I also want to mention that even advanced attackers use bad shells. You can check out the logs from the Operation Wocao concerning the Advanced Persistent Threat (APT) group 20. Here the commands, such as whoami and dir, are visible in the htaccess log. Note that the htaccess log is just a subset of a raw and decrypted network log, which is what we consider here.

In the webserver logs below, two operators of the group attempt to access the deleted webshells, executing several Windows commands on one of the webshells, all of which no longer return any of the expected responses.
Screenshot of webserver log from Operation Wocao
From Operation Wocao.


Here I propose my solution. DHAShell (Diffie Hellman AES Shell).


The shell uses openssl_pkey_new to generate a new asymmetric key pair using randomness from the server. This means that the private key is never sent over the network. The client generates similar keys and then the Diffie Hellman exchange is performed, resulting in the shared secret. This shared secret is then used as a symmetric key to encrypt the communication.


Using the shared secret, the client encrypts the payload using AES and sends it to the server (shell). Since we are focusing on web pages, which should be stateless, the client also needs to send it's public key so that the server can compute the shared secret. The AES is running in GCM mode which also allows for authenticating messages.


I'll publish this on Github after some revision. For now it's available here. The attacker will use client.php on their own server, or any server not controlled by the victim. The server.php file is uploaded to the victim.


To incentive people to break my method I've set up a challenge in a FRA challenge style, with a 0.5 Monero (XMR) prize pot (~$20). This network log contains an attack using DHAShell to read the mnemonic seed for a Monero private key.

Please note that the private key is not stored on this server, except for in the network log. Don't waste energy on attacking this website. I'm mean, feel free, but not for the sake of finding the private key.


I'm an intern from Berg Gox and I'm afraid we have been hacked.

Some of our cryptocurrency customers have started to complain about lost funds. I think the attackers might have been able to steal our private key. Can you recover it from this network log?

Unfortunately we also lost our physical backups of the keys in a boating accident.


The major drawback of using Diffie Hellman is that it is vulnerable to MITM. In theory this means that the defender could set up a proxy that would intercept the handshake and eavesdrop on the communication. However, at this point the defender would know an attack was being mounted and should just block the attacker and remove the shell. It could be of interest to researchers and honeypots owner where the attack can be rendered harmless but the patterns can still be observed.


  1. Web shell
  2. Shell
  3. Atlassian Zero Day Bug
  4. Researchers release free decryption tools for PowerWare and Bart ransomware

Write your comment!


Goldilocks !52244cd3cd5b No. 91 >>93 2020-01-07 19:43:31
Very clever solution! I can think of one possible but very unlikely problem. What if the server logs every function call, its arguments and return value? That would mean that the plaintext in openssl_encrypt and the returned plaintext from openssl_decrypt are logged on the server. It should be possible to do with Xdebug ( although seems extremely unlikely that someone would use it in a production system and it's not in the scope of your defense model.
Benjamin ## Admin !d2782292df32 No. 93 2020-01-09 20:01:01
Thanks for the insightful comment! I've heard about Xdebug before but actually not in the context of tracking function arguments, cool! Indeed that would totally break the confidentiality, good point!
From what I remember, Xdebug adds a lot of overhead so you are probably correct in that it won't be used in production.
ZAP No. 3995 2023-11-09 21:36:09
Zaproxy alias impedit expedita quisquam pariatur exercitationem. Nemo rerum eveniet dolores rem quia dignissimos.
ZAP No. 4011 2023-11-09 21:36:14
Zaproxy alias impedit expedita quisquam pariatur exercitationem. Nemo rerum eveniet dolores rem quia dignissimos.
ZAP No. 4033 2023-11-09 21:37:29
Zaproxy alias impedit expedita quisquam pariatur exercitationem. Nemo rerum eveniet dolores rem quia dignissimos.
ZAP No. 4050 2023-11-09 21:38:14
Zaproxy alias impedit expedita quisquam pariatur exercitationem. Nemo rerum eveniet dolores rem quia dignissimos.
ZAP No. 4069 2023-11-09 21:46:54
Zaproxy alias impedit expedita quisquam pariatur exercitationem. Nemo rerum eveniet dolores rem quia dignissimos.
ZAP No. 4090 2023-11-09 21:47:21
Zaproxy alias impedit expedita quisquam pariatur exercitationem. Nemo rerum eveniet dolores rem quia dignissimos.
ZAP No. 4109 2023-11-09 21:48:30
Zaproxy alias impedit expedita quisquam pariatur exercitationem. Nemo rerum eveniet dolores rem quia dignissimos.