Unable to build valid Win64 PyInstaller version
1mm0rt41PC opened this issue · 7 comments
Hello,
I'm trying to build an Winx64 version but at the end I get a binary that don't have the live lsa
.
Steps:
set py64=C:\python38\python.exe
%py64% -m pip install -U pip wheel ldap3 pywin32 pypiwin32
%py64% -m pip install -U tinyaes dnspython
%py64% -m pip install -U git+https://github.com/pyinstaller/pyinstaller
git clone https://github.com/skelsec/pypykatz
cd pypykatz
%py64% -m pip install minidump minikerberos aiowinreg msldap winsspi winacl pycryptodome
%py64% -m pip install git+https://github.com/skelsec/unicrypto
%py64% setup.py install
:: This version fail, but in 2021 that entry point worked
:: %py64% -m PyInstaller --onefile pypykatz\__main__.py --noupx
%py64% -m PyInstaller --onefile pypykatz\__amain__.py --noupx
The dist\__amain__.exe live lsa
returns
usage: __amain__.exe live [-h] {process,token,users} ...
__amain__.exe live: error: argument module: invalid choice: 'lsa' (choose from 'process', 'token', 'users')
If I set the entry point to __main__.py
and run the final binary I get:
Traceback (most recent call last):
File "pypykatz\__main__.py", line 156, in <module>
File "pypykatz\__main__.py", line 17, in main
File "PyInstaller\loader\pyimod02_importers.py", line 499, in exec_module
File "pypykatz\kerberos\cmdhelper.py", line 19, in <module>
File "PyInstaller\loader\pyimod02_importers.py", line 499, in exec_module
File "pypykatz\kerberos\kerberos.py", line 7, in <module>
File "PyInstaller\loader\pyimod02_importers.py", line 499, in exec_module
File "minikerberos\security.py", line 11, in <module>
File "PyInstaller\loader\pyimod02_importers.py", line 499, in exec_module
File "minikerberos\aioclient.py", line 24, in <module>
File "PyInstaller\loader\pyimod02_importers.py", line 499, in exec_module
File "minikerberos\protocol\encryption.py", line 57, in <module>
File "PyInstaller\loader\pyimod02_importers.py", line 499, in exec_module
File "unicrypto\symmetric.py", line 82, in <module>
File "unicrypto\__init__.py", line 79, in get_preferred_cipher
File "unicrypto\__init__.py", line 57, in get_cipher_by_name
File "unicrypto\__init__.py", line 14, in import_from
ModuleNotFoundError: No module named 'unicrypto.backends.pycryptodomex'
[2276] Failed to execute script '__main__' due to unhandled exception!
How to build a working version for Winx64 ?
Hello,
yes that is a problem. Since moving to unicrypto
compiling pypykatz into an executable is a bit more difficult, because unicrypto
is dynamically loading/selecting one of the available crypto libraries. You'd need to explicitly install one crypto library then specify it to pyinstaller. It looks a bit ugly, but works if you put this in a bat file:
set hiddenimports= --hidden-import cryptography --hidden-import cffi --hidden-import cryptography.hazmat.backends.openssl --hidden-import cryptography.hazmat.bindings._openssl --hidden-import unicrypto --hidden-import unicrypto.backends.pycryptodome.DES --hidden-import unicrypto.backends.pycryptodome.TDES --hidden-import unicrypto.backends.pycryptodome.AES --hidden-import unicrypto.backends.pycryptodome.RC4 --hidden-import unicrypto.backends.pure.DES --hidden-import unicrypto.backends.pure.TDES --hidden-import unicrypto.backends.pure.AES --hidden-import unicrypto.backends.pure.RC4 --hidden-import unicrypto.backends.cryptography.DES --hidden-import unicrypto.backends.cryptography.TDES --hidden-import unicrypto.backends.cryptography.AES --hidden-import unicrypto.backends.cryptography.RC4
python -m PyInstaller -F __main__.py --icon %~dp0progress\pypykatz\repo\pypykatz\pypykatz\buildtools\pypykatz.ico %hiddenimports%
no need to include all backends.
there are currently 6 backends in unicrypto:
pyCryptodomex, pyCryptodome, cryptography, pyCrypto, mbedtls, pure
but you may use only one backend. for include just that one:(mine is pycryptodome
)
import unicrypto.backends.pycryptodome
in your app header and PyInstaller will correctly include all needed files.
Hello !
I'm still unable to build a valid binary. If I only use the hiddenimports
I get the same error about ModuleNotFoundError: No module named 'unicrypto.backends.pycryptodomex'
set py64=C:\python310-x64\python.exe
%py64% -m pip install -U pip wheel ldap3 pywin32 pypiwin32 tinyaes dnspython pyinstaller
git clone https://github.com/skelsec/pypykatz
cd pypykatz
%py64% -m pip install minidump minikerberos aiowinreg msldap winsspi winacl pycryptodome
%py64% -m pip install unicrypto
%py64% setup.py install
set hiddenimports= --hidden-import cryptography --hidden-import cffi --hidden-import cryptography.hazmat.backends.openssl --hidden-import cryptography.hazmat.bindings._openssl --hidden-import unicrypto --hidden-import unicrypto.backends.pycryptodome.DES --hidden-import unicrypto.backends.pycryptodome.TDES --hidden-import unicrypto.backends.pycryptodome.AES --hidden-import unicrypto.backends.pycryptodome.RC4 --hidden-import unicrypto.backends.pure.DES --hidden-import unicrypto.backends.pure.TDES --hidden-import unicrypto.backends.pure.AES --hidden-import unicrypto.backends.pure.RC4 --hidden-import unicrypto.backends.cryptography.DES --hidden-import unicrypto.backends.cryptography.TDES --hidden-import unicrypto.backends.cryptography.AES --hidden-import unicrypto.backends.cryptography.RC4
%py64% -m PyInstaller -F __main__.py %hiddenimports%
If I add some code inside __main__.py
there is no more error but the process return nothing:
I get the same behavior if I build without %hiddenimports%
and with the code modification
You are right, this is indeed a bug. :( I'll try to fix it this week.
Update: I made the previous comment in a hurry, this is not a bug :)
set hiddenimports= --hidden-import cryptography --hidden-import cffi --hidden-import cryptography.hazmat.backends.openssl --hidden-import cryptography.hazmat.bindings._openssl --hidden-import unicrypto --hidden-import unicrypto.backends.pycryptodome.DES --hidden-import unicrypto.backends.pycryptodome.TDES --hidden-import unicrypto.backends.pycryptodome.AES --hidden-import unicrypto.backends.pycryptodome.RC4 --hidden-import unicrypto.backends.pure.DES --hidden-import unicrypto.backends.pure.TDES --hidden-import unicrypto.backends.pure.AES --hidden-import unicrypto.backends.pure.RC4 --hidden-import unicrypto.backends.cryptography.DES --hidden-import unicrypto.backends.cryptography.TDES --hidden-import unicrypto.backends.cryptography.AES --hidden-import unicrypto.backends.cryptography.RC4 --hidden-import unicrypto.backends.pycryptodomex.DES --hidden-import unicrypto.backends.pycryptodomex.TDES --hidden-import unicrypto.backends.pycryptodomex.AES --hidden-import unicrypto.backends.pycryptodomex.RC4
using the hidden imports I generated an executable that works just fine
I don't understand where my mistake is :/
I just redid a test in a clean VM in AppVeyor with the new hiddenimports variable, but the result is still a non-working binary
What version of python are you using?
Are you using exactly the same command lines for build ?
I found my error, the import unicrypto.backends.pycryptodomex
was not added to the exe. I added this import in the var hiddenimports
. It builds well now.
set py64=C:\python38\python.exe
%py64% -m pip install -U pip wheel ldap3 pywin32 pypiwin32
%py64% -m pip install -U tinyaes dnspython
%py64% -m pip install -U git+https://github.com/pyinstaller/pyinstaller
git clone https://github.com/skelsec/pypykatz
cd pypykatz
%py64% -m pip install minidump minikerberos aiowinreg msldap winsspi winacl pycryptodome
%py64% -m pip install git+https://github.com/skelsec/unicrypto
%py64% setup.py install
set hiddenimports= --hidden-import cryptography --hidden-import cffi --hidden-import cryptography.hazmat.backends.openssl --hidden-import cryptography.hazmat.bindings._openssl --hidden-import unicrypto --hidden-import unicrypto.backends.pycryptodome.DES --hidden-import unicrypto.backends.pycryptodome.TDES --hidden-import unicrypto.backends.pycryptodome.AES --hidden-import unicrypto.backends.pycryptodome.RC4 --hidden-import unicrypto.backends.pure.DES --hidden-import unicrypto.backends.pure.TDES --hidden-import unicrypto.backends.pure.AES --hidden-import unicrypto.backends.pure.RC4 --hidden-import unicrypto.backends.cryptography.DES --hidden-import unicrypto.backends.cryptography.TDES --hidden-import unicrypto.backends.cryptography.AES --hidden-import unicrypto.backends.cryptography.RC4 --hidden-import unicrypto.backends.pycryptodomex.DES --hidden-import unicrypto.backends.pycryptodomex.TDES --hidden-import unicrypto.backends.pycryptodomex.AES --hidden-import unicrypto.backends.pycryptodomex.RC4 --hidden-import unicrypto.backends.pycryptodomex
%py64% -m PyInstaller --onefile pypykatz\__main__.py --noupx %hiddenimports%