pwntools icon indicating copy to clipboard operation
pwntools copied to clipboard

Do not store files in /tmp or pyinstaller can not work

Open gogo2464 opened this issue 1 year ago • 1 comments

I can not import pwntools and then use my python program with pyinstaller.

Update Pwntools First

I even tried with pwntools from source.

Debug Output

$ virtualenv -p python3 myenv ;
$ source myenv/bin/activate
$ pyinstaller ./script.py -y --onefile
$ ./script
  File "pwnlib/shellcraft/__init__.py", line 37, in __init__
FileNotFoundError: [Errno 2] No such file or directory: '/tmp/_MEICaCgkD/pwnlib/shellcraft/templates/__doc__'
[547041] Failed to execute script 'main' due to unhandled exception!```

When doing:

`from pwn import *`

and then pyinstaller ./script.py -y --onefile
I got errors with at the end:

```File "pwnlib/shellcraft/__init__.py", line 171, in <module>
  File "pwnlib/shellcraft/__init__.py", line 37, in __init__
FileNotFoundError: [Errno 2] No such file or directory: '/tmp/_MEICaCgkD/pwnlib/shellcraft/templates/__doc__'
[547041] Failed to execute script 'main' due to unhandled exception!```

After investigation, I think the setup.py somewhere store the doc in the /tmp folder. This may raise issue for pyinstaller.

gogo2464 avatar Jul 15 '22 22:07 gogo2464

Supporting pyinstaller is tricky and I don't see the use case for bundling pwntools together with python into an exploit binary.

Out of curiosity I played around with it following the basic pyinstaller tutorial and came up with this

pyinstaller --add-data 'pwnlib/shellcraft/templates/*:pwnlib/shellcraft/templates' --add-data 'pwnlib/data:pwnlib/data' --hidden-import pwnlib.atexception --hidden-import pwnlib.pep237 --hidden-import pwnlib.useragents --hidden-import pwnlib.update ./ttest.py

or expressed as package hook:

hook-pwnlib.py:

hiddenimports = [
    "pwnlib.atexception",
    "pwnlib.pep237",
    "pwnlib.useragents",
    "pwnlib.update",
]

datas = [
    ("pwnlib/shellcraft/templates", "pwnlib/shellcraft/templates"),
    ("pwnlib/data", "pwnlib/data"),
]

when placing that file into pwnlib/internal/pyinstaller next to an __init__.py file containing

import os

def get_hook_dirs():
    return [os.path.dirname(__file__)]

and telling setuptools about the entrypoint in pyproject.toml:

[project.entry-points.pyinstaller40]
hook-dirs = "pwnlib.internal.pyinstaller:get_hook_dirs"

allows to package basic exploits with pyinstaller solve.py, but fails when using shellcraft :/

Traceback (most recent call last):
  File "ttest.py", line 3, in <module>
    print(asm(shellcraft.sh()).hex())
  File "pwnlib/shellcraft/internal.py", line 123, in res
    lines = template.render(*args, **kwargs).split('\n')
  File "mako/template.py", line 439, in render
  File "mako/runtime.py", line 874, in _render
  File "mako/runtime.py", line 916, in _render_context
  File "mako/runtime.py", line 943, in _exec_template
  File "/home/peace/.cache/.pwntools-cache-3.10/mako/i386/linux/sh.asm.py", line 28, in render_body
    __M_writer(str(i386.linux.execve('/bin///sh', ['sh'], 0)))
  File "pwnlib/shellcraft/__init__.py", line 92, in __getattr__
    raise AttributeError("'module' object has no attribute '%s'" % key)
AttributeError: 'module' object has no attribute 'execve'
[6493] Failed to execute script 'ttest' due to unhandled exception!

It appears to ignore the syscalls symlink while packaging the shellcraft/templates folder. If anyone wants to debug this further, feel free to comment your findings! You'd need to include all of binutils in the package as well for asm/disasm to work I guess.

peace-maker avatar Jun 26 '23 22:06 peace-maker