hasherezade / pe_to_shellcode

Converts PE into a shellcode
https://www.youtube.com/watch?v=WQCiM0X11TA
BSD 2-Clause "Simplified" License
2.39k stars 433 forks source link

"Cannot open PyInstaller archive from executable" error #32

Closed Pheelbert closed 1 year ago

Pheelbert commented 1 year ago

I create a PE from python code using pyinstaller, and this is the error I am getting:

PS C:\safe> .\transfer\pe2shc.exe .\dist\client.exe .\dist\client_shellcode.exe
Using: Loader v2
Reading module from: .\dist\client.exe
[INFO] This is a console application.
[INFO] Saved as: .\dist\client_shellcode.exe

PS C:\safe> .\dist\client_shellcode.exe -h
[23976] Cannot open PyInstaller archive from executable (C:\safe\dist\client_shellcode.exe) or external archive (C:\safe\dist\client_shellcode.pkg)

PS C:\safe> .\dist\client.exe -h
usage: client [-h] -s SERVER_IP [-p SERVER_PORT] [--secure]
[...]
[~] Good Bye!

PS C:\safe> .\transfer\runshc64.exe .\dist\client_shellcode.exe
[*] Reading module from: .\dist\client_shellcode.exe
>>> Creating a new thread...
[*] Running the shellcode [1f4da000000 - 1f4da054600]
[17556] Cannot open PyInstaller archive from executable (C:\safe\transfer\runshc64.exe) or external archive (C:\safe\transfer\runshc64.pkg)

I am at a loss, I would really appreciate any help!

hasherezade commented 1 year ago

hi @Pheelbert ! Unfortunately, Pyinstaller compiled EXE cannot be run manually, because if you run them from an external loader, the initial stub will not be able to find the python archive that is appended to the original executable.

This is a demo with a different manual loader, and my own test EXE compiled with Pyinstaller:

py_loader

The error that you see comes from within the initial Pyinstaller stub.

archive_error

(The text of the error is slightly different than in your example, because of different version of Pyinstaller, but it is basically an equivalent.)

So, although technically your executable is converted properly, some data required for further execution is missing. This is not an issue specific to pe2shellcode, but a general problem with with manual loading of Pyinstaller executables,

hasherezade commented 1 year ago

@Pheelbert - I found some - yet far from perfect - workaround to this problem. The package containing Python code is added to the Pyinstaller executable as an overlay. So, if you dump the overlay of your original executable, and save it in a separate file, named [your loader].pkg, your manually loaded Pyinstaller executable will refer to it, and continue execution by loading that external package:

demo_python

This is how this additional file looks - it is a compressed content containing the Python code:

package

This solution is flawed, because to run it in this way, your loader would first have to dump this file on the disk. Yet, the dumped content is not a PE, just a compressed content, so it may raise less alerts. Whether it is worth it or not, it will require more research.

Pheelbert commented 1 year ago

@hasherezade Thank you for your help! I tried doing the same solution and ran into the following issue: issue screenshot

I'm fairly sure that this is related to link1 and link2 (_pyi_allow_pkg_sideload function) which mention a special signature / magic bytes which should match.

I'd also like to mention that the .pkg is available in the pyinstaller build output directory, however I extracted it from the binary as well to ensure they matched.

I'll try appending those magic bytes and update this comment with the results.

Pheelbert commented 1 year ago

Adding the magic bytes anywhere in the output loader (generated by your tool pe_to_shellcode) fixed the issue for me! Here are the magic bytes which you can add into your binary (should be anywhere, as long as you don't break the file structure): 4d 45 49 0d 0b 0a 0b 0e

hasherezade commented 1 year ago

@Pheelbert - thank you for sharing, and I am glad that it is solved! The file that I used for test was using an old version of Pyinstaller, so I guess this is why I didn't face this problem. Good find!

jsdhasfedssad commented 1 year ago

I am trying to convert ntlmrelay_exe to shellcode hoping that that will bypass AV. I can convert the file without issues but during testing with runshc64.exe I get the error reported here. How does one add magic bytes? Is there a simpler solution to this?

Thanks!