-
Notifications
You must be signed in to change notification settings - Fork 14.4k
Add TLV encryption support to Python Meterpreter #13432
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
More info to come, but this does a few things with magic!~
I'm sorry, but I'm also not sorry.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The use of var b
overwrites the base64
module from the outer namespace in a couple of functions. It's also a little confusing in general due to it's use as a string prefix. Also, I don't think the b
string prefix to define byte-literals works on Python 2.5.
This forces python to use zlib and base64 when transferring the stages around. In my testing this dropped the stage for reverse_tcp from 111801 bytes to 36200 bytes (while still including the encryption libs).
Update from the last commit. From:
To:
|
|
I'll update the payload cache sizes when the Metasploit Payloads PR lands. |
I submitted OJ#23 to you for some changes around Python version compatibility. There were some issues with older 2.x versions and the |
Thank you @smcintyre-r7 I'll get it this soon! |
Tested this once more with the current 6.x changes at this time. Everything still looks good so I'm going to look at updating the payload sizes and then landing this assuming I'm successful. To test all the versions I used a simple harness around pyenv. Test resultsThe one failure you'll see in here is from Python 2.4 which isn't supported so that failure is expected. Meterpreter output:
Test harness output:
|
I missed a bug on my first pass that surfaced as I was doing a last minute check before landing this. The issue was the stage being double encoded which broke the unstaged payloads. Fix proposed in OJ#24. With that sorted out I should be able to land this. Luckily it's framework side so the payloads build is just fine. |
Release NotesAdded TLV encryption support to the Python Meterpreter, allowing it to securely communicate with Metasploit Framework. |
Thank you!
…On Tue, 16 Jun 2020, 23:32 Spencer McIntyre, ***@***.***> wrote:
Landed after one more quick test in the 6.x branch. Checked both a staged
and an unstaged payload to ensure they were both functioning and encrypted.
Bumped the payloads gem and updated the cached sizes in 4ce610e
<4ce610e>.
Thanks @OJ <https://github.com/OJ> !
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#13432 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAAHBYCSJA7SGOZ2EPCJ3PTRW5X5RANCNFSM4M5ZR6LA>
.
|
Dependencies
Details
This PR aims to bring us another step closer to having TLV encryption support in all versions of Meterpreter. After this, Java/Android is the only beast that's left.
This PR contains supporting code that allows Python Meterpreter to function with TLV encryption. This was not a simple, pleasant nor easy thing. The approach that I have gone with here is up for discussion, and so I hope to get some interesting feedback and constructive criticism (imma lookin' at you @smcintyre-r7!).
The Pain of Python
I will keep my opinions of Python out of this because it's not relevant and it'd be totally indiscrete and unprofessional let people know that I think Python is a steaming pile of dynamic horse manure. So I won't say that, and instead I'll focus on the issues at hand.
When Python Meterp runs it doesn't know anything at all about the environment it's spinning up in. It could be 2.4, 2.7, 3.1, 3.7 ... who knows! It also doesn't know which operating system it's on, nor does it know which libraries are installed and available. This poses all kinds of issues in general, but when it comes to crypto, things are worse.
Python has a stack of crypto libraries available that can be installed out of bad. Some libs might even exist by default in more recent intallations. Unfortunately, we are not in a position to assume that any of them area installed and available for us to use. As a result, we need to write code that provides an implementation that will work no matter what.
This means that there's not point in even trying to use them if they're present, because our own code has to work anyway.
So what do we do? Well, we have to bring our own to the party! This code includes the following:
I've split these changes up into separate chunks for a few reasons. The code for handling the packets and whatnot lives in
meterpreter.py
with the rest of the stuff. That's where it belongs. I didn't want to include the AES/DER/RSA stuff directly in the same file because:In order to support this, I modified the Meterpreter loader to patch this stuff in on the fly when the payload is generated. This means Meterpreter remains clean as a module, but MSF is responsible for inserting it. Meterpreter will call
met_aes_encrypt
,met_aes_decrypt
andmet_rsa_encrypt
functions when required. MSF inserts those functions and abstracts how they're implemented. There are advantages and disadvantages to this approach, and I'm happy to hear some views as to how this might be improved. I favoured this because:met_rsa
andmet_aes
) so that they're functionally separate.This means we can still modify raw python code in MSF, and all the wiring handles the process of getting it inserted cleanly into a separate namespace. We couldn't do this very easily directly in meterpreter.py
EDIT -- 12th May 2020
I changed a couple of things:
zlib
andbase64
to pull the stage apart before executing it. Assuming that these libs are in all the pythons, this should be good to go!Full disclosure
Yes, I wrote this code. I used a bunch of other resources as references, and there was some copy/pasta. I minimized the code manually to reduce the size on the wire, clearly at the cost of readability. I know you should never write your own crypto. Technically I didn't, I just wrote my own implementation of existing crypto. Yes, this is probably as bad.
Verification
Note that I have seen issues with Python3 and resilient transports. I will log a bug about this, but at the moment it's not a result of the code changes in this PR.
Sample Run
Things to do
When the PEM to DER PR is landed, this stuff needs to be updated so that Meterp just reads the DER off the wire instead of converting from PEM to DER first.