Compare commits

...
9 Commits
Author SHA1 Message Date
heapcrash f9ac7cc230 Pin legacy release to v0.24 2020-06-02 16:52:27 +02:00
Mathias Svensson df7c1fef9d Release 3.9.2 2017-10-05 09:40:21 +02:00
Zach Riggle b234b319df Do not attempt to populate the libraries used by statically-linked binaries (#1043)
This causes a background instance to be spawned, which is not intended.
2017-09-29 16:34:47 -05:00
Mathias Svensson 91768424ba Release 3.9.1 2017-09-28 11:33:14 +02:00
Zach Riggle af2f8b4bf4 Fix shellcraft.arm.trap (#1041) 2017-09-27 16:21:32 -05:00
Zach Riggle ab0ac00c73 Disable glibc buffering in fread for processes using PTYs
See issue #1038 for extensive details
2017-09-26 11:26:45 -05:00
Zach Riggle d87ab3ac65 Try to cut down on the crazy verbosity of logging (#1036)
* Prevent Sphinx from dumping all level=INFO logging output to stdout.

See Gallopsled/pwntools#1036 for more information.

* Filter out Paramiko logs too, apply filter to all root handlers during testing

* Remove unused import

(cherry picked from commit 54c47b3daa)
2017-09-26 11:26:45 -05:00
Zach Riggle 23cd5cb819 Fix some unicode problems in readline (#1029)
Technically this introduces issues with e.g. 'unhex ffdf | python foo.py' if
foo.py uses .interactive().  However, that was already broken for other reasons.

Fixes #1004

(cherry picked from commit ebbe917713)
2017-09-26 11:26:45 -05:00
Kristoffer Søholm bb25140807 DynELF bug fixes (#1017)
* DynELF: trust ELF base address

* Bug fixes for DynELF:

 * Fixed lookup when not using libcdb
 * Fixed _find_linkmap returning 0 instead of None when linkmap doesn't
   exist
 * Fixed _lookup_build_id crashing if linkmap cannot be found
 * Misc cleanup

* Changes based on feedback
2017-09-21 14:10:21 -07:00
10 changed files with 94 additions and 42 deletions

No files matched your search

+19 -1
View File
@@ -11,7 +11,9 @@ The table below shows which release corresponds to each branch, and what date th
| ---------------- | -------- | ---------------------- |
| [3.11.0](#3110) | `dev` | Dec 2, 2017 (planned)
| [3.10.0](#3100) | `beta` | Oct 21, 2017 (planned)
| [3.9.0](#390) | `stable` | Sep 11, 2017
| [3.9.2](#392) | `stable` | Oct 5, 2017
| [3.9.1](#391) | | Sep 28, 2017
| [3.9.0](#390) | | Sep 11, 2017
| [3.8.0](#380) | | Jul 29, 2017
| [3.7.1](#371) | | Jul 14, 2017
| [3.7.0](#370) | | Jun 19, 2017
@@ -45,6 +47,22 @@ To be released on Dec 2, 2017.
To be released on Oct 21, 2017.
## 3.9.2
- [#1043][1043] Do not attempt to populate the libraries used by statically-linked binaries
[1043]: https://github.com/Gallopsled/pwntools/pull/1043
## 3.9.1
- [#1038][1038] Fix an issue with `process()` where glibc would buffer data internally, causing a hang on `select()`
- [#1036][1036] Fix Travis CI logging verbosity
- [#1029][1029] Fix some `unicode` issues when using the `readline` command history in `tube.interactive()`
[1038]: https://github.com/Gallopsled/pwntools/pull/1038
[1036]: https://github.com/Gallopsled/pwntools/pull/1036
[1029]: https://github.com/Gallopsled/pwntools/pull/1029
## 3.9.0
- [#1003][1003] Make `concat_all` faster while also simplifying it's logic
+1 -1
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/badge/pypi-v3.9.0-green.svg?style=flat)](https://pypi.python.org/pypi/pwntools/)
[![PyPI](https://img.shields.io/badge/pypi-v3.9.2-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)
+17
View File
@@ -44,6 +44,23 @@ extensions = [
'sphinxcontrib.napoleon'
]
# Disable "info" logging directly to stdout by Sphinx
import logging
class SphinxPwnlibFilter(logging.Filter):
def filter(self, record):
if record.name.startswith('pwn'):
return False
if record.name.startswith('paramiko'):
return False
return True
log_filter = SphinxPwnlibFilter()
for i, handler in enumerate(logging.root.handlers):
print("Filtering Sphinx handler", handler)
handler.addFilter(log_filter)
# Napoleon settings
napoleon_use_ivar = True
napoleon_use_rtype = False
+18 -16
View File
@@ -417,7 +417,7 @@ class DynELF(object):
def _find_linkmap(self, pltgot=None, debug=None):
"""
The linkmap is a chained structure created by the loader at runtime
which contains information on the names and load addresses osf all
which contains information on the names and load addresses of all
libraries.
For non-RELRO binaries, a pointer to this is stored in the .got.plt
@@ -431,7 +431,7 @@ class DynELF(object):
Got = {32: elf.Elf_i386_GOT, 64: elf.Elf_x86_64_GOT}[self.elfclass]
r_debug = {32: elf.Elf32_r_debug, 64: elf.Elf64_r_debug}[self.elfclass]
result = None
linkmap = None
if not pltgot:
w.status("Finding linkmap: DT_PLTGOT")
@@ -439,24 +439,24 @@ class DynELF(object):
if pltgot:
w.status("GOT.linkmap")
result = self.leak.field(pltgot, Got.linkmap)
w.status("GOT.linkmap %#x" % result)
linkmap = self.leak.field(pltgot, Got.linkmap)
w.status("GOT.linkmap %#x" % linkmap)
if not result:
if not linkmap:
debug = debug or self._find_dt(constants.DT_DEBUG)
if debug:
w.status("r_debug.linkmap")
result = self.leak.field(debug, r_debug.r_map)
linkmap = self.leak.field(debug, r_debug.r_map)
w.status("r_debug.linkmap %#x" % result)
if not (pltgot or debug):
if not linkmap:
w.failure("Could not find DT_PLTGOT or DT_DEBUG")
return None
result = self._make_absolute_ptr(result)
linkmap = self._make_absolute_ptr(linkmap)
w.success('%#x' % result)
return result
w.success('%#x' % linkmap)
return linkmap
def waitfor(self, msg):
if not self._waitfor:
@@ -523,6 +523,7 @@ class DynELF(object):
Arguments:
symb(str): Named routine to look up
If omitted, the base address of the library will be returned.
lib(str): Substring to match for the library name.
If omitted, the current library is searched.
If set to ``'libc'``, ``'libc.so'`` is assumed.
@@ -566,7 +567,6 @@ class DynELF(object):
# Try a quick lookup by build ID
self.status("Trying lookup based on Build ID")
build_id = dynlib._lookup_build_id(lib=lib)
result = None
if build_id:
log.info("Trying lookup based on Build ID: %s" % build_id)
path = libcdb.search_by_build_id(build_id)
@@ -575,11 +575,10 @@ class DynELF(object):
e = ELF(path)
e.address = dynlib.libbase
result = e.symbols[symb]
if not result:
self.status("Trying remote lookup")
result = dynlib._lookup(symb)
else:
if symb and not result:
self.status("Trying remote lookup")
result = dynlib._lookup(symb)
if not symb:
result = dynlib.libbase
#
@@ -839,6 +838,9 @@ class DynELF(object):
def _lookup_build_id(self, lib = None):
libbase = self.libbase
if not self.link_map:
self.status("No linkmap found")
return None
if lib is not None:
libbase = self.lookup(symb = None, lib = lib)
+12 -1
View File
@@ -55,6 +55,7 @@ from elftools.elf.enums import ENUM_P_TYPE
from elftools.elf.gnuversions import GNUVerDefSection
from elftools.elf.relocation import RelocationSection
from elftools.elf.sections import SymbolTableSection
from elftools.elf.segments import InterpSegment
import intervaltree
@@ -605,10 +606,20 @@ class ELF(ELFFile):
>>> any(map(lambda x: 'libc' in x, bash.libs.keys()))
True
"""
if not self.get_section_by_name('.dynamic'):
# We need a .dynamic section for dynamically linked libraries
if not self.get_section_by_name('.dynamic') or self.statically_linked:
self.libs= {}
return
# We must also specify a 'PT_INTERP', otherwise it's a 'statically-linked'
# binary which is also position-independent (and as such has a .dynamic).
for segment in self.iter_segments_by_type('PT_INTERP'):
break
else:
self.libs = {}
return
try:
cmd = 'ulimit -s unlimited; LD_TRACE_LOADED_OBJECTS=1 LD_WARN=1 LD_BIND_NOW=1 %s 2>/dev/null' % sh_string(self.path)
+1 -7
View File
@@ -1,8 +1,2 @@
<%docstring>A trap instruction.</%docstring>
nop
nop
nop
mov r0, 12
mov r1, sp
BKPT 0xab
B .
BKPT
+20 -10
View File
@@ -1,3 +1,5 @@
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
from __future__ import absolute_import
from pwnlib.term import keyconsts as kc
@@ -7,7 +9,7 @@ from pwnlib.term import text
cursor = text.reverse
buffer_left, buffer_right = u'', u''
buffer_left, buffer_right = '', ''
saved_buffer = None
history = []
history_idx = None
@@ -29,6 +31,14 @@ suggest_hook = None
tabs = 0
def force_to_bytes(data):
if isinstance(data, bytes):
return data
try:
return data.encode('utf-8')
except Exception:
return data.encode('latin-1')
def set_completer(completer):
global complete_hook, suggest_hook
if completer is None:
@@ -80,7 +90,7 @@ def handle_keypress(trace):
def clear():
global buffer_left, buffer_right, history_idx, search_idx
buffer_left, buffer_right = u'', u''
buffer_left, buffer_right = '', ''
history_idx = None
search_idx = None
redisplay()
@@ -141,7 +151,7 @@ def cancel_search(*_):
def commit_search():
global search_idx
if search_idx is not None and search_results:
set_buffer(history[search_results[search_idx][0]], u'')
set_buffer(history[search_results[search_idx][0]], '')
search_idx = None
redisplay()
@@ -169,7 +179,7 @@ def update_search_results():
def search_history(*_):
global buffer_left, buffer_right, history_idx, search_idx
if search_idx is None:
buffer_left, buffer_right = buffer_left + buffer_right, u''
buffer_left, buffer_right = buffer_left + buffer_right, ''
history_idx = None
search_idx = 0
update_search_results()
@@ -187,7 +197,7 @@ def history_prev(*_):
history_idx = -1
if history_idx < len(history) - 1:
history_idx += 1
set_buffer(history[history_idx], u'')
set_buffer(history[history_idx], '')
def history_next(*_):
global history_idx, saved_buffer
@@ -200,7 +210,7 @@ def history_next(*_):
saved_buffer = None
else:
history_idx -= 1
set_buffer(history[history_idx], u'')
set_buffer(history[history_idx], '')
def backward_char(*_):
global buffer_left, buffer_right
@@ -319,11 +329,11 @@ def forward_word(*_):
def go_beginning(*_):
commit_search()
set_buffer(u'', buffer_left + buffer_right)
set_buffer('', buffer_left + buffer_right)
def go_end(*_):
commit_search()
set_buffer(buffer_left + buffer_right, u'')
set_buffer(buffer_left + buffer_right, '')
keymap = km.Keymap({
'<nomatch>' : self_insert,
@@ -382,10 +392,10 @@ def readline(_size = None, prompt = '', float = True, priority = 10):
if eof:
return ''
else:
buffer = (buffer_left + buffer_right).encode('utf-8')
buffer = (buffer_left + buffer_right)
if buffer:
history.insert(0, buffer)
return buffer + '\n'
return force_to_bytes(buffer) + '\n'
except KeyboardInterrupt:
control_c()
finally:
+3 -3
View File
@@ -336,11 +336,11 @@ class process(tube):
if self.pty is not None:
if stdin is slave:
self.proc.stdin = os.fdopen(os.dup(master), 'r+')
self.proc.stdin = os.fdopen(os.dup(master), 'r+', 0)
if stdout is slave:
self.proc.stdout = os.fdopen(os.dup(master), 'r+')
self.proc.stdout = os.fdopen(os.dup(master), 'r+', 0)
if stderr is slave:
self.proc.stderr = os.fdopen(os.dup(master), 'r+')
self.proc.stderr = os.fdopen(os.dup(master), 'r+', 0)
os.close(master)
os.close(slave)
+1 -1
View File
@@ -1 +1 @@
__version__ = '3.9.0'
__version__ = '3.9.3'
+2 -2
View File
@@ -44,7 +44,7 @@ for filename in glob.glob('pwnlib/commandline/*'):
install_requires = ['paramiko>=1.15.2',
'mako>=1.0.0',
'pyelftools>=0.2.4',
'pyelftools==0.24',
'capstone',
'ropgadget>=5.3',
'pyserial>=2.7',
@@ -86,7 +86,7 @@ except Exception as e:
setup(
name = 'pwntools',
packages = find_packages(),
version = '3.9.0',
version = '3.9.3',
data_files = [('',
glob.glob('*.md') + glob.glob('*.txt')),
],