mirror of
https://github.com/Gallopsled/pwntools.git
synced 2026-11-09 17:13:08 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
72a93f7a3c | ||
|
|
c520efca42 | ||
|
|
a743ccc7fe | ||
|
|
0eb7fdbd88 | ||
|
|
ec4cc53bd0 | ||
|
|
99d3cd708f | ||
|
|
0ee2939a9d | ||
|
|
917ffd8667 | ||
|
|
3ff46ff8d4 | ||
|
|
2fcc39eb6e | ||
|
|
ccb49abe35 | ||
|
|
0a978df7bf | ||
|
|
ad4c62b9fd | ||
|
|
21c9d00078 | ||
|
|
1b6393f381 | ||
|
|
1f68bf6560 | ||
|
|
9706275a3d | ||
|
|
8210bba2ab | ||
|
|
c0e4db94f1 | ||
|
|
163c19dd49 | ||
|
|
c4c11a37f8 | ||
|
|
9b56b58f95 | ||
|
|
c4dd1c22ba | ||
|
|
3d4853f9a7 |
No files matched your search
@@ -0,0 +1,54 @@
|
||||
---
|
||||
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 18.04. We provide a Dockerfile based on Ubuntu 18.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
|
||||
```
|
||||
@@ -0,0 +1,18 @@
|
||||
---
|
||||
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 exit
|
||||
* 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!
|
||||
@@ -0,0 +1,18 @@
|
||||
---
|
||||
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.
|
||||
+119
-29
@@ -10,6 +10,12 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Git History 2
|
||||
run: git log --oneline --graph -10
|
||||
|
||||
- name: Cache for pip
|
||||
uses: actions/cache@v1
|
||||
id: cache-pip
|
||||
@@ -17,13 +23,6 @@ jobs:
|
||||
path: ~/.cache/pip
|
||||
key: ${{ matrix.os }}-cache-pip
|
||||
|
||||
- name: Cache for dependencies
|
||||
uses: actions/cache@v1
|
||||
id: cache-deps
|
||||
with:
|
||||
path: android-?dk
|
||||
key: ${{ matrix.os }}-cache-deps
|
||||
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v1
|
||||
with:
|
||||
@@ -35,42 +34,53 @@ jobs:
|
||||
flake8 . --count --select=E9,F63,F7 --show-source --statistics --exclude=android-?dk # TODO: Add F82
|
||||
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics --exclude=pwnlib/constants,android-?dk,.git,__pycache__
|
||||
|
||||
- name: Detect whether java is needed
|
||||
id: java-needed
|
||||
env:
|
||||
GITHUB_REF: ${{ github.event.ref }}
|
||||
GITHUB_COMMIT_RANGE: ${{ github.event.before }}...${{ github.event.after }}
|
||||
run: |
|
||||
if echo "$GITHUB_REF" | grep -Eq 'staging|tags'; then
|
||||
echo "Found release or important branch ($GITHUB_REF), forcing tests."
|
||||
elif ! git show "$GITHUB_COMMIT_RANGE" >/dev/null; then
|
||||
echo 'Incorrect commit range, forcing android tests.'
|
||||
elif git log --stat "$GITHUB_COMMIT_RANGE" | grep -iE 'android|\<adb\>'; then
|
||||
echo 'Found Android-related commits, forcing tests.'
|
||||
else
|
||||
# clear files that cause Android doctests
|
||||
: > docs/source/adb.rst > docs/source/protocols/adb.rst
|
||||
exit 0
|
||||
fi
|
||||
echo ::set-output name=need::openjdk-8-jre-headless
|
||||
|
||||
- name: Install Linux dependencies
|
||||
env:
|
||||
ANDROID_JRE: ${{ steps.java-needed.outputs.need }}
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y --no-install-recommends -o Acquire::Retries=3 \
|
||||
ash bash-static dash ksh mksh zsh \
|
||||
pandoc gdb socat sshpass \
|
||||
pandoc gdb gdbserver socat sshpass \
|
||||
binutils-multiarch qemu-user-static \
|
||||
binutils-aarch64-linux-gnu \
|
||||
binutils-arm-linux-gnueabihf \
|
||||
binutils-mips-linux-gnu \
|
||||
binutils-powerpc-linux-gnu \
|
||||
gcc-multilib \
|
||||
openjdk-8-jre-headless
|
||||
$ANDROID_JRE
|
||||
sudo apt-get install -y -o Acquire::Retries=3 \
|
||||
gcc-aarch64-linux-gnu \
|
||||
gcc-arm-linux-gnueabihf
|
||||
|
||||
- name: Install android avd
|
||||
if: steps.cache-deps.outputs.cache-hit != 'true'
|
||||
if: steps.java-needed.outputs.need
|
||||
run: |
|
||||
USER=travis source travis/install.sh
|
||||
adb emu kill
|
||||
set | egrep '^(ANDROID|PATH)' >android-sdk/.android.env
|
||||
set | egrep '^(ANDROID|PATH)' >.android.env
|
||||
|
||||
- name: Set up SSH
|
||||
run: |
|
||||
chmod og-rw ~ # see https://stackoverflow.com/a/60367309/3869724
|
||||
ssh-keygen -t ed25519 -f ~/.ssh/pwntools-ci -N ''
|
||||
cat > ~/.ssh/config <<EOF
|
||||
Host example.pwnme
|
||||
User $USER
|
||||
HostName 127.0.0.1
|
||||
IdentityFile ~/.ssh/pwntools-ci
|
||||
EOF
|
||||
echo -n 'from="127.0.0.1" ' | cat - ~/.ssh/pwntools-ci.pub > ~/.ssh/authorized_keys
|
||||
ssh -o 'StrictHostKeyChecking no' example.pwnme id
|
||||
travis/ssh_setup.sh
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
@@ -85,23 +95,103 @@ jobs:
|
||||
- name: Install documentation dependencies
|
||||
run: pip install -r docs/requirements.txt
|
||||
|
||||
- name: Disable broken tests
|
||||
run: |
|
||||
rm -f docs/source/elf/corefile.rst
|
||||
rm -f docs/source/ui.rst
|
||||
|
||||
- name: Manually install non-broken Unicorn
|
||||
run: pip install unicorn==1.0.2rc3
|
||||
|
||||
- name: Coverage doctests
|
||||
run: |
|
||||
source android-sdk/.android.env
|
||||
android-sdk/emulator/emulator -avd android-$ANDROID_ABI -no-window -no-boot-anim -read-only -no-audio -no-window -no-snapshot &
|
||||
adb wait-for-device
|
||||
source .android.env || :
|
||||
echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope # required by some gdb doctests
|
||||
PWNLIB_NOTERM=1 coverage run -m sphinx -b doctest docs/source docs/build/doctest
|
||||
coverage combine
|
||||
|
||||
- name: Coverage running examples
|
||||
run: |
|
||||
export TERM=linux
|
||||
set -x
|
||||
python travis/coverage_chdir.py examples/fmtstr examples/fmtstr/exploit.py
|
||||
python travis/coverage_chdir.py examples/fmtstr examples/fmtstr/exploit2.py || : # can fail randomly?
|
||||
coverage run examples/asm.py
|
||||
coverage run examples/asm.py
|
||||
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() { coverage run -m pwnlib.commandline.main "$@"; }
|
||||
set -x
|
||||
|
||||
pwn cyclic 32
|
||||
pwn cyclic -l 0x62616161
|
||||
|
||||
pwn shellcraft -f asm --color amd64.linux.sh
|
||||
|
||||
pwn disasm --color ff3424c3ebfe
|
||||
|
||||
pwn hex abcd
|
||||
pwn unhex 4141 4141
|
||||
|
||||
head -c256 /dev/urandom | pwn phd
|
||||
|
||||
pwn errno 2
|
||||
|
||||
pwn constgrep -c freebsd -m ^PROT_ '3 + 4'
|
||||
pwn constgrep ^MAP_ 0
|
||||
pwn constgrep ^O_
|
||||
|
||||
- name: Build source and wheel distributions
|
||||
run: |
|
||||
python setup.py sdist
|
||||
python setup.py bdist_wheel --universal
|
||||
|
||||
- uses: actions/upload-artifact@v2-preview
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
path: dist/*
|
||||
name: packages
|
||||
path: dist/
|
||||
|
||||
- name: Upload coverage to coveralls.io
|
||||
run: COVERALLS_REPO_TOKEN=PP20MEgztXIQJJTguQwe2jeCh6Bm4lkbv coveralls
|
||||
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: build
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
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"
|
||||
|
||||
pypi:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags')
|
||||
needs: build
|
||||
steps:
|
||||
- name: Download artifacts
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: packages
|
||||
path: dist
|
||||
|
||||
- name: Publish package
|
||||
uses: pypa/[email protected]
|
||||
with:
|
||||
user: __token__
|
||||
password: ${{ secrets.pypi_password }}
|
||||
|
||||
- if: failure()
|
||||
run: ls -R
|
||||
+4
-2
@@ -2,7 +2,6 @@ language: python
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- gcc-multilib
|
||||
- lib32stdc++6
|
||||
- ash
|
||||
- bash
|
||||
@@ -21,6 +20,10 @@ addons:
|
||||
- binutils-arm-linux-gnueabihf
|
||||
- binutils-mips-linux-gnu
|
||||
- binutils-powerpc-linux-gnu
|
||||
- gcc-aarch64-linux-gnu
|
||||
- gcc-arm-linux-gnueabihf
|
||||
- bash-static
|
||||
|
||||
cache:
|
||||
- pip
|
||||
- directories:
|
||||
@@ -54,7 +57,6 @@ script:
|
||||
# stop the build if there are Python syntax errors or undefined names
|
||||
- flake8 . --count --select=E9,F63,F7 --show-source --statistics --exclude=android-?dk # TODO: Add F82
|
||||
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
|
||||
- flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics --exclude=pwnlib/constants,android-?dk,.git,__pycache__
|
||||
- PWNLIB_NOTERM=1 coverage run -m sphinx -b doctest docs/source docs/build/doctest
|
||||
- coverage combine
|
||||
after_success:
|
||||
|
||||
+54
-39
@@ -10,11 +10,13 @@ The table below shows which release corresponds to each branch, and what date th
|
||||
| Version | Branch | Release Date |
|
||||
| ---------------- | -------- | ---------------------- |
|
||||
| [4.3.0](#430) | `dev` | Jun 30, 2020 (planned)
|
||||
| [4.2.0](#420) | `beta` | May 30, 2020 (planned)
|
||||
| [4.1.0](#410) | `stable` | May 8, 2020
|
||||
| [4.2.0](#420) | `beta` | Jun 5, 2020 (planned)
|
||||
| [4.1.1](#411) | `stable` | 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
|
||||
@@ -53,17 +55,27 @@ To be released on Jun 30, 2020.
|
||||
|
||||
## 4.2.0 (`beta`)
|
||||
|
||||
To be released on May 30, 2020.
|
||||
To be released on Jun 5, 2020.
|
||||
|
||||
- #1436 Add ret2dlresolve automation
|
||||
- [#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 Support for windows console colors
|
||||
- [#1454][1454] Support for windows console colors
|
||||
|
||||
[fecf9f]: http://github.com/Gallopsled/pwntols/commit/fecf9f
|
||||
[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.1 (`stable`)
|
||||
|
||||
## 4.1.0 (`stable`)
|
||||
- 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
|
||||
@@ -72,15 +84,19 @@ To be released on May 30, 2020.
|
||||
- [#1241][1241] Launch QEMU with sysroot if specified
|
||||
- [#1218][1218] Support for FileStructure exploitation
|
||||
|
||||
[1241]: https://github.com/Gallopsled/pwntools/pulls/1218
|
||||
[1218]: https://github.com/Gallopsled/pwntools/pulls/1218
|
||||
[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/pulls/1412
|
||||
[1412]: https://github.com/Gallopsled/pwntools/pull/1412
|
||||
|
||||
## 4.0.0
|
||||
|
||||
@@ -94,12 +110,13 @@ To be released on May 30, 2020.
|
||||
- [#1202][1202] Docker: Kill 14 layers in pwntools base images
|
||||
- [#1182][1182] shellcraft.dupio() for mips
|
||||
|
||||
[1391]: https://github.com/Gallopsled/pwntools/pulls/1391
|
||||
[1317]: https://github.com/Gallopsled/pwntools/pulls/1317
|
||||
[1285]: https://github.com/Gallopsled/pwntools/pulls/1285
|
||||
[1216]: https://github.com/Gallopsled/pwntools/pulls/1216
|
||||
[1202]: https://github.com/Gallopsled/pwntools/pulls/1202
|
||||
[1182]: https://github.com/Gallopsled/pwntools/pulls/1182
|
||||
[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
|
||||
@@ -110,32 +127,16 @@ To be released on May 30, 2020.
|
||||
- [#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/pulls/1175
|
||||
[1204]: https://github.com/Gallopsled/pwntools/pulls/1355
|
||||
[1277]: https://github.com/Gallopsled/pwntools/pulls/1277
|
||||
[1292]: https://github.com/Gallopsled/pwntools/pulls/1292
|
||||
[1355]: https://github.com/Gallopsled/pwntools/pulls/1355
|
||||
|
||||
## 3.12.1
|
||||
|
||||
- [#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
|
||||
|
||||
[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
|
||||
[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][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
|
||||
@@ -153,7 +154,15 @@ To be released on May 30, 2020.
|
||||
- [#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
|
||||
@@ -163,6 +172,12 @@ To be released on May 30, 2020.
|
||||
[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
|
||||
|
||||
|
||||
@@ -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
|
||||
For the most part, you will also only get the bits you import. You for instance would
|
||||
not get access to :mod:`pwnlib.util.packing` simply by doing ``import
|
||||
pwnlib.util``.
|
||||
|
||||
|
||||
@@ -25,9 +25,9 @@ pwntools is available as a ``pip`` package.
|
||||
.. code-block:: bash
|
||||
|
||||
$ 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
|
||||
$ 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
|
||||
|
||||
Development
|
||||
--------------
|
||||
|
||||
@@ -3,6 +3,7 @@ from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
|
||||
import argparse
|
||||
import six
|
||||
import string
|
||||
import sys
|
||||
|
||||
@@ -20,7 +21,8 @@ parser = common.parser_commands.add_parser(
|
||||
parser.add_argument(
|
||||
'-a', '--alphabet',
|
||||
metavar = 'alphabet',
|
||||
default = string.ascii_lowercase,
|
||||
default = string.ascii_lowercase.encode(),
|
||||
type = six.ensure_binary,
|
||||
help = 'The alphabet to use in the cyclic pattern (defaults to all lower case letters)',
|
||||
)
|
||||
|
||||
@@ -64,9 +66,10 @@ def main(args):
|
||||
pat = args.lookup
|
||||
|
||||
try:
|
||||
pat = packing.pack(int(pat, 0), subsize*8)
|
||||
pat = int(pat, 0)
|
||||
except ValueError:
|
||||
pass
|
||||
pat = flat(pat)
|
||||
|
||||
if len(pat) != subsize:
|
||||
log.critical('Subpattern must be %d bytes' % subsize)
|
||||
@@ -90,10 +93,11 @@ def main(args):
|
||||
if got < want:
|
||||
log.failure("Alphabet too small (max length = %i)" % got)
|
||||
|
||||
sys.stdout.write(result)
|
||||
out = getattr(sys.stdout, 'buffer', sys.stdout)
|
||||
out.write(result)
|
||||
|
||||
if sys.stdout.isatty():
|
||||
sys.stdout.write('\n')
|
||||
if out.isatty():
|
||||
out.write(b'\n')
|
||||
|
||||
if __name__ == '__main__':
|
||||
pwnlib.commandline.common.main(__file__)
|
||||
+8
-12
@@ -945,16 +945,11 @@ class Corefile(ELF):
|
||||
|
||||
# Sanity check!
|
||||
try:
|
||||
assert stack[address] == b'\x00'
|
||||
except AssertionError:
|
||||
# Something weird is happening. Just don't touch it.
|
||||
log.debug("Something is weird")
|
||||
return
|
||||
if stack[address] != b'\x00':
|
||||
log.warning("Error parsing corefile stack: Could not find end of environment")
|
||||
return
|
||||
except ValueError:
|
||||
# If the stack is not actually present in the coredump, we can't
|
||||
# read from the stack. This will fail as:
|
||||
# ValueError: 'seek out of range'
|
||||
log.debug("ValueError")
|
||||
log.warning("Error parsing corefile stack: Address out of bounds")
|
||||
return
|
||||
|
||||
# address is currently set to the NULL terminator of the last
|
||||
@@ -968,12 +963,14 @@ class Corefile(ELF):
|
||||
p_last_env_addr = stack.find(pack(last_env_addr), None, last_env_addr)
|
||||
if p_last_env_addr < 0:
|
||||
# Something weird is happening. Just don't touch it.
|
||||
log.warn_once("Found bad environment at %#x", last_env_addr)
|
||||
log.warn_once("Error parsing corefile stack: Found bad environment at %#x", last_env_addr)
|
||||
return
|
||||
|
||||
# Sanity check that we did correctly find the envp NULL terminator.
|
||||
envp_nullterm = p_last_env_addr+context.bytes
|
||||
assert self.unpack(envp_nullterm) == 0
|
||||
if self.unpack(envp_nullterm) != 0:
|
||||
log.warning("Error parsing corefile stack: Could not find end of environment variables")
|
||||
return
|
||||
|
||||
# We've successfully located the end of the envp[] array.
|
||||
#
|
||||
@@ -1535,4 +1532,3 @@ class CorefileFinder(object):
|
||||
return keys['interpreter']
|
||||
|
||||
return ''
|
||||
|
||||
+3
-1
@@ -591,6 +591,8 @@ class ELF(ELFFile):
|
||||
self.symbols = dotdict({k:update(v) for k,v in self.symbols.items()})
|
||||
self.plt = dotdict({k:update(v) for k,v in self.plt.items()})
|
||||
self.got = dotdict({k:update(v) for k,v in self.got.items()})
|
||||
for f in self.functions.values():
|
||||
f.address += delta
|
||||
|
||||
# Update our view of memory
|
||||
memory = intervaltree.IntervalTree()
|
||||
@@ -1871,7 +1873,7 @@ class ELF(ELFFile):
|
||||
def unpack(self, address, *a, **kw):
|
||||
"""Unpacks an integer from the specified ``address``."""
|
||||
self._update_args(kw)
|
||||
return packing.unpack(self.read(address, context.bytes), *a, **kw)
|
||||
return packing.unpack(self.read(address, self.bytes), *a, **kw)
|
||||
|
||||
def string(self, address):
|
||||
"""string(address) -> str
|
||||
|
||||
+6
-6
@@ -383,7 +383,7 @@ def debug(args, gdbscript=None, exe=None, ssh=None, env=None, sysroot=None, **kw
|
||||
>>> # Connect to the SSH server
|
||||
|
||||
>>> # Start a process on the server
|
||||
>>> shell = ssh('runner', 'example.pwnme', password='demopass')
|
||||
>>> shell = ssh('travis', 'example.pwnme', password='demopass')
|
||||
>>> io = gdb.debug(['bash'],
|
||||
... ssh = shell,
|
||||
... gdbscript = '''
|
||||
@@ -564,9 +564,9 @@ def attach(target, gdbscript = '', exe = None, need_ptrace_scope = True, gdb_arg
|
||||
... ''')
|
||||
|
||||
>>> # Interact with the process
|
||||
>>> bash.sendline("whoami")
|
||||
>>> bash.sendline("/bin/echo hello")
|
||||
>>> bash.recvline()
|
||||
b'runner\n'
|
||||
b'hello\n'
|
||||
>>> bash.close()
|
||||
|
||||
>>> # Start a forking server
|
||||
@@ -591,7 +591,7 @@ def attach(target, gdbscript = '', exe = None, need_ptrace_scope = True, gdb_arg
|
||||
>>> io.close()
|
||||
|
||||
>>> # Connect to the SSH server
|
||||
>>> shell = ssh('runner', 'example.pwnme', password='demopass')
|
||||
>>> shell = ssh('travis', 'example.pwnme', password='demopass')
|
||||
|
||||
>>> # Start a process on the server
|
||||
>>> cat = shell.process(['cat'])
|
||||
@@ -649,7 +649,7 @@ def attach(target, gdbscript = '', exe = None, need_ptrace_scope = True, gdb_arg
|
||||
if context.os == 'android':
|
||||
pidof = adb.pidof
|
||||
|
||||
pids = pidof(target)
|
||||
pids = list(pidof(target))
|
||||
if not pids:
|
||||
log.error('No such process: %s' % target)
|
||||
pid = pids[0]
|
||||
@@ -866,7 +866,7 @@ def find_module_addresses(binary, ssh=None, ulimit=False):
|
||||
Example:
|
||||
|
||||
>>> with context.local(log_level=9999):
|
||||
... shell = ssh(host='example.pwnme', user='runner', password='demopass')
|
||||
... shell = ssh(host='example.pwnme', user='travis', password='demopass')
|
||||
... bash_libs = gdb.find_module_addresses('/bin/bash', shell)
|
||||
>>> os.path.basename(bash_libs[0].path)
|
||||
'libc.so.6'
|
||||
|
||||
+4
-1
@@ -966,7 +966,10 @@ class ROP(object):
|
||||
SYS_sigreturn = constants.SYS_rt_sigreturn
|
||||
|
||||
for register, value in zip(frame.arguments, arguments):
|
||||
frame[register] = value
|
||||
if not isinstance(value, six.integer_types + (Unresolved,)):
|
||||
frame[register] = AppendedArgument(value)
|
||||
else:
|
||||
frame[register] = value
|
||||
|
||||
# Set up a call frame which will set EAX and invoke the syscall
|
||||
call = Call('SYS_sigreturn',
|
||||
|
||||
+18
-18
@@ -561,11 +561,11 @@ class ssh(Timeout, Logger):
|
||||
Example proxying:
|
||||
|
||||
>>> s1 = ssh(host='example.pwnme',
|
||||
... user='runner',
|
||||
... user='travis',
|
||||
... password='demopass')
|
||||
>>> r1 = s1.remote('localhost', 22)
|
||||
>>> s2 = ssh(host='example.pwnme',
|
||||
... user='runner',
|
||||
... user='travis',
|
||||
... password='demopass',
|
||||
... proxy_sock=r1.sock)
|
||||
>>> r2 = s2.remote('localhost', 22) # and so on...
|
||||
@@ -702,7 +702,7 @@ class ssh(Timeout, Logger):
|
||||
|
||||
Examples:
|
||||
>>> s = ssh(host='example.pwnme',
|
||||
... user='runner',
|
||||
... user='travis',
|
||||
... password='demopass')
|
||||
>>> sh = s.shell('/bin/sh')
|
||||
>>> sh.sendline(b'echo Hello; exit')
|
||||
@@ -781,7 +781,7 @@ class ssh(Timeout, Logger):
|
||||
|
||||
Examples:
|
||||
>>> s = ssh(host='example.pwnme',
|
||||
... user='runner',
|
||||
... user='travis',
|
||||
... password='demopass')
|
||||
>>> sh = s.process('/bin/sh', env={'PS1':''})
|
||||
>>> sh.sendline(b'echo Hello; exit')
|
||||
@@ -1127,7 +1127,7 @@ os.execve(exe, argv, env)
|
||||
|
||||
Examples:
|
||||
>>> s = ssh(host='example.pwnme',
|
||||
... user='runner',
|
||||
... user='travis',
|
||||
... password='demopass')
|
||||
>>> py = s.run('python -i')
|
||||
>>> _ = py.recvuntil(b'>>> ')
|
||||
@@ -1188,7 +1188,7 @@ from ctypes import *; libc = CDLL('libc.so.6'); print(libc.getenv(%r))
|
||||
|
||||
Examples:
|
||||
>>> s = ssh(host='example.pwnme',
|
||||
... user='runner',
|
||||
... user='travis',
|
||||
... password='demopass')
|
||||
>>> print(s.run_to_end('echo Hello; exit 17'))
|
||||
(b'Hello\n', 17)
|
||||
@@ -1213,7 +1213,7 @@ from ctypes import *; libc = CDLL('libc.so.6'); print(libc.getenv(%r))
|
||||
>>> from pwn import *
|
||||
>>> l = listen()
|
||||
>>> s = ssh(host='example.pwnme',
|
||||
... user='runner',
|
||||
... user='travis',
|
||||
... password='demopass')
|
||||
>>> a = s.connect_remote(s.host, l.lport)
|
||||
>>> a=a; b = l.wait_for_connection() # a=a; prevents hangs
|
||||
@@ -1238,7 +1238,7 @@ from ctypes import *; libc = CDLL('libc.so.6'); print(libc.getenv(%r))
|
||||
|
||||
>>> from pwn import *
|
||||
>>> s = ssh(host='example.pwnme',
|
||||
... user='runner',
|
||||
... user='travis',
|
||||
... password='demopass')
|
||||
>>> l = s.listen_remote()
|
||||
>>> a = remote(s.host, l.port)
|
||||
@@ -1258,7 +1258,7 @@ from ctypes import *; libc = CDLL('libc.so.6'); print(libc.getenv(%r))
|
||||
Examples:
|
||||
|
||||
>>> s = ssh(host='example.pwnme',
|
||||
... user='runner',
|
||||
... user='travis',
|
||||
... password='demopass')
|
||||
>>> print(repr(s['echo hello']))
|
||||
b'hello'
|
||||
@@ -1271,7 +1271,7 @@ from ctypes import *; libc = CDLL('libc.so.6'); print(libc.getenv(%r))
|
||||
Examples:
|
||||
|
||||
>>> s = ssh(host='example.pwnme',
|
||||
... user='runner',
|
||||
... user='travis',
|
||||
... password='demopass')
|
||||
>>> print(repr(s('echo hello')))
|
||||
b'hello'
|
||||
@@ -1284,12 +1284,12 @@ from ctypes import *; libc = CDLL('libc.so.6'); print(libc.getenv(%r))
|
||||
Examples:
|
||||
|
||||
>>> s = ssh(host='example.pwnme',
|
||||
... user='runner',
|
||||
... user='travis',
|
||||
... password='demopass')
|
||||
>>> s.echo('hello')
|
||||
b'hello'
|
||||
>>> s.whoami()
|
||||
b'runner'
|
||||
b'travis'
|
||||
>>> s.echo(['huh','yay','args'])
|
||||
b'huh yay args'
|
||||
"""
|
||||
@@ -1317,7 +1317,7 @@ from ctypes import *; libc = CDLL('libc.so.6'); print(libc.getenv(%r))
|
||||
Example:
|
||||
|
||||
>>> s = ssh(host='example.pwnme',
|
||||
... user='runner',
|
||||
... user='travis',
|
||||
... password='demopass')
|
||||
>>> s.connected()
|
||||
True
|
||||
@@ -1475,7 +1475,7 @@ from ctypes import *; libc = CDLL('libc.so.6'); print(libc.getenv(%r))
|
||||
>>> with open('/tmp/bar','w+') as f:
|
||||
... _ = f.write('Hello, world')
|
||||
>>> s = ssh(host='example.pwnme',
|
||||
... user='runner',
|
||||
... user='travis',
|
||||
... password='demopass',
|
||||
... cache=False)
|
||||
>>> s.download_data('/tmp/bar')
|
||||
@@ -1565,7 +1565,7 @@ from ctypes import *; libc = CDLL('libc.so.6'); print(libc.getenv(%r))
|
||||
|
||||
Example:
|
||||
>>> s = ssh(host='example.pwnme',
|
||||
... user='runner',
|
||||
... user='travis',
|
||||
... password='demopass')
|
||||
>>> s.upload_data(b'Hello, world', '/tmp/upload_foo')
|
||||
>>> print(open('/tmp/upload_foo').read())
|
||||
@@ -1796,7 +1796,7 @@ from ctypes import *; libc = CDLL('libc.so.6'); print(libc.getenv(%r))
|
||||
|
||||
Examples:
|
||||
>>> s = ssh(host='example.pwnme',
|
||||
... user='runner',
|
||||
... user='travis',
|
||||
... password='demopass')
|
||||
>>> cwd = s.set_working_directory()
|
||||
>>> s.ls()
|
||||
@@ -1805,7 +1805,7 @@ from ctypes import *; libc = CDLL('libc.so.6'); print(libc.getenv(%r))
|
||||
True
|
||||
|
||||
>>> s = ssh(host='example.pwnme',
|
||||
... user='runner',
|
||||
... user='travis',
|
||||
... password='demopass')
|
||||
>>> homedir = s.pwd()
|
||||
>>> _=s.touch('foo')
|
||||
@@ -1975,7 +1975,7 @@ from ctypes import *; libc = CDLL('libc.so.6'); print(libc.getenv(%r))
|
||||
|
||||
Example:
|
||||
|
||||
>>> s = ssh("runner", "example.pwnme")
|
||||
>>> s = ssh("travis", "example.pwnme")
|
||||
>>> s.aslr
|
||||
True
|
||||
"""
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
__version__ = '4.1.0'
|
||||
__version__ = '4.1.2'
|
||||
@@ -60,7 +60,8 @@ install_requires = ['paramiko>=1.15.2',
|
||||
'psutil>=3.3.0',
|
||||
'intervaltree>=3.0',
|
||||
'sortedcontainers',
|
||||
'unicorn>=1.0.2rc1', # see unicorn-engine/unicorn#1100, unicorn-engine/unicorn#1170
|
||||
'unicorn>=1.0.2rc1,<1.0.2rc4', # see unicorn-engine/unicorn#1100, unicorn-engine/unicorn#1170, Gallopsled/pwntools#1538
|
||||
'six>=1.12.0',
|
||||
]
|
||||
|
||||
# Check that the user has installed the Python development headers
|
||||
@@ -82,7 +83,7 @@ setup(
|
||||
name = 'pwntools',
|
||||
python_requires = '>=2.7',
|
||||
packages = find_packages(),
|
||||
version = '4.1.0',
|
||||
version = '4.1.2',
|
||||
data_files = [('',
|
||||
glob.glob('*.md') + glob.glob('*.txt')),
|
||||
],
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
import coverage
|
||||
import os
|
||||
import sys
|
||||
|
||||
os.environ.setdefault("COVERAGE_PROCESS_START", ".coveragerc")
|
||||
coverage.process_startup()
|
||||
|
||||
__file__ = os.path.abspath(sys.argv.pop(2))
|
||||
with open(__file__) as fp:
|
||||
code = compile(fp.read(), __file__, 'exec')
|
||||
os.chdir(sys.argv.pop(1))
|
||||
exec(code, globals())
|
||||
Regular → Executable
File mode changed.
Regular → Executable
+8
-1
@@ -32,6 +32,7 @@ fi
|
||||
|
||||
# Generate a new key so that we can log into it
|
||||
ssh-keygen -t rsa -f ~/.ssh/$U -N ''
|
||||
chmod og-rw ~/.ssh
|
||||
|
||||
# Load the public key into a memory for below
|
||||
pubkey=$(cat ~/.ssh/$U.pub)
|
||||
@@ -42,6 +43,7 @@ USUDO mkdir $H/.ssh || true
|
||||
USUDO tee -a $H/.ssh/authorized_keys <<EOF
|
||||
from="127.0.0.1" $pubkey
|
||||
EOF
|
||||
USUDO chmod 700 $H $H/.ssh $H/.ssh/authorized_keys
|
||||
|
||||
# In the pwntools examples, we ssh to 'example.pwnme'
|
||||
# Set up an SSH config entry to make this actually work
|
||||
@@ -51,8 +53,13 @@ Host example.pwnme
|
||||
User $U
|
||||
HostName 127.0.0.1
|
||||
IdentityFile ~/.ssh/$U
|
||||
StrictHostKeyChecking no
|
||||
EOF
|
||||
chmod 700 ~ ~/.ssh
|
||||
|
||||
ssh -o "StrictHostKeyChecking no" -vvvv [email protected] id
|
||||
ls -la ~/.ssh
|
||||
USUDO ls -la $H/.ssh
|
||||
|
||||
ssh -v [email protected] id
|
||||
|
||||
set +ex
|
||||
Regular → Executable
File mode changed.
Reference in new issue
Block a user