Compare commits

...
429 Commits
Author SHA1 Message Date
Mathias Svensson 6709a4f747 Release 3.6.1 2017-05-12 10:01:41 +02:00
Mathias Svensson 1a4a1e11ba Follow-up to #980 making it actually work 2017-05-12 09:57:34 +02:00
Zach Riggle f82c0aa3a2 Add mako files to MANIFEST (#980) 2017-05-10 19:59:41 -05:00
Zach Riggle 646ca1eb26 Attempt at fixing #974; I don't have a keyboard with a keypad right now, so can't test. (#979) 2017-05-10 17:00:33 -05:00
Mathias Svensson 043627a56d Release 3.6.0 2017-05-08 20:00:47 +02:00
Mathias Svensson a40a0ecab4 Merge branch 'stable' into beta 2017-05-08 19:59:31 +02:00
Zach Riggle eaea783e2a Verify corefiles are the same via hash before using cached copy (#970) 2017-05-04 13:04:48 -05:00
Zach Riggle f4b3469fb4 Fix incorrect ordering in template for non-ssh remotes (#968) 2017-05-01 23:49:57 -05:00
David Tomaschik 7fe6dd0e8e Respect TERM_PROGRAM for run_in_new_terminal. Fixes #964. (#967)
* Respect TERM_PROGRAM for run_in_terminal.  Fixes #964.

* Set args for TERM_PROGRAM.
2017-05-01 01:22:49 -05:00
Roman 42692c685e Add ability to set env vars in template (#960)
* added ability to set env vars in template

* changed env param to general *a, **kw
2017-04-21 15:11:09 -05:00
Mathias Svensson 9b50163760 Allow setting the terminal through a tuple instead of a list (#957) 2017-04-20 01:25:25 +02:00
Roman e90fb15596 Fixed processing of lists in config file (#954)
* fixed handling of lists in config file

* changed list to tuple
2017-04-18 13:44:40 -05:00
Mathias Svensson 2714a30488 Release 3.6.0beta1 2017-04-15 10:52:38 +02:00
Mathias Svensson ac386877d1 Release 3.5.1 2017-04-15 10:43:55 +02:00
Zach Riggle 4f08b6d79c Allow setting context.device=None, and use context.arch to determine default ABI for adb.compile (#950) 2017-04-13 13:54:17 -05:00
Zach Riggle 80219df5cc Require a path for 'pwn template' (#947)
Closes Gallopsled/pwntools#943
2017-04-13 10:37:21 -05:00
Zach Riggle 065c79d29c Speed up ssh via caching checksec results (#945)
* Speed up ssh via caching checksec results

Closes Gallopsled/pwntools#944

* Fix logging message

(cherry picked from commit 8a7bb9b9f4)
2017-04-12 21:47:41 -05:00
Zach Riggle 310f186e5f Do not attempt to populate GOT and PLT symbols for Corefiles (#948)
Closes Gallopsled/pwntools#946
2017-04-12 21:47:05 -05:00
Mathias Svensson 8120b5c037 Merge branch 'stable' into beta 2017-03-26 22:18:01 +02:00
Mathias Svensson 55456814fc Release 3.5.0 2017-03-26 21:13:03 +02:00
Zach Riggle eb3e3797cd Update CHANGELOG for 3.6.0beta release 2017-03-23 13:15:03 -05:00
Zach Riggle 3416b7c949 Fix conditional for logging 2017-03-19 17:11:33 -05:00
Zach Riggle dc9882abe7 Use _run for objdump output 2017-03-06 14:27:13 -06:00
Zach Riggle 664622fa07 Use all symbols in inverted PLT search 2017-03-06 14:05:53 -06:00
Zach Riggle 930f2a4a32 Do not dump PLT emulation data to DEBUG logs unless explicitly set via PLT_DEBUG 2017-03-04 18:31:24 -06:00
Zach Riggle 10ef77b997 Add missing link to Changelog 2017-03-04 16:10:50 -06:00
Zach Riggle ecba8e4b38 Update changelog for 3.5.0 2017-03-04 16:09:08 -06:00
Mathias Svensson 0d3b97b378 Merge branch 'beta' into dev 2017-03-03 23:20:08 +01:00
Zach Riggle 33945f6885 Clean up socket-class and socket-type code in sock/remote/listen (#920)
* Clean up socket-class and socket-type code in sock/remote/listen

* Slight change to docs

* Add doctests for listen and attribute documentation

* Fix bug in listen.close()

* Fix regression on ipv6 sockets

* Simplify documentation

* Fix doctest
2017-03-03 14:04:58 -06:00
Zach Riggle b7ddfa995e Fix ARM PLT parsing, and big-endian ARM emulation (#910)
* Do not use UC_MODE_BIG_ENDIAN, its support is poor

* Ghetto-swap endianness for emulation of PLT instructions

* Reduce instruction alignment so that all ARM PLT entries are found

* Add tests for ELF PLT loading

* Fix canary detection on PowerPC

* Fix x32 emulation

* Fix two failing doctests

* Add AArch64 to supported big-endian architectures

* Add MIPS GOT parsing code, fix unpack macros to use ELF settings

* Why, MIPS, are you so complicated?

* Catch weird edge cases

* I don't know what's real anymore

* Fix synthetic symbol generation and add tests

* Remove canary test

* Guard against errors in MIPS GOT

* Fix doctests
2017-03-02 19:03:45 -06:00
Mathias Svensson 3b2be2b2a7 Merge branch 'stable' into beta 2017-03-02 11:47:55 +01:00
Zach Riggle 0a3ac521ad Work around appdirs error for Travis CI builds (#924)
Closes Gallopsled/pwntools#921
2017-03-01 17:58:22 -06:00
Zach Riggle 1f72e45eaf Attempt appdirs workaround 2017-02-25 01:44:55 -05:00
Zach Riggle 421a3093fc Remove spinners that will probably get us yelled at 2017-02-25 01:25:08 -05:00
Zach Riggle d08fc6d3a0 Simplify Travis Dockerfile 2017-02-24 15:50:33 -05:00
Zach Riggle dd6931907a Update user-agents 2017-02-24 14:15:29 -05:00
Zach Riggle de3a68d8b4 Update 'pwn template' template to support argv and auto-downloading the target file (#919) 2017-02-22 12:09:55 -05:00
Zach Riggle 93b828ff97 Add missing basic templates for AArch64 (#918)
* Add missing basic templates for AArch64

* Simplify aarch64 templates

* Fix broken doctests
2017-02-21 19:48:58 -05:00
Zach Riggle 326dd83321 Handle errors during ssh.checksec() (#917)
* Handle errors during ssh.checksec()

Closes Gallopsled/pwntools#916

* Add additional error handling for ulimit checks
2017-02-21 14:57:58 -05:00
Mathias Svensson f8bb49c78f Merge branch 'beta' into dev 2017-02-17 14:56:39 +01:00
Mathias Svensson 510e247034 Merge branch 'stable' into beta 2017-02-17 14:48:14 +01:00
Mathias Svensson 4d529cd543 Release 3.4.1 2017-02-17 14:29:51 +01:00
Kristoffer Søholm e021f57806 Fixed bug in generatePadding (issue #891) 2017-02-17 14:15:31 +01:00
Zach Riggle b6cfec6284 Do not fail with gdb.debug() over ssh when given an absolute path (#894)
* Do not fail with gdb.debug() over ssh when given an absolute path

Fixes Gallopsled/pwntools#885

* Prevent failing on stable since this directory doesn't exist
2017-02-17 00:02:53 -05:00
Zach Riggle 4834032b14 Doctest all members, even if they are not exported via __all__ (#914)
* Doctest all members

* Fix doctest failures in asm and remove canary in context

* Fix failing doctest

* Use automodule for pwnlib.context

* Fix failing tests in context module

* Use automodule for pwnlib.memleak
2017-02-16 23:40:50 -05:00
Zach Riggle 1273552189 Do not skip "hidden" doctests (#912)
* Check to see if hidden members are doctested

* Do not skip undocumented members

* Fix broken tests, promote missing tests
2017-02-16 21:30:35 -05:00
Zach Riggle ef1e3cfb97 Fix regression in f4b0e3a5 2017-02-16 19:43:26 -05:00
Zach Riggle e9fc0125a6 Add "pwn template" command for generating templates (#909) 2017-02-16 19:38:34 -05:00
Zach Riggle 81239be429 Fix checksec nx, execstack, relro reporting (#904)
* Fix checksec nx, execstack, relro reporting

Also add a disable_nx function

* Add disablenx command-line utility

Also fix bug where invoking command-line utilities directly by module name
(python -m pwnlib.commandline.foo) would fail
2017-02-16 17:20:28 -05:00
Zach Riggle f4b0e3a5b9 Do not allow interactive assembly, it doesn't work anyway 2017-02-16 16:48:59 -05:00
Kristoffer Søholm 1f1a6667a1 Added test for issue #891 (#903) 2017-02-15 17:00:54 -05:00
Zach Riggle 464e9e54e1 Add 'pwn debug' command-line utility (#905)
Also fixes a bug in process() which would throw the wrong exception
when qemu-user cannot be located for a non-native binary.
2017-02-15 17:00:24 -05:00
Zach Riggle a786a58db7 Emulate PLT for better symbols (#899)
* Emulate all relocation sections for PLT symbols

This adds a dependency on Unicorn

* Don't look up empty symbols
2017-02-15 16:57:24 -05:00
Zach Riggle bc471d13f9 Fix MIPS ELF bit-ness by checking masks in increasing order (#901)
Closes Gallopsled/pwntools#900
2017-02-14 11:36:28 -05:00
Zach Riggle 6af464fc0e Make SROP doctests slightly more verbose 2017-02-13 18:12:52 -05:00
Zach Riggle 29e38a7d49 Add missing --init to docker invocation 2017-02-13 18:02:11 -05:00
Zach Riggle 658589704a Add pwnlib.config module and documentation (#893)
This adds functionality for user configuration files at ~/.pwn.conf
and /etc/pwn.conf.  Previously this was only used by the pwnlib.log
module, and was entirely undocumented.

This is now documented, and offers an easy mechanism for other parts
of the code to have extension points.
2017-02-13 17:55:01 -05:00
Zach Riggle 71855ebd2f Fix Aarch64 syscalls (#897)
* Remove unavailable syscalls from AArch64

The Linux kernel has apparently stopped supporting these

* Rewrite shellcraft.aarch64.linux.cat, add open which uses openat

Fixes Gallopsled/pwntools#896

* Fix doctests to use openat
2017-02-13 17:50:45 -05:00
Zach Riggle 393751351b Add dockerfile for testing-in-a-box on Xenial (#895) 2017-02-13 17:34:26 -05:00
Mathias Svensson c8a690d617 Removed all uses of sh_command_with and sh_prepare (#892) 2017-02-13 14:59:27 -05:00
Kristoffer Søholm 8b8a50b580 Fixed bug in generatePadding (issue #891) 2017-02-13 11:39:42 +01:00
Mathias Svensson 3b07dfe7cc Begin work on 3.6.0 2017-02-13 01:52:59 +01:00
Mathias Svensson 5877f8e97e Merge branch 'stable' into beta-staging 2017-02-13 01:34:31 +01:00
Mathias Svensson 4ebcbee34b Release 3.4.0 2017-02-13 01:31:16 +01:00
Mathias Svensson d25d62c126 Merge branch 'stable' into stable-staging 2017-02-13 01:31:00 +01:00
Zach Riggle 5392611ed5 Use updated testing scripts from 3.5.0 on 3.4.0 2017-02-13 01:17:57 +01:00
Zach Riggle 7c139c7179 Shellcode syscall templates (#871)
* Add templates from generator

* Add abi.stack to all ABIs

* Enable shellcraft.arch.os.foobar.template

* Add pwnlib.registers.current()

* Add syscalls symlinks

* Add syscall generator

* Enable shellcraft.foo() shortcut for shellcraft.arch.os.syscalls.foo()

* Make templates more verbose

* Remove old templates

* Add makefile

* Delete old templates, make shellcraft --list work

This also speeds up boot time by like 0.05 seconds

* Remove unnecessary execve wrappers

* Check for common arch as well

* Don't explode on string arguments that are register names

* Catch bad argument names

* Remove accidental import

* Add aarch64 ABIs since we enabled aarch64 tests

* Fix mmap vs mmap2 syscall

* Make shellcraft command-line work for syscalls

* Remove unnecessary wrapper templates

* Set all default values to zero

* Add example of automatic determination of types

* Add missing register architectures

* Add PowerPC ABIs

* More syscall examples

* Handle mmap vs mmap2

* Add missing import, use full path

* Just use the string name

* Fix rt_sigreturn on amd64

* __NR_ --> SYS_ because of old expectations

* rstrip to remove blankline

* Fix Thumb doctests which uses unpredictable jump labels

* Import additional syscalls by updating the function source.

Support variable-argument syscalls.

Support spilling to the stack.

* Simplified constants.eval logic means no extra parens

* Simplify vararg representation; fix oepn() argument name explicitly

* Fix syscall examples

* Fix reordering of arguments, since we have to support stack spill

* Fix argument name in doctest

* Make Codacy happy

* Restore connect template accidentally removed in 9fceb12b

* Scrape all architectures for syscall names

* Enable void* and void** to be pushed

* Make Codacy happy

* Add __doc__ to sdist

* Follow shellcraft template symlinks

* Detect syscall shellcodes in shellcraft based on path

(cherry picked from commit 94462845fa)
2017-02-12 18:37:20 -05:00
Zach Riggle da9ce55dfd Fix changelog formatting 2017-02-12 18:26:11 -05:00
Zach Riggle 9d394e0df1 Add missing info to 3.4.0 changelog 2017-02-12 18:26:02 -05:00
Zach Riggle f962d2bd21 Add missing info to 3.4.0 changelog 2017-02-12 18:24:50 -05:00
Zach Riggle 667d290d9b Fix regression from 189b1fb3c 2017-02-11 15:16:14 -05:00
Zach Riggle 766c4d8a7f sh_string should return '' for empty strings (#887) 2017-02-11 15:02:46 -05:00
Zach Riggle 189b1fb3c2 Add missing registers to AArch64 sigreturn frame, and update test 2017-02-10 22:54:24 -05:00
Zach Riggle 6c1b882b40 Upgrade warnings to errors in demo 2017-02-10 22:38:04 -05:00
Zach Riggle 0c76348072 Fix AArch64 SROP register name 2017-02-10 22:37:23 -05:00
Zach Riggle 2f7d78bc64 Add sigreturn/corefile examples and sanity tests 2017-02-10 22:34:27 -05:00
Zach Riggle 646723fa8e Remove unneded arg from aarch64 sigreturn 2017-02-10 22:19:11 -05:00
Zach Riggle e77915fba6 Handle PC/SP being invalid in Corefiles 2017-02-10 22:16:13 -05:00
Zach Riggle a02e8da1ea Add AArch64 support to corefiles 2017-02-10 22:16:13 -05:00
Zach Riggle 6979cb0d2b Search for QEMU coredumps first 2017-02-10 21:57:18 -05:00
Zach Riggle bc8942006b Convert alignment error to a warning; add AArch64 2017-02-10 21:54:26 -05:00
Zach Riggle 07c7b51f25 Add ip and fp aliases to user_regs_struct on arm 2017-02-10 21:51:53 -05:00
Zach Riggle ee655cac60 Add Android and AArch64 support to SigreturnFrame 2017-02-10 21:19:48 -05:00
Zach Riggle b668815323 Fix elf.functions not containing back-references 2017-02-10 21:07:56 -05:00
Zach Riggle a26a1a1f35 Permit setting SROP arguments directly 2017-02-10 21:03:26 -05:00
Zach Riggle ab42519e26 Enable disassembling entire functions 2017-02-10 19:28:59 -05:00
Zach Riggle 59b44b4fe6 Fix typo from 0c8006ca 2017-02-10 19:28:26 -05:00
Zach Riggle f4f21f147b Squelch error messages when restarting the server 2017-02-10 12:54:01 -05:00
Zach Riggle c06822571f Do not overrite tube.flat with ADB protocol Client 2017-02-10 12:40:22 -05:00
Zach Riggle 383a4f4596 adb.push() should return the target path 2017-02-09 15:25:13 -05:00
Zach Riggle 25d63da30e Do not print connection messages when using AdbClient 2017-02-09 15:20:01 -05:00
Zach Riggle dd2ad30a51 Catch exceptions when SSHing into machines with unsupported architectures (#884)
Fixes fefd48f34
2017-02-05 17:00:09 -05:00
Zach Riggle d160f9b7c9 Make corefiles great again (#839)
Adds a large amount of functionality around Corefiles, to support smarter exploitation

Adds a ".corefile" property to both local and remote (ssh) processes.  See the
documentation for the corefile module for extensive examples and tests.

Additionally, context.delete_corefiles and context.rename_corefiles have been added,
to control the behavior of the ".corefile" property.
2017-02-05 10:49:50 -05:00
Zach Riggle 0bdbc2b8c3 Make pwnlib.rop consistent with context.bytes (#882)
Fixes Gallopsled/pwntools#879
2017-02-05 09:36:45 -05:00
Zach Riggle d0c4d8488e Disable exit-on-error at the end of bash scripts (#881) 2017-02-05 07:43:38 -05:00
Zach Riggle f3968afbbb Add aarch64 documentation, which enables doctests (#875)
* Add aarch64 documentation, which enables doctests

* Fix failing doctest

* Attempt to figure out whats going on with Travis

* Use the Xenial version of qemu-static since the Zesty version is broken for AArch64
2017-02-02 00:32:25 -05:00
Zach Riggle 2d04acb867 Enhance adb.which to support all=True 2017-01-31 15:05:26 -05:00
Zach Riggle 62842e20f0 Make command-line tools work better 2017-01-29 18:50:46 -05:00
Zach Riggle c929217947 Restore dupsh from d21af22f82
Closes Gallopsled/pwntools#873
2017-01-27 08:17:16 -05:00
Zach Riggle ff08a859f8 Docker: Install unprivileged user pwntools, use correct tags 2017-01-26 16:03:26 -05:00
Zach Riggle ba24b440c5 Convert symlink to actual file, since Docker Hub doesnt like symlinks 2017-01-26 14:40:34 -05:00
Zach Riggle b31adf27d0 Update dockerfiles and add various distros / release versions 2017-01-26 14:04:37 -05:00
Zach Riggle 20d27c651a Silence commits in the build logs 2017-01-25 18:14:06 -05:00
Zach Riggle ba7911651e Install a recent version of GDB onto Travis (#872)
These files should be cached automagically.
2017-01-25 17:21:59 -05:00
Zach Riggle cded6cda47 Make upgrades / add fields to process() (#869)
- Show the PID when a process is created
- Make process.cwd into a property, which fetches the real CWD from procs
- Record the UID/GID and SUID/SGID of the executed file
- Add a few doctests
- Make _stop_noticed a timestamp
2017-01-24 19:30:26 -05:00
Zach Riggle 25941b52bb Multiple SSH enhancements (#868)
- Break out ssh_channel into subclass ssh_process
- Make ssh.process() directly instantiate ssh_process
- Add ssh_process().ELF
- Add ssh_process().corefile
- Record the UID and GID of the executed binary
- Add the created PID to the ssh_process message
2017-01-24 19:02:57 -05:00
Zach Riggle b79a750af6 Force-install libcapstone3 since it is causing errors 2017-01-24 18:02:43 -05:00
Zach Riggle eede2e2e1d Always upgrade Pip first 2017-01-24 17:43:19 -05:00
Zach Riggle 2a59f5cf4c Fix chunked reading of ELF files (#865)
* Fix chunked reading of ELF files

This introduces a new dependency on 'intervaltree', which is used
to automatically select segments which are relevant for a given
virtual-address range.

This also introduces a new ELF.memory attribute, which is the tree
of memory ranges, which point at the segment objects that describe
the memory range.

These are recalculated when ELF.address is adjusted, and we have
tests for that.

This also optimizes some of the other routines to avoid the wrapped
file-seeking, and to just use the mmap.

* Rewrite install scripts to use more modern versions of binutils

* Load segments in file-order, chop any overlaps
2017-01-24 13:41:29 -05:00
Mathias Svensson a3e82e27bb Fix a few edge cases in weird ELF files (#867)
* Fix a few edge cases in weird ELF files

* Add a check for PT_LOAD
2017-01-24 19:14:29 +01:00
Zach Riggle 368a708663 Upgrade documentation requirements on Travis 2017-01-24 12:00:34 -05:00
Zach Riggle 4a7de306f0 Convert impossible doctest into a code-block 2017-01-23 15:47:43 -05:00
Zach Riggle 69bbd0839a Clean up pwnlib.asm documentation and doctests 2017-01-23 15:39:36 -05:00
Zach Riggle 475ffa632e Always run Android tests on staging branches and new tags (#866) 2017-01-23 14:43:32 -05:00
Zach Riggle 06db497901 Add a bit more documentation to context.rst 2017-01-23 12:16:30 -05:00
Zach Riggle 5106c4eb75 Fix test in dpkg_search_for_binutils 2017-01-23 12:11:02 -05:00
Zach Riggle 08b7b190a7 A few documentation touch-ups 2017-01-23 12:08:36 -05:00
Zach Riggle 8259d07207 Remove useless doctest lines 2017-01-23 12:01:27 -05:00
Zach Riggle ad2eb77cfa Explicitly run a few asm tests 2017-01-23 12:00:08 -05:00
Zach Riggle ec04c860c0 Remove unnecessary doctests:: blocks 2017-01-23 11:59:48 -05:00
Zach Riggle ffe4cf6807 Add doctest for print_binutils_instructions 2017-01-23 11:19:36 -05:00
Zach Riggle 673073f08d Add a test for pwnlib.asm.dpkg_search_for_binutils 2017-01-23 11:15:57 -05:00
Zach Riggle 0e45f23af8 Add pwnlib.protocols module (#860)
* Add pwnlib.protocols module

Migrate pwnlib.adb.protocol into that directory, and add compatibility shims

* Add documentation links, and run doctests

* Make doctests run

* pwnlib.protocols.adb.Client.transport should work with no device
2017-01-20 18:59:23 -05:00
Zach Riggle 31cd98affe Do not truncate the ELF file when saving to the same path 2017-01-20 15:27:46 -05:00
Zach Riggle 3e4a1bcc72 Fix errant version number printing 2017-01-20 15:22:59 -05:00
Zach Riggle 85c3074574 Allow calling ELF.save() with no arguments 2017-01-20 15:22:59 -05:00
Zach Riggle 178e64a4f7 Add symlink option for ssh.set_working_directory to simplify exploits (#862)
* Add symlink option for ssh.set_working_directory to simplify exploit code

* Add additional options and tests to symlink=xxx
2017-01-20 14:58:08 -05:00
Zach Riggle 179476604e Fix error message format string
Closes Gallopsled/pwntools#863
2017-01-20 14:38:37 -05:00
Zach Riggle fc6e00d9f0 Update changelog for 3.5.0 2017-01-19 15:18:17 -05:00
Zach Riggle 8b1f1dce84 Update changelog for 3.5.0 2017-01-19 15:11:44 -05:00
Zach Riggle 8345bc3824 Add parse_kconfig and kernel information to pwnlib.elf.ELF (#861) 2017-01-19 11:01:31 -05:00
Zach Riggle 300f8e0c1a Speed up processing of symbols slightly, by not checking for each entry 2017-01-17 16:38:01 -05:00
Zach Riggle 9ace73a977 Replace broken function-decorator context.quiet with working context.quietfunc
Fixes: ae6a0745f
2017-01-17 15:10:25 -05:00
Zach Riggle fb16e158ec Use tubes.buffer for net.wget, add more tests 2017-01-17 13:58:49 -05:00
Jakub Wilk e519874947 Fix typos (#859) 2017-01-16 11:42:38 -05:00
Zach Riggle 2e90d05156 Actually implement ssh.sftp setter, so it can be set to None 2017-01-14 15:05:15 -05:00
Zach Riggle b6e3d5d8c5 Fix register usage in execve shellcode (#857)
The previous code worked, but we emitted a register swap that hid the fact we were using the wrong registers

Fixes Gallopsled/pwntools#856
2017-01-13 14:00:28 -05:00
Zach Riggle 0726d8d339 Fix hexdump alignment for weird widths
Closes Gallopsled/pwntools#849
2017-01-12 17:57:54 -05:00
Mathias Svensson bd5a368754 Merge branch 'beta' into dev 2017-01-12 23:48:54 +01:00
Mathias Svensson 602efd2790 Release 3.4.0beta4 2017-01-12 23:42:25 +01:00
Mathias Svensson 2f7f0de984 Release 3.3.4 2017-01-12 23:40:13 +01:00
Zach Riggle 45d2c11535 Update changelog for 3.3.4 2017-01-12 17:30:30 -05:00
Zach Riggle 16b507e197 Change hexdump_iter to not rely on the length of its input file (#850)
We cannot determine the length of the file if passed e.g. a tube or a pipe or PTY or character device (e.g. stdin or /dev/null).

Supercedes: 9c2f0f4e
(cherry picked from commit 14f717b7b4)
2017-01-12 17:20:15 -05:00
Zach Riggle 53f041a4d2 Fix shellcraft.amd64.popad registers (#853)
Fixes Gallopsled/pwntools#848
2017-01-12 16:47:44 -05:00
Zach Riggle b2a5b76cf7 Do not perform temporary register selection if we don't need to (#852)
Fixes Gallopsled/pwntools#847
2017-01-12 16:36:49 -05:00
Zach Riggle 9cb438842c Use class- and init-level documentation for Sphinx autodocs 2017-01-12 16:09:23 -05:00
Zach Riggle 14f717b7b4 Change hexdump_iter to not rely on the length of its input file
We cannot determine the length of the file if passed e.g. a tube or a pipe or
or PTY or character device (e.g. stdin or /dev/null).
2017-01-12 15:01:42 -05:00
Zach Riggle f792407c19 Remove hanging comment 2017-01-11 19:22:48 -05:00
Zach Riggle 9c2f0f4e89 Fix hexdump_iter for actual file objects, like those used by phd (#846) 2017-01-11 15:06:11 -05:00
Zach Riggle eb0bb6ea8d Add doctest for hexdump_iter 2017-01-11 00:51:28 -05:00
Zach Riggle f46112e873 Fix hexdump_iter for actual file objects, like those used by phd 2017-01-11 00:45:39 -05:00
Zach Riggle 975844d83d Add SigreturnFrame.__flat__ 2017-01-10 21:29:36 -05:00
Zach Riggle 466c0e4179 Add elf.process, elf.fit, process.fit
Also fix the implementation of elf.flag
2017-01-10 21:27:50 -05:00
Zach Riggle 17e4f01976 Enhance output of amd64.mov shellcraft for very large values 2017-01-10 18:18:34 -05:00
Mathias Svensson fecd6f8222 Merge branch 'beta' into dev 2017-01-11 00:03:09 +01:00
Mathias Svensson 7ba3a1b32f Release 3.4.0beta3 2017-01-10 23:53:59 +01:00
Mathias Svensson d1edd275d9 Release 3.3.3 2017-01-10 23:52:50 +01:00
Zach Riggle 8f012947e9 Add build-essential and pip upgrade to installation steps (#845)
Fixes Gallopsled/pwntools#844
2017-01-10 17:35:50 -05:00
Zach Riggle 36b05bac2b Add doctests for the hexdump utility (#842)
Related: Gallopsled/pwntools#837
Related: Gallopsled/pwntools#840
2017-01-10 17:21:54 -05:00
Zach Riggle cb4991c41d Fix regression in amd64.mov with 32-bit values >= 0x80000000 (#843)
Fixes Gallopsled/pwntools#841
Caused by: Gallopsled/pwntools#504 (9ca377c)
2017-01-10 15:56:50 -05:00
Mathias Svensson 65f18b6091 Merge branch 'beta' into dev 2017-01-10 18:43:46 +01:00
Mathias Svensson 48616c633d Release 3.4.0beta2 2017-01-10 18:30:16 +01:00
Mathias Svensson 323975f343 Release 3.3.2 2017-01-10 18:28:24 +01:00
Zach Riggle f65c258956 Fix hexdump regression in 3.3.1 (#840) 2017-01-10 12:15:34 -05:00
Mathias Svensson c928a0425e Merge branch 'beta' into dev 2017-01-10 17:00:15 +01:00
Mathias Svensson f5e16d3db6 Release 3.4.0beta1 2017-01-10 16:59:22 +01:00
Mathias Svensson d55874a6d3 Release 3.3.1 2017-01-10 16:53:24 +01:00
Zach Riggle 0426d498d9 Resolve feature regression in hexdump(..., cyclic=True)
This code wasnt updated when the code was changed to operate on file descriptors.

Additionally, there was a functional regression, that the first line would be skipped.

Fixes: Gallopsled/pwntools#836
Caused by: Gallopsled/pwntools#695 (d65991d)
2017-01-09 21:59:19 -05:00
Zach Riggle fefd48f341 Add ssh.checksec functionality (#835)
Looks like this:

[x] Connecting to example.pwnme on port 22
[+] Connecting to example.pwnme on port 22: Done
[*] [email protected]:
    Distro    Ubuntu 14.04
    OS:       linux
    Arch:     amd64
    Version:  3.11.0
    ASLR:     Enabled
    Note:     Susceptible to ASLR ulimit trick (CVE-2016-3672)

Fixes Gallopsled/pwntools#753
2017-01-09 13:55:38 -05:00
Zach Riggle 132f48e6ee Fix failing doctest. Not sure what changed, but it was clearly not guaranteed to be right, given global state. 2017-01-07 19:16:04 -05:00
Zach Riggle e205e17b6d Fix doctests in ELF module 2017-01-07 18:32:37 -05:00
Zach Riggle d0267f3ee7 packing.fit() should handle extremely large offsets as if they are cyclic patterns 2017-01-07 18:21:14 -05:00
Zach Riggle 0c8006ca4e Enable passing an elf.Function to flat() 2017-01-07 18:14:57 -05:00
Zach Riggle bd88c92991 Greatly enhance and update the pwnlib.elf module documentation. 2017-01-07 18:10:59 -05:00
Zach Riggle 12f1bb9126 Add signal names to negative exit codes for process.poll() 2017-01-07 16:37:57 -05:00
Zach Riggle 3fa2c659fd Merge branch 'beta' into dev 2017-01-05 12:41:28 -05:00
Zach Riggle a2c67e5075 Merge branch 'stable' into beta 2017-01-05 12:39:25 -05:00
Zach Riggle 54e722819b Defer attempts to start ADB server until we actually fail to connect (#833)
* Defer attempts to start ADB server until we actually fail to connect

* Upgrade to a warning message; fix .version() multiple calls with _autoclose

* Add doctest which tests the kill/restart behavior
2017-01-05 12:38:51 -05:00
Zach Riggle 179a0656f5 Add better example of NOPTRACE 2017-01-04 23:16:22 -05:00
Zach Riggle 58b2e36a1b Fix empty code-block 2017-01-04 23:13:50 -05:00
Zach Riggle 24ae51dae4 Greatly enhance documentation for the GDB module, and expose its members in toplevel 2017-01-04 23:06:34 -05:00
Zach Riggle 14e68ec226 Remove _raw variants from public documentation 2017-01-04 14:57:22 -05:00
Zach Riggle 485dcede2c Fix heading style for ADB docs 2017-01-04 14:45:54 -05:00
Zach Riggle 50acdbbe41 Add hyperlinks to tube class 2017-01-04 14:44:30 -05:00
Zach Riggle 4e0e9d2acb Add hyperlinks to process class 2017-01-04 14:43:51 -05:00
Zach Riggle bc7c8cd423 Add missing :const: to docstrings 2017-01-04 14:37:43 -05:00
Zach Riggle a8446bef47 Fix sh_string RST formatting 2017-01-04 14:36:21 -05:00
Zach Riggle afdcdec577 Fix sh_string docs 2017-01-04 14:23:06 -05:00
Zach Riggle c13ff2cb08 Clarify documentation and remove leading process.XXX in docs 2017-01-04 14:18:02 -05:00
Zach Riggle a12d0b6a4c Move PTY, PIPE, STDOUT to toplevel 2017-01-04 14:15:38 -05:00
Zach Riggle 3dd6045488 Fix regression caused by 0cead77 2017-01-04 14:14:23 -05:00
Zach Riggle cca9782424 Add PR_SET_PTRACER to process and ssh.process (#828)
* Add PR_SET_PTRACER to initialization, and add doctests for process.leak/corefile

* Add PR_SET_PTRACER to SSH processes

* Do not warn about YAMA if we dont need to

* Fix doctest to use raw strings

* Fix typo in doctest

* Apparently GDB is not installed on Travis by default

* Add warning message to process("foo") vs process("./foo")

* Add gdb.corefile; make run_in_new_terminal return a PID

* Intentionally break doctest because I dont believe that it worked

* Fix codacy issues

* Fix gdb.attach return value

* Add missing import

* Fix typo, use waitpid

* Refactor some code into gdb.version / gdb.binary

* Permit GDB with multipart versions

* Fix repr() on Corefile

* Silence run-in-new-terminal message for gdb.corefile

* Fix version number

* Remove Yama warning message entirely, it should no longer be necessary

* Version detection is hard.  Regular expressions to the rescue!

* Remove process.kill/stop/resume, those will be a different PR

* Fix doctests

* The GDB used by Travis must be so old!

* Apparently Travis is entirely borked.  Use a less robust test.
2017-01-04 12:59:22 -05:00
Zach Riggle 5ce5339ab5 Silence warning during doctests 2017-01-04 12:58:04 -05:00
Zach Riggle 0cead77039 Move STDOUT/PIPE to process class, so they can be referenced directly 2017-01-04 12:52:19 -05:00
Zach Riggle 1d59a90fa8 Change all imports to absolute per PEP-328, and sort imports (#832) 2017-01-03 18:04:45 -05:00
Zach Riggle ac017d97dc Enable leaking memory relatively with MemLeak (#822)
* Enable leaking memory relatively with MemLeak

Fixes Gallopsled/pwntools#758

* Add RelativeMemLeak alias for MemLeak(..., relative=True)

* Make codacy happy
2016-12-29 13:21:02 -05:00
WGH b584ca349a fixed RuntimeError in setup.py caused by pandoc on non-amd64 arches (#820)
If pandoc is not installed locally, pwntools' setup.py
tells pypandoc to download one.

Unfortunately, it fails on non-amd64 arches because
pypandocs provides precompiled binaries only for amd64.

Since pypandoc is not hard dependency for pwntools,
this error can be skipped without major harm.

In fact, pwntools' setup.py already handles ImportError
gracefully. The problem is, arch mismatch causes
a completely different exception.
2016-12-28 19:12:47 -05:00
Mathias Svensson 8b30700f92 Bump to 3.5.0dev 2016-12-24 12:14:05 +01:00
Mathias Svensson 7ed118763b Merge branch 'dev' into beta 2016-12-24 11:54:21 +01:00
Mathias Svensson 5a370162e5 Release 3.3.0 2016-12-24 11:26:18 +01:00
Mathias Svensson 253ab78e4c Merge branch 'stable' into beta 2016-12-24 11:25:12 +01:00
Mathias Svensson e997c17397 Merge branch 'beta' into dev 2016-12-24 11:10:10 +01:00
Mathias Svensson 0acc8ee499 Merge branch 'stable' into beta 2016-12-24 11:00:32 +01:00
Mathias Svensson d39f9a145e Release 3.2.1 2016-12-24 10:53:02 +01:00
Zach Riggle f14e0e5652 Reorder get_buffer_size so that the value is validated
This prevents silly things like tube.recv("abcdef") which will hang
2016-12-22 16:41:51 -05:00
Zach Riggle aaa83983ad Merge branch 'beta' into dev 2016-12-22 16:27:46 -05:00
Zach Riggle 1b76a27bd5 Merge remote-tracking branch 'upstream/stable' into beta-staging 2016-12-22 16:26:31 -05:00
Zach Riggle 87491bf6dc Fix install script for new branches, where TRAVIS_COMMIT_RANGE is empty 2016-12-22 14:40:43 -05:00
Zach Riggle b30835ec5b Fix regression introduced in 386e68691f 2016-12-22 14:03:09 -05:00
Zach Riggle 1241073391 Remove support for installation without psutil (#821)
* Remove support for installation without psutil.

OpenBSD was the edge case we cared about, it is supported for over a year (giampaolo/psutil#615)

* Bump psutil version to when they introduced OpenBSD support
2016-12-20 14:06:06 -05:00
Zach Riggle cfcd79e169 Update install strings to include libffi-dev and be consistent 2016-12-16 11:37:13 -06:00
Zach Riggle 706a784904 Directly invoke sock.close() when we hit POLLHUP 2016-12-15 20:20:07 -06:00
Zach Riggle 70c96330de Make sock.connected much more robust by using socket.poll (#817)
* Make sock.connected much more robust by using socket.poll

* Fix use of socket.socket.recv vs. ssh transport recv
2016-12-15 20:15:19 -06:00
Zach Riggle cae3cddc07 Fix incorrect error message in serialtube 2016-12-15 20:04:12 -06:00
Zach Riggle 5373dcdeed Fix dev-only regression in serialtube constructor, and use Timeout object properties 2016-12-15 20:04:12 -06:00
Zach Riggle 5d4bf3db6c Add MemLeak.u64/u32/... aliases 2016-12-15 17:15:10 -06:00
Zach Riggle fbfa54ad61 Fix failing doctestse on dev 2016-12-15 16:45:08 -06:00
Zach Riggle b323264032 Merge branch 'beta' into dev 2016-12-15 15:05:16 -06:00
Zach Riggle 332c9d2031 Merge remote-tracking branch 'upstream/stable' into beta-staging 2016-12-15 14:52:39 -06:00
Zach Riggle 036397c861 Fix adb.uninstall() typo (#816)
Closes Gallopsled/pwntools#783
2016-12-15 14:52:25 -06:00
Zach Riggle dcf03fd44d Bugfix for None data from field (#815) 2016-12-15 14:13:36 -06:00
Zach Riggle df54bf2bb3 Dont barf if home directory is not writable (#814)
* Handle the home directory being read-only / cache directory being unavailable

Fixes Gallopsled/pwntools#799

* Add doctest for context.cache_dir
2016-12-15 14:04:45 -06:00
Zach Riggle 386e68691f Multiple ADB performance and functionality fixes (#811)
* Fix ADB wait_for_device with ANDROID_SERIAL set, and fix performance

* Fix QEMU usage for native binaries

* Fix adb.write and adb.listdir operating on the wrong type of object

* Fix failing unit test with new behavior in adb.protocol.Client.list

* Fix adb server startup issue

* Rework deferred initialization to work around class-scope superclass attributes, and add test for AdbDevice
2016-12-14 17:34:18 -06:00
Zach Riggle 2c841eaa21 Add adb.{unlink,mkdir,makedirs,isdir,exists} (#809)
* Add adb.{unlink,mkdir,makedirs,isdir,exists}

* Change unlink() to throw an exception rather than return a string

* Fix doctest and code for isdir

* Remove unused variable
2016-12-14 16:49:41 -06:00
Zach Riggle 22f170abc7 Check the name before attempting to call startswith() (#805) 2016-12-14 16:47:38 -06:00
Zach Riggle 350610fbee Fix error message with StrictHostKeyChecking (#813) 2016-12-14 16:37:05 -06:00
Zach Riggle c7b3852eae Fix exception thrown under 32-bit Python interpreters. (#804)
Fixes Gallopsled/pwntools#518
2016-12-14 16:26:29 -06:00
Zach Riggle eaf6402198 Fix adb.partitions listing (#802)
* Fix adb.partitions listing

* Add adb.walk and adb.find functions to ensure adb.partitions works on devices without a find binary

* Add adb.readlink to simplify logic for reading symlinks
2016-12-14 15:37:47 -06:00
Zach Riggle d2c6184a00 Add missing changelog entry 2016-12-14 14:58:00 -06:00
Zach Riggle e5645e7b53 Update CHANGELOG missing links 2016-12-14 14:49:54 -06:00
Zach Riggle 09dbe0a54d Update CHANGELOG links 2016-12-14 14:49:27 -06:00
Zach Riggle 0bd0de78f9 Update CHANGELOG 2016-12-14 14:48:19 -06:00
Zach Riggle 546061e577 Modify coredump_filter of spawned processes so that library contents are included 2016-12-12 18:26:46 -06:00
Zach Riggle 5ebc8b5bb7 Check the name before attempting to call startswith() 2016-12-12 18:26:46 -06:00
Zach Riggle b83a6c7db8 Fix process.leak by providing a sane default leak size 2016-12-05 15:44:04 -05:00
Owlz 5d9792fb4c Variable Size Buffer Fill (#806)
Support custom buffer-read sizes for `tube` objects via their internal `Buffer` object.  Default buffer size is 4096.  Buffer size can be set per-object at instantiation-time (`tube(buffer_fill_size=...)`), by attribute (`tube.buffer_fill_size=...`), or in a context (`context.buffer_size=...`).
2016-12-05 15:21:08 -05:00
Zach Riggle 1c54e347f2 Add 'shell' option for ssh.process to pass to "sh -c" (#800)
Add 'shell' option for ssh.process to pass to "sh -c"
2016-11-29 11:52:44 -07:00
Ricky Zhou 2f597f41d4 Properly handle exceptions in remote._connect. (#793)
Previously, if getaddrinfo or socket.socket threw an exception,
_connect would return without ever calling h.success or h.failure. As a
result, progress indicators would continue to update indefinitely.

Fix this by using a with statement instead.

(Also remove an unused variable and fix a typo.)
2016-11-28 14:45:20 -07:00
Zach Riggle 7545dafffb Wrap context.log_console when using terminal I/O (#797)
Fixes Gallopsled/pwntools#792
2016-11-23 11:11:17 -07:00
Zach Riggle 3acec5421f Set shell=False 2016-11-12 23:16:32 -08:00
Mathias Svensson 620364dd1d Fixed a link in CHANGELOG.md 2016-11-12 21:10:05 +01:00
Mathias Svensson b441cf967a Start work on 3.4.0 2016-11-12 20:39:25 +01:00
Mathias Svensson 76c21548db Release 3.3.0beta0 2016-11-12 19:33:58 +01:00
Mathias Svensson ad71d9235b Release 3.2.0 2016-11-12 13:43:56 +01:00
Mathias Svensson 2e5f8061b2 Merge branch 'stable' into beta 2016-11-12 12:59:46 +01:00
Zach Riggle 099404277e Enhance documentation and error logging for ssh.process preexec_fn usage (#787)
Also fix other incorrect log usage

Fixes Gallopsled/pwntools#786
2016-11-12 12:58:24 +01:00
Zach Riggle 30c34b785a Fix ROP.call(Function(...)) breaking dump()
Fixes #770
2016-11-10 14:23:28 -08:00
Zach Riggle 6c304d3511 Add a bit more docs to the ADB module 2016-11-10 13:50:15 -08:00
Zach Riggle dc297e17ae Fix docstring commit [skip ci] 2016-11-07 18:52:12 -08:00
Zach Riggle fa402ceb57 Add adb.uptime and adb.boot_time 2016-11-07 17:53:52 -08:00
Zach Riggle 483adb8e2d Update ISSUE_TEMPLATE.md 2016-11-07 12:05:00 -08:00
Zach Riggle 76fe04e356 Fix log message error in adb.uninstall 2016-11-01 16:14:55 -07:00
Justin Steven 82312baba0 Add cyclic_metasploit() and cyclic_metasploit_find() (#785)
* Add cyclic_metasploit and cyclic_metasploit_find

* Stop using mutable default arguments
2016-10-26 17:19:19 -07:00
Zach Riggle d101a775aa Fix adb.uninstall() typo
Closes Gallopsled/pwntools#783
2016-10-26 10:25:34 -07:00
Mathias Svensson 5fda6580e8 Expose the BitPolynom (#755) 2016-10-23 22:38:50 +02:00
Mathias Svensson 9185437626 Merge branch 'beta' into dev 2016-10-23 11:35:03 +02:00
Mathias Svensson bde40c36ae Merge branch 'stable' into beta 2016-10-23 11:12:35 +02:00
Mathias Svensson 894b17e74a Release 3.1.1 2016-10-23 11:11:39 +02:00
Mathias Svensson 33b734cbc6 Added a doctest for MemLeak.struct 2016-10-23 11:11:32 +02:00
Morten Brøns-Pedersen 3e8454412e Bugfix in MemLeak.struct. (#768)
The function didn't work due to `sizeof` not being defined.  This PR imports
`ctypes` and uses `ctypes.sizeof`.
2016-10-23 10:53:04 +02:00
Zach Riggle 420f99c5d0 Automatic update checking should not log to stdout. (#774)
This breaks piping into files for all of the command-line utilities.
2016-10-20 15:41:00 -07:00
Zach Riggle 98052e4166 Add an error to cyclic() if the requested length is too long (#782)
$ cyclic 999999999
[ERROR] Can't create a pattern length=999999999 with len(alphabet)==26 and n==4

Fixes Gallopsled/pwntools#781
2016-10-19 09:18:41 -07:00
Mathias Svensson e971856c74 Merge branch 'beta' into dev 2016-10-18 23:09:45 +02:00
Mathias Svensson 09ee73c31d Merge branch 'stable' into beta 2016-10-18 22:58:20 +02:00
Zach Riggle 0c4d1365e9 Fix documentation generation since autoprogram broke Python2 2016-10-18 22:57:32 +02:00
Mathias Svensson b3f941c3f5 Merge branch 'beta' into dev 2016-10-18 22:42:29 +02:00
Justin Steven 67e11a9aeb Fix typos in cyclic.py's docstrings (#775) 2016-10-18 13:26:42 -07:00
Mathias Svensson 7d5f8ca4b4 Release 3.2.0beta4 2016-10-18 22:22:19 +02:00
Zach Riggle 7695acc798 Fix bash completion regression (#772)
Fixes Gallopsled/pwntools#767
2016-10-18 22:17:31 +02:00
Zach Riggle 3f48a0b803 Remove all Github update checks (#761)
These were nice-to-have, but as long as PyPi is updated and functioning
properly, we don't need to check Github.

Fixes Gallopsled/pwntools#756
2016-10-18 21:58:03 +02:00
Zach Riggle fd731154ff Make process.argv optional, using context.binary 2016-10-15 14:29:13 -07:00
Isaac 906bc94a5f fix typo in TESTING.md (#769) 2016-10-15 13:31:42 +02:00
bstub db03e7de10 Adding escaped hex output format to shellcraft -f option (#765)
* adding output format for python hex-notation

* cleaned up implementation

* changed format identifier to {a} --escaped

* {a] was taken by asm, changed format identifier to {d} --escaped

* adding {e}lf to help
2016-10-14 13:13:02 -07:00
Morten Brøns-Pedersen 97e03fd29f Bugfix in MemLeak.struct. (#768)
The function didn't work due to `sizeof` not being defined.  This PR imports
`ctypes` and uses `ctypes.sizeof`.
2016-10-14 13:11:18 -07:00
Zach Riggle 09b8bb93a7 Fix regressions introduced by f9133b1680 2016-10-14 13:10:13 -07:00
Zach Riggle f9133b1680 Add STDERR argument, and write docs for args module (#760)
Add STDERR argument, and write docs for args module

Fixes Gallopsled/pwntools#759
2016-10-10 19:13:45 -07:00
Mathias Svensson 8aa21bd99a Merge branch 'beta' into dev 2016-10-11 03:06:21 +02:00
Mathias Svensson e5b6aedd3d Release 3.2.0beta3 2016-10-11 03:00:18 +02:00
Zach Riggle 4b405c69b6 Fix incorrect usage of argv in unhex 2016-10-11 02:59:52 +02:00
Zach Riggle 9af20c778f Fix incorrect usage of argv in unhex 2016-10-10 17:55:13 -07:00
Mathias Svensson d1621dca87 Merge branch 'beta' into dev 2016-10-10 15:50:53 +02:00
Mathias Svensson 31b047d29b Release 3.2.0beta2 because pypi is being retarded 2016-10-10 15:48:52 +02:00
Mathias Svensson 39970c3847 Merge branch 'beta' into dev 2016-10-10 14:59:41 +02:00
Mathias Svensson e0c65c9d6d Release 3.2.0beta1 2016-10-10 14:58:51 +02:00
Zach Riggle 59d0cd2eeb Fix wait-for-device with kick=True re-using the same client (#757) 2016-10-10 14:58:00 +02:00
Zach Riggle 8d11fb8594 Fix wait-for-device with kick=True re-using the same client (#757) 2016-10-09 20:00:00 -07:00
Zach Riggle aec3fa6879 Remove all Github update checks (#761)
These were nice-to-have, but as long as PyPi is updated and functioning
properly, we don't need to check Github.

Fixes Gallopsled/pwntools#756
2016-10-07 15:30:38 -07:00
Zach Riggle ab6602407e Move issue/pr templates to .github 2016-10-07 15:18:58 -07:00
Zach Riggle 42ab0c985d Sort inputs with isort 2016-10-05 15:51:05 -07:00
Zach Riggle b215828133 Make tube.stream() more robust 2016-10-05 15:49:41 -07:00
Zach Riggle e3af4ce6a7 Update changelog 2016-10-05 15:44:13 -07:00
Zach Riggle 96c6edcc37 Update changelog 2016-10-05 15:44:03 -07:00
Zach Riggle b198ec8633 Add tube.stream() 2016-10-05 15:43:04 -07:00
Mathias Svensson c8a87381e8 Merge branch 'beta' into dev 2016-10-02 20:38:08 +02:00
Mathias Svensson 548e033e7e Release 3.2.0beta0 by merging branch 'stable' into beta 2016-10-02 20:32:09 +02:00
Mathias Svensson fc097f3446 Fixed a link in the CHANGELOG 2016-10-02 20:27:51 +02:00
Mathias Svensson eb92a95134 Release 3.1.0 2016-10-02 20:12:51 +02:00
Zach Riggle c706461f10 Add branch table 2016-10-02 20:07:12 +02:00
Zach Riggle b0ad5eb915 Add branch table 2016-09-28 13:31:56 -07:00
Zach Riggle 94f88cc8ba Update changelog 2016-09-28 13:13:53 -07:00
Zach Riggle 1e414afbeb Add connect() alias for remote(), add docs for tcp() and udp() aliases 2016-09-28 13:05:54 -07:00
Zach Riggle 869ec42082 Add ssh.read and ssh.write aliases 2016-09-28 13:04:28 -07:00
Zach Riggle 4893819b4c Add adb.install, adb.uninstall, and adb.packages 2016-09-28 12:42:22 -07:00
Zach Riggle fb1b952769 Do not wrap non-functions 2016-09-27 19:31:50 -07:00
Zach Riggle 859380285f Handle missing properties for AdbDevice 2016-09-27 19:08:41 -07:00
Zach Riggle 2af55c9bc3 Allow device-scoped access to ADB facilities off of AdbDevice 2016-09-27 19:04:24 -07:00
Zach Riggle 4725b1be96 adb.adb(["shell", ...]) should go through adb.process() 2016-09-27 13:55:35 -07:00
Zach Riggle 5af5f0c55d Fix adb.push statement ordering 2016-09-26 18:10:18 -07:00
Zach Riggle e84f395c97 Wait for the currently-selected device in wait_for_device 2016-09-26 18:03:27 -07:00
Zach Riggle fbf51ad96e Fix target adb.push() 2016-09-26 17:56:28 -07:00
Zach Riggle 52433339ec adb.protocol.Connection should always pack as 32-bit 2016-09-26 17:43:26 -07:00
Zach Riggle f277d5502f Allow adb.push to specify a full target filename in an existing directory 2016-09-26 16:53:31 -07:00
Zach Riggle 794122ec13 Add kwargs to handle weird "adb devices" output 2016-09-26 16:49:34 -07:00
Zach Riggle 65b266e9b3 Revert part of 8793dec, fix commands, remove shippable.yml 2016-09-26 16:49:34 -07:00
Zach Riggle ca6eddc235 shellcraft.xxx.linux.sh now passes argv0 (#734)
shellcraft.xxx.linux.sh now passes argv0

If you need shorter shellcode, use "execve" directly.

Fixes Gallopsled/pwntools#626
2016-09-25 18:31:29 -07:00
Zach Riggle 8793decd1c Remove additional references to "--pre" and use "python setup.py develop" instead of "-e" magic
Related to Gallopsled/pwntools#735
2016-09-19 17:18:57 -07:00
Mathias Svensson 628aaabd04 Bump the version number in the pip badge 2016-09-19 23:24:01 +02:00
Mathias Svensson 3544167f26 Merge branch 'beta' into dev 2016-09-19 23:16:04 +02:00
Mathias Svensson 9cca9c989b Merge branch 'stable' into beta 2016-09-19 23:07:53 +02:00
Mathias Svensson f42c291fef Release 3.0.4 2016-09-19 22:57:54 +02:00
Zach Riggle dacdd397ab Merge remote-tracking branch 'upstream/stable' into beta 2016-09-19 13:10:34 -07:00
Zach Riggle c0f02d453a Merge pull request #752 from zachriggle/fix-setup
Add all MD and TXT files to binary distribution; include correct file…
2016-09-19 21:52:55 +02:00
Felix Yan 627ed5cbd5 Fix a typo: termianl -> terminal (#750) 2016-09-19 10:28:18 -07:00
Mathias Svensson 3fb64f9fe0 Merge branch 'beta' into dev 2016-09-19 00:31:31 +02:00
Mathias Svensson 254958bae9 Merge branch 'stable' into beta 2016-09-19 00:28:50 +02:00
Mathias Svensson 1cb47220f1 Fixed this binutils-multiarch path 2016-09-19 00:27:56 +02:00
Mathias Svensson d9be4f9ce0 Made the wget timeout longer 2016-09-19 00:18:37 +02:00
Mathias Svensson 2cd5aadf9d Merge branch 'beta' into dev 2016-09-18 22:58:32 +02:00
Mathias Svensson 6ebcc6f3a2 Merge branch 'stable' into beta 2016-09-18 22:31:34 +02:00
Mathias Svensson 21ce572dd6 Make CHANGELOG.md closer follow dev for easier forwardporting in the future 2016-09-18 22:30:23 +02:00
Mathias Svensson 1c47a30446 Bump the version number in README.md 2016-09-18 22:26:44 +02:00
Mathias Svensson 5b8ccb60a6 Merge branch 'beta' into dev 2016-09-18 22:14:53 +02:00
Mathias Svensson 89fc74facf Merge branch 'stable' into beta 2016-09-18 21:35:21 +02:00
Mathias Svensson 5a79a5e609 Release 3.0.3 2016-09-18 21:21:42 +02:00
Mathias Svensson c92f9bed42 I was being stupid when I did #744, since @zachriggle was not done. This is (hopefully) a more proper fix. 2016-09-18 21:09:29 +02:00
Mathias Svensson bfb534378b Removed verbosity from travis files 2016-09-18 19:35:28 +02:00
Mathias Svensson 0ddcf8b129 Add a test that we will *not* update when we have a never local version 2016-09-18 19:35:06 +02:00
Mathias Svensson a66376b8a0 Merge branch 'faster-update-import' of https://github.com/zachriggle/pwntools into merge-738 2016-09-18 15:23:25 +02:00
Mathias Svensson 9cb53d90fe Merge branch 'corefile-pyelftools' of https://github.com/binjitsu/binjitsu into release-3.0.3 2016-09-18 15:00:37 +02:00
Mathias Svensson a31cec5e81 Removed aarch64 install as it is broken and not currently needed and stopped bailing out even if .ssh exists 2016-09-18 14:50:52 +02:00
Zach Riggle 5367a3528d Promote binutils installation 2016-09-18 14:49:59 +02:00
Zach Riggle 669e7295c6 Auto-detect the current URL for QEMU rather than relying on a hard-coded URL 2016-09-18 14:49:03 +02:00
Zach Riggle a7f32d1b0f Bail on any error 2016-09-18 14:48:05 +02:00
Mathias Svensson efc531a2a9 Merge pull request #744 from Idolf/fix-tests
Fix Travis CI (building upon #743)
2016-09-18 14:45:53 +02:00
Mathias Svensson 8b959c9ede Removed aarch64 install as it is broken and not currently needed and stopped bailing out even if .ssh exists 2016-09-18 14:39:43 +02:00
Zach Riggle 68051f9987 Promote binutils installation 2016-09-17 20:50:20 -07:00
Zach Riggle 3636657ca0 Auto-detect the current URL for QEMU rather than relying on a hard-coded URL 2016-09-17 20:40:26 -07:00
Zach Riggle f282ef8bbc Bail on any error 2016-09-17 20:09:17 -07:00
Zach Riggle d5fbb21f72 Switch from pkg_resources to packaging, for performance reasons
Also backports the PyPi documentation changes to stable.

Fixes #736
2016-09-17 18:13:57 -07:00
Zach Riggle 57e9bf58a5 Update changelog 2016-09-17 18:06:30 -07:00
Zach Riggle 0ce21d9b45 Add pandoc requirement for Travis 2016-09-14 19:00:36 -07:00
Zach Riggle 89649fbeb0 Use HTTPS for link 2016-09-14 15:28:14 -07:00
Zach Riggle 5924c0f340 Use new domain for update_demo 2016-09-14 14:57:05 -07:00
Zach Riggle 2f9f10c182 Remove SSH info 2016-09-14 14:27:34 -07:00
Zach Riggle d7c98c4819 Remove reference to --pre until Gallopsled/pwntools#735 has a solution 2016-09-14 14:10:22 -07:00
Zach Riggle cd0ba369b8 Fix bug introduced by internal changes to pyelftools v0.2.4 2016-09-14 12:23:47 -07:00
Zach Riggle bebc84522d Make update mechanism more robust, add tests (#729)
* Make update mechanism more robust, add tests
* Add pwnlib.update to documentation, enable doctests

Fixes Gallopsled/pwntools#723
Fixes Gallopsled/pwntools#724
2016-09-12 21:09:52 -07:00
Zach Riggle e7875c78bc Add pwnlib.flag and submit_flag (#732)
* Add pwnlib.flag and submit_flag
2016-09-12 21:03:16 -07:00
Zach Riggle 0a37694436 Sort imports with isort 2016-09-12 20:35:36 -07:00
Zach Riggle 742a11bfdc Add links to CONTRIBUTING and TESTING in templates 2016-09-10 17:33:22 -07:00
Zach Riggle 1e7262ce31 Add templates for Pull Requests and Issues (#733)
Fixes #651
2016-09-10 17:27:02 -07:00
Zach Riggle d733cf6560 Fix failing doctest because of httpbin slowness (#731) 2016-09-09 17:46:34 -07:00
Zach Riggle 3818dda9d9 Extract copy-pasted callback routine, add better errors and doctests … (#728)
* Extract copy-pasted callback routine, add better errors and doctests for adb.{push,pull}
* Add protocol submodule to documentation and doctests
* Add and fix doctests in adb.protocol
* Use pprint to sort dicts
2016-09-09 15:29:38 -07:00
Zach Riggle 18c4a49aa3 Add pprint to toplevel 2016-09-08 14:34:47 -07:00
Zach Riggle 77f7a362d0 Version bump 2016-09-08 10:56:38 -07:00
Zach Riggle 738fadc016 Add .os to Device and set it automatically (#727)
The use case here is setting context.os via:

>>> context.device = adb.wait_for_device()
2016-09-07 16:34:10 -07:00
Zach Riggle b97f30f36f Add better description to PyPI, more classifiers (#721) 2016-09-07 16:34:00 -07:00
Mathias Svensson de05e7a4b8 Merge branch 'beta' into dev 2016-09-06 11:46:45 -10:00
Mathias Svensson 5fe024838b Release 3.1.0beta1 2016-09-06 11:36:27 -10:00
Mathias Svensson cd828d6bca Merge branch 'beta' into dev 2016-09-06 11:31:21 -10:00
Mathias Svensson b60103b839 Merge branch 'stable' into beta 2016-09-06 11:30:58 -10:00
Mathias Svensson 5acc4c8ec3 Merge branch 'beta' into dev 2016-09-06 10:07:53 -10:00
Mathias Svensson a5c2b9276a Merge branch 'stable' into beta 2016-09-06 10:07:33 -10:00
Zach Riggle 913a3eba9e Pwn update (#720)
* Fix help printing e.g. "shellcraft shellcraft" instead of "pwn shellcraft" when invoking legacy entry points [skip ci]

* Add "pwn update" command; prevent automatic updates from showing pre-release
2016-09-02 16:58:47 -07:00
Zach Riggle 041e62bf0b Update changelog [skip ci] 2016-09-02 15:20:14 -07:00
Zach Riggle e61f571f7c Add adb.protocol module, and use it for most things (#709) 2016-09-02 15:16:26 -07:00
Zach Riggle 36d00b615d Update changelog [skip ci] 2016-09-02 15:10:10 -07:00
Zach Riggle 25d340b5c5 Re-implement sh_string to use embedded literals, add lots of tests (#717)
* Re-implement sh_string to use embedded literals, add lots of tests
* Add docs for sh_string so that unit tests get picked up
* Mark the docstrings as raw
* Rewrite doctests to not "print" since this breaks with invisible characters (issue with doctest itself)
* Add test which uses 16KB of random non-NUL data
2016-09-02 14:56:05 -07:00
Zach Riggle 8f06c1f90f Add docs for Xenial binutils, and attempt to auto-detect Debian packages (#718)
An error message will be printed like this when a package is found:

>>> context.arch='powerpc'
>>> pwnlib.asm.print_binutils_instructions('objdump', context)
[ERROR] Could not find 'objdump' installed for ContextType(arch = 'powerpc', bits = 32, endian = 'big')
    Try installing binutils for this architecture:
    $ sudo apt-get install binutils-powerpc-linux-gnu
2016-09-02 14:21:40 -07:00
Zach Riggle ae6a0745ff Fix function-decorator use-case for context.quiet (#714) 2016-09-01 16:23:32 -07:00
Zach Riggle 1d924af9d2 Update changelog [skip ci] 2016-09-01 15:36:47 -07:00
Zach Riggle fed432877c Merge pull request #711 from binjitsu/brk
Add heap leak from the linker. Fixes Gallopsled/pwntools#435
2016-09-01 15:35:19 -07:00
Zach Riggle 46261091dd Update date formatting 2016-09-01 15:17:59 -07:00
Zach Riggle c356b69a13 Add notices 2016-09-01 15:16:24 -07:00
Zach Riggle 6cff484b8c Update changelog [skip ci] 2016-09-01 15:15:30 -07:00
Zach Riggle 8314dff386 Update changelog [skip ci] 2016-09-01 15:14:24 -07:00
Zach Riggle dc40ac1117 Add heap leak from the linker. Fixes Gallopsled/pwntools#435
(cherry picked from commit 5808882cfe)
2016-09-01 14:57:00 -07:00
Zach Riggle 288b9668b7 Add Android emulator to Travis (#705)
* Add Android emulator to Travis

* More robust handling of ADB device status, and lack of devices

* Add platform-tools to PATH for adb, fastboot, etc.

* Add basic tests for some ADB code

* Add with_device annotation to auto-detect a device

* Skip Android emulator installation if we dont need it

* Do not install emulator in all cases (e.g. OSX)
2016-08-30 17:44:14 -07:00
Zach Riggle 3c0697b81e Refactor command-line tools to use a single "pwn" entry point. (#701)
Adds an install-time option to disable legacy commands, and only use 'pwn':

  $ pip install --install-option='--only-use-pwn-command'

Documentation is updated to show 'pwn' entry point and sub-commands.

Fixes #404
Fixes #660
2016-08-30 17:37:28 -07:00
Zach Riggle 6e4e46386f Do not install emulator in all cases (e.g. OSX) 2016-08-30 17:30:29 -07:00
Zach Riggle 9b179567da Remove un-cacheable Android SDK and NDK directories from Travis cache 2016-08-30 17:28:30 -07:00
Zach Riggle b20e17dd13 Skip Android emulator installation if we dont need it 2016-08-30 17:27:33 -07:00
Zach Riggle 3dcfafc0de Fix unit test quote style and ELLIPSE formatting 2016-08-30 16:32:05 -07:00
Zach Riggle 348bcac0ff Fix unit test failures in ADB module 2016-08-30 14:40:32 -07:00
Zach Riggle a43c3b4967 Add with_device annotation to auto-detect a device 2016-08-29 14:43:04 -07:00
Zach Riggle 40bf991153 Add basic tests for some ADB code 2016-08-29 14:43:04 -07:00
Zach Riggle 8f98c01b77 More robust handling of ADB device status, and lack of devices 2016-08-29 14:43:04 -07:00
Zach Riggle 18a8cfb88d Disable verbose logging 2016-08-29 14:43:04 -07:00
Zach Riggle 2acdeef320 Add missing bracket 2016-08-29 14:43:04 -07:00
Zach Riggle 23c09b4b1b Add platform-tools to PATH for adb, fastboot, etc. 2016-08-29 14:43:04 -07:00
Zach Riggle 84c71d6b07 Squelch travis 4MB log error 2016-08-29 14:43:04 -07:00
Zach Riggle c6aa6bccb8 Add Android emulator to Travis 2016-08-29 14:43:04 -07:00
Zach Riggle 041c665185 Reorganize Travis stuff; add hook to re-generate demo.pwntools.com on pushes to stable (#708) 2016-08-29 14:24:51 -07:00
Zach Riggle 70f9c0305d Add alarm option for process() (#704)
* Add `alarm` option for process()

* Add signal to toplevel import
2016-08-29 14:20:37 -07:00
Zach Riggle 66e41bd862 Refactor command-line tools to use a single "pwn" entry point.
Adds an install-time option to disable legacy commands, and only use 'pwn':

  $ pip install --install-option='--only-use-pwn-command'

Documentation is updated to show 'pwn' entry point and sub-commands.

Fixes #404
Fixes #660
2016-08-28 11:46:09 -07:00
Zach Riggle 5140d03b4d Add MIPS documentation, which should also trigger doctests (#700)
* Add MIPS documentation, which should also trigger doctests
* Fix broken and missing doctests for MIPS pushstr / syscall
* Add optimization for mips.mov to fix doctest
* Exit cleanly so QEMU doesn't complain
2016-08-28 11:40:42 -07:00
Mathias Svensson b016179ccc Merge branch 'beta' into dev 2016-08-24 20:04:59 -07:00
Mathias Svensson efaea581a1 Merge branch 'stable' into beta 2016-08-24 20:04:06 -07:00
Zach Riggle f4a72da40e Update MIPS execve to use pushstr_array 2016-08-24 14:59:50 -07:00
Zach Riggle 6376d07266 Add MIPS pushstr_array
Example resulting state:

$ shellcraft mips.pushstr_array '$t1' '["hello", "world", "boss!"]' -d --after
...
pwndbg> telescope $t1 4
00:0000| t1 sp  0x76ffec7c --> 0x76ffec8c <-- 'hello'
01:0004|        0x76ffec80 --> 0x76ffec92 <-- 'world'
02:0008|        0x76ffec84 --> 0x76ffec98 <-- 'boss!'
03:000c|        0x76ffec88 <-- 0x0
2016-08-24 17:57:24 -04:00
Zach Riggle ea94ee4ca5 Disallow usage of semicolons in run_in_new_terminal.
Fixes Gallopsled/pwntools#690
Fixes Gallopsled/pwntools#635
2016-08-24 14:36:43 -07:00
Zach Riggle 452605e854 Fix pwnlib.gdb temporary file removal.
In two instances, the file was not removed because of an incorrect lambda.

In two further instances, use of shell concatenation via run_in_new_terminal
were changed into GDB 'shell' commands.

This fixes Gallopsled/pwntools#629
2016-08-24 14:36:43 -07:00
Mathias Svensson dea8f00c01 Merge pull request #698 from Idolf/dev
Merged beta into dev and fixed the version number and changelog
2016-08-24 14:35:11 -07:00
Mathias Svensson b9d6b27b4e Merge branch 'beta' into dev 2016-08-24 14:24:21 -07:00
Mathias Svensson 300ef0b462 Merge branch 'Idolf-beta-changelog' into beta 2016-08-24 14:20:02 -07:00
Mathias Svensson 6e79272e8d Updated the changelog 2016-08-24 14:17:46 -07:00
Morten Brøns-Pedersen d65991d402 Changed util.fiddling.hexdump_iter to take a file object instead of a string. This massively speeds up phd <file> | less for huge files. (#695) 2016-08-24 14:15:29 -07:00
Zach Riggle de94449a87 Remove unreleased version from Changelog 2016-08-22 17:34:44 -07:00
Zach Riggle faeb57b35c Use manual 3.0.1 shield until we figure out how to make this automagic 2016-08-22 16:42:45 -07:00
Mathias Svensson e1332d277c Merge branch 'beta' into dev (#678) 2016-08-22 15:26:40 -07:00
Mathias Svensson e4c2a48696 Merge pull request #679 from Gallopsled/stable
Even more documentation (#678)
2016-08-22 15:22:39 -07:00
Mathias Svensson fcf2842d87 I am an idiot 2016-08-22 14:58:42 -07:00
Mathias Svensson 422dccd8da Merge branch 'beta' into dev 2016-08-22 14:54:33 -07:00
Mathias Svensson abd08a94ea Fixed the logo path to be closer to stable 2016-08-22 14:48:26 -07:00
Mathias Svensson e877f7455a Merge branch 'stable' into beta 2016-08-22 14:37:33 -07:00
Mathias Svensson e635bcfea7 Merging #674 into dev 2016-08-20 18:40:54 -07:00
Mathias Svensson 12b60447da Merging #674 into beta 2016-08-20 18:39:00 -07:00
Mathias Svensson 77da84c5a8 Prepare the dev branch 2016-08-20 17:51:55 -07:00
Mathias Svensson 2663762a9a Prepare the beta branch 2016-08-20 17:48:37 -07:00
3661 changed files with 52002 additions and 26169 deletions

No files matched your search

+9
View File
@@ -0,0 +1,9 @@
# Pwntools Issue Template
Thanks for contributing to Pwntools!
When reporting an issue, be sure that you are running the latest released version of pwntools (`pip install --upgrade pwntools`).
Please verify that your issue occurs on 64-bit Ubuntu 14.04. You can use the Dockerfile in `extra/docker/Dockerfile` to save time.
If possible, provide a proof-of-concept which demonstrates the problem. Include any binaries or scripts necessary to reproduce the issue, and please include the full debug output via setting the environment variable `PWNLIB_DEBUG=1`.
+27
View File
@@ -0,0 +1,27 @@
# Pwntools Pull Request
Thanks for contributing to Pwntools! Take a moment to look at [`CONTRIBUTING.md`][contributing] to make sure you're familiar with Pwntools development.
Please provide a high-level explanation of what this pull request is for.
## Testing
Pull Requests that introduce new code should try to add doctests for that code. See [`TESTING.md`][testing] for more information.
## Target Branch
Depending on what the PR is for, it needs to target a different branch.
You can always [change the branch][change] after you create the PR if it's against the wrong branch.
| Branch | Type of PR |
| -------- | ---------------------------------------------------------------- |
| `dev` | New features, and enhancements
| `dev` | Documentation fixes and new tests
| `stable` | Bug fixes that affect the current `stable` branch
| `beta` | Bug fixes that affect the current `beta` branch, but not `stable`
| `dev` | Bug fixes for code that has never been released
[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
+1
View File
@@ -14,3 +14,4 @@ dist
*.egg-info
*.core
.coverage
.tox
+20 -6
View File
@@ -5,6 +5,15 @@ addons:
packages:
- gcc-multilib
- gcc-4.6-arm-linux-gnueabihf
- lib32stdc++6
- ash
- bash
- dash
- ksh
- mksh
- zsh
- pandoc
- gdb
cache:
- pip
- directories:
@@ -13,14 +22,16 @@ cache:
- /home/travis/virtualenv/python2.7.9/bin/
python:
- "2.7"
after_success:
- coveralls
before_install:
- source .travis_install.sh
- source .travis_ssh_setup.sh
- echo $-
- source travis/install.sh
- source travis/ssh_setup.sh
- echo $-
install:
- pip install -e .
- pip install -r docs/requirements.txt
- 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'
@@ -28,3 +39,6 @@ before_script:
- 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
-88
View File
@@ -1,88 +0,0 @@
#!/usr/bin/env bash -e
local_deb_extract()
{
wget $1
ar vx *.deb
tar xvf data.tar.*
rm -f *.tar.* *deb*
}
get_binutils()
{
BINUTILS_PREFIX='https://launchpad.net/~pwntools/+archive/ubuntu/binutils/+files/binutils-'
BINUTILS_SUFFIX='-linux-gnu_2.22-6ubuntu1.1cross0.11pwntools12~precise_amd64.deb'
local_deb_extract "${BINUTILS_PREFIX}${1}${BINUTILS_SUFFIX}"
}
get_qemu()
{
echo "Installing qemu"
QEMU_URL='https://mirrors.kernel.org/ubuntu/pool/universe/q/qemu/qemu-user-static_2.6%2bdfsg-3ubuntu1_amd64.deb'
local_deb_extract "$QEMU_URL"
}
setup_travis()
{
export PATH=$PWD/usr/bin:$PATH
export LD_LIBRARY_PATH=$PWD/usr/lib
if [ ! -d usr/bin ];
then
# Install our custom binutils
which arm-linux-as || get_binutils arm
which mips-linux-as || get_binutils mips
which powerpc-linux-as || get_binutils powerpc
which aarch64-linux-as || get_binutils aarch64
# Install the multiarch binutils
local_deb_extract http://mirrors.mit.edu/ubuntu/ubuntu/pool/universe/b/binutils/binutils-multiarch_2.22-6ubuntu1_amd64.deb
fi
if ! (which qemu-arm-static && qemu-arm-static -version | grep 2.6.0); then
get_qemu
fi
# Get rid of files we don't want cached
rm -rf usr/share
pushd usr/lib
ln -sf libbfd-2.22-multiarch.so libbfd-2.22.so
ln -sf libopcodes-2.22-multiarch.so libopcodes-2.22.so
popd
which arm-linux-gnu-as
which mips-linux-gnu-as
which powerpc-linux-gnu-as
which aarch64-linux-gnu-as
which qemu-arm-static
}
setup_linux()
{
sudo apt-get install -y software-properties-common openssh-server libncurses5-dev libncursesw5-dev
sudo apt-add-repository --yes ppa:pwntools/binutils
sudo apt-get update
sudo apt-get install binutils-arm-linux-gnu binutils-mips-linux-gnu binutils-powerpc-linux-gnu
}
setup_osx()
{
brew update
brew install binutils
brew install capstone
}
if [[ "$USER" == "travis" ]]; then
setup_travis
elif [[ "$USER" == "shippable" ]]; then
sudo apt-get update
sudo apt-get install openssh-server gcc-multilib
sudo /usr/sbin/sshd -f /etc/ssh/sshd_config &
setup_travis
elif [[ "$(uname)" == "Darwin" ]]; then
setup_osx
elif [[ "$(uname)" == "Linux" ]]; then
setup_linux
fi
dpkg -l
-54
View File
@@ -1,54 +0,0 @@
#!/usr/bin/env bash
#
# Install a demo user for SSH purposes
#
# All of the "conditional sudo" is to do container-based builds on
# Travis which are much, much faster.
U=travis
H=/home/$U
USUDO()
{
if [[ "$USER" == "travis" ]];
then
$*
else
sudo -u $U $*
fi
}
if [[ "$USER" == "travis" ]];
then
rm -f ~/.ssh/*
else
# Create the new user account
# Disable password login for the user, and ensure the account is not locked
sudo useradd -m $U
sudo passwd --delete --unlock $U
fi
# Generate a new key so that we can log into it
ssh-keygen -t rsa -f ~/.ssh/$U -N ''
# Load the public key into a memory for below
pubkey=$(cat ~/.ssh/$U.pub)
# Set the authorized_keys entry to only permit login from localhost,
# and only with
USUDO mkdir $H/.ssh
USUDO tee -a $H/.ssh/authorized_keys <<EOF
from="127.0.0.1" $pubkey
EOF
# In the pwntools examples, we ssh to 'example.pwnme'
# Set up an SSH config entry to make this actually work
cat >> ~/.ssh/config <<EOF
Host example.pwnme
User $U
HostName 127.0.0.1
IdentityFile ~/.ssh/$U
EOF
ssh -o "StrictHostKeyChecking no" -vvvv [email protected] id
+360 -6
View File
@@ -3,17 +3,371 @@
This changelog only includes added major features and changes. Bugfixes and
minor changes are omitted.
## 3.0.2 (September 6 2016)
## Release History
The table below shows which release corresponds to each branch, and what date the version was released.
| Version | Branch | Release Date |
| ---------------- | -------- | ---------------------- |
| [3.8.0](#380) | `dev` | Jul 28, 2017 (planned)
| [3.7.0](#370) | `beta` | Jun 17, 2017 (planned)
| [3.6.1](#361) | `stable` | May 12, 2017
| [3.6.0](#360) | | May 8, 2017
| [3.5.1](#351) | | Apr 15, 2017
| [3.5.0](#350) | | Mar 26, 2017
| [3.4.1](#341) | | Feb 17, 2017
| [3.4.0](#340) | | Feb 13, 2017
| [3.3.4](#334) | | Jan 12, 2016
| [3.3.3](#333) | | Jan 10, 2016
| [3.3.2](#332) | | Jan 10, 2016
| [3.3.1](#331) | | Jan 10, 2016
| [3.3.0](#330) | | Dec 24, 2016
| [3.2.1](#321) | | Dec 24, 2016
| [3.2.0](#320) | | Nov 12, 2016
| [3.1.1](#311) | | Oct 23, 2016
| [3.1.0](#310) | | Oct 2, 2016
| [3.0.4](#304) | | Sept 19, 2016
| [3.0.3](#303) | | Sept 18, 2016
| [3.0.2](#302) | | Sept 6, 2016
| [3.0.1](#301) | | Aug 20, 2016
| [3.0.0](#300) | | Aug 20, 2016
| [2.2.0](#220) | | Jan 5, 2015
## 3.8.0
To be on Jul 28, 2017.
## 3.7.0
To be on Jun 17, 2017.
As of May 4, 2017, there have been no new features or major notable changes since 3.6.0.
A few typos were fixed, a few Linux kernel configuration flags were added, and a few error messages were enhanced.
## 3.6.1
- [#979][979]+[1a4a1e1][1a4a1e1] Fixed [#974][974], a bug related to the terminal handling and numlock.
- [#980][980] Fixed the `pwn template` command.
[974]: https://github.com/Gallopsled/pwntools/issues/974
[979]: https://github.com/Gallopsled/pwntools/pull/979
[980]: https://github.com/Gallopsled/pwntools/pull/980
[1a4a1e1]: https://github.com/Gallopsled/pwntools/commit/1a4a1e1
## 3.6.0
- [#895][895] Added a Dockerfile to simplify testing setup and allow testing on OSX
- [#897][897] Fixed some incorrect AArch64 syscals
- [#893][893] Added the `pwnlib.config` module
+ Configuration options can now be set in `~/.pwn.conf`
+ This replaces the old, **undocumented** mechanism for changing logging colors. Only @br0ns and @ebeip90 were likely using this.
+ More information is available in the documentation [here](http://docs.pwntools.com/en/dev/config.html).
- [#899][899] Pwntools now uses Unicorn Engine to emulate PLT instructions to ensure correct mapping of PIE / RELRO binaries.
- [#904][904] Enhancements to the accuracy of the `pwn checksec` command.
- [#905][905] Added a `pwn debug` command-line utility which automates the process of `gdb.attach(process(...))` to spawn GDB
+ More information is available in the documentation [here](http://docs.pwntools.com/en/dev/commandline.html#pwn-debug)
- [#919][919] Added a `pwn template` command-line utility to simplify the process of bootstrapping a new exploit.
+ More information is available in the documentation [here](http://docs.pwntools.com/en/dev/commandline.html#pwn-template).
- [#948][948] Fix unnecessary warning for Core files
- [#954][954] Fix list processing in `~/.pwn.conf`
- [#967][967] Respect `TERM_PROGRAM` for `run_in_new_terminal`
- [#970][970] Fix overly-aggressive corefile caching
[947]: https://github.com/Gallopsled/pwntools/pull/947
[948]: https://github.com/Gallopsled/pwntools/pull/948
[954]: https://github.com/Gallopsled/pwntools/pull/954
[960]: https://github.com/Gallopsled/pwntools/pull/960
[967]: https://github.com/Gallopsled/pwntools/pull/967
[968]: https://github.com/Gallopsled/pwntools/pull/968
[970]: https://github.com/Gallopsled/pwntools/pull/970
[895]: https://github.com/Gallopsled/pwntools/pull/895
[897]: https://github.com/Gallopsled/pwntools/pull/897
[893]: https://github.com/Gallopsled/pwntools/pull/893
[899]: https://github.com/Gallopsled/pwntools/pull/899
[904]: https://github.com/Gallopsled/pwntools/pull/904
[905]: https://github.com/Gallopsled/pwntools/pull/905
[919]: https://github.com/Gallopsled/pwntools/pull/919
## 3.5.1
- [#945][945] Speed up ssh via caching checksec results (fixes [#944][944])
- [#950][950] Fixes a bug where setting `context.arch` does not have an effect on `adb.compile()` output architecture
[944]: https://github.com/Gallopsled/pwntools/issues/944
[945]: https://github.com/Gallopsled/pwntools/pull/945
[950]: https://github.com/Gallopsled/pwntools/pull/950
## 3.5.0
- [b584ca3][b584ca3] Fixed an issue running `setup.py` on ARM
- [#822][822] Enabled relative leaks with `MemLeak`
+ This should be useful for e.g. heap-relative leaks
- [#832][832] Changed all internal imports to use absolute imports (no functional changes)
- [a12d0b6][a12d0b6] Move `STDOUT`, `PIPE`, `PTY` constants to globals
+ `process(..., stdin=process.PTY)` --> `process(..., stdin=PTY)`
- [#828][828] Use `PR_SET_PTRACER` for all `process()` and `ssh.process()` instances
+ This simplifies debugging on systems with YAMA ptrace enabled
- Various documentation enhancements
+ In particular, the [gdb][gdb], [elf][elf], and [ssh][ssh] docs are much better
- [#833][833] Performance enhancements for `adb` module
- [d0267f3][d0267f3] `packing.fit()` now treats large offsets as cyclic patterns (e.g. `0x61616161` behaves the same as `"aaaa"`)
- [#835][835] Added `ssh.checksec`
+ Reports the kernel version and other relevant information on connection
- [#857][857] Slightly shortened `execve` shellcode
- [300f8e0][300f8e0] Slightly speed up processing of large ELF files
- [#861][861] Adds support for extracting `IKCONFIG` configs from Linux kernel images, and extends `checksec` to report on any insecure configurations discovered
- [#871][871] Moves all of the basic syscall templates to `shellcraft/common` and exposes them via symlinks. Closed [#685][685]
+ Should not have any visible effects from any documented APIs
+ `shellcraft.arch.os.syscall_function()` still works the same
+ We now have the ability to differentiate between the `connect` syscall, and a TCP `connect` helper
- [#887][887] `sh_string` now returns a quoted empty string `''` rather than just an empty string
- [#839][839] Exposes a huge amount of functionality via corefiles which was not previously availble. See the [docs][corefile_docs] for examples.
+ `process().corefile` will automatically instantiate a Corefile for the process
+ QEMU-emulated processes are supported
+ Native processes are supported, including extraction of coredumps from `apport` crash logs
+ Native processes can be dumped *while running*, in a manner similar to `GDB`'s `gcore` script
- [#875][857] Added [documentation][aarch64] (and tests) for AArch64 shellcode
- [#882][882] The `ROP` class now respects `context.bytes` instead of using the hard-coded value of `4` (fixed [#879][879])
- [#869][869] Added several fields to the `process` class (`uid`, `gid`, `suid`, `sgid`) which are recorded at execution time, based on the file permissions
- [#868][868] Changed the way that `ssh.process()` works internally, and it now returns a more specialized class, `ssh_process`.
+ Added `ssh_process.corefile` for fetching remote corefiles
+ Added `ssh_process.ELF` for getting an ELF of the remote executable
+ The `uid`, `gid`, and `suid`, and `sgid` which are recorded at execution time, based on the file permissions
- [#865][865] Fixes `ELF.read` to support contiguous memory reads across non-contiguous file-backed segments
- [#862][862] Adds a `symlink=` argument to `ssh.set_working_directory`, which will automatically symlink all of the files in the "old" working directory into the "new" working directory
[ssh]: http://docs.pwntools.com/en/dev/tubes/ssh.html
[gdb]: http://docs.pwntools.com/en/dev/gdb.html
[elf]: http://docs.pwntools.com/en/dev/elf.html
[corefile_docs]: http://docs.pwntools.com/en/dev/elf/corefile.html
[aarch64]: http://docs.pwntools.com/en/dev/shellcraft/aarch64.html
[685]: https://github.com/Gallopsled/pwntools/pull/685
[822]: https://github.com/Gallopsled/pwntools/pull/822
[828]: https://github.com/Gallopsled/pwntools/pull/828
[832]: https://github.com/Gallopsled/pwntools/pull/832
[833]: https://github.com/Gallopsled/pwntools/pull/833
[835]: https://github.com/Gallopsled/pwntools/pull/835
[839]: https://github.com/Gallopsled/pwntools/pull/839
[857]: https://github.com/Gallopsled/pwntools/pull/857
[861]: https://github.com/Gallopsled/pwntools/pull/861
[862]: https://github.com/Gallopsled/pwntools/pull/862
[865]: https://github.com/Gallopsled/pwntools/pull/865
[868]: https://github.com/Gallopsled/pwntools/pull/868
[869]: https://github.com/Gallopsled/pwntools/pull/869
[871]: https://github.com/Gallopsled/pwntools/pull/871
[875]: https://github.com/Gallopsled/pwntools/pull/857
[879]: https://github.com/Gallopsled/pwntools/issues/879
[882]: https://github.com/Gallopsled/pwntools/pull/882
[887]: https://github.com/Gallopsled/pwntools/pull/887
[b584ca3]: https://github.com/Gallopsled/pwntools/commit/b584ca3
[a12d0b6]: https://github.com/Gallopsled/pwntools/commit/a12d0b6
[d0267f3]: https://github.com/Gallopsled/pwntools/commit/d0267f3
[300f8e0]: https://github.com/Gallopsled/pwntools/commit/300f8e0
## 3.4.1
- [#894][894] Fix a bug when using `gdb.debug()` over ssh.
- [e021f57][e021f57] Fix a bug ([#891][891]) in `rop` when needing to insert padding to fix alignment
[e021f57]: https://github.com/Gallopsled/pwntools/commit/e021f57
[894]: https://github.com/Gallopsled/pwntools/pull/894
[891]: https://github.com/Gallopsled/pwntools/issues/891
## 3.4.0
- [#800][800] Add `shell=` option to `ssh.process()`
- [#806][806] Add `context.buffer_size` for fine-tuning `tube` performance
+ Also adds `buffer_fill_size=` argument for all tubes
- [b83a6c7][b83a6c7] Fix undocumented `process.leak` function
- [546061e][546061e] Modify `coredump_filter` of all spawned processes, so that core dumps are more complete
- [#809][809] Add several functions to `adb` (`unlink`, `mkdir`, `makedirs`, `isdir`, `exists`)
- [#817][817] Make disconnection detection more robust
[800]: https://github.com/Gallopsled/pwntools/pull/800
[806]: https://github.com/Gallopsled/pwntools/pull/806
[809]: https://github.com/Gallopsled/pwntools/pull/809
[817]: https://github.com/Gallopsled/pwntools/pull/817
[5d9792f]: https://github.com/Gallopsled/pwntools/commit/5d9792f
[b83a6c7]: https://github.com/Gallopsled/pwntools/commit/b83a6c7
[546061e]: https://github.com/Gallopsled/pwntools/commit/546061e
## 3.3.4
- [#850][850] and [#846][846] fix issues with `hexdump` and the `phd` command-line utility, when using pipes (e.g. `echo foo | phd`)
- [#852][852] Fixes register ordering in `regsort`
- [#853][853] Fixes the registers restored in `shellcraft.amd64.popad`
[846]: https://github.com/gallopsled/pwntools/pull/846
[850]: https://github.com/gallopsled/pwntools/pull/850
[852]: https://github.com/gallopsled/pwntools/pull/852
[853]: https://github.com/gallopsled/pwntools/pull/853
## 3.3.3
- [#843][843] fixed a bug in `amd64.mov`.
[843]: https://github.com/gallopsled/pwntools/pull/843
## 3.3.2
- [#840][840] fixed a regression introduced by [#837][837].
[840]: https://github.com/gallopsled/pwntools/pull/840
## 3.3.1
- [#833][833] Fixed a performance-impacting bug in the adb module.
- [#837][837] Fixed a bug([#836][836]) causing `hexdump(cyclic=True)` to throw an exception.
[833]: https://github.com/Gallopsled/pwntools/pull/833
[837]: https://github.com/Gallopsled/pwntools/pull/837
[836]: https://github.com/Gallopsled/pwntools/issues/836
## 3.3.0
- [b198ec8][b198ec8] Added `tube.stream()` function, which is like `tube.interact()` without a prompt or keyboard input.
+ Effectively, this is similar to `cat file` and just prints data as fast as it is received.
- [aec3fa6][aec3fa6] Disable update checks against GitHub
+ These checks frequently broke due to GitHub query limits
- [#757][757] Fixed `adb.wait_for_device()` re-use of the same connection
- [f9133b1][f9133b1] Add a `STDERR` magic argument to make logging go to `stderr` instead of `stdout`
+ Usage is e.g. `python foo.py STDERR` or `PWNLIB_STDERR=1 python foo.py`
+ Also adds `context.log_console` to log to any file or terminal
- [67e11a9][67e11a9] Add faster error checking to `cyclic()` when provided very large values
- [5fda658][5fda658] Expose BitPolynom in `globals()`
- [#765][765] Added `-d` option for hex-escaped output for `shellcraft` command-line tool
- [#772][772] Fixed bash completion regressions
- [30c34b7][30c34b7] Fix `ROP.call()` with `Function` objects from `ELF.functions`
- [fa402ce][fa402ce] Add `adb.uptime` and `adb.boot_time`
- [82312ba][82312ba] Add `cyclic_metasploit` and `cyclic_metasploit_find`
[757]: https://github.com/Gallopsled/pwntools/pull/757
[765]: https://github.com/Gallopsled/pwntools/pull/765
[772]: https://github.com/Gallopsled/pwntools/pull/772
[b198ec8]: https://github.com/Gallopsled/pwntools/commit/b198ec8
[aec3fa6]: https://github.com/Gallopsled/pwntools/commit/aec3fa6
[f9133b1]: https://github.com/Gallopsled/pwntools/commit/f9133b1
[67e11a9]: https://github.com/Gallopsled/pwntools/commit/67e11a9
[5fda658]: https://github.com/Gallopsled/pwntools/commit/5fda658
[30c34b7]: https://github.com/Gallopsled/pwntools/commit/30c34b7
[fa402ce]: https://github.com/Gallopsled/pwntools/commit/fa402ce
[82312ba]: https://github.com/Gallopsled/pwntools/commit/82312ba
## 3.2.1
Multiple bug fixes.
- [#783][783] Fix `adb.uninstall` typo
- [#787][787] Added error handling for `ssh.process` argument `preexec_fn`
- [#793][793] Fixed progress message in `remote()` when connections failed
- [#802][802] Fixed partition listing in `adb.partitions`, which accidentally shelled out to the `adb` binary
- [#804][804] Fix error message for 32-bit distributions
- [#805][805] Fix exception in `Core.segments` when a segment has no name
- [#811][811] Fixes and performance improvements for `adb.wait_for_device()`
- [#813][813] Fixed a release script
- [#814][814] Fixed exceptions thrown if the `$HOME` directory is not writable
- [#815][815] Properly handle `None` in `MemLeak`
[783]: https://github.com/Gallopsled/pwntools/pull/783
[787]: https://github.com/Gallopsled/pwntools/pull/787
[793]: https://github.com/Gallopsled/pwntools/pull/793
[802]: https://github.com/Gallopsled/pwntools/pull/802
[804]: https://github.com/Gallopsled/pwntools/pull/804
[805]: https://github.com/Gallopsled/pwntools/pull/805
[811]: https://github.com/Gallopsled/pwntools/pull/811
[813]: https://github.com/Gallopsled/pwntools/pull/813
[814]: https://github.com/Gallopsled/pwntools/pull/814
[815]: https://github.com/Gallopsled/pwntools/pull/815
## 3.2.0
- [#695][695] Fixed a performance regression in `phd`.
- [452605e][452605e] Fixed [#629][629] related to correct removal of temporary files.
- [ea94ee4][ea94ee4] Disallows semi-colons in for the `run_in_terminal` function, since it did not work properly in all cases.
- [6376d07][6376d07] Added the mips shellcode `pushstr_array`.
- [#700][700] Added missing MIPS shellcode documentation to readthedocs, and enabled unit tests
- [#701][701] Command line tools refactored to have a common `pwn` entry point.
+ Added an option to *not* install the traditional `asm`, `disasm`, `checksec`, etc scripts
+ All existing tools can be accessed from the `pwn` command (e.g. `pwn asm nop`).
- [#704][704] The `process` object has a new, optional argument `alarm` for setting a `SIGALRM` timeout for processes.
- [#705][705] Added the Android Emulator to the test suite and Travis CI.
+ Android Emulator is now required for the full test suite
+ Android Emulator tests are skipped if no Android-related changes are detected
- [#711][711] `DynELF` has a new attribute, `heap`, which leaks the current `brk` address (heap base). This is useful for finding heap allocations with dlmalloc-derived allocators like those used by Glibc.
- [#717][717] `sh_string` was rewritten to emit more compact and compatible strings
+ This was achieved by embedding single-quoted non-printable literals
+ Much more testing was added
+ Emitted strings are no longer copy-paste compatible, but work fine with e.g. `tubes` module and the default `subprocess` module
- [#709][709] The `adb` module now directly talks to the `adb` server process via a new module, `adb.protocol`
+ Removes the need to shell out to `adb`
+ Avoids version-compatibility issues with `adb` server vs. client
- [#703][703] Added new methods to `adb`
+ `install` - Installs an APK
+ `uninstall` - Uninstalls a package
+ `packages` - Lists installed packages
- [4893819][4893819] Modified `shellcraft.sh` on all platforms to provide `argv[0]` and set `argc==1`
+ This is needed for systems which have Busybox or other minimal shell for `/bin/sh` which does not behave well with `argc==0` or `argv[0]==NULL`.
- [1e414af][1e414af] Added `connect()` alias for `remote()`
+ For example, `io=connect('google.com', 80)`
+ This also works with `tcp(...)` and `udp(...)` aliases
- [869ec42][869ec42] Added `ssh.read()` and `ssh.write()` aliases
- [2af55c9][2af55c9] `AdbDevice` objects exposed via e.g. `adb.devices()` now offer scoped access to all `adb` module properties
+ It is now possible to e.g. `map(lambda d: d.process(['id']).recvall(), adb.devices())`
[629]: https://github.com/Gallopsled/pwntools/issues/629
[695]: https://github.com/Gallopsled/pwntools/pull/695
[700]: https://github.com/Gallopsled/pwntools/pull/700
[701]: https://github.com/Gallopsled/pwntools/pull/701
[704]: https://github.com/Gallopsled/pwntools/pull/704
[711]: https://github.com/Gallopsled/pwntools/pull/711
[717]: https://github.com/Gallopsled/pwntools/pull/717
[709]: https://github.com/Gallopsled/pwntools/pull/709
[705]: https://github.com/Gallopsled/pwntools/pull/705
[703]: https://github.com/Gallopsled/pwntools/pull/703
[452605e]: https://github.com/Gallopsled/pwntools/commit/452605e854f4870ef5ccfdf7fb110dfd75c50feb
[ea94ee4]: https://github.com/Gallopsled/pwntools/commit/ea94ee4ca5a8060567cc9bd0dc33796a89ad0b95
[6376d07]: https://github.com/Gallopsled/pwntools/commit/6376d072660fb2250f48bd22629bbd7e3c61c758
[1e414af]: https://github.com/Gallopsled/pwntools/commit/1e414afbeb3a01242f4918f111febaa63b640eb7
[869ec42]: https://github.com/Gallopsled/pwntools/commit/869ec42082b4b98958dfe85103da9b101dde7daa
[4893819]: https://github.com/Gallopsled/pwntools/commit/4893819b4c23182da570e2f4ea4c14d73af2c0df
[2af55c9]: https://github.com/Gallopsled/pwntools/commit/2af55c9bc382eca23f89bc0abc7a07c075521f94
## 3.1.1
Fixed a bug in `MemLeak.struct` (PR: #768).
## 3.1.0
A number of smaller bugfixes and documentation tweaks.
## 3.0.4
- Fixed a bug that made 3.0.3 uninstallable (Issue: #751, PR: #752)
## 3.0.3
- Fixed some performance and usability problems with the update system (Issues:
#723, #724, #736. PRs: #729, #738, #747).
- Fixed a bug related to internals in pyelftools (PRs: #730, #746).
- Fixed an issue with travis (Issue: #741, PRs: #743, #744, #745).
## 3.0.2
- Cherry-pick #695, as this was a regression-fix.
- Added a fix for the update checker, as it would suggest prereleases as updates to stable releases.
- Various documentation fixes.
## 3.0.1 (August 20 2016)
## 3.0.1
A small bugfix release. There were a lot of references to the `master`-branch, however after 3.0.0 we use the names `stable`, `beta` and `dev` for our branches.
## 3.0.0 (August 20 2016)
## 3.0.0
This was a large release (1305 commits since 2.2.0) with a lot of bugfixes and changes. The Binjitsu project, a fork of Pwntools, was merged back into Pwntools. As such, its features are now available here.
@@ -48,8 +402,8 @@ Android support via a new `adb` module, `context.device`, `context.adb_host`, an
- Added `context.log_file` setting for sending logs to a file. This can be set with the `LOG_FILE` magic command-line option.
- Added `context.noptrace` setting for disabling actions which require `ptrace` support. This is useful for turning all `gdb.debug` and `gdb.attach` options into no-ops, and can be set via the `NOPTRACE` magic command-line option.
- Added `context.proxy` which hooks all connections and sends them to a SOCKS4/SOCKS5. This can be set via the `PROXY` magic command-line option.
- Added `context.randomize` to control randommization of settings like XOR keys and register ordering (default off).
- Added `context.termianl` for setting how to launch commands in a new terminal.
- Added `context.randomize` to control randomization of settings like XOR keys and register ordering (default off).
- Added `context.terminal` for setting how to launch commands in a new terminal.
#### DynELF and MemLeak Module
@@ -61,7 +415,7 @@ Android support via a new `adb` module, `context.device`, `context.adb_host`, an
#### Encoders Module
- Added a `pwnlib.encoders` module for assembled-shellcode encoders/decoders
- Includes position-indepentent basic XOR encoders
- Includes position-independent basic XOR encoders
- Includes position-independent delta encoders
- Includes non-position-independent alphanumeric encoders for Intel
- Includes position-independent alphanumeric encoders for ARM/Thumb
+7 -1
View File
@@ -1 +1,7 @@
include *.txt
graft examples
graft extra
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
recursive-exclude *.pyc
+5 -10
View File
@@ -2,7 +2,7 @@
![pwntools logo](https://github.com/Gallopsled/pwntools/blob/stable/docs/source/logo.png?raw=true)
[![Docs](https://readthedocs.org/projects/pwntools/badge/?version=stable)](https://docs.pwntools.com/)
[![PyPI](https://img.shields.io/pypi/v/pwntools.svg?style=flat)](https://pypi.python.org/pypi/pwntools/)
[![PyPI](https://img.shields.io/badge/pypi-v3.6.1-green.svg?style=flat)](https://pypi.python.org/pypi/pwntools/)
[![Travis](https://travis-ci.org/Gallopsled/pwntools.svg)](https://travis-ci.org/Gallopsled/pwntools)
[![Coveralls](https://img.shields.io/coveralls/Gallopsled/pwntools/dev.svg)](https://coveralls.io/github/Gallopsled/pwntools?branch=dev)
[![Twitter](https://img.shields.io/badge/twitter-pwntools-4099FF.svg?style=flat)](https://twitter.com/pwntools)
@@ -22,13 +22,10 @@ r.interactive()
# Try It Now!
You can now do a live demo of Pwntools, [right in your browser](http://demo.pwntools.com). Alternately, you can SSH to the same host, and log in as user `zerocool` with [this private key][key] (password `i_promise_not_to_be_evil`).
It will drop you into a clean, Docker-ized container. There is nothing of value on the VPS, so please don't be evil.
[key]: https://gist.githubusercontent.com/zachriggle/efa2e0080ae6de2e8344/raw/4b503e9db54f009d97477d03d4ba5678471f8ff0/id_rsa
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/)
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).
@@ -41,13 +38,11 @@ Most of the functionality of pwntools is self-contained and Python-only. You sh
```sh
apt-get update
apt-get install python2.7 python-pip python-dev git libssl-dev
apt-get install python2.7 python-pip python-dev git libssl-dev libffi-dev build-essential
pip install --upgrade pip
pip install --upgrade pwntools
```
If you'd like to be an early tester of the the current beta release, add
`--pre` to the command-line.
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).
+11 -8
View File
@@ -4,18 +4,21 @@ Pwntools makes extensive use of unit tests and integration tests to ensure every
## Test Suite
To run the test suite, it is beste to use Ubuntu 12.04 or 14.04, and run the following commands. **Be aware** that this will add a user to the machine, and create a public key for SSH login!
To run the test suite, it is best to use Ubuntu 12.04 or 14.04, and run the following commands. **Be aware** that this will add a user to the machine, and create a public key for SSH login!
```sh
bash .travis_install.sh
bash .travis_ssh_setup.sh
pip install -e .
pip install -r docs/requirements.txt
cd docs
PWNLIB_NOTERM=1 make clean doctest
bash travis/install.sh
bash travis/ssh_setup.sh
pip install --upgrade --editable .
PWNLIB_NOTERM=1 make -C docs doctest
```
## Testing in Docker
A `Dockerfile` has been provided which has a clean testing environment with Ubuntu Xenial. It is very similar to the online Travis CI testing environment, but uses a more modern version of Ubuntu.
See `travis/docker/README.md` for more information.
## New Tests
To add a new test to an existing module, just add an inline doctest. If the test needs access to an external module, add the import statement to the `testsetup` block in the corresponding file in `docs/source/<module>.rst`.
+1 -1
View File
@@ -1,5 +1,5 @@
sphinxcontrib-napoleon
sphinxcontrib-autoprogram
sphinxcontrib-autoprogram==0.1.2
isort
paramiko>=1.15.2
mako>=1.0.0
+5 -1
View File
@@ -1,9 +1,13 @@
.. testsetup:: *
from pwn import *
adb = pwnlib.adb
:mod:`pwnlib.adb` --- Android Debug Bridge
=====================================================
.. automodule:: pwnlib.adb
.. automodule:: pwnlib.adb.adb
:members:
.. automodule:: pwnlib.adb.protocol
:members:
+9
View File
@@ -0,0 +1,9 @@
.. testsetup:: *
from pwn import *
:mod:`pwnlib.args` --- Magic Command-Line Arguments
=====================================================
.. automodule:: pwnlib.args
:members:
+10
View File
@@ -13,3 +13,13 @@
.. automodule:: pwnlib.asm
:members:
Internal Functions
=========================================
These are only included so that their tests are run.
You should never need these.
.. autofunction:: pwnlib.asm.dpkg_search_for_binutils
.. autofunction:: pwnlib.asm.print_binutils_instructions
+2 -42
View File
@@ -14,45 +14,5 @@ pwntools comes with a handful of useful command-line utilities which serve as wr
.. toctree::
.. autoprogram:: pwnlib.commandline.asm:parser
:prog: asm
.. autoprogram:: pwnlib.commandline.checksec:parser
:prog: checksec
.. autoprogram:: pwnlib.commandline.constgrep:p
:prog: constgrep
.. autoprogram:: pwnlib.commandline.cyclic:parser
:prog: cyclic
.. autoprogram:: pwnlib.commandline.disasm:parser
:prog: disasm
.. autoprogram:: pwnlib.commandline.elfdiff:p
:prog: elfdiff
.. autoprogram:: pwnlib.commandline.elfpatch:p
:prog: elfpatch
.. autoprogram:: pwnlib.commandline.errno:parser
:prog: errno
.. autoprogram:: pwnlib.commandline.hex:parser
:prog: hex
.. autoprogram:: pwnlib.commandline.phd:parser
:prog: phd
.. autoprogram:: pwnlib.commandline.pwnstrip:p
:prog: pwnstrip
.. autoprogram:: pwnlib.commandline.scramble:parser
:prog: scramble
.. autoprogram:: pwnlib.commandline.shellcraft:p
:prog: shellcraft
.. autoprogram:: pwnlib.commandline.unhex:parser
:prog: unhex
.. autoprogram:: pwnlib.commandline.main:parser
:prog: pwn
+66 -3
View File
@@ -44,6 +44,10 @@ extensions = [
'sphinxcontrib.napoleon'
]
# Napoleon settings
napoleon_use_ivar = True
napoleon_use_rtype = False
doctest_global_setup = '''
import sys, os
os.environ['PWNLIB_NOTERM'] = '1'
@@ -52,17 +56,29 @@ import pwnlib
pwnlib.context.context.reset_local()
pwnlib.context.ContextType.defaults['log_level'] = 'ERROR'
pwnlib.context.ContextType.defaults['randomize'] = False
pwnlib.util.fiddling.default_style = {}
pwnlib.term.text.when = 'never'
pwnlib.log.install_default_handler()
pwnlib.log.rootlogger.setLevel(1)
# Sphinx modifies sys.stdout, and context.log_terminal has
# a reference to the original instance. We need to update
# it for logging to be captured.
class stdout(object):
def __getattr__(self, name):
return getattr(sys.stdout, name)
def __setattr__(self, name, value):
return setattr(sys.stdout, name, value)
pwnlib.context.ContextType.defaults['log_console'] = stdout()
'''
autodoc_member_order = 'alphabetical'
autoclass_content = 'both'
autodoc_member_order = 'groupwise' # 'alphabetical'
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
doctest_test_doctest_blocks = True
doctest_test_doctest_blocks = 'true'
# The suffix of source filenames.
source_suffix = '.rst'
@@ -221,7 +237,7 @@ latex_documents = [
]
intersphinx_mapping = {'python': ('https://docs.python.org/2.7', None),
'paramiko': ('https://paramiko-docs.readthedocs.org/en/1.15/', 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.
@@ -337,3 +353,50 @@ if build_dash:
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 False
# 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):
app.connect('autodoc-skip-member', dont_skip_any_doctests)
sphinx.ext.autodoc.ModuleDocumenter = ModuleDocumenter
+4
View File
@@ -0,0 +1,4 @@
:mod:`pwnlib.config` --- Pwntools Configuration File
====================================================
.. automodule:: pwnlib.config
+22 -4
View File
@@ -3,13 +3,31 @@
from pwn import *
import logging
log = pwnlib.log.getLogger('pwnlib.context')
context.clear()
:mod:`pwnlib.context` --- Setting runtime variables
=====================================================
.. autodata:: pwnlib.context.context
Many settings in ``pwntools`` are controlled via the global variable :data:`.context, such as the selected target operating system, architecture, and bit-width.
.. autoclass:: pwnlib.context.ContextType
:members:
In general, exploits will start with something like:
.. autoclass:: pwnlib.context.Thread
.. code-block:: python
from pwn import *
context.arch = 'amd64'
Which sets up everything in the exploit for exploiting a 64-bit Intel binary.
The recommended method is to use ``context.binary`` to automagically set all of the appropriate values.
.. code-block:: python
from pwn import *
context.binary = './challenge-binary'
Module Members
----------------------------------------------------
.. automodule:: pwnlib.context
:members:
+11 -3
View File
@@ -3,8 +3,16 @@
from pwnlib.elf import *
from pwnlib.util.misc import which
:mod:`pwnlib.elf` --- Working with ELF binaries
===============================================
:mod:`pwnlib.elf` --- ELF Executables and Libraries
===================================================
.. automodule:: pwnlib.elf
:members:
ELF Modules
-------------------
.. toctree::
elf/elf
elf/config
elf/corefile
+10
View File
@@ -0,0 +1,10 @@
.. testsetup:: *
from pwn import *
from pwnlib.elf.config import parse_kconfig
:mod:`pwnlib.elf.config` --- Kernel Config Parsing
===========================================================
.. automodule:: pwnlib.elf.config
:members:
+15
View File
@@ -0,0 +1,15 @@
.. testsetup:: *
from pwn import *
:mod:`pwnlib.elf.corefile` --- Core Files
===========================================================
.. automodule:: pwnlib.elf.corefile
.. autoclass:: pwnlib.elf.corefile.Corefile
:members:
:show-inheritance:
.. autoclass:: pwnlib.elf.corefile.Mapping
:members:
+28
View File
@@ -0,0 +1,28 @@
.. testsetup:: *
from pwn import *
from glob import glob
:mod:`pwnlib.elf.elf` --- ELF Files
===========================================================
.. automodule:: pwnlib.elf.elf
.. autoclass:: pwnlib.elf.elf.ELF
:members:
:show-inheritance:
:inherited-members:
:exclude-members: address_offsets,
get_data,
get_dwarf_info,
get_section,
get_segment,
has_dwarf_info,
iter_sections,
iter_segments
.. autoclass:: pwnlib.elf.elf.Function
:members:
.. autoclass:: pwnlib.elf.elf.dotdict
:members:
+10
View File
@@ -0,0 +1,10 @@
.. testsetup:: *
from pwn import *
:mod:`pwnlib.flag` --- CTF Flag Management
==========================================
.. automodule:: pwnlib.flag
:members:
+4
View File
@@ -1,3 +1,7 @@
.. testsetup:: *
from pwn import *
:mod:`pwnlib.gdb` --- Working with GDB
======================================
+6 -6
View File
@@ -13,11 +13,11 @@ 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.
- ``context``
- :obj:`.context`
- :data:`pwnlib.context.context`
- Responsible for most of the pwntools convenience settings
- Set `context.log_level = 'debug'` when troubleshooting your exploit
- Scope-aware, so you can disable logging for a subsection of code via ``pwnlib.context.ContextType.local``
- Scope-aware, so you can disable logging for a subsection of code via :meth:`.ContextType.local`
- ``remote``, ``listen``, ``ssh``, ``process``
- :mod:`pwnlib.tubes`
- Super convenient wrappers around all of the common functionality for CTF challenges
@@ -57,11 +57,11 @@ This is a quick list of most of the objects and routines imported, in rough orde
- ``gdb.debug`` and ``gdb.attach``
- :mod:`pwnlib.gdb`
- Launch a binary under GDB and pop up a new terminal to interact with it. Automates setting breakpoints and makes iteration on exploits MUCH faster.
- Alternately, attach to a running process given a PID, ``pwnlib.tubes`` object, or even just a socket that's connected to it
- Alternately, attach to a running process given a PID, :mod:`pwnlib.tubes` object, or even just a socket that's connected to it
- ``args``
- Dictionary contining all-caps command-line arguments for quick access
- Dictionary containing all-caps command-line arguments for quick access
- Run via ``python foo.py REMOTE=1`` and ``args['REMOTE'] == '1'``.
- Can also control logging verbosity and terminal fancyness
- Can also control logging verbosity and terminal fanciness
- `NOTERM`
- `SILENT`
- `DEBUG`
@@ -78,7 +78,7 @@ This is a quick list of most of the objects and routines imported, in rough orde
- It's the new ``getch``
- ``safeeval``
- :mod:`pwnlib.util.safeeval`
- Functions for safely evalutaing python code without nasty side-effects.
- Functions for safely evaluating python code without nasty side-effects.
These are all pretty self explanatory, but are useful to have in the global namespace.
+5
View File
@@ -43,19 +43,23 @@ Each of the ``pwntools`` modules is documented here.
:glob:
adb
args
asm
atexception
atexit
constants
config
context
dynelf
encoders
elf
exception
flag
fmtstr
gdb
log
memleak
protocols
replacements
rop
rop/*
@@ -67,6 +71,7 @@ Each of the ``pwntools`` modules is documented here.
tubes
tubes/*
ui
update
useragents
util/*
+4 -11
View File
@@ -24,17 +24,11 @@ pwntools is available as a ``pip`` package.
.. code-block:: bash
$ apt-get install python2.7 python2.7-dev python-pip
$ 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
Alternatively you can get early access to the beta release if you want to help
file bugs or simple get newer features:
.. code-block:: bash
$ pip install --upgrade --pre pwntools
Development
--------------
@@ -43,7 +37,6 @@ If you are hacking on Pwntools locally, you'll want to do something like this:
.. code-block:: bash
$ git clone https://github.com/Gallopsled/pwntools
$ cd pwntools
$ pip install -e .
$ pip install --upgrade --editable ./pwntools
.. _Ubuntu: https://launchpad.net/~pwntools/+archive/ubuntu/binutils
+4 -1
View File
@@ -11,7 +11,10 @@ Building `binutils` from source takes about 60 seconds on a modern 8-core machin
Ubuntu
^^^^^^^^^^^^^^^^
First, add our `Personal Package Archive repository <http://binutils.pwntools.com>`__.
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
+4 -4
View File
@@ -176,8 +176,8 @@ 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!
>>> asm(shellcraft.setreuid() + shellcraft.dupsh(4)).encode('hex')
'6a3158cd8089c36a465889d9cd806a045b6a0359496a3f58cd8075f86a68682f2f2f73682f62696e6a0b5889e331c999cd80'
>>> asm(shellcraft.setreuid() + shellcraft.dupsh(4)).encode('hex') # doctest: +ELLIPSIS
'6a3158cd80...'
Misc Tools
@@ -212,8 +212,8 @@ Stop hard-coding things! Look them up at runtime with :mod:`pwnlib.elf`.
You can even patch and save the files.
>>> e = ELF('/bin/cat')
>>> e.read(e.address+1, 3)
'ELF'
>>> e.read(e.address, 4)
'\x7fELF'
>>> e.asm(e.address, 'ret')
>>> e.save('/tmp/quiet-cat')
>>> disasm(file('/tmp/quiet-cat','rb').read(1))
+3 -5
View File
@@ -1,11 +1,9 @@
.. testsetup:: *
from pwnlib.memleak import *
from pwn import *
:mod:`pwnlib.memleak` --- Helper class for leaking memory
=========================================================
.. module:: pwnlib.memleak
.. autoclass:: MemLeak
:members:
.. automodule:: pwnlib.memleak
:members:
+15
View File
@@ -0,0 +1,15 @@
:mod:`pwnlib.protocols` --- Wire Protocols
=============================================
.. automodule:: pwnlib.protocols
Supported Protocols
-------------------
.. toctree::
:maxdepth: 3
:glob:
protocols/*
+10
View File
@@ -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:
+19
View File
@@ -0,0 +1,19 @@
.. testsetup:: *
from pwn import *
context.clear(arch='aarch64')
:mod:`pwnlib.shellcraft.aarch64` --- Shellcode for AArch64
===========================================================
:mod:`pwnlib.shellcraft.aarch64`
--------------------------------
.. automodule:: pwnlib.shellcraft.aarch64
:members:
:mod:`pwnlib.shellcraft.aarch64.linux`
--------------------------------------
.. automodule:: pwnlib.shellcraft.aarch64.linux
:members:
+19
View File
@@ -0,0 +1,19 @@
.. testsetup:: *
from pwn import *
context.clear(arch='mips')
:mod:`pwnlib.shellcraft.mips` --- Shellcode for MIPS
===========================================================
:mod:`pwnlib.shellcraft.mips`
-----------------------------
.. automodule:: pwnlib.shellcraft.mips
:members:
:mod:`pwnlib.shellcraft.mips.linux`
-----------------------------------
.. automodule:: pwnlib.shellcraft.mips.linux
:members:
+1 -1
View File
@@ -27,4 +27,4 @@ Types of Tubes
.. autoclass:: pwnlib.tubes.tube.tube()
:members:
:exclude-members: recv_raw, send_raw, settimeout_raw,
can_recv_raw
can_recv_raw, shutdown_raw, connected_raw,
+10
View File
@@ -0,0 +1,10 @@
.. testsetup:: *
from pwn import *
from pwnlib.update import *
:mod:`pwnlib.update` --- Updating Pwntools
===================================================
.. automodule:: pwnlib.update
:members:
+2 -1
View File
@@ -1,6 +1,7 @@
.. testsetup:: *
from pwnlib.util.fiddling import *
from pwn import *
from pwnlib.util.fiddling import *
:mod:`pwnlib.util.fiddling` --- Utilities bit fiddling
+1
View File
@@ -1,6 +1,7 @@
.. testsetup:: *
from pwnlib.util.safeeval import *
_get_opcodes = pwnlib.util.safeeval._get_opcodes
:mod:`pwnlib.util.safeeval` --- Safe evaluation of python code
+10
View File
@@ -0,0 +1,10 @@
.. testsetup:: *
from pwn import *
test = pwnlib.util.sh_string.test
:mod:`pwnlib.util.sh_string` --- Shell Expansion is Hard
===============================================================
.. automodule:: pwnlib.util.sh_string
:members:
+31
View File
@@ -0,0 +1,31 @@
from pwn import *
context.arch='aarch64'
frame = SigreturnFrame()
registers = ['x%i' % i for i in range(0, 31)]
registers += ['sp', 'pc']
for index, register in enumerate(registers):
setattr(frame, register, index)
assembly = '\n'.join([
shellcraft.read(constants.STDIN_FILENO, 'sp', 1024),
shellcraft.syscall(constants.SYS_rt_sigreturn)
])
binary = ELF.from_assembly(assembly)
io = binary.process()
io.flat(frame)
io.wait()
assert io.poll() == -11
corefile = io.corefile
for index, register in enumerate(registers):
value = getattr(corefile, register)
if index != value:
log.error("%s != %i (%i)" % (register, index, value))
else:
log.success("%s == %i" % (register, value))
+32
View File
@@ -0,0 +1,32 @@
from pwn import *
context.arch='amd64'
frame = SigreturnFrame()
registers = ['rax', 'rbx', 'rcx', 'rdx',
'rdi', 'rsi', 'rbp', 'rsp',
'rip',
'r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15']
for index, register in enumerate(registers):
setattr(frame, register, index)
assembly = '\n'.join([
shellcraft.read(constants.STDIN_FILENO, 'rsp', 1024),
shellcraft.sigreturn()
])
binary = ELF.from_assembly(assembly)
io = binary.process()
io.flat(frame)
io.wait()
assert io.poll() == -11
corefile = io.corefile
for index, register in enumerate(registers):
value = getattr(corefile, register)
if index != value:
log.error("%s != %i (%i)" % (register, index, value))
else:
log.success("%s == %i" % (register, value))
+32
View File
@@ -0,0 +1,32 @@
from pwn import *
context.arch='arm'
frame = SigreturnFrame()
registers = ['r0', 'r1', 'r2', 'r3', 'r4', 'r5', 'r6', 'r7',
'r8', 'r9', 'r10', 'fp', 'ip', 'sp', 'pc', 'lr']
for index, register in enumerate(registers):
setattr(frame, register, index)
assembly = '\n'.join([
shellcraft.read(constants.STDIN_FILENO, 'sp', 1024),
shellcraft.sigreturn()
])
binary = ELF.from_assembly(assembly)
io = binary.process()
io.flat(frame)
io.wait()
assert io.poll() == -11
corefile = io.corefile
for index, register in enumerate(registers):
value = getattr(corefile, register)
if index != value:
log.error("%s != %i (%i)" % (register, index, value))
else:
log.success("%s == %i" % (register, value))
+31
View File
@@ -0,0 +1,31 @@
from pwn import *
context.kernel='amd64'
frame = SigreturnFrame()
registers = ['eax', 'ebx', 'ecx', 'edx',
'edi', 'esi', 'ebp', 'esp',
'eip']
for index, register in enumerate(registers):
setattr(frame, register, index)
assembly = '\n'.join([
shellcraft.read(constants.STDIN_FILENO, 'esp', 1024),
shellcraft.sigreturn()
])
binary = ELF.from_assembly(assembly)
io = binary.process()
io.flat(frame)
io.wait()
assert io.poll() == -11
corefile = io.corefile
for index, register in enumerate(registers):
value = getattr(corefile, register)
if index != value:
log.error("%s != %i (%i)" % (register, index, value))
else:
log.success("%s == %i" % (register, value))
+3 -1
View File
@@ -1,5 +1,6 @@
#!/usr/bin/env bash
# cache list of shellcodes
_shellcraft_shellcodes=$(shellcraft)
_shellcraft_shellcodes=$(pwn shellcraft -l)
_shellcraft()
{
@@ -43,4 +44,5 @@ _shellcraft()
COMPREPLY=( $(compgen -W "${_shellcraft_shellcodes}" -- ${cur}) )
}
complete -F _shellcraft pwn shellcraft
complete -F _shellcraft shellcraft
-58
View File
@@ -1,58 +0,0 @@
############################################################
# Dockerfile to build Pwntools container
# Based on Ubuntu
############################################################
FROM ubuntu:trusty
MAINTAINER Maintainer Gallopsled et al.
RUN apt-get update && apt-get install -y software-properties-common
RUN apt-add-repository --yes ppa:pwntools/binutils
RUN apt-get update
RUN apt-get install -y \
binutils \
binutils-aarch64-linux-gnu \
binutils-arm-linux-gnueabihf \
curl \
gdb \
gdbserver \
gdb-multiarch \
git \
libc6-i386 \
libc6-arm64-cross \
libc6-armhf-cross \
libc6-dev-i386 \
libffi-dev \
libglib2.0-dev \
libncurses5-dev \
libncursesw5-dev \
ltrace \
python-dev \
python-pip \
python3-pip \
python2.7 \
qemu \
qemu-user-static \
strace \
tmux \
wget
RUN pip install --upgrade ipython
RUN useradd -m zerocool
RUN usermod -U zerocool
RUN mkdir -p /etc/qemu-binfmt
RUN ln -s /usr/aarch64-linux-gnu /etc/qemu-binfmt/aarch64
RUN ln -s /usr/arm-linux-gnueabihf /etc/qemu-binfmt/arm
RUN pip install --upgrade pip pycparser psutil python-ptrace
RUN pip3 install --upgrade pip pycparser psutil python-ptrace
RUN pip install --upgrade git+https://github.com/Gallopsled/pwntools.git
RUN locale-gen en_US.UTF-8
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en
ENV LC_ALL en_US.UTF-8
RUN chown -R zerocool.zerocool /home/zerocool
RUN chsh -s /bin/bash zerocool
+13
View File
@@ -0,0 +1,13 @@
subdirs=xenial stable $(wildcard */)
makefiles=$(wildcard */Makefile)
tags=stable beta dev
all: $(makefiles) $(subdirs)
$(subdirs):
docker build -t pwntools/pwntools:$(shell basename $(@)) "$@"
$(makefiles):
make -C $(shell dirname $@)
.PHONY: all $(subdirs) $(makefiles)
+6
View File
@@ -0,0 +1,6 @@
FROM pwntools/pwntools:stable
USER root
RUN pip install --upgrade git+https://github.com/Gallopsled/pwntools@beta
RUN PWNLIB_NOTERM=1 pwn update
USER pwntools
+6
View File
@@ -0,0 +1,6 @@
FROM pwntools/pwntools:stable
USER root
RUN pip install --upgrade git+https://github.com/Gallopsled/pwntools@dev
RUN PWNLIB_NOTERM=1 pwn update
USER pwntools
+26
View File
@@ -0,0 +1,26 @@
############################################################
# Dockerfile to build Pwntools container
# Based on Ubuntu
############################################################
FROM kalilinux/kali-linux-docker
MAINTAINER Maintainer Gallopsled et al.
RUN apt-get update
RUN apt-get install -y build-essential
RUN apt-get install -y git
RUN apt-get install -y libssl-dev
RUN apt-get install -y libffi-dev
RUN apt-get install -y python2.7
RUN apt-get install -y python-pip
RUN apt-get install -y python-dev
RUN pip install --upgrade pip
RUN python -m pip install --upgrade pwntools
RUN PWNLIB_NOTERM=1 pwn update
RUN apt-get install -y sudo
RUN useradd -m pwntools
RUN passwd --delete --unlock pwntools
RUN echo "pwntools ALL=(ALL:ALL) NOPASSWD: ALL" > /etc/sudoers.d/pwntools
USER pwntools
WORKDIR /home/pwntools
+8
View File
@@ -0,0 +1,8 @@
all: Dockerfile
Dockerfile: ../stable/Dockerfile FORCE
sed "s|ubuntu:xenial|kalilinux/kali-linux-docker|" < "$<" > "$@"
FORCE:
.PHONY: all
+26
View File
@@ -0,0 +1,26 @@
############################################################
# Dockerfile to build Pwntools container
# Based on Ubuntu
############################################################
FROM ubuntu:precise
MAINTAINER Maintainer Gallopsled et al.
RUN apt-get update
RUN apt-get install -y build-essential
RUN apt-get install -y git
RUN apt-get install -y libssl-dev
RUN apt-get install -y libffi-dev
RUN apt-get install -y python2.7
RUN apt-get install -y python-pip
RUN apt-get install -y python-dev
RUN pip install --upgrade pip
RUN python -m pip install --upgrade pwntools
RUN PWNLIB_NOTERM=1 pwn update
RUN apt-get install -y sudo
RUN useradd -m pwntools
RUN passwd --delete --unlock pwntools
RUN echo "pwntools ALL=(ALL:ALL) NOPASSWD: ALL" > /etc/sudoers.d/pwntools
USER pwntools
WORKDIR /home/pwntools
+8
View File
@@ -0,0 +1,8 @@
all: Dockerfile
Dockerfile: ../xenial/Dockerfile FORCE
sed "s|ubuntu:xenial|ubuntu:precise|" < "$<" > "$@"
FORCE:
.PHONY: all
+26
View File
@@ -0,0 +1,26 @@
############################################################
# Dockerfile to build Pwntools container
# Based on Ubuntu
############################################################
FROM ubuntu:xenial
MAINTAINER Maintainer Gallopsled et al.
RUN apt-get update
RUN apt-get install -y build-essential
RUN apt-get install -y git
RUN apt-get install -y libssl-dev
RUN apt-get install -y libffi-dev
RUN apt-get install -y python2.7
RUN apt-get install -y python-pip
RUN apt-get install -y python-dev
RUN pip install --upgrade pip
RUN python -m pip install --upgrade pwntools
RUN PWNLIB_NOTERM=1 pwn update
RUN apt-get install -y sudo
RUN useradd -m pwntools
RUN passwd --delete --unlock pwntools
RUN echo "pwntools ALL=(ALL:ALL) NOPASSWD: ALL" > /etc/sudoers.d/pwntools
USER pwntools
WORKDIR /home/pwntools
+8
View File
@@ -0,0 +1,8 @@
all: Dockerfile
Dockerfile: ../xenial/Dockerfile FORCE
cp "$<" "$@"
FORCE:
.PHONY: all
+26
View File
@@ -0,0 +1,26 @@
############################################################
# Dockerfile to build Pwntools container
# Based on Ubuntu
############################################################
FROM ubuntu:trusty
MAINTAINER Maintainer Gallopsled et al.
RUN apt-get update
RUN apt-get install -y build-essential
RUN apt-get install -y git
RUN apt-get install -y libssl-dev
RUN apt-get install -y libffi-dev
RUN apt-get install -y python2.7
RUN apt-get install -y python-pip
RUN apt-get install -y python-dev
RUN pip install --upgrade pip
RUN python -m pip install --upgrade pwntools
RUN PWNLIB_NOTERM=1 pwn update
RUN apt-get install -y sudo
RUN useradd -m pwntools
RUN passwd --delete --unlock pwntools
RUN echo "pwntools ALL=(ALL:ALL) NOPASSWD: ALL" > /etc/sudoers.d/pwntools
USER pwntools
WORKDIR /home/pwntools
+8
View File
@@ -0,0 +1,8 @@
all: Dockerfile
Dockerfile: ../xenial/Dockerfile FORCE
sed "s|ubuntu:xenial|ubuntu:trusty|" < "$<" > "$@"
FORCE:
.PHONY: all
+26
View File
@@ -0,0 +1,26 @@
############################################################
# Dockerfile to build Pwntools container
# Based on Ubuntu
############################################################
FROM ubuntu:xenial
MAINTAINER Maintainer Gallopsled et al.
RUN apt-get update
RUN apt-get install -y build-essential
RUN apt-get install -y git
RUN apt-get install -y libssl-dev
RUN apt-get install -y libffi-dev
RUN apt-get install -y python2.7
RUN apt-get install -y python-pip
RUN apt-get install -y python-dev
RUN pip install --upgrade pip
RUN python -m pip install --upgrade pwntools
RUN PWNLIB_NOTERM=1 pwn update
RUN apt-get install -y sudo
RUN useradd -m pwntools
RUN passwd --delete --unlock pwntools
RUN echo "pwntools ALL=(ALL:ALL) NOPASSWD: ALL" > /etc/sudoers.d/pwntools
USER pwntools
WORKDIR /home/pwntools
+6 -2
View File
@@ -1,8 +1,11 @@
# Promote useful stuff to toplevel
from .toplevel import *
from __future__ import absolute_import
from pwn.toplevel import *
pwnlib.args.initialize()
pwnlib.log.install_default_handler()
pwnlib.config.initialize()
log = pwnlib.log.getLogger('pwnlib.exploit')
args = pwnlib.args.args
@@ -13,4 +16,5 @@ if not platform.architecture()[0].startswith('64'):
See Gallopsled/pwntools#518 for more information."""
log.warn_once('Pwntools does not support 32-bit Python. Use a 64-bit release.')
pwnlib.update.check_automatically()
with context.local(log_console=sys.stderr):
pwnlib.update.check_automatically()
+12 -6
View File
@@ -6,6 +6,7 @@ import operator
import os
import re
import socks
import signal
import string
import struct
import subprocess
@@ -14,6 +15,8 @@ import tempfile
import threading
import time
from pprint import pprint
import pwnlib
from pwnlib import *
from pwnlib.asm import *
@@ -21,14 +24,15 @@ from pwnlib.context import Thread
from pwnlib.context import context
from pwnlib.dynelf import DynELF
from pwnlib.encoders import *
from pwnlib.elf import Core
from pwnlib.elf import ELF
from pwnlib.elf import load
from pwnlib.elf.corefile import Core, Corefile, Coredump
from pwnlib.elf.elf import ELF, load
from pwnlib.encoders import *
from pwnlib.exception import PwnlibException
from pwnlib.gdb import attach, debug, debug_assembly, debug_shellcode
from pwnlib.flag import *
from pwnlib.fmtstr import FmtStr, fmtstr_payload
from pwnlib.log import getLogger
from pwnlib.memleak import MemLeak
from pwnlib.memleak import MemLeak, RelativeMemLeak
from pwnlib.regsort import *
from pwnlib.replacements import *
from pwnlib.rop import ROP
@@ -36,8 +40,8 @@ from pwnlib.rop.srop import SigreturnFrame
from pwnlib.runner import *
from pwnlib.timeout import Timeout
from pwnlib.tubes.listen import listen
from pwnlib.tubes.process import process
from pwnlib.tubes.remote import remote, tcp, udp
from pwnlib.tubes.process import process, PTY, PIPE, STDOUT
from pwnlib.tubes.remote import remote, tcp, udp, connect
from pwnlib.tubes.serialtube import serialtube
from pwnlib.tubes.ssh import ssh
from pwnlib.tubes.tube import tube
@@ -47,6 +51,7 @@ from pwnlib.util import iters
from pwnlib.util import net
from pwnlib.util import proc
from pwnlib.util import safeeval
from pwnlib.util.crc import BitPolynom
from pwnlib.util.cyclic import *
from pwnlib.util.fiddling import *
from pwnlib.util.getdents import *
@@ -55,6 +60,7 @@ from pwnlib.util.lists import *
from pwnlib.util.misc import *
from pwnlib.util.packing import *
from pwnlib.util.proc import pidof
from pwnlib.util.sh_string import sh_string, sh_prepare, sh_command_with
from pwnlib.util.splash import *
from pwnlib.util.web import *
+4 -1
View File
@@ -1,6 +1,8 @@
from __future__ import absolute_import
import importlib
from .version import __version__
from pwnlib.version import __version__
version = __version__
@@ -12,6 +14,7 @@ __all__ = [
'commandline',
'constants',
'context',
'data',
'dynelf',
'encoders',
'elf',
+49 -24
View File
@@ -1,6 +1,8 @@
# -*- coding: utf-8 -*-
from .context import LocalContext
from .context import context
from __future__ import absolute_import
from pwnlib.context import LocalContext
from pwnlib.context import context
class ABI(object):
@@ -24,7 +26,8 @@ class ABI(object):
#: Indicates that this ABI returns to the next address on the slot
returns = True
def __init__(self, regs, align, minimum):
def __init__(self, stack, regs, align, minimum):
self.stack = stack
self.register_arguments = regs
self.arg_alignment = align
self.stack_minimum = minimum
@@ -32,35 +35,52 @@ class ABI(object):
@staticmethod
@LocalContext
def default():
if context.os == 'android':
context.os = 'linux'
return {
(32, 'i386', 'linux'): linux_i386,
(64, 'aarch64', 'linux'): linux_aarch64,
(64, 'amd64', 'linux'): linux_amd64,
(32, 'arm', 'linux'): linux_arm,
(32, 'thumb', 'linux'): linux_arm,
(32, 'mips', 'linux'): linux_mips,
(32, 'i386', 'windows'): windows_i386,
(64, 'amd64', 'windows'): windows_amd64,
(32, 'powerpc', 'linux'): linux_ppc,
(64, 'powerpc', 'linux'): linux_ppc64,
}[(context.bits, context.arch, context.os)]
@staticmethod
@LocalContext
def syscall():
if context.os == 'android':
context.os = 'linux'
return {
(32, 'i386', 'linux'): linux_i386_syscall,
(64, 'amd64', 'linux'): linux_amd64_syscall,
(64, 'aarch64', 'linux'): linux_aarch64_syscall,
(32, 'arm', 'linux'): linux_arm_syscall,
(32, 'thumb', 'linux'): linux_arm_syscall,
(32, 'mips', 'linux'): linux_mips_syscall,
(64, 'aarch64', 'linux'): linux_aarch64_syscall,
(32, 'powerpc', 'linux'): linux_ppc_syscall,
(64, 'powerpc', 'linux'): linux_ppc64_syscall,
}[(context.bits, context.arch, context.os)]
@staticmethod
@LocalContext
def sigreturn():
if context.os == 'android':
context.os = 'linux'
return {
(32, 'i386', 'linux'): linux_i386_sigreturn,
(64, 'amd64', 'linux'): linux_amd64_sigreturn,
(32, 'arm', 'linux'): linux_arm_sigreturn,
(32, 'thumb', 'linux'): linux_arm_sigreturn,
(64, 'aarch64', 'linux'): linux_aarch64_sigreturn,
}[(context.bits, context.arch, context.os)]
class SyscallABI(ABI):
@@ -68,9 +88,9 @@ class SyscallABI(ABI):
The syscall ABI treats the syscall number as the zeroth argument,
which must be loaded into the specified register.
"""
def __init__(self, register_arguments, *a, **kw):
super(SyscallABI, self).__init__(register_arguments, *a, **kw)
self.syscall_register = register_arguments[0]
def __init__(self, *a, **kw):
super(SyscallABI, self).__init__(*a, **kw)
self.syscall_register = self.register_arguments[0]
class SigreturnABI(SyscallABI):
"""
@@ -81,26 +101,31 @@ class SigreturnABI(SyscallABI):
returns = False
linux_i386 = ABI([], 4, 0)
linux_amd64 = ABI(['rdi','rsi','rdx','rcx','r8','r9'], 8, 0)
linux_arm = ABI(['r0', 'r1', 'r2', 'r3'], 8, 0)
linux_aarch64 = ABI(['x0', 'x1', 'x2', 'x3'], 16, 0)
linux_mips = ABI(['$a0','$a1','$a2','$a3'], 4, 0)
linux_i386 = ABI('esp', [], 4, 0)
linux_amd64 = ABI('rsp', ['rdi','rsi','rdx','rcx','r8','r9'], 8, 0)
linux_arm = ABI('sp', ['r0', 'r1', 'r2', 'r3'], 8, 0)
linux_aarch64 = ABI('sp', ['x0', 'x1', 'x2', 'x3'], 16, 0)
linux_mips = ABI('$sp', ['$a0','$a1','$a2','$a3'], 4, 0)
linux_ppc = ABI('sp', ['r3', 'r4', 'r5', 'r6', 'r7', 'r8', 'r9', 'r10'], 4, 0)
linux_ppc64 = ABI('sp', ['r3', 'r4', 'r5', 'r6', 'r7', 'r8', 'r9', 'r10'], 8, 0)
linux_i386_syscall = SyscallABI(['eax', 'ebx', 'ecx', 'edx', 'esi', 'edi', 'ebp'], 4, 0)
linux_amd64_syscall = SyscallABI(['rax','rdi', 'rsi', 'rdx', 'r10', 'r8', 'r9'], 8, 0)
linux_arm_syscall = SyscallABI(['r7', 'r0', 'r1', 'r2', 'r3', 'r4', 'r5', 'r6'], 4, 0)
linux_aarch64_syscall = SyscallABI(['x8', 'x0', 'x1', 'x2', 'x3', 'x4', 'x5', 'x6'], 16, 0)
linux_mips_syscall = ABI(['$v0', '$a0','$a1','$a2','$a3'], 4, 0)
linux_i386_syscall = SyscallABI('esp', ['eax', 'ebx', 'ecx', 'edx', 'esi', 'edi', 'ebp'], 4, 0)
linux_amd64_syscall = SyscallABI('rsp', ['rax', 'rdi', 'rsi', 'rdx', 'r10', 'r8', 'r9'], 8, 0)
linux_arm_syscall = SyscallABI('sp', ['r7', 'r0', 'r1', 'r2', 'r3', 'r4', 'r5', 'r6'], 4, 0)
linux_aarch64_syscall = SyscallABI('sp', ['x8', 'x0', 'x1', 'x2', 'x3', 'x4', 'x5', 'x6'], 16, 0)
linux_mips_syscall = SyscallABI('$sp', ['$v0','$a0','$a1','$a2','$a3'], 4, 0)
linux_ppc_syscall = ABI('sp', ['r0', 'r3', 'r4', 'r5', 'r6', 'r7', 'r8', 'r9'], 4, 0)
linux_ppc64_syscall = ABI('sp', ['r0', 'r3', 'r4', 'r5', 'r6', 'r7', 'r8', 'r9'], 8, 0)
linux_i386_sigreturn = SigreturnABI(['eax'], 4, 0)
linux_amd64_sigreturn = SigreturnABI(['rax'], 4, 0)
linux_arm_sigreturn = SigreturnABI(['r7'], 4, 0)
linux_i386_sigreturn = SigreturnABI('esp', ['eax'], 4, 0)
linux_amd64_sigreturn = SigreturnABI('rsp', ['rax'], 4, 0)
linux_arm_sigreturn = SigreturnABI('sp', ['r7'], 4, 0)
linux_aarch64_sigreturn = SigreturnABI('sp', ['x8'], 16, 0)
windows_i386 = ABI([], 4, 0)
windows_amd64 = ABI(['rcx','rdx','r8','r9'], 32, 32)
windows_i386 = ABI('esp', [], 4, 0)
windows_amd64 = ABI('rsp', ['rcx','rdx','r8','r9'], 32, 32)
# Fake ABIs used by SROP
linux_i386_srop = ABI(['eax'], 4, 0)
linux_amd64_srop = ABI(['rax'], 4, 0)
linux_arm_srop = ABI(['r7'], 4, 0)
linux_i386_srop = ABI('esp', ['eax'], 4, 0)
linux_amd64_srop = ABI('rsp', ['rax'], 4, 0)
linux_arm_srop = ABI('sp', ['r7'], 4, 0)
-723
View File
@@ -1,723 +0,0 @@
"""Provides utilities for interacting with Android devices via the Android Debug Bridge.
"""
import glob
import os
import platform
import re
import shutil
import tempfile
import time
import dateutil.parser
from . import atexit
from . import tubes
from .context import context
from .context import LocalContext
from .device import Device
from .log import getLogger
from .util import misc
log = getLogger(__name__)
def adb(argv, *a, **kw):
"""Returns the output of an ADB subcommand."""
if isinstance(argv, (str, unicode)):
argv = [argv]
log.debug("$ " + ' '.join(context.adb + argv))
return tubes.process.process(context.adb + argv, *a, **kw).recvall()
def root():
"""Restarts adbd as root."""
log.info("Enabling root on %s" % context.device)
with context.quiet:
reply = adb('root')
if 'already running as root' in reply:
return
elif not reply or 'restarting adbd as root' in reply:
with context.quiet:
wait_for_device()
else:
log.error("Could not run as root:\n%s" % reply)
def reboot(wait=True):
"""Reboots the device."""
log.info('Rebooting device %s' % context.device)
with context.quiet:
adb('reboot')
if wait:
wait_for_device()
def reboot_bootloader():
"""Reboots the device to the bootloader."""
log.info('Rebooting %s to bootloader' % context.device)
with context.quiet:
adb('reboot-bootloader')
class AdbDevice(Device):
"""Encapsulates information about a connected device."""
def __init__(self, serial, type, port, product='unknown', model='unknown', device='unknown'):
self.serial = serial
self.type = type
self.port = port
self.product = product
self.model = model.replace('_', ' ')
self.device = device
if product == 'unknown':
return
with context.local(device=serial):
abi = str(properties.ro.product.cpu.abi)
context.clear()
context.arch = str(abi)
self.arch = context.arch
self.bits = context.bits
self.endian = context.endian
def __str__(self):
return self.serial
def __repr__(self):
fields = ['serial', 'type', 'port', 'product', 'model', 'device']
return '%s(%s)' % (self.__class__.__name__,
', '.join(('%s=%r' % (field, getattr(self, field)) for field in fields)))
@staticmethod
def from_adb_output(line):
fields = line.split()
"""
Example output:
ZX1G22LM7G device usb:336789504X product:shamu model:Nexus_6 device:shamu features:cmd,shell_v2
84B5T15A29020449 device usb:336855040X product:angler model:Nexus_6P device:angler
0062741b0e54b353 unauthorized usb:337641472X
"""
# The last few fields need to be split at colons.
split = lambda x: x.split(':')[-1]
fields[3:] = list(map(split, fields[3:]))
return AdbDevice(*fields[:6])
@context.quiet
def devices(serial=None):
"""Returns a list of ``Device`` objects corresponding to the connected devices."""
lines = adb(['devices', '-l'])
result = []
for line in lines.splitlines():
# Skip the first 'List of devices attached' line, and the final empty line.
if 'List of devices' in line or not line.strip():
continue
device = AdbDevice.from_adb_output(line)
if device.serial == serial:
return device
result.append(device)
return tuple(result)
@LocalContext
def wait_for_device(kick=False):
"""Waits for a device to be connected."""
with log.waitfor("Waiting for device to come online") as w:
with context.quiet:
if kick:
try:
adb(['reconnect'])
except Exception:
pass
adb('wait-for-device')
for device in devices():
if context.device == device:
return device
break
else:
log.error("Could not find any devices")
with context.local(device=device):
# There may be multiple devices, so context.device is
# insufficient. Pick the first device reported.
w.success('%s (%s %s %s)' % (device,
product(),
build(),
_build_date()))
return context.device
def disable_verity():
"""Disables dm-verity on the device."""
with log.waitfor("Disabling dm-verity on %s" % context.device) as w:
root()
with context.quiet:
reply = adb('disable-verity')
if 'Verity already disabled' in reply:
return
elif 'Now reboot your device' in reply:
reboot(wait=True)
else:
log.error("Could not disable verity:\n%s" % reply)
def remount():
"""Remounts the filesystem as writable."""
with log.waitfor("Remounting filesystem on %s" % context.device) as w:
disable_verity()
root()
with context.quiet:
reply = adb('remount')
if 'remount succeeded' not in reply:
log.error("Could not remount filesystem:\n%s" % reply)
def unroot():
"""Restarts adbd as AID_SHELL."""
log.info("Unrooting %s" % context.device)
with context.quiet:
reply = adb('unroot')
if 'restarting adbd as non root' not in reply:
log.error("Could not run as root:\n%s" % reply)
def pull(remote_path, local_path=None):
"""Download a file from the device.
Arguments:
remote_path(str): Path or directory of the file on the device.
local_path(str): Path to save the file to.
Uses the file's name by default.
"""
if local_path is None:
local_path = os.path.basename(remote_path)
msg = "Pulling %r from %r" % (remote_path, local_path)
if context.log_level == 'debug':
msg += ' (%s)' % context.device
result = ''
with log.waitfor(msg) as w:
with context.quiet:
args = context.adb + ['pull', remote_path, local_path]
io = tubes.process.process(args)
result = io.recvall()
if 0 != io.poll(block=True):
log.error(result)
return result
def push(local_path, remote_path):
"""Upload a file to the device.
Arguments:
local_path(str): Path to the local file to push.
remote_path(str): Path or directory to store the file on the device.
"""
msg = "Pushing %r to %r" % (local_path, remote_path)
if context.log_level == 'debug':
msg += ' (%s)' % context.device
with log.waitfor(msg) as w:
with context.quiet:
args = context.adb + ['push', local_path, remote_path]
io = tubes.process.process(args)
result = io.recvall()
if 0 != io.poll(block=True):
log.error(result)
return result
@context.quiet
def read(path, target=None):
"""Download a file from the device, and extract its contents.
Arguments:
path(str): Path to the file on the device.
target(str): Optional, location to store the file.
Uses a temporary file by default.
"""
with tempfile.NamedTemporaryFile() as temp:
target = target or temp.name
pull(path, target)
result = misc.read(target)
return result
@context.quiet
def write(path, data=''):
"""Create a file on the device with the provided contents.
Arguments:
path(str): Path to the file on the device
data(str): Contents to store in the file
"""
with tempfile.NamedTemporaryFile() as temp:
misc.write(temp.name, data)
push(temp.name, path)
def process(argv, *a, **kw):
"""Execute a process on the device.
See ``pwnlib.tubes.process.process`` documentation for more info.
Returns:
A ``process`` tube.
"""
argv = argv or []
if isinstance(argv, (str, unicode)):
argv = [argv]
display = argv
argv = context.adb + ['shell'] + argv
kw.setdefault('display', display)
kw.setdefault('where', 'Android')
return tubes.process.process(argv, *a, **kw)
def interactive(**kw):
"""Spawns an interactive shell."""
return shell(**kw).interactive()
def shell(**kw):
"""Returns an interactive shell."""
return process([], **kw)
@context.quiet
def which(name):
"""Retrieves the full path to a binary in ``PATH`` on the device"""
return process(['which', name]).recvall().strip()
def whoami():
return process(['whoami']).recvall().strip()
def forward(port):
"""Sets up a port to forward to the device."""
tcp_port = 'tcp:%s' % port
start_forwarding = adb(['forward', tcp_port, tcp_port])
atexit.register(lambda: adb(['forward', '--remove', tcp_port]))
@context.quiet
def logcat(stream=False):
"""Reads the system log file.
By default, causes logcat to exit after reading the file.
Arguments:
stream(bool): If ``True``, the contents are streamed rather than
read in a one-shot manner. Default is ``False``.
Returns:
If ``stream`` is ``False``, returns a string containing the log data.
Otherwise, it returns a ``tube`` connected to the log output.
"""
if stream:
return process(['logcat'])
else:
return adb(['logcat', '-d'])
def pidof(name):
"""Returns a list of PIDs for the named process."""
with context.quiet:
io = process(['pidof', name])
data = io.recvall().split()
return list(map(int, data))
def proc_exe(pid):
"""Returns the full path of the executable for the provided PID."""
with context.quiet:
io = process(['readlink','-e','/proc/%d/exe' % pid])
data = io.recvall().strip()
return data
def getprop(name=None):
"""Reads a properties from the system property store.
Arguments:
name(str): Optional, read a single property.
Returns:
If ``name`` is not specified, a ``dict`` of all properties is returned.
Otherwise, a string is returned with the contents of the named property.
"""
with context.quiet:
if name:
return process(['getprop', name]).recvall().strip()
result = process(['getprop']).recvall()
expr = r'\[([^\]]+)\]: \[(.*)\]'
props = {}
for line in result.splitlines():
if not line.startswith('['):
continue
name, value = re.search(expr, line).groups()
if value.isdigit():
value = int(value)
props[name] = value
return props
def setprop(name, value):
"""Writes a property to the system property store."""
return process(['setprop', name, value]).recvall().strip()
def listdir(directory='/'):
"""Returns a list containing the entries in the provided directory.
Note:
Because ``adb shell`` is used to retrieve the listing, shell
environment variable expansion and globbing are in effect.
"""
io = process(['find', directory, '-maxdepth', '1', '-print0'])
data = io.recvall()
paths = filter(len, data.split('\x00'))
relpaths = [os.path.relpath(path, directory) for path in paths]
if '.' in relpaths:
relpaths.remove('.')
return relpaths
def fastboot(args, *a, **kw):
"""Executes a fastboot command.
Returns:
The command output.
"""
serial = context.device
if not serial:
log.error("Unknown device")
return tubes.process.process(['fastboot', '-s', serial] + list(args), **kw).recvall()
def fingerprint():
"""Returns the device build fingerprint."""
return str(properties.ro.build.fingerprint)
def product():
"""Returns the device product identifier."""
return str(properties.ro.build.product)
def build():
"""Returns the Build ID of the device."""
return str(properties.ro.build.id)
def unlock_bootloader():
"""Unlocks the bootloader of the device.
Note:
This requires physical interaction with the device.
"""
adb(['reboot-bootloader'])
fastboot(['oem', 'unlock'])
fastboot(['continue'])
class Kernel(object):
_kallsyms = None
@property
def address(self):
return self.symbols['_text']
@property
@context.quiet
def symbols(self):
"""Returns a dictionary of kernel symbols"""
result = {}
for line in self.kallsyms.splitlines():
fields = line.split()
address = int(fields[0], 16)
name = fields[-1]
result[name] = address
return result
@property
@context.quiet
def kallsyms(self):
"""Returns the raw output of kallsyms"""
if not self._kallsyms:
self._kallsyms = {}
root()
write('/proc/sys/kernel/kptr_restrict', '1')
self._kallsyms = read('/proc/kallsyms')
return self._kallsyms
@property
@context.quiet
def version(self):
"""Returns the kernel version of the device."""
root()
return read('/proc/version').strip()
@property
@context.quiet
def cmdline(self):
root()
return read('/proc/cmdline').strip()
@property
@context.quiet
def lastmsg(self):
root()
if 'last_kmsg' in listdir('/proc'):
return read('/proc/last_kmsg')
if 'console-ramoops' in listdir('/sys/fs/pstore/'):
return read('/sys/fs/pstore/console-ramoops')
def enable_uart(self):
"""Reboots the device with kernel logging to the UART enabled."""
model = str(properties.ro.product.model)
known_commands = {
'Nexus 4': None,
'Nexus 5': None,
'Nexus 6': 'oem config console enable',
'Nexus 5X': None,
'Nexus 6P': 'oem uart enable',
'Nexus 7': 'oem uart-on',
}
with log.waitfor('Enabling kernel UART') as w:
if model not in known_commands:
log.error("Device UART is unsupported.")
command = known_commands[model]
if command is None:
w.success('Always enabled')
return
# Check the current commandline, it may already be enabled.
if any(s.startswith('console=tty') for s in self.cmdline.split()):
w.success("Already enabled")
return
# Need to be root
with context.local(device=context.device):
# Save off the command line before rebooting to the bootloader
cmdline = kernel.cmdline
reboot_bootloader()
# Wait for device to come online
while context.device not in fastboot(['devices',' -l']):
time.sleep(0.5)
# Try the 'new' way
fastboot(command.split())
fastboot(['continue'])
wait_for_device()
kernel = Kernel()
class Property(object):
def __init__(self, name=None):
self.__dict__['_name'] = name
def __str__(self):
return getprop(self._name).strip()
def __repr__(self):
return repr(str(self))
def __getattr__(self, attr):
if self._name:
attr = '%s.%s' % (self._name, attr)
return Property(attr)
def __setattr__(self, attr, value):
if attr in self.__dict__:
return super(Property, self).__setattr__(attr, value)
if self._name:
attr = '%s.%s' % (self._name, attr)
setprop(attr, value)
properties = Property()
def _build_date():
"""Returns the build date in the form YYYY-MM-DD as a string"""
as_string = getprop('ro.build.date')
as_datetime = dateutil.parser.parse(as_string)
return as_datetime.strftime('%Y-%b-%d')
def find_ndk_project_root(source):
'''Given a directory path, find the topmost project root.
tl;dr "foo/bar/jni/baz.cpp" ==> "foo/bar"
'''
ndk_directory = os.path.abspath(source)
while ndk_directory != '/':
if os.path.exists(os.path.join(ndk_directory, 'jni')):
break
ndk_directory = os.path.dirname(ndk_directory)
else:
return None
return ndk_directory
_android_mk_template = '''
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := poc
LOCAL_SRC_FILES := %(local_src_files)s
include $(BUILD_EXECUTABLE)
'''.lstrip()
_application_mk_template = '''
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
APP_ABI:= %(app_abi)s
APP_PLATFORM:=%(app_platform)s
'''.lstrip()
def _generate_ndk_project(file_list, abi='arm-v7a', platform_version=21):
# Create our project root
root = tempfile.mkdtemp()
if not isinstance(file_list, (list, tuple)):
file_list = [file_list]
# Copy over the source file(s)
jni_directory = os.path.join(root, 'jni')
os.mkdir(jni_directory)
for file in file_list:
shutil.copy(file, jni_directory)
# Create the directories
# Populate Android.mk
local_src_files = ' '.join(list(map(os.path.basename, file_list)))
Android_mk = os.path.join(jni_directory, 'Android.mk')
with open(Android_mk, 'w+') as f:
f.write(_android_mk_template % locals())
# Populate Application.mk
app_abi = abi
app_platform = 'android-%s' % platform_version
Application_mk = os.path.join(jni_directory, 'Application.mk')
with open(Application_mk, 'w+') as f:
f.write(_application_mk_template % locals())
return root
def compile(source):
"""Compile a source file or project with the Android NDK."""
# Ensure that we can find the NDK.
ndk = os.environ.get('NDK', None)
if ndk is None:
log.error('$NDK must be set to the Android NDK directory')
ndk_build = os.path.join(ndk, 'ndk-build')
# Determine whether the source is an NDK project or a single source file.
project = find_ndk_project_root(source)
if not project:
project = _generate_ndk_project(source,
str(properties.ro.product.cpu.abi),
str(properties.ro.build.version.sdk))
# Remove any output files
lib = os.path.join(project, 'libs')
if os.path.exists(lib):
shutil.rmtree(lib)
# Build the project
io = tubes.process.process(ndk_build, cwd=os.path.join(project, 'jni'))
result = io.recvall()
if 0 != io.poll():
log.error("Build failed:\n%s" % result)
# Find all of the output files
output = glob.glob(os.path.join(lib, '*', '*'))
return output[0]
class Partition(object):
def __init__(self, path, name, blocks=0):
self.path = path
self.name = name
self.blocks = blocks
self.size = blocks * 1024
@property
def data(self):
with log.waitfor('Fetching %r partition (%s)' % (self.name, self.path)):
return read(self.path)
class Partitions(object):
@property
@context.quiet
def by_name_dir(self):
cmd = ['shell','find /dev/block/platform -type d -name by-name']
return adb(cmd).strip()
@context.quiet
def __dir__(self):
return list(self)
@context.quiet
def __iter__(self):
root()
# Find all named partitions
for name in listdir(self.by_name_dir):
yield name
@context.quiet
def __getattr__(self, attr):
for name in self:
if name == attr:
break
else:
raise AttributeError("No partition %r" % attr)
path = os.path.join(self.by_name_dir, name)
# Find the actual path of the device
devpath = process(['readlink', '-n', path]).recvall()
devname = os.path.basename(devpath)
# Get the size of the partition
for line in read('/proc/partitions').splitlines():
if not line.strip():
continue
major, minor, blocks, name = line.split(None, 4)
if devname == name:
break
else:
log.error("Could not find size of partition %r" % name)
return Partition(devpath, attr, int(blocks))
partitions = Partitions()
+4
View File
@@ -0,0 +1,4 @@
from __future__ import absolute_import
from pwnlib.adb.adb import *
from pwnlib.adb.protocol import Client
+1383
View File
File diff suppressed because it is too large. Load diff
+5
View File
@@ -0,0 +1,5 @@
"""
This file exists only for backward compatibility
"""
from pwnlib.protocols.adb import AdbClient
Client = AdbClient
+101 -24
View File
@@ -1,18 +1,74 @@
#!/usr/bin/env python2
"""
Pwntools exposes several magic command-line arguments and environment
variables when operating in `from pwn import *` mode.
The arguments extracted from the command-line and removed from ``sys.argv``.
Arguments can be set by appending them to the command-line, or setting
them in the environment prefixed by ``PWNLIB_``.
The easiest example is to enable more verbose debugging. Just set ``DEBUG``.
.. code-block:: bash
$ PWNLIB_DEBUG=1 python exploit.py
$ python exploit.py DEBUG
These arguments are automatically extracted, regardless of their name, and
exposed via :mod:`pwnlib.args.args`, which is exposed as the global variable
:data:`args`. Arguments which ``pwntools`` reserves internally are not exposed
this way.
.. code-block:: bash
$ python -c 'from pwn import *; print args' A=1 B=Hello HOST=1.2.3.4 DEBUG
defaultdict(<type 'str'>, {'A': '1', 'HOST': '1.2.3.4', 'B': 'Hello'})
This is very useful for conditional code, for example determining whether to
run an exploit locally or to connect to a remote server. Arguments which are
not specified evaluate to an empty string.
.. code-block:: python
if args['REMOTE']:
io = remote('exploitme.com', 4141)
else:
io = process('./pwnable')
The full list of supported "magic arguments" and their effects are listed
below.
"""
from __future__ import absolute_import
import collections
import logging
import os
import string
import sys
from . import term
from .context import context
from pwnlib import term
from pwnlib.context import context
class PwnlibArgs(collections.defaultdict):
def __getattr__(self, attr):
return self[attr]
args = PwnlibArgs(str)
term_mode = True
args = collections.defaultdict(str)
env_prefix = 'PWNLIB_'
free_form = True
# Check to see if we were invoked as one of the 'pwn xxx' scripts.
# If so, we don't want to remove e.g. "SYS_" from the end of the command
# line, as this breaks things like constgrep.
import pwnlib.commandline
basename = os.path.basename(sys.argv[0])
if basename == 'pwn' or basename in pwnlib.commandline.__all__:
free_form = False
def isident(s):
"""
@@ -42,46 +98,67 @@ def asbool(s):
else:
raise ValueError('must be integer or boolean: %r' % s)
def set_log_level(x):
def LOG_LEVEL(x):
"""Sets the logging verbosity used via ``context.log_level``,
e.g. ``LOG_LEVEL=debug``.
"""
with context.local(log_level=x):
context.defaults['log_level']=context.log_level
def set_log_file(x):
def LOG_FILE(x):
"""Sets a log file to be used via ``context.log_file``, e.g.
``LOG_FILE=./log.txt``"""
context.log_file=x
def set_log_level_error(x):
set_log_level('error')
def SILENT(x):
"""Sets the logging verbosity to ``error`` which silences most
output."""
LOG_LEVEL('error')
def set_log_level_debug(x):
set_log_level('debug')
def DEBUG(x):
"""Sets the logging verbosity to ``debug`` which displays much
more information, including logging each byte sent by tubes."""
LOG_LEVEL('debug')
def set_noterm(v):
def NOTERM(v):
"""Disables pretty terminal settings and animations."""
if asbool(v):
global term_mode
term_mode = False
def set_timeout(v):
def TIMEOUT(v):
"""Sets a timeout for tube operations (in seconds) via
``context.timeout``, e.g. ``TIMEOUT=30``"""
context.defaults['timeout'] = int(v)
def set_randomize(v):
def RANDOMIZE(v):
"""Enables randomization of various pieces via ``context.randomize``"""
context.defaults['randomize'] = asbool(v)
def set_aslr(v):
def NOASLR(v):
"""Disables ASLR via ``context.aslr``"""
context.defaults['aslr'] = not asbool(v)
def set_noptrace(v):
def NOPTRACE(v):
"""Disables facilities which require ``ptrace`` such as ``gdb.attach()``
statements, via ``context.noptrace``."""
context.defaults['noptrace'] = asbool(v)
def STDERR(v):
"""Sends logging to ``stderr`` by default, instead of ``stdout``"""
context.log_console = sys.stderr
hooks = {
'LOG_LEVEL': set_log_level,
'LOG_FILE': set_log_file,
'DEBUG': set_log_level_debug,
'NOTERM': set_noterm,
'SILENT': set_log_level_error,
'RANDOMIZE': set_randomize,
'TIMEOUT': set_timeout,
'NOASLR': set_aslr,
'NOPTRACE': set_noptrace,
'LOG_LEVEL': LOG_LEVEL,
'LOG_FILE': LOG_FILE,
'DEBUG': DEBUG,
'NOTERM': NOTERM,
'SILENT': SILENT,
'RANDOMIZE': RANDOMIZE,
'TIMEOUT': TIMEOUT,
'NOASLR': NOASLR,
'NOPTRACE': NOPTRACE,
'STDERR': STDERR,
}
def initialize():
@@ -113,7 +190,7 @@ def initialize():
sys.argv.remove(orig)
hooks[arg](value)
elif isident(arg):
elif free_form and isident(arg):
sys.argv.remove(orig)
args[arg] = value
+210 -95
View File
@@ -27,8 +27,8 @@ Assembly
Finally, :func:`asm` is used to assemble shellcode provided by ``pwntools``
in the :mod:`shellcraft` module.
>>> asm(shellcraft.sh())
'jhh///sh/binj\x0bX\x89\xe31\xc9\x99\xcd\x80'
>>> asm(shellcraft.nop())
'\x90'
Disassembly
------------------------
@@ -39,6 +39,8 @@ Disassembly
' 0: b8 0b 00 00 00 mov eax,0xb'
"""
from __future__ import absolute_import
import errno
import os
import platform
@@ -53,11 +55,11 @@ from glob import glob
from os import environ
from os import path
from . import atexit
from . import shellcraft
from .context import LocalContext
from .context import context
from .log import getLogger
from pwnlib import atexit
from pwnlib import shellcraft
from pwnlib.context import LocalContext
from pwnlib.context import context
from pwnlib.log import getLogger
log = getLogger(__name__)
@@ -66,6 +68,75 @@ __all__ = ['asm', 'cpp', 'disasm', 'make_elf', 'make_elf_from_assembly']
_basedir = path.split(__file__)[0]
_incdir = path.join(_basedir, 'data', 'includes')
def dpkg_search_for_binutils(arch, util):
"""Use dpkg to search for any available assemblers which will work.
Returns:
A list of candidate package names.
::
>>> pwnlib.asm.dpkg_search_for_binutils('aarch64', 'as')
['binutils-aarch64-linux-gnu']
"""
# Example output:
# $ dpkg -S 'arm*linux*-as'
# binutils-arm-linux-gnu: /usr/bin/arm-linux-gnu-as
# binutils-arm-linux-gnueabihf: /usr/bin/arm-linux-gnueabihf-as
# binutils-arm-linux-gnueabihf: /usr/x86_64-linux-gnu/arm-linux-gnueabihf/include/dis-asm.h
# binutils-arm-linux-gnu: /usr/x86_64-linux-gnu/arm-linux-gnu/include/dis-asm.h
packages = []
try:
filename = 'bin/%s*linux*-%s' % (arch, util)
output = subprocess.check_output(['dpkg','-S',filename])
for line in output.strip().splitlines():
package, path = line.split(':', 1)
packages.append(package)
except OSError:
pass
except subprocess.CalledProcessError:
pass
return packages
def print_binutils_instructions(util, context):
"""On failure to find a binutils utility, inform the user of a way
they can get it easily.
Doctest:
>>> context.clear(arch = 'amd64')
>>> pwnlib.asm.print_binutils_instructions('as', context)
Traceback (most recent call last):
...
PwnlibException: Could not find 'as' installed for ContextType(arch = 'amd64', bits = 64, endian = 'little')
Try installing binutils for this architecture:
$ sudo apt-get install binutils
"""
# This links to our instructions on how to manually install binutils
# for several architectures.
instructions = 'https://docs.pwntools.com/en/stable/install/binutils.html'
# However, if we can directly provide a useful command, go for it.
binutils_arch = {
'amd64': 'x86_64',
'arm': 'armeabi',
'thumb': 'armeabi',
}.get(context.arch, context.arch)
packages = dpkg_search_for_binutils(binutils_arch, util)
if packages:
instructions = '$ sudo apt-get install %s' % packages[0]
log.error("""
Could not find %(util)r installed for %(context)s
Try installing binutils for this architecture:
%(instructions)s
""".strip() % locals())
@LocalContext
def which_binutils(util):
"""
@@ -75,8 +146,9 @@ def which_binutils(util):
Examples:
>>> import platform
>>> which_binutils = pwnlib.asm.which_binutils
>>> which_binutils('as', arch=platform.machine())
'.../bin/as'
'.../bin/...as'
>>> which_binutils('as', arch='arm') #doctest: +ELLIPSIS
'.../bin/arm-...-as'
>>> which_binutils('as', arch='powerpc') #doctest: +ELLIPSIS
@@ -119,23 +191,20 @@ def which_binutils(util):
for arch in arches:
for gutil in utils:
# e.g. objdump
if arch is None: pattern = gutil
if arch is None:
pattern = gutil
# e.g. aarch64-linux-gnu-objdump
else: pattern = '%s*linux*-%s' % (arch,gutil)
else:
pattern = '%s*linux*-%s' % (arch,gutil)
for dir in environ['PATH'].split(':'):
res = sorted(glob(path.join(dir, pattern)))
if res:
return res[0]
locals()['context'] = context
log.warning("""
Could not find %(util)r installed for %(context)s
Try installing binutils for this architecture:
https://docs.pwntools.com/en/stable/install/binutils.html
""".strip() % locals())
raise Exception('Could not find %(util)r installed for %(context)s' % locals())
# No dice!
print_binutils_instructions(util, context)
checked_assembler_version = defaultdict(lambda: False)
@@ -331,16 +400,14 @@ def cpp(shellcode):
Examples:
.. doctest::
>>> cpp("mov al, SYS_setresuid", arch = "i386", os = "linux")
'mov al, 164\n'
>>> cpp("weee SYS_setresuid", arch = "arm", os = "linux")
'weee (0+164)\n'
>>> cpp("SYS_setresuid", arch = "thumb", os = "linux")
'(0+164)\n'
>>> cpp("SYS_setresuid", os = "freebsd")
'311\n'
>>> cpp("mov al, SYS_setresuid", arch = "i386", os = "linux")
'mov al, 164\n'
>>> cpp("weee SYS_setresuid", arch = "arm", os = "linux")
'weee (0+164)\n'
>>> cpp("SYS_setresuid", arch = "thumb", os = "linux")
'(0+164)\n'
>>> cpp("SYS_setresuid", os = "freebsd")
'311\n'
"""
arch = context.arch
os = context.os
@@ -357,17 +424,39 @@ def cpp(shellcode):
return _run(cmd, code).strip('\n').rstrip() + '\n'
@LocalContext
def make_elf_from_assembly(assembly, vma = None, extract=False, shared = False):
r"""
Builds an ELF file with the specified assembly as its
executable code.
def make_elf_from_assembly(assembly,
vma=None,
extract=False,
shared=False,
strip=False,
**kwargs):
r"""make_elf_from_assembly(assembly, vma=None, extract=None, shared=False, strip=False, **kwargs) -> str
Builds an ELF file with the specified assembly as its executable code.
This differs from :func:`.make_elf` in that all ELF symbols are preserved,
such as labels and local variables. Use :func:`.make_elf` if size matters.
Additionally, the default value for ``extract`` in :func:`.make_elf` is
different.
Note:
This is effectively a wrapper around :func:`.asm`. with setting
``extract=False``, ``vma=0x10000000``, and marking the resulting
file as executable (``chmod +x``).
Note:
ELF files created with `arch=thumb` will prepend an ARM stub
which switches to Thumb mode.
Arguments:
assembly(str): Assembly
assembly(str): Assembly code to build into an ELF
vma(int): Load address of the binary
extract(bool): Whether to return the data extracted from the file created,
or the path to it.
(Default: ``0x10000000``, or ``0`` if ``shared=True``)
extract(bool): Extract the full ELF data from the file.
(Default: ``False``)
shared(bool): Create a shared library
(Default: ``False``)
kwargs(dict): Arguments to pass to :func:`.asm`.
Returns:
@@ -376,6 +465,9 @@ def make_elf_from_assembly(assembly, vma = None, extract=False, shared = False):
Example:
This example shows how to create a shared library, and load it via
``LD_PRELOAD``.
>>> context.clear()
>>> context.arch = 'amd64'
>>> sc = 'push rbp; mov rbp, rsp;'
@@ -384,6 +476,18 @@ def make_elf_from_assembly(assembly, vma = None, extract=False, shared = False):
>>> solib = make_elf_from_assembly(sc, shared=1)
>>> subprocess.check_output(['echo', 'World'], env={'LD_PRELOAD': solib})
'Hello\nWorld\n'
The same thing can be done with :func:`.make_elf`, though the sizes
are different. They both
>>> file_a = make_elf(asm('nop'), extract=True)
>>> file_b = make_elf_from_assembly('nop', extract=True)
>>> file_a[:4] == file_b[:4]
True
>>> len(file_a) < 0x200
True
>>> len(file_b) > 0x1000
True
"""
if shared and vma:
log.error("Cannot specify a VMA for a shared library.")
@@ -400,38 +504,44 @@ def make_elf_from_assembly(assembly, vma = None, extract=False, shared = False):
if not assembly.startswith(to_thumb):
assembly = to_thumb + assembly
path = asm(assembly, vma = vma, extract = extract, shared = shared)
result = asm(assembly, vma = vma, shared = shared, extract = False, **kwargs)
if not extract:
os.chmod(path, 0755)
os.chmod(result, 0755)
else:
with open(result, 'rb') as io:
result = io.read()
return path
return result
@LocalContext
def make_elf(data, vma = None, strip=True, extract=True, shared=False):
r"""
Builds an ELF file with the specified binary data as its
executable code.
def make_elf(data,
vma=None,
strip=True,
extract=True,
shared=False):
r"""make_elf(data, vma=None, strip=True, extract=True, shared=False, **kwargs) -> str
Builds an ELF file with the specified binary data as its executable code.
Arguments:
data(str): Assembled code
vma(int): Load address for the ELF file
strip(bool): Strip the resulting ELF file. Only matters if ``extract=False``.
(Default: ``True``)
extract(bool): Extract the assembly from the ELF file.
If ``False``, the path of the ELF file is returned.
(Default: ``True``)
shared(bool): Create a Dynamic Shared Object (DSO, i.e. a ``.so``)
which can be loaded via ``dlopen`` or ``LD_PRELOAD``.
Examples:
This example creates an i386 ELF that just does
execve('/bin/sh',...).
>>> context.clear()
>>> context.arch = 'i386'
>>> context.bits = 32
>>> filename = tempfile.mktemp()
>>> context.clear(arch='i386')
>>> bin_sh = '6a68682f2f2f73682f62696e89e331c96a0b5899cd80'.decode('hex')
>>> data = make_elf(bin_sh)
>>> with open(filename,'wb+') as f:
... f.write(data)
... f.flush()
>>> os.chmod(filename,0777)
>>> filename = make_elf(bin_sh, extract=False)
>>> p = process(filename)
>>> p.sendline('echo Hello; exit')
>>> p.recvline()
@@ -499,38 +609,37 @@ def make_elf(data, vma = None, strip=True, extract=True, shared=False):
@LocalContext
def asm(shellcode, vma = 0, extract = True, shared = False):
r"""asm(code, vma = 0, extract = True, ...) -> str
r"""asm(code, vma = 0, extract = True, shared = False, ...) -> str
Runs :func:`cpp` over a given shellcode and then assembles it into bytes.
To see which architectures or operating systems are supported,
look in :mod:`pwnlib.contex`.
To support all these architecture, we bundle the GNU assembler
and objcopy with pwntools.
Assembling shellcode requires that the GNU assembler is installed
for the target architecture.
See :doc:`Installing Binutils </install/binutils>` for more information.
Arguments:
shellcode(str): Assembler code to assemble.
vma(int): Virtual memory address of the beginning of assembly
extract(bool): Extract the raw assembly bytes from the assembled
file. If ``False``, returns the path to an ELF file
with the assembly embedded.
Kwargs:
Any arguments/properties that can be set on ``context``
shellcode(str): Assembler code to assemble.
vma(int): Virtual memory address of the beginning of assembly
extract(bool): Extract the raw assembly bytes from the assembled
file. If :const:`False`, returns the path to an ELF file
with the assembly embedded.
shared(bool): Create a shared object.
kwargs(dict): Any attributes on :data:`.context` can be set, e.g.set
``arch='arm'``.
Examples:
.. doctest::
>>> asm("mov eax, SYS_select", arch = 'i386', os = 'freebsd')
'\xb8]\x00\x00\x00'
>>> asm("mov eax, SYS_select", arch = 'amd64', os = 'linux')
'\xb8\x17\x00\x00\x00'
>>> asm("mov rax, SYS_select", arch = 'amd64', os = 'linux')
'H\xc7\xc0\x17\x00\x00\x00'
>>> asm("mov r0, #SYS_select", arch = 'arm', os = 'linux', bits=32)
'R\x00\xa0\xe3'
>>> asm("mov eax, SYS_select", arch = 'i386', os = 'freebsd')
'\xb8]\x00\x00\x00'
>>> asm("mov eax, SYS_select", arch = 'amd64', os = 'linux')
'\xb8\x17\x00\x00\x00'
>>> asm("mov rax, SYS_select", arch = 'amd64', os = 'linux')
'H\xc7\xc0\x17\x00\x00\x00'
>>> asm("mov r0, #SYS_select", arch = 'arm', os = 'linux', bits=32)
'R\x00\xa0\xe3'
"""
result = ''
@@ -562,11 +671,20 @@ def asm(shellcode, vma = 0, extract = True, shared = False):
ldflags = ['-z', 'execstack', '-o', step3, step2]
if vma:
ldflags += ['--section-start=.shellcode=%#x' % vma,
'--entry=%#x' % vma,
'-z', 'max-page-size=4096',
'-z', 'common-page-size=4096']
'--entry=%#x' % vma]
elif shared:
ldflags += ['-shared', '-init=_start']
# In order to ensure that we generate ELF files with 4k pages,
# and not e.g. 65KB pages (AArch64), force the page size.
# This is a result of GNU Gold being silly.
#
# Introduced in commit dd58f409 without supporting evidence,
# this shouldn't do anything except keep consistent page granularity
# across architectures.
ldflags += ['-z', 'max-page-size=4096',
'-z', 'common-page-size=4096']
_run(linker + ldflags)
elif file(step2,'rb').read(4) == '\x7fELF':
@@ -618,24 +736,21 @@ def disasm(data, vma = 0, byte = True, offset = True, instructions = True):
Examples:
.. doctest::
>>> print disasm('b85d000000'.decode('hex'), arch = 'i386')
0: b8 5d 00 00 00 mov eax,0x5d
>>> print disasm('b85d000000'.decode('hex'), arch = 'i386', byte = 0)
0: mov eax,0x5d
>>> print disasm('b85d000000'.decode('hex'), arch = 'i386', byte = 0, offset = 0)
mov eax,0x5d
>>> print disasm('b817000000'.decode('hex'), arch = 'amd64')
0: b8 17 00 00 00 mov eax,0x17
>>> print disasm('48c7c017000000'.decode('hex'), arch = 'amd64')
0: 48 c7 c0 17 00 00 00 mov rax,0x17
>>> print disasm('04001fe552009000'.decode('hex'), arch = 'arm')
0: e51f0004 ldr r0, [pc, #-4] ; 0x4
4: 00900052 addseq r0, r0, r2, asr r0
>>> print disasm('4ff00500'.decode('hex'), arch = 'thumb', bits=32)
0: f04f 0005 mov.w r0, #5
>>>
>>> print disasm('b85d000000'.decode('hex'), arch = 'i386')
0: b8 5d 00 00 00 mov eax,0x5d
>>> print disasm('b85d000000'.decode('hex'), arch = 'i386', byte = 0)
0: mov eax,0x5d
>>> print disasm('b85d000000'.decode('hex'), arch = 'i386', byte = 0, offset = 0)
mov eax,0x5d
>>> print disasm('b817000000'.decode('hex'), arch = 'amd64')
0: b8 17 00 00 00 mov eax,0x17
>>> print disasm('48c7c017000000'.decode('hex'), arch = 'amd64')
0: 48 c7 c0 17 00 00 00 mov rax,0x17
>>> print disasm('04001fe552009000'.decode('hex'), arch = 'arm')
0: e51f0004 ldr r0, [pc, #-4] ; 0x4
4: 00900052 addseq r0, r0, r2, asr r0
>>> print disasm('4ff00500'.decode('hex'), arch = 'thumb', bits=32)
0: f04f 0005 mov.w r0, #5
"""
result = ''
@@ -669,7 +784,7 @@ def disasm(data, vma = 0, byte = True, offset = True, instructions = True):
res = _run(objcopy + [step1, step2])
output0 = subprocess.check_output(objdump + [step2])
output0 = _run(objdump + [step2])
output1 = output0.split('<.text>:\n')
if len(output1) != 2:
+2 -1
View File
@@ -2,12 +2,13 @@
Analogous to atexit, this module allows the programmer to register functions to
be run if an unhandled exception occurs.
"""
from __future__ import absolute_import
import sys
import threading
import traceback
from .context import context
from pwnlib.context import context
__all__ = ['register', 'unregister']
+2 -1
View File
@@ -7,12 +7,13 @@ this replacement module also defines :func:`unregister`.
This module also fixes a the issue that exceptions raised by an exit handler is
printed twice when the standard :mod:`atexit` is used.
"""
from __future__ import absolute_import
import sys
import threading
import traceback
from .context import context
from pwnlib.context import context
__all__ = ['register', 'unregister']
+22 -1
View File
@@ -1 +1,22 @@
# empty
#!/usr/bin/env python2
__all__ = [
'asm',
'checksec',
'common',
'constgrep',
'cyclic',
'debug',
'disasm',
'disablenx',
'elfdiff',
'elfpatch',
'errno',
'hex',
'main',
'phd',
'pwnstrip',
'scramble',
'shellcraft',
'unhex',
'update'
]
+13 -7
View File
@@ -1,13 +1,15 @@
#!/usr/bin/env python2
from __future__ import absolute_import
import argparse
import sys
from pwn import *
from pwnlib.commandline import common
from . import common
parser = argparse.ArgumentParser(
description = 'Assemble shellcode into bytes'
parser = common.parser_commands.add_parser(
'asm',
help = 'Assemble shellcode into bytes'
)
parser.add_argument(
@@ -91,10 +93,13 @@ parser.add_argument(
action='store_true'
)
def main():
args = parser.parse_args()
def main(args):
tty = args.output.isatty()
if args.infile.isatty() and not args.lines:
parser.print_usage()
sys.exit(1)
data = '\n'.join(args.lines) or args.infile.read()
output = asm(data.replace(';', '\n'))
fmt = args.format or ('hex' if tty else 'raw')
@@ -123,4 +128,5 @@ def main():
if tty and fmt is not 'raw':
args.output.write('\n')
if __name__ == '__main__': main()
if __name__ == '__main__':
pwnlib.commandline.common.main(__file__)
+9 -9
View File
@@ -1,16 +1,16 @@
#!/usr/bin/env python2
from __future__ import absolute_import
import argparse
import sys
from pwn import *
from pwnlib.commandline import common
from . import common
parser = argparse.ArgumentParser(
description = 'Check binary security settings'
parser = common.parser_commands.add_parser(
'checksec',
help = 'Check binary security settings'
)
parser.add_argument(
'elf',
nargs='*',
@@ -26,8 +26,7 @@ parser.add_argument(
help='File to check (for compatibility with checksec.sh)'
)
def main():
args = parser.parse_args()
def main(args):
files = args.elf or args.elf2 or []
if not files:
@@ -37,4 +36,5 @@ def main():
for f in files:
e = ELF(f.name)
if __name__ == '__main__': main()
if __name__ == '__main__':
pwnlib.commandline.common.main(__file__)
+12 -2
View File
@@ -1,10 +1,10 @@
import argparse
import os
import sys
import pwnlib
from pwnlib.context import context
pwnlib.log.console.stream = sys.stderr
choices = map(str, [16,32,64])
choices += list(context.oses)
choices += list(context.architectures)
@@ -20,3 +20,13 @@ def context_arg(arg):
try: context.endian = arg
except Exception: pass
return arg
parser = argparse.ArgumentParser(description='Pwntools Command-line Interface',
prog='pwn')
parser_commands = parser.add_subparsers(dest='command')
def main(file=sys.argv[0]):
import pwnlib.commandline.main
name = os.path.splitext(os.path.basename(file))[0]
sys.argv.insert(1, name)
pwnlib.commandline.main.main()
+13 -8
View File
@@ -1,14 +1,19 @@
#!/usr/bin/env python2
from __future__ import absolute_import
import argparse
import os
import re
from pwn import *
from . import common
import pwnlib
pwnlib.args.free_form = False
p = argparse.ArgumentParser(
description = "Looking up constants from header files.\n\nExample: constgrep -c freebsd -m ^PROT_ '3 + 4'",
from pwn import *
from pwnlib.commandline import common
p = common.parser_commands.add_parser(
'constgrep',
help = "Looking up constants from header files.\n\nExample: constgrep -c freebsd -m ^PROT_ '3 + 4'",
formatter_class = argparse.RawDescriptionHelpFormatter,
)
@@ -55,9 +60,7 @@ p.add_argument(
help = 'The os/architecture/endianness/bits the shellcode will run in (default: linux/i386), choose from: %s' % common.choices,
)
def main():
args = p.parse_args()
def main(args):
if args.exact:
# This is the simple case
print cpp(args.exact).strip()
@@ -75,6 +78,7 @@ def main():
else:
matcher = re.compile(args.regex)
# Evaluate the given constant
if args.constant:
try:
@@ -134,4 +138,5 @@ def main():
print
print '(%s) == %s' % (' | '.join(k for v, k in good), args.constant)
if __name__ == '__main__': main()
if __name__ == '__main__':
pwnlib.commandline.common.main(__file__)
+12 -7
View File
@@ -1,14 +1,19 @@
#!/usr/bin/env python2
from __future__ import absolute_import
import argparse
import string
import sys
import pwnlib
pwnlib.args.free_form = False
from pwn import *
from pwnlib.commandline import common
from . import common
parser = argparse.ArgumentParser(
description = "Cyclic pattern creator/finder"
parser = common.parser_commands.add_parser(
'cyclic',
help = "Cyclic pattern creator/finder"
)
parser.add_argument(
@@ -50,8 +55,7 @@ group.add_argument(
help = 'Number of characters to print'
)
def main():
args = parser.parse_args()
def main(args):
alphabet = args.alphabet
subsize = args.length
@@ -90,4 +94,5 @@ def main():
if sys.stdout.isatty():
sys.stdout.write('\n')
if __name__ == '__main__': main()
if __name__ == '__main__':
pwnlib.commandline.common.main(__file__)
+69
View File
@@ -0,0 +1,69 @@
#!/usr/bin/env python2
from __future__ import absolute_import
import argparse
import sys
from pwn import *
from pwnlib.commandline import common
parser = common.parser_commands.add_parser(
'debug',
help = 'Debug a binary in GDB'
)
parser.add_argument(
'-x', metavar='GDBSCRIPT',
type=file,
help='Execute GDB commands from this file.'
)
parser.add_argument(
'--pid',
type=int,
help="PID to attach to"
)
parser.add_argument(
'-c', '--context',
metavar = 'context',
action = 'append',
type = common.context_arg,
choices = common.choices,
help = 'The os/architecture/endianness/bits the shellcode will run in (default: linux/i386), choose from: %s' % common.choices,
)
parser.add_argument(
'--exec', type=file, dest='executable',
help='File to debug'
)
parser.add_argument(
'--process', metavar='PROCESS_NAME',
help='Name of the process to attach to (e.g. "bash")'
)
def main(args):
gdbscript = ''
if args.x:
gdbscript = args.x.read()
if context.os == 'android':
context.device = adb.wait_for_device()
if args.executable:
context.binary = ELF(args.executable.name)
target = context.binary.path
elif args.pid:
target = int(args.pid)
elif args.process:
if context.os == 'android':
target = adb.pidof(process)
else:
target = pidof(process)
else:
parser.print_usage()
return 1
if args.pid or args.process:
gdb.attach(target, gdbscript=gdbscript)
else:
gdb.debug(target, gdbscript=gdbscript).interactive()
if __name__ == '__main__':
pwnlib.commandline.common.main(__file__)
+25
View File
@@ -0,0 +1,25 @@
#!/usr/bin/env python2
from __future__ import absolute_import
from pwn import *
from pwnlib.commandline import common
parser = common.parser_commands.add_parser(
'disablenx',
help = 'Disable NX for an ELF binary'
)
parser.add_argument(
'elf',
nargs='+',
type=file,
help='Files to check'
)
def main(args):
for f in args.elf:
e = ELF(f.name)
e.disable_nx()
ELF(e.path)
if __name__ == '__main__':
pwnlib.commandline.common.main(__file__)
+12 -8
View File
@@ -1,14 +1,19 @@
#!/usr/bin/env python2
from __future__ import absolute_import
import argparse
import string
import sys
import pwnlib
pwnlib.args.free_form = False
from pwn import *
from pwnlib.commandline import common
from . import common
parser = argparse.ArgumentParser(
description = 'Disassemble bytes into text format'
parser = common.parser_commands.add_parser(
'disasm',
help = 'Disassemble bytes into text format'
)
parser.add_argument(
@@ -52,9 +57,7 @@ parser.add_argument(
)
def main():
args = parser.parse_args()
def main(args):
if len(args.hex) > 0:
dat = ''.join(args.hex)
dat = dat.translate(None, string.whitespace)
@@ -88,4 +91,5 @@ def main():
print disasm(dat, vma=safeeval.const(args.address))
if __name__ == '__main__': main()
if __name__ == '__main__':
pwnlib.commandline.common.main(__file__)
+15 -6
View File
@@ -1,12 +1,18 @@
#!/usr/bin/env python2
import shutil
from __future__ import absolute_import
import shutil
from argparse import ArgumentParser
from subprocess import CalledProcessError
from subprocess import check_output
from tempfile import NamedTemporaryFile
import pwnlib
pwnlib.args.free_form = False
from pwn import *
from pwnlib.commandline import common
def dump(objdump, path):
n = NamedTemporaryFile(delete=False)
@@ -20,13 +26,15 @@ def diff(a,b):
except CalledProcessError as e:
return e.output
p = ArgumentParser()
p = common.parser_commands.add_parser(
'elfdiff',
help = 'Compare two ELF files'
)
p.add_argument('a')
p.add_argument('b')
def main():
a = p.parse_args()
def main(a):
with context.silent:
x = ELF(a.a)
y = ELF(a.b)
@@ -49,4 +57,5 @@ def main():
print diff(x, y)
if __name__ == '__main__': main()
if __name__ == '__main__':
pwnlib.commandline.common.main(__file__)
+14 -4
View File
@@ -1,8 +1,19 @@
#!/usr/bin/env python2
from __future__ import absolute_import
import argparse
import sys
import pwnlib
pwnlib.args.free_form = False
from pwn import *
from pwnlib.commandline import common
p = common.parser_commands.add_parser(
'elfpatch',
help = 'Patch an ELF file'
)
p = argparse.ArgumentParser()
p.add_argument('elf',help="File to patch")
@@ -10,9 +21,7 @@ p.add_argument('offset',help="Offset to patch in virtual address (hex encoded)")
p.add_argument('bytes',help='Bytes to patch (hex encoded)')
def main():
a = p.parse_args()
def main(a):
if not a.offset.startswith('0x'):
a.offset = '0x' + a.offset
@@ -25,4 +34,5 @@ def main():
elf.write(offset, bytes)
sys.stdout.write(elf.get_data())
if __name__ == '__main__': main()
if __name__ == '__main__':
pwnlib.commandline.common.main(__file__)
+10 -6
View File
@@ -1,17 +1,20 @@
from __future__ import absolute_import
import argparse
import os
parser = argparse.ArgumentParser(
description = 'Prints out error messages'
from pwnlib.commandline import common
parser = common.parser_commands.add_parser(
'errno',
help = 'Prints out error messages'
)
parser.add_argument(
'error', help='Error message or value', type=str
)
def main():
args, unknown = parser.parse_known_args()
def main(args):
try:
value = int(args.error, 0)
@@ -40,4 +43,5 @@ def main():
print '#define', name, value
print os.strerror(value)
if __name__ == '__main__': main()
if __name__ == '__main__':
pwnlib.commandline.common.main(__file__)
+11 -5
View File
@@ -1,18 +1,24 @@
#!/usr/bin/env python2
from __future__ import absolute_import
import argparse
import sys
parser = argparse.ArgumentParser(description='''
Hex-encodes data provided on the command line or via stdin.
from pwnlib.commandline import common
parser = common.parser_commands.add_parser(
'hex',
help = '''
Hex-encodes data provided on the command line or stdin
''')
parser.add_argument('data', nargs='*',
help='Data to convert into hex')
def main():
args = parser.parse_args()
def main(args):
if not args.data:
print sys.stdin.read().encode('hex')
else:
print ' '.join(args.data).encode('hex')
if __name__ == '__main__': main()
if __name__ == '__main__':
pwnlib.commandline.common.main(__file__)
+54
View File
@@ -0,0 +1,54 @@
from __future__ import absolute_import
import sys
from pwnlib.commandline import asm
from pwnlib.commandline import checksec
from pwnlib.commandline import common
from pwnlib.commandline import constgrep
from pwnlib.commandline import cyclic
from pwnlib.commandline import debug
from pwnlib.commandline import disasm
from pwnlib.commandline import disablenx
from pwnlib.commandline import elfdiff
from pwnlib.commandline import elfpatch
from pwnlib.commandline import errno
from pwnlib.commandline import hex
from pwnlib.commandline import phd
from pwnlib.commandline import pwnstrip
from pwnlib.commandline import scramble
from pwnlib.commandline import shellcraft
from pwnlib.commandline import template
from pwnlib.commandline import unhex
from pwnlib.commandline import update
from pwnlib.commandline.common import parser
from pwnlib.context import context
commands = {
'asm': asm.main,
'checksec': checksec.main,
'constgrep': constgrep.main,
'cyclic': cyclic.main,
'debug': debug.main,
'disasm': disasm.main,
'disablenx': disablenx.main,
'elfdiff': elfdiff.main,
'elfpatch': elfpatch.main,
'errno': errno.main,
'hex': hex.main,
'phd': phd.main,
'pwnstrip': pwnstrip.main,
'scramble': scramble.main,
'shellcraft': shellcraft.main,
'template': template.main,
'unhex': unhex.main,
'update': update.main,
}
def main():
args = parser.parse_args()
with context.local(log_console = sys.stderr):
commands[args.command](args)
if __name__ == '__main__':
main()
+13 -7
View File
@@ -1,12 +1,19 @@
#!/usr/bin/env python2
from __future__ import absolute_import
import argparse
import os
import sys
from pwn import *
import pwnlib
pwnlib.args.free_form = False
parser = argparse.ArgumentParser(
description = 'Pwnlib HexDump'
from pwn import *
from pwnlib.commandline import common
parser = common.parser_commands.add_parser(
'phd',
help = 'Pwnlib HexDump'
)
parser.add_argument(
@@ -64,9 +71,7 @@ def asint(s):
else:
return int(s, 10)
def main():
args = parser.parse_args()
def main(args):
infile = args.file
width = asint(args.width)
skip = asint(args.skip)
@@ -95,4 +100,5 @@ def main():
except (KeyboardInterrupt, IOError):
pass
if __name__ == '__main__': main()
if __name__ == '__main__':
pwnlib.commandline.common.main(__file__)
+11 -10
View File
@@ -1,12 +1,16 @@
from __future__ import absolute_import
import argparse
import pwnlib
pwnlib.args.free_form = False
from pwn import *
from pwnlib.commandline import common
from . import common
p = argparse.ArgumentParser(
description = 'Strip binaries for CTF usage',
formatter_class = argparse.RawDescriptionHelpFormatter,
p = common.parser_commands.add_parser(
'pwnstrip',
help = 'Strip binaries for CTF usage',
)
g = p.add_argument_group("actions")
@@ -15,9 +19,7 @@ g.add_argument('-p', '--patch', metavar='FUNCTION', help="Patch function", actio
p.add_argument('-o', '--output', type=file, default=sys.stdout)
p.add_argument('file', type=file)
def main():
args = p.parse_args()
def main(args):
if not (args.patch or args.build_id):
sys.stderr.write("Must specify at least one action\n")
sys.stderr.write(p.format_usage())
@@ -48,6 +50,5 @@ def main():
args.output.write(result)
if __name__ == '__main__':
main()
pwnlib.commandline.common.main(__file__)
+13 -8
View File
@@ -1,15 +1,19 @@
from __future__ import absolute_import
import argparse
import sys
import pwnlib
pwnlib.args.free_form = False
from pwn import *
from pwnlib.commandline import common
from . import common
parser = argparse.ArgumentParser(
description = 'Shellcode encoder'
parser = common.parser_commands.add_parser(
'scramble',
help = 'Shellcode encoder'
)
parser.add_argument(
"-f", "--format",
help="Output format (defaults to hex for ttys, otherwise raw)",
@@ -68,8 +72,7 @@ parser.add_argument(
action='store_true'
)
def main():
args = parser.parse_args()
def main(args):
tty = args.output.isatty()
if sys.stdin.isatty():
@@ -100,4 +103,6 @@ def main():
if tty and fmt is not 'raw':
args.output.write('\n')
if __name__ == '__main__': main()
if __name__ == '__main__':
pwnlib.commandline.common.main(__file__)
+37 -34
View File
@@ -1,24 +1,16 @@
#!/usr/bin/env python2
from __future__ import absolute_import
import argparse
import os
import sys
import types
import pwnlib
pwnlib.args.free_form = False
from pwn import *
from . import common
r = text.red
g = text.green
b = text.blue
banner = '\n'.join([' ' + r('____') + ' ' + g('_') + ' ' + r('_') + ' ' + g('_') + ' ' + b('__') + ' ' + r('_'),
' ' + r('/ ___|') + g('| |__') + ' ' + b('___') + r('| |') + ' ' + g('|') + ' ' + b('___') + ' ' + r('_ __') + ' ' + g('__ _') + ' ' + b('/ _|') + ' ' + r('|_'),
' ' + r('\___ \\') + g('| \'_ \\') + ' ' + b('/ _ \\') + ' ' + r('|') + ' ' + g('|') + b('/ __|') + ' ' + r('\'__/') + ' ' + g('_` |') + ' ' + b('|_') + r('| __|'),
' ' + r('___) |') + ' ' + g('| | |') + ' ' + b('__/') + ' ' + r('|') + ' ' + g('|') + ' ' + b('(__') + r('| |') + ' ' + g('| (_| |') + ' ' + b('_|') + ' ' + r('|_'),
' ' + r('|____/') + g('|_| |_|') + b('\\___|') + r('_|') + g('_|') + b('\\___|') + r('_|') + ' ' + g('\\__,_|') + b('_|') + ' ' + r('\\__|'),
'\n'
])
from pwnlib.commandline import common
# ____ _ _ _ __ _
@@ -37,9 +29,10 @@ def _string(s):
out.append('\\x%02x' % co)
return '"' + ''.join(out) + '"\n'
p = argparse.ArgumentParser(
description = 'Microwave shellcode -- Easy, fast and delicious',
formatter_class = argparse.RawDescriptionHelpFormatter,
p = common.parser_commands.add_parser(
'shellcraft',
help = 'Microwave shellcode -- Easy, fast and delicious',
)
@@ -68,21 +61,19 @@ p.add_argument(
'p',
'i', 'hexii',
'e', 'elf',
'd', 'escaped',
'default'],
default = 'default',
help = 'Output format (default: hex), choose from {r}aw, {s}tring, {c}-style array, {h}ex string, hex{i}i, {a}ssembly code, {p}reprocssed code',
help = 'Output format (default: hex), choose from {e}lf, {r}aw, {s}tring, {c}-style array, {h}ex string, hex{i}i, {a}ssembly code, {p}reprocssed code, escape{d} hex string',
)
p.add_argument(
'shellcode',
nargs = '?',
choices = shellcraft.templates,
metavar = 'shellcode',
help = 'The shellcode you want',
type = str
)
p.epilog = 'Available shellcodes are:\n' + '\n'.join(shellcraft.templates)
p.add_argument(
'args',
nargs = '*',
@@ -167,6 +158,12 @@ p.add_argument(
default=None
)
p.add_argument(
'-l', '--list',
action='store_true',
help='List available shellcodes, optionally provide a filter'
)
def get_template(name):
func = shellcraft
for attr in name.split('.'):
@@ -175,23 +172,27 @@ def get_template(name):
def is_not_a_syscall_template(name):
template_src = shellcraft._get_source(name)
return 'man 2' not in read(template_src)
return '/syscalls' not in template_src
def main():
# Banner must be added here so that it doesn't appear in the autodoc
# generation for command line tools
p.description = banner + p.description
args = p.parse_args()
if not args.shellcode:
def main(args):
if args.list:
templates = shellcraft.templates
if not args.syscalls:
if args.shellcode:
templates = filter(lambda a: args.shellcode in a, templates)
elif not args.syscalls:
templates = filter(is_not_a_syscall_template, templates)
print '\n'.join(templates)
exit()
if not args.shellcode:
common.parser.print_usage()
exit()
if args.shellcode not in shellcraft.templates:
log.error("Unknown shellcraft template %r. Use --list to see available shellcodes." % args.shellcode)
func = get_template(args.shellcode)
if args.show:
@@ -326,17 +327,19 @@ def main():
sys.exit(0)
if args.format in ['s', 'str', 'string']:
code = _string(code) + '"\n'
code = _string(code)
elif args.format == 'c':
code = '{' + ', '.join(map(hex, bytearray(code))) + '}' + '\n'
elif args.format in ['h', 'hex']:
code = pwnlib.util.fiddling.enhex(code) + '\n'
elif args.format in ['i', 'hexii']:
code = hexii(code) + '\n'
elif args.format in ['d', 'escaped']:
code = ''.join('\\x%02x' % ord(c) for c in code) + '\n'
if not sys.stdin.isatty():
args.out.write(sys.stdin.read())
args.out.write(code)
if __name__ == '__main__': main()
if __name__ == '__main__':
pwnlib.commandline.common.main(__file__)
+64
View File
@@ -0,0 +1,64 @@
#!/usr/bin/env python2
from __future__ import absolute_import
import re
from pwn import *
from pwnlib.commandline import common
from mako.lookup import TemplateLookup
parser = common.parser_commands.add_parser(
'template',
help = 'Generate an exploit template'
)
parser.add_argument('exe', nargs='?', help='Target binary')
parser.add_argument('--host', help='Remote host / SSH server')
parser.add_argument('--port', help='Remote port / SSH port')
parser.add_argument('--user', help='SSH Username')
parser.add_argument('--pass', help='SSH Password', dest='password')
parser.add_argument('--path', help='Remote path of file on SSH server')
def main(args):
cache = None
if cache:
cache = os.path.join(context.cache_dir, 'mako')
lookup = TemplateLookup(
directories = [os.path.join(pwnlib.data.path, 'templates')],
module_directory = cache
)
# For the SSH scenario, check that the binary is at the
# same path on the remote host.
if args.user:
if not args.path or args.exe:
log.error("Must specify --path or a exe")
s = ssh(args.user, args.host, args.port or 22, args.password or None)
s.download(args.path or args.exe)
if not args.exe:
args.exe = os.path.basename(args.path)
template = lookup.get_template('pwnup.mako')
output = template.render(args.exe,
args.host,
args.port,
args.user,
args.password,
args.path)
# Fix Mako formatting bs
output = re.sub('\n\n\n', '\n\n', output)
print output
if not sys.stdout.isatty():
try: os.fchmod(sys.stdout.fileno(), 0700)
except OSError: pass
if __name__ == '__main__':
pwnlib.commandline.common.main(__file__)
+12 -5
View File
@@ -1,23 +1,30 @@
#!/usr/bin/env python2
from __future__ import absolute_import
import argparse
import sys
from string import whitespace
parser = argparse.ArgumentParser(description='''
from pwnlib.commandline import common
parser = common.parser_commands.add_parser(
'unhex',
help = '''
Decodes hex-encoded data provided on the command line or via stdin.
''')
parser.add_argument('hex', nargs='*',
help='Hex bytes to decode')
def main():
args = parser.parse_args()
def main(args):
try:
if not args.hex:
s = sys.stdin.read().translate(None, whitespace)
sys.stdout.write(s.decode('hex'))
else:
sys.stdout.write(''.join(sys.argv[1:]).decode('hex'))
sys.stdout.write(''.join(args.hex).decode('hex'))
except TypeError, e:
sys.stderr.write(str(e) + '\n')
if __name__ == '__main__': main()
if __name__ == '__main__':
pwnlib.commandline.common.main(__file__)
+31
View File
@@ -0,0 +1,31 @@
#!/usr/bin/env python2
from __future__ import absolute_import
import subprocess
import pwnlib
pwnlib.args.free_form = False
from pwn import *
from pwnlib.commandline import common
p = common.parser_commands.add_parser(
'update',
help = 'Check for pwntools updates'
)
p.add_argument('--install', action='store_true', help='''
Install the update automatically.
''')
p.add_argument('--pre', action='store_true', help='''
Check for pre-releases.
''')
def main(a):
result = pwnlib.update.perform_check(prerelease=a.pre)
if a.install:
subprocess.check_call(result, shell=False)
if __name__ == '__main__':
pwnlib.commandline.common.main(__file__)
+60
View File
@@ -0,0 +1,60 @@
# -*- coding: utf-8 -*-
"""Allows per-user and per-host configuration of Pwntools settings.
The list of configurable options includes all of the logging symbols
and colors, as well as all of the default values on the global context
object.
The configuration file is read from ``~/.pwn.conf`` and ``/etc/pwn.conf``.
The configuration file is only read in ``from pwn import *`` mode, and not
when used in library mode (``import pwnlib``). To read the configuration
file in library mode, invoke :func:`.config.initialize`.
The ``context`` section supports complex types, at least as far as is
supported by ``pwnlib.util.safeeval.expr``.
::
[log]
success.symbol=😎
error.symbol=☠
info.color=blue
[context]
adb_port=4141
randomize=1
timeout=60
terminal=['x-terminal-emulator', '-e']
"""
from __future__ import absolute_import
import ConfigParser
import os
registered_configs = {}
def register_config(section, function):
"""Registers a configuration section.
Arguments:
section(str): Named configuration section
function(callable): Function invoked with a dictionary of
``{option: value}`` for the entries in the section.
"""
registered_configs[section] = function
def initialize():
"""Read the configuration files."""
from pwnlib.log import getLogger
log = getLogger(__name__)
c = ConfigParser.ConfigParser()
c.read(['/etc/pwn.conf', os.path.expanduser('~/.pwn.conf')])
for section in c.sections():
if section not in registered_configs:
log.warn("Unknown configuration section %r" % section)
continue
settings = dict(c.items(section))
registered_configs[section](settings)
+20 -16
View File
@@ -39,14 +39,26 @@ Example:
... print int(constants.SYS_stat)
4
>>> with context.local(arch = 'i386', os = 'linux'):
... print constants.SYS_execve + constants.PROT_WRITE
13
>>> with context.local(arch = 'amd64', os = 'linux'):
... print constants.SYS_execve + constants.PROT_WRITE
61
>>> with context.local(arch = 'amd64', os = 'linux'):
... print constants.SYS_execve + constants.PROT_WRITE
61
"""
from __future__ import absolute_import
import importlib
import sys
from types import ModuleType
from ..context import context
from ..util import safeeval
from .constant import Constant
from pwnlib.constants.constant import Constant
from pwnlib.context import context
from pwnlib.util import safeeval
class ConstantsModule(ModuleType):
@@ -54,19 +66,6 @@ class ConstantsModule(ModuleType):
ModuleType specialization in order to automatically
route queries down to the correct module based on the
current context arch / os.
>>> with context.local(arch = 'i386', os = 'linux'):
... print constants.SYS_execve + constants.PROT_WRITE
13
>>> with context.local(arch = 'amd64', os = 'linux'):
... print constants.SYS_execve + constants.PROT_WRITE
61
>>> with context.local(arch = 'amd64', os = 'linux'):
... print constants.SYS_execve + constants.PROT_WRITE
61
>>> False
True
"""
Constant = Constant
@@ -137,6 +136,11 @@ class ConstantsModule(ModuleType):
if not isinstance(string, str):
return string
simple = getattr(self, string, None)
if simple is not None:
return simple
key = context.os, context.arch
if key not in self._env_store:
self._env_store[key] = {key: getattr(self, key) for key in dir(self) if not key.endswith('__')}
-111
View File
@@ -1,5 +1,4 @@
from pwnlib.constants.constant import Constant
__NR_io_setup = Constant('__NR_io_setup',0)
__NR_io_destroy = Constant('__NR_io_destroy',1)
__NR_io_submit = Constant('__NR_io_submit',2)
@@ -259,63 +258,6 @@ __NR_process_vm_readv = Constant('__NR_process_vm_readv',270)
__NR_process_vm_writev = Constant('__NR_process_vm_writev',271)
__NR_kcmp = Constant('__NR_kcmp',272)
__NR_finit_module = Constant('__NR_finit_module',273)
__NR_open = Constant('__NR_open',1024)
__NR_link = Constant('__NR_link',1025)
__NR_unlink = Constant('__NR_unlink',1026)
__NR_mknod = Constant('__NR_mknod',1027)
__NR_chmod = Constant('__NR_chmod',1028)
__NR_chown = Constant('__NR_chown',1029)
__NR_mkdir = Constant('__NR_mkdir',1030)
__NR_rmdir = Constant('__NR_rmdir',1031)
__NR_lchown = Constant('__NR_lchown',1032)
__NR_access = Constant('__NR_access',1033)
__NR_rename = Constant('__NR_rename',1034)
__NR_readlink = Constant('__NR_readlink',1035)
__NR_symlink = Constant('__NR_symlink',1036)
__NR_utimes = Constant('__NR_utimes',1037)
__NR_stat = Constant('__NR_stat',1038)
__NR_lstat = Constant('__NR_lstat',1039)
__NR_pipe = Constant('__NR_pipe',1040)
__NR_dup2 = Constant('__NR_dup2',1041)
__NR_epoll_create = Constant('__NR_epoll_create',1042)
__NR_inotify_init = Constant('__NR_inotify_init',1043)
__NR_eventfd = Constant('__NR_eventfd',1044)
__NR_signalfd = Constant('__NR_signalfd',1045)
__NR_sendfile64 = Constant('__NR_sendfile64',1046)
__NR_ftruncate64 = Constant('__NR_ftruncate64',1047)
__NR_truncate64 = Constant('__NR_truncate64',1048)
__NR_stat64 = Constant('__NR_stat64',1049)
__NR_lstat64 = Constant('__NR_lstat64',1050)
__NR_fstat64 = Constant('__NR_fstat64',1051)
__NR_fcntl64 = Constant('__NR_fcntl64',1052)
__NR_newfstatat = Constant('__NR_newfstatat',1054)
__NR_fstatfs64 = Constant('__NR_fstatfs64',1055)
__NR_statfs64 = Constant('__NR_statfs64',1056)
__NR_lseek64 = Constant('__NR_lseek64',1057)
__NR_mmap64 = Constant('__NR_mmap64',1058)
__NR_alarm = Constant('__NR_alarm',1059)
__NR_getpgrp = Constant('__NR_getpgrp',1060)
__NR_pause = Constant('__NR_pause',1061)
__NR_time = Constant('__NR_time',1062)
__NR_utime = Constant('__NR_utime',1063)
__NR_creat = Constant('__NR_creat',1064)
__NR_getdents = Constant('__NR_getdents',1065)
__NR_futimesat = Constant('__NR_futimesat',1066)
__NR_select = Constant('__NR_select',1067)
__NR_poll = Constant('__NR_poll',1068)
__NR_epoll_wait = Constant('__NR_epoll_wait',1069)
__NR_ustat = Constant('__NR_ustat',1070)
__NR_vfork = Constant('__NR_vfork',1071)
__NR_oldwait4 = Constant('__NR_oldwait4',1072)
__NR_recv = Constant('__NR_recv',1073)
__NR_send = Constant('__NR_send',1074)
__NR_bdflush = Constant('__NR_bdflush',1075)
__NR_umount = Constant('__NR_umount',1076)
__NR_uselib = Constant('__NR_uselib',1077)
__NR__sysctl = Constant('__NR__sysctl',1078)
__NR_fork = Constant('__NR_fork',1079)
__NR_syscalls = Constant('__NR_syscalls',(1079+1))
__NR_sigreturn = Constant('__NR_sigreturn',1999)
MAP_32BIT = Constant('MAP_32BIT',0x40)
INADDR_ANY = Constant('INADDR_ANY',0)
INADDR_BROADCAST = Constant('INADDR_BROADCAST',0xffffffff)
@@ -944,19 +886,14 @@ CC_N_BIT = Constant('CC_N_BIT',(1 << 31))
PCMASK = Constant('PCMASK',0)
SYS_accept = Constant('SYS_accept',202)
SYS_accept4 = Constant('SYS_accept4',242)
SYS_access = Constant('SYS_access',1033)
SYS_acct = Constant('SYS_acct',89)
SYS_add_key = Constant('SYS_add_key',217)
SYS_adjtimex = Constant('SYS_adjtimex',171)
SYS_alarm = Constant('SYS_alarm',1059)
SYS_bdflush = Constant('SYS_bdflush',1075)
SYS_bind = Constant('SYS_bind',200)
SYS_brk = Constant('SYS_brk',214)
SYS_capget = Constant('SYS_capget',90)
SYS_capset = Constant('SYS_capset',91)
SYS_chdir = Constant('SYS_chdir',49)
SYS_chmod = Constant('SYS_chmod',1028)
SYS_chown = Constant('SYS_chown',1029)
SYS_chroot = Constant('SYS_chroot',51)
SYS_clock_getres = Constant('SYS_clock_getres',114)
SYS_clock_gettime = Constant('SYS_clock_gettime',113)
@@ -965,17 +902,12 @@ SYS_clock_settime = Constant('SYS_clock_settime',112)
SYS_clone = Constant('SYS_clone',220)
SYS_close = Constant('SYS_close',57)
SYS_connect = Constant('SYS_connect',203)
SYS_creat = Constant('SYS_creat',1064)
SYS_delete_module = Constant('SYS_delete_module',106)
SYS_dup = Constant('SYS_dup',23)
SYS_dup2 = Constant('SYS_dup2',1041)
SYS_dup3 = Constant('SYS_dup3',24)
SYS_epoll_create = Constant('SYS_epoll_create',1042)
SYS_epoll_create1 = Constant('SYS_epoll_create1',20)
SYS_epoll_ctl = Constant('SYS_epoll_ctl',21)
SYS_epoll_pwait = Constant('SYS_epoll_pwait',22)
SYS_epoll_wait = Constant('SYS_epoll_wait',1069)
SYS_eventfd = Constant('SYS_eventfd',1044)
SYS_eventfd2 = Constant('SYS_eventfd2',19)
SYS_execve = Constant('SYS_execve',221)
SYS_exit = Constant('SYS_exit',93)
@@ -991,27 +923,20 @@ SYS_fchmodat = Constant('SYS_fchmodat',53)
SYS_fchown = Constant('SYS_fchown',55)
SYS_fchownat = Constant('SYS_fchownat',54)
SYS_fcntl = Constant('SYS_fcntl',25)
SYS_fcntl64 = Constant('SYS_fcntl64',1052)
SYS_fdatasync = Constant('SYS_fdatasync',83)
SYS_fgetxattr = Constant('SYS_fgetxattr',10)
SYS_flistxattr = Constant('SYS_flistxattr',13)
SYS_flock = Constant('SYS_flock',32)
SYS_fork = Constant('SYS_fork',1079)
SYS_fremovexattr = Constant('SYS_fremovexattr',16)
SYS_fsetxattr = Constant('SYS_fsetxattr',7)
SYS_fstat = Constant('SYS_fstat',80)
SYS_fstat64 = Constant('SYS_fstat64',1051)
SYS_fstatat64 = Constant('SYS_fstatat64',79)
SYS_fstatfs = Constant('SYS_fstatfs',44)
SYS_fstatfs64 = Constant('SYS_fstatfs64',1055)
SYS_fsync = Constant('SYS_fsync',82)
SYS_ftruncate = Constant('SYS_ftruncate',46)
SYS_ftruncate64 = Constant('SYS_ftruncate64',1047)
SYS_futex = Constant('SYS_futex',98)
SYS_futimesat = Constant('SYS_futimesat',1066)
SYS_getcpu = Constant('SYS_getcpu',168)
SYS_getcwd = Constant('SYS_getcwd',17)
SYS_getdents = Constant('SYS_getdents',1065)
SYS_getdents64 = Constant('SYS_getdents64',61)
SYS_getegid = Constant('SYS_getegid',177)
SYS_geteuid = Constant('SYS_geteuid',175)
@@ -1021,7 +946,6 @@ SYS_getitimer = Constant('SYS_getitimer',102)
SYS_get_mempolicy = Constant('SYS_get_mempolicy',236)
SYS_getpeername = Constant('SYS_getpeername',205)
SYS_getpgid = Constant('SYS_getpgid',155)
SYS_getpgrp = Constant('SYS_getpgrp',1060)
SYS_getpid = Constant('SYS_getpid',172)
SYS_getppid = Constant('SYS_getppid',173)
SYS_getpriority = Constant('SYS_getpriority',141)
@@ -1039,7 +963,6 @@ SYS_getuid = Constant('SYS_getuid',174)
SYS_getxattr = Constant('SYS_getxattr',8)
SYS_init_module = Constant('SYS_init_module',105)
SYS_inotify_add_watch = Constant('SYS_inotify_add_watch',27)
SYS_inotify_init = Constant('SYS_inotify_init',1043)
SYS_inotify_init1 = Constant('SYS_inotify_init1',26)
SYS_inotify_rm_watch = Constant('SYS_inotify_rm_watch',28)
SYS_io_cancel = Constant('SYS_io_cancel',3)
@@ -1053,9 +976,7 @@ SYS_io_submit = Constant('SYS_io_submit',2)
SYS_kexec_load = Constant('SYS_kexec_load',104)
SYS_keyctl = Constant('SYS_keyctl',219)
SYS_kill = Constant('SYS_kill',129)
SYS_lchown = Constant('SYS_lchown',1032)
SYS_lgetxattr = Constant('SYS_lgetxattr',9)
SYS_link = Constant('SYS_link',1025)
SYS_linkat = Constant('SYS_linkat',37)
SYS_listen = Constant('SYS_listen',201)
SYS_listxattr = Constant('SYS_listxattr',11)
@@ -1064,15 +985,11 @@ SYS_lookup_dcookie = Constant('SYS_lookup_dcookie',18)
SYS_lremovexattr = Constant('SYS_lremovexattr',15)
SYS_lseek = Constant('SYS_lseek',62)
SYS_lsetxattr = Constant('SYS_lsetxattr',6)
SYS_lstat = Constant('SYS_lstat',1039)
SYS_lstat64 = Constant('SYS_lstat64',1050)
SYS_madvise = Constant('SYS_madvise',233)
SYS_mbind = Constant('SYS_mbind',235)
SYS_migrate_pages = Constant('SYS_migrate_pages',238)
SYS_mincore = Constant('SYS_mincore',232)
SYS_mkdir = Constant('SYS_mkdir',1030)
SYS_mkdirat = Constant('SYS_mkdirat',34)
SYS_mknod = Constant('SYS_mknod',1027)
SYS_mknodat = Constant('SYS_mknodat',33)
SYS_mlock = Constant('SYS_mlock',228)
SYS_mlockall = Constant('SYS_mlockall',230)
@@ -1096,17 +1013,12 @@ SYS_munlock = Constant('SYS_munlock',229)
SYS_munlockall = Constant('SYS_munlockall',231)
SYS_munmap = Constant('SYS_munmap',215)
SYS_nanosleep = Constant('SYS_nanosleep',101)
SYS_newfstatat = Constant('SYS_newfstatat',1054)
SYS_nfsservctl = Constant('SYS_nfsservctl',42)
SYS_open = Constant('SYS_open',1024)
SYS_openat = Constant('SYS_openat',56)
SYS_pause = Constant('SYS_pause',1061)
SYS_perf_event_open = Constant('SYS_perf_event_open',241)
SYS_personality = Constant('SYS_personality',92)
SYS_pipe = Constant('SYS_pipe',1040)
SYS_pipe2 = Constant('SYS_pipe2',59)
SYS_pivot_root = Constant('SYS_pivot_root',41)
SYS_poll = Constant('SYS_poll',1068)
SYS_ppoll = Constant('SYS_ppoll',73)
SYS_prctl = Constant('SYS_prctl',167)
SYS_pread64 = Constant('SYS_pread64',67)
@@ -1119,21 +1031,17 @@ SYS_pwritev = Constant('SYS_pwritev',70)
SYS_quotactl = Constant('SYS_quotactl',60)
SYS_read = Constant('SYS_read',63)
SYS_readahead = Constant('SYS_readahead',213)
SYS_readlink = Constant('SYS_readlink',1035)
SYS_readlinkat = Constant('SYS_readlinkat',78)
SYS_readv = Constant('SYS_readv',65)
SYS_reboot = Constant('SYS_reboot',142)
SYS_recv = Constant('SYS_recv',1073)
SYS_recvfrom = Constant('SYS_recvfrom',207)
SYS_recvmmsg = Constant('SYS_recvmmsg',243)
SYS_recvmsg = Constant('SYS_recvmsg',212)
SYS_remap_file_pages = Constant('SYS_remap_file_pages',234)
SYS_removexattr = Constant('SYS_removexattr',14)
SYS_rename = Constant('SYS_rename',1034)
SYS_renameat = Constant('SYS_renameat',38)
SYS_request_key = Constant('SYS_request_key',218)
SYS_restart_syscall = Constant('SYS_restart_syscall',128)
SYS_rmdir = Constant('SYS_rmdir',1031)
SYS_rt_sigaction = Constant('SYS_rt_sigaction',134)
SYS_rt_sigpending = Constant('SYS_rt_sigpending',136)
SYS_rt_sigprocmask = Constant('SYS_rt_sigprocmask',135)
@@ -1152,14 +1060,11 @@ SYS_sched_setaffinity = Constant('SYS_sched_setaffinity',122)
SYS_sched_setparam = Constant('SYS_sched_setparam',118)
SYS_sched_setscheduler = Constant('SYS_sched_setscheduler',119)
SYS_sched_yield = Constant('SYS_sched_yield',124)
SYS_select = Constant('SYS_select',1067)
SYS_semctl = Constant('SYS_semctl',191)
SYS_semget = Constant('SYS_semget',190)
SYS_semop = Constant('SYS_semop',193)
SYS_semtimedop = Constant('SYS_semtimedop',192)
SYS_send = Constant('SYS_send',1074)
SYS_sendfile = Constant('SYS_sendfile',71)
SYS_sendfile64 = Constant('SYS_sendfile64',1046)
SYS_sendmsg = Constant('SYS_sendmsg',211)
SYS_sendto = Constant('SYS_sendto',206)
SYS_setdomainname = Constant('SYS_setdomainname',162)
@@ -1190,28 +1095,20 @@ SYS_shmdt = Constant('SYS_shmdt',197)
SYS_shmget = Constant('SYS_shmget',194)
SYS_shutdown = Constant('SYS_shutdown',210)
SYS_sigaltstack = Constant('SYS_sigaltstack',132)
SYS_signalfd = Constant('SYS_signalfd',1045)
SYS_signalfd4 = Constant('SYS_signalfd4',74)
SYS_sigreturn = Constant('SYS_sigreturn',1999)
SYS_socket = Constant('SYS_socket',198)
SYS_socketpair = Constant('SYS_socketpair',199)
SYS_splice = Constant('SYS_splice',76)
SYS_stat = Constant('SYS_stat',1038)
SYS_stat64 = Constant('SYS_stat64',1049)
SYS_statfs = Constant('SYS_statfs',43)
SYS_statfs64 = Constant('SYS_statfs64',1056)
SYS_swapoff = Constant('SYS_swapoff',225)
SYS_swapon = Constant('SYS_swapon',224)
SYS_symlink = Constant('SYS_symlink',1036)
SYS_symlinkat = Constant('SYS_symlinkat',36)
SYS_sync = Constant('SYS_sync',81)
SYS_sync_file_range2 = Constant('SYS_sync_file_range2',84)
SYS__sysctl = Constant('SYS__sysctl',1078)
SYS_sysinfo = Constant('SYS_sysinfo',179)
SYS_syslog = Constant('SYS_syslog',116)
SYS_tee = Constant('SYS_tee',77)
SYS_tgkill = Constant('SYS_tgkill',131)
SYS_time = Constant('SYS_time',1062)
SYS_timer_create = Constant('SYS_timer_create',107)
SYS_timer_delete = Constant('SYS_timer_delete',111)
SYS_timerfd_create = Constant('SYS_timerfd_create',85)
@@ -1223,20 +1120,12 @@ SYS_timer_settime = Constant('SYS_timer_settime',110)
SYS_times = Constant('SYS_times',153)
SYS_tkill = Constant('SYS_tkill',130)
SYS_truncate = Constant('SYS_truncate',45)
SYS_truncate64 = Constant('SYS_truncate64',1048)
SYS_umask = Constant('SYS_umask',166)
SYS_umount = Constant('SYS_umount',1076)
SYS_umount2 = Constant('SYS_umount2',39)
SYS_uname = Constant('SYS_uname',160)
SYS_unlink = Constant('SYS_unlink',1026)
SYS_unlinkat = Constant('SYS_unlinkat',35)
SYS_unshare = Constant('SYS_unshare',97)
SYS_uselib = Constant('SYS_uselib',1077)
SYS_ustat = Constant('SYS_ustat',1070)
SYS_utime = Constant('SYS_utime',1063)
SYS_utimensat = Constant('SYS_utimensat',88)
SYS_utimes = Constant('SYS_utimes',1037)
SYS_vfork = Constant('SYS_vfork',1071)
SYS_vhangup = Constant('SYS_vhangup',58)
SYS_vmsplice = Constant('SYS_vmsplice',75)
SYS_wait4 = Constant('SYS_wait4',260)
+158 -16
View File
@@ -4,12 +4,15 @@
Implements context management so that nested/scoped contexts and threaded
contexts work properly and as expected.
"""
from __future__ import absolute_import
import collections
import functools
import logging
import os
import platform
import socket
import stat
import string
import subprocess
import sys
@@ -18,8 +21,11 @@ import time
import socks
from ..device import Device
from ..timeout import Timeout
from pwnlib.config import register_config
from pwnlib.device import Device
from pwnlib.timeout import Timeout
__all__ = ['context', 'ContextType', 'Thread']
_original_socket = socket.socket
@@ -243,9 +249,10 @@ def _longest(d):
as it ensures the most complete match will be found.
>>> data = {'a': 1, 'bb': 2, 'ccc': 3}
>>> _longest(data) == data
>>> pwnlib.context._longest(data) == data
True
>>> for i in _longest(data): print i
>>> for i in pwnlib.context._longest(data):
... print i
ccc
bb
a
@@ -260,7 +267,7 @@ class ContextType(object):
r"""
Class for specifying information about the target machine.
Intended for use as a pseudo-singleton through the global
variable ``pwnlib.context.context``, available via
variable :data:`.context`, available via
``from pwn import *`` as ``context``.
The context is usually specified at the top of the Python file for clarity. ::
@@ -329,18 +336,22 @@ class ContextType(object):
'aslr': True,
'binary': None,
'bits': 32,
'buffer_size': 4096,
'delete_corefiles': False,
'device': os.getenv('ANDROID_SERIAL', None) or None,
'endian': 'little',
'kernel': None,
'log_level': logging.INFO,
'log_file': _devnull(),
'log_console': sys.stdout,
'randomize': False,
'rename_corefiles': True,
'newline': '\n',
'noptrace': False,
'os': 'linux',
'proxy': None,
'signed': False,
'terminal': None,
'terminal': tuple(),
'timeout': Timeout.maximum,
}
@@ -530,6 +541,18 @@ class ContextType(object):
level = None
return self.local(function, log_level=level)
def quietfunc(self, function):
"""Similar to :attr:`quiet`, but wraps a whole function."""
@functools.wraps(function)
def wrapper(*a, **kw):
level = 'error'
if context.log_level <= logging.DEBUG:
level = None
with self.local(function, log_level=level):
return function(*a, **kw)
return wrapper
@property
def verbose(self):
"""Enable all logging within the enclosed scope.
@@ -549,6 +572,7 @@ class ContextType(object):
Examples:
>>> # Default value
>>> context.clear()
>>> context.arch == 'i386'
True
>>> context.arch = 'arm'
@@ -675,7 +699,7 @@ class ContextType(object):
"""
ASLR settings for new processes.
If ``False``, attempt to disable ASLR in all processes which are
If :const:`False`, attempt to disable ASLR in all processes which are
created via ``personality`` (``setarch -R``) and ``setrlimit``
(``ulimit -s unlimited``).
@@ -742,7 +766,7 @@ class ContextType(object):
"""
# Cyclic imports... sorry Idolf.
from ..elf import ELF
from pwnlib.elf import ELF
if not isinstance(binary, ELF):
binary = ELF(binary)
@@ -911,6 +935,24 @@ class ContextType(object):
value.flush()
return value
@_validator
def log_console(self, stream):
"""
Sets the default logging console target.
Examples:
>>> context.log_level = 'warn'
>>> log.warn("Hello")
[!] Hello
>>> context.log_console=open('/dev/null', 'w')
>>> log.warn("Hello")
>>> context.clear()
"""
if isinstance(stream, str):
stream = open(stream, 'wt')
return stream
@property
def mask(self):
return (1 << self.bits) - 1
@@ -953,7 +995,7 @@ class ContextType(object):
Can be set to any non-string truthy value, or the specific string
values ``'signed'`` or ``'unsigned'`` which are converted into
``True`` and ``False`` correspondingly.
:const:`True` and :const:`False` correspondingly.
Examples:
@@ -1086,17 +1128,23 @@ class ContextType(object):
self.arch = device.arch or self.arch
self.bits = device.bits or self.bits
self.endian = device.endian or self.endian
self.os = device.os or self.os
elif isinstance(device, str):
device = Device(device)
else:
elif device is not None:
raise AttributeError("device must be either a Device object or a serial number as a string")
return device
@property
def adb(self):
"""Returns an argument array for connecting to adb."""
command = ['adb']
"""Returns an argument array for connecting to adb.
Unless ``$ADB_PATH`` is set, uses the default ``adb`` binary in ``$PATH``.
"""
ADB_PATH = os.environ.get('ADB_PATH', 'adb')
command = [ADB_PATH]
if self.adb_host != self.defaults['adb_host']:
command += ['-H', self.adb_host]
@@ -1109,6 +1157,79 @@ class ContextType(object):
return command
@_validator
def buffer_size(self, size):
"""Internal buffer size to use for :class:`pwnlib.tubes.tube.tube` objects.
This is not the maximum size of the buffer, but this is the amount of data
which is passed to each raw ``read`` syscall (or equivalent).
"""
return int(size)
@property
def cache_dir(self):
"""Directory used for caching data.
Note:
May be either a path string, or :const:`None`.
Example:
>>> cache_dir = context.cache_dir
>>> cache_dir is not None
True
>>> os.chmod(cache_dir, 0o000)
>>> context.cache_dir is None
True
>>> os.chmod(cache_dir, 0o755)
>>> cache_dir == context.cache_dir
True
"""
home = os.path.expanduser('~')
if not os.access(home, os.W_OK):
return None
cache = os.path.join(home, '.pwntools-cache')
if not os.path.exists(cache):
try:
os.mkdir(cache)
except OSError:
return None
# Some wargames e.g. pwnable.kr have created dummy directories
# which cannot be modified by the user account (owned by root).
if not os.access(cache, os.W_OK):
return None
return cache
@_validator
def delete_corefiles(self, v):
"""Whether pwntools automatically deletes corefiles after exiting.
This only affects corefiles accessed via :attr:`.process.corefile`.
Default value is ``False``.
"""
return bool(v)
@_validator
def rename_corefiles(self, v):
"""Whether pwntools automatically renames corefiles.
This is useful for two things:
- Prevent corefiles from being overwritten, if ``kernel.core_pattern``
is something simple like ``"core"``.
- Ensure corefiles are generated, if ``kernel.core_pattern`` uses ``apport``,
which refuses to overwrite any existing files.
This only affects corefiles accessed via :attr:`.process.corefile`.
Default value is ``True``.
"""
return bool(v)
#*************************************************************************
# ALIASES
@@ -1184,11 +1305,14 @@ class ContextType(object):
Thread = Thread
#: Global ``context`` object, used to store commonly-used pwntools settings.
#: Global :class:`.ContextType` object, used to store commonly-used pwntools settings.
#:
#: In most cases, the context is used to infer default variables values.
#: For example, :meth:`pwnlib.asm.asm` can take an ``os`` parameter as a
#: keyword argument. If it is not supplied, the ``os`` specified by
#: ``context`` is used instead.
#: For example, :func:`.asm` can take an ``arch`` parameter as a
#: keyword argument.
#:
#: If it is not supplied, the ``arch`` specified by ``context`` is used instead.
#:
#: Consider it a shorthand to passing ``os=`` and ``arch=`` to every single
#: function call.
context = ContextType()
@@ -1206,6 +1330,7 @@ def LocalContext(function):
Example:
>>> context.clear()
>>> @LocalContext
... def printArch():
... print(context.arch)
@@ -1223,3 +1348,20 @@ def LocalContext(function):
with context.local(**{k:kw.pop(k) for k,v in kw.items() if isinstance(getattr(ContextType, k, None), property)}):
return function(*a, **kw)
return setter
# Read configuration options from the context section
def update_context_defaults(section):
# Circular imports FTW!
from pwnlib.util import safeeval
from pwnlib.log import getLogger
log = getLogger(__name__)
for key, value in section.items():
if key not in ContextType.defaults:
log.warn("Unknown configuration option %r in section %r" % (key, 'context'))
continue
if isinstance(ContextType.defaults[key], (str, unicode, tuple)):
value = safeeval.expr(value)
ContextType.defaults[key] = value
register_config('context', update_context_defaults)
+12
View File
@@ -0,0 +1,12 @@
from __future__ import absolute_import
try:
# These files are not distributed with Pwntools, but
# are in the source tree and used for testing.
from pwnlib.data import elf
except ImportError:
pass
import os
path = os.path.dirname(__file__)
+5
View File
@@ -0,0 +1,5 @@
import os
path = os.path.dirname(__file__)
def get(x):
return os.path.join(path, x)
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loaded 100 of 3661 files, more files were not shown because too many files have changed in this diff. Show more