├── .gitignore ├── README.md ├── minipwn.py └── setup.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.gitignore.io/api/vim,python 2 | 3 | ### Python ### 4 | # Byte-compiled / optimized / DLL files 5 | __pycache__/ 6 | *.py[cod] 7 | *$py.class 8 | 9 | # C extensions 10 | *.so 11 | 12 | # Distribution / packaging 13 | .Python 14 | build/ 15 | develop-eggs/ 16 | dist/ 17 | downloads/ 18 | eggs/ 19 | .eggs/ 20 | lib/ 21 | lib64/ 22 | parts/ 23 | sdist/ 24 | var/ 25 | wheels/ 26 | *.egg-info/ 27 | .installed.cfg 28 | *.egg 29 | MANIFEST 30 | 31 | # PyInstaller 32 | # Usually these files are written by a python script from a template 33 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 34 | *.manifest 35 | *.spec 36 | 37 | # Installer logs 38 | pip-log.txt 39 | pip-delete-this-directory.txt 40 | 41 | # Unit test / coverage reports 42 | htmlcov/ 43 | .tox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | 53 | # Translations 54 | *.mo 55 | *.pot 56 | 57 | # Django stuff: 58 | *.log 59 | local_settings.py 60 | db.sqlite3 61 | 62 | # Flask stuff: 63 | instance/ 64 | .webassets-cache 65 | 66 | # Scrapy stuff: 67 | .scrapy 68 | 69 | # Sphinx documentation 70 | docs/_build/ 71 | 72 | # PyBuilder 73 | target/ 74 | 75 | # Jupyter Notebook 76 | .ipynb_checkpoints 77 | 78 | # IPython 79 | profile_default/ 80 | ipython_config.py 81 | 82 | # pyenv 83 | .python-version 84 | 85 | # celery beat schedule file 86 | celerybeat-schedule 87 | 88 | # SageMath parsed files 89 | *.sage.py 90 | 91 | # Environments 92 | .env 93 | .venv 94 | env/ 95 | venv/ 96 | ENV/ 97 | env.bak/ 98 | venv.bak/ 99 | 100 | # Spyder project settings 101 | .spyderproject 102 | .spyproject 103 | 104 | # Rope project settings 105 | .ropeproject 106 | 107 | # mkdocs documentation 108 | /site 109 | 110 | # mypy 111 | .mypy_cache/ 112 | .dmypy.json 113 | dmypy.json 114 | 115 | ### Python Patch ### 116 | .venv/ 117 | 118 | ### Python.VirtualEnv Stack ### 119 | # Virtualenv 120 | # http://iamzed.com/2009/05/07/a-primer-on-virtualenv/ 121 | [Bb]in 122 | [Ii]nclude 123 | [Ll]ib 124 | [Ll]ib64 125 | [Ll]ocal 126 | [Ss]cripts 127 | pyvenv.cfg 128 | pip-selfcheck.json 129 | 130 | ### Vim ### 131 | # Swap 132 | [._]*.s[a-v][a-z] 133 | [._]*.sw[a-p] 134 | [._]s[a-rt-v][a-z] 135 | [._]ss[a-gi-z] 136 | [._]sw[a-p] 137 | 138 | # Session 139 | Session.vim 140 | 141 | # Temporary 142 | .netrwhist 143 | *~ 144 | # Auto-generated tag files 145 | tags 146 | # Persistent undo 147 | [._]*.un~ 148 | 149 | 150 | # End of https://www.gitignore.io/api/vim,python 151 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # mini-pwntools 2 | 3 | Minimum pwntools features, including `remote` class and `p64, u64, flat, ...` 4 | 5 | Useful when `pwntools` failed to be installed ( ex: sagemath ) 6 | 7 | ## install 8 | 9 | ``` 10 | python setup.py install 11 | ``` 12 | 13 | or 14 | 15 | ``` 16 | pip install git+https://github.com/OAlienO/mini-pwntools.git 17 | ``` 18 | 19 | ## example 20 | 21 | ```python 22 | from minipwn import * 23 | 24 | r = remote('127.0.0.1', 20000) 25 | r.recvuntil('hello') 26 | r.recvline() 27 | r.recvlines(3) 28 | r.send('hello') 29 | r.sendline('hello') 30 | r.sendafter('hello', 'world') 31 | r.sendlineafter('hello', 'world') 32 | 33 | p64(0x4006c0) 34 | # b'\xc0\x06@\x00\x00\x00\x00\x00' 35 | 36 | u64(b'\xc0\x06@\x00\x00\x00\x00\x00') 37 | # 4196032 38 | 39 | flat(0, 1, 2) 40 | # b'\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00' 41 | ``` 42 | -------------------------------------------------------------------------------- /minipwn.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import socket 3 | import struct 4 | 5 | class remote: 6 | def __init__(self, host, port): 7 | self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 8 | self.s.connect((host, port)) 9 | self.buffer = b'' 10 | def recvuntil(self, text): 11 | text = self._convert_to_bytes(text) 12 | while text not in self.buffer: 13 | self.buffer += self.s.recv(1024) 14 | index = self.buffer.find(text) + len(text) 15 | result, self.buffer = self.buffer[:index], self.buffer[index:] 16 | return result 17 | def recvline(self): 18 | return self.recvuntil(b'\n') 19 | def recvlines(self, n): 20 | lines = [] 21 | for _ in range(n): 22 | lines.append(self.recvline()) 23 | return lines 24 | def _convert_to_bytes(self, text): 25 | if type(text) is not bytes: 26 | text = str(text) 27 | if type(text) is str: 28 | text = text.encode() 29 | return text 30 | def send(self, text): 31 | text = self._convert_to_bytes(text) 32 | self.s.sendall(text) 33 | def sendline(self, text): 34 | text = self._convert_to_bytes(text) 35 | self.send(text + b'\n') 36 | def sendafter(self, prefix, text): 37 | self.recvuntil(prefix) 38 | self.send(text) 39 | def sendlineafter(self, prefix, text): 40 | self.recvuntil(prefix) 41 | self.sendline(text) 42 | 43 | def p64(x): 44 | return struct.pack('