The official Poison Ivy Metasploit module has just been released. With the help of Juan Vazquez, the official module is a major upgrade to the original module I published. Here is some important information on how to use it.
The module’s name is poisonivy_bof, and it resides under windows/misc. The original module was universal, and used ROP chains to bypass DEP and ASLR. Apparently, out-of-the-box Poison Ivy can’t run on DEP-enabled systems due to its unpacker, so the ROP chains were removed from the official module, and a regular return-to-payload was put there instead. The targets were updated accordingly. If, for some reason, you encounter a Poison Ivy C&C server on a DEP-enabled system, refer to the original module for the ROP chains.
Another important addition is the ability to send random headers to the server, instead of a precooked header. When running the check function, it’s important to note whether it reports that the password used is “admin” or not. If it does, just use the hardcoded header, and it should work just fine. The server expects a header encrypted with Camellia, using the password as the key. It then decrypts the header and processes it. The hardcoded header was encrypted using “admin” as the key, but it’s not feasible to do this with all possible keys.
If check() reports that the password is not “admin”, decrypting the header is going to produce gibberish on the server’s side. All is not lost though, as this gibberish may still work. If it doesn’t work, it usually fails silently, and the thread that got spawned for our connection exits cleanly. Only in extreme cases will something “bad” happen, like a message box popping up, or a server crash. In case there was a silent failure, we can just try again with a random header and see what happens. For that, we have two possible modes:
- Use the RANDHEADER setting to send a single random header and see what happens. Rerun until exploitation is successful.
- Use a brute-force approach by selection target #1. The brute-forcer will try up to 5 different headers, with the first one being the one for “admin”, and the rest being random headers. If it still doesn’t succeed, simply run it again.
The reason for having the brute-forcer is pretty obvious, as it may take more than a single try to succeed. Why do we have an option to send a single random header, then? Well, the brute-forcer stops after 5 tries, or (hopefully
) when a session is established. If your payload doesn’t establish a session (consider windows/exec for example), the brute-forcer won’t stop even after successful exploitation. That is, you may end up performing a successful exec 5 times in a row, which could be more than you’ve bargained for. For sessionless payloads, I suggest using the manual approach and not the brute-forcer.
Make sure this doesn’t happen to you:
The problem appears when the session creation time is longer than the brute-forcer’s time between tries. Fortunately, we can control that through an advanced option:
So just raise BruteWait, and that should fix things:
That’s all there is to it. Good luck!







