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.
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.
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.
Goal: Confidentially run commands and extract data from server. I.e. the defender should not be able to tell which commands where issued.
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 key4Not 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.
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
concerning the Advanced Persistent Threat (APT) group 20.
Here the commands, such as
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.
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.
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.