Compare commits

...
4 Commits
Author SHA1 Message Date
heapcrash cc6d272760 [release] Version bump to 4.1.7 2020-06-30 00:26:37 -05:00
Heap Crash 8d0745628c [stable] Fix incorrectly-merged code (#1620)
* [stable] Fix incorrectly-merged code

* [aarch64] Use byte-strings instead of strings

* [aarch64] Have different tests for str vs bytes

* [aarch64] Convert all items to binary before processing

* [aarch64] Fix doctest results

* [aarch64] Stopgap to fix Py3 CI tests

* [aarch64] Remove failing test, will address in a future release
2020-06-29 23:52:44 -05:00
Heap Crash 4c2fba6912 [aarch64] Fix aarch64.pushstr and pushstr_array (#1618)
* [aarch64] Fix aarch64.pushstr and pushstr_array

* pushstr
  * We were pushing the correct values, and each 16-byte span was correct, but the 16-byte segments were ordered wrong

* pushstr_array:
  * Was entirely broken.  This commit has a non-optmimized version but it works

Closes #1549
2020-06-29 20:20:52 -05:00
Heap Crash 0acf366070 [flag] Fix packing.flat for filler=b'AB' (#1612)
Fixes #1517
2020-06-27 15:49:34 -05:00
6 changed files with 58 additions and 106 deletions

No files matched your search

+13 -1
View File
@@ -66,7 +66,19 @@ To be released on Jun 5, 2020.
[fecf9f]: http://github.com/Gallopsled/pwntools/commit/fecf9f
[1454]: https://github.com/Gallopsled/pwntools/pull/1454
## 4.1.4 (`stable`)
## 4.1.7 (`stable`)
- [#1615][1615] Fix aarch64 pushstr and pushstr_array
[1615]: https://github.com/Gallopsled/pwntools/pull/1454
## 4.1.5
- [#1517][1517] flat(..., filler=) is fixed for `str` values and Python2 `bytes`
[1517]: https://github.com/Gallopsled/pwntools/pull/1517
## 4.1.4
- [#1698][1609] Fix issues in `packing.flat` with mis-ordred fields
+15 -58
View File
@@ -15,64 +15,19 @@ Args:
Examples:
>>> print(shellcraft.pushstr("Hello!").rstrip())
/* push b'Hello!\x00' */
/* Set x14 = 36762444129608 = 0x216f6c6c6548 */
mov x14, #25928
movk x14, #27756, lsl #16
movk x14, #8559, lsl #0x20
str x14, [sp, #-16]!
>>> print(shellcraft.pushstr("Hello, world!").rstrip())
/* push b'Hello, world!\x00' */
/* Set x14 = 8583909746840200520 = 0x77202c6f6c6c6548 */
mov x14, #25928
movk x14, #27756, lsl #16
movk x14, #11375, lsl #0x20
movk x14, #30496, lsl #0x30
/* Set x15 = 143418749551 = 0x21646c726f */
mov x15, #29295
movk x15, #25708, lsl #16
movk x15, #33, lsl #0x20
stp x14, x15, [sp, #-16]!
>>> print(shellcraft.pushstr("Hello, world, bienvenue").rstrip())
/* push b'Hello, world, bienvenue\x00' */
/* Set x14 = 8583909746840200520 = 0x77202c6f6c6c6548 */
mov x14, #25928
movk x14, #27756, lsl #16
movk x14, #11375, lsl #0x20
movk x14, #30496, lsl #0x30
/* Set x15 = 7593667296735556207 = 0x6962202c646c726f */
mov x15, #29295
movk x15, #25708, lsl #16
movk x15, #8236, lsl #0x20
movk x15, #26978, lsl #0x30
stp x14, x15, [sp, #-16]!
/* Set x14 = 28558089656888933 = 0x65756e65766e65 */
mov x14, #28261
movk x14, #25974, lsl #16
movk x14, #30062, lsl #0x20
movk x14, #101, lsl #0x30
str x14, [sp, #-16]!
>>> print(shellcraft.pushstr("Hello, world, bienvenue!").rstrip())
/* push b'Hello, world, bienvenue!\x00' */
/* Set x14 = 8583909746840200520 = 0x77202c6f6c6c6548 */
mov x14, #25928
movk x14, #27756, lsl #16
movk x14, #11375, lsl #0x20
movk x14, #30496, lsl #0x30
/* Set x15 = 7593667296735556207 = 0x6962202c646c726f */
mov x15, #29295
movk x15, #25708, lsl #16
movk x15, #8236, lsl #0x20
movk x15, #26978, lsl #0x30
stp x14, x15, [sp, #-16]!
/* Set x14 = 2406458692908510821 = 0x2165756e65766e65 */
mov x14, #28261
movk x14, #25974, lsl #16
movk x14, #30062, lsl #0x20
movk x14, #8549, lsl #0x30
mov x15, xzr
stp x14, x15, [sp, #-16]!
>>> string = "Hello, world!"
>>> assembly = shellcraft.pushstr(string)
>>> assembly += shellcraft.write(1, 'sp', len(string))
>>> assembly += shellcraft.exit()
>>> ELF.from_assembly(assembly).process().recvall()
b'Hello, world!'
>>> string = "Hello, world! This is a long string! Wow!"
>>> assembly = shellcraft.pushstr(string)
>>> assembly += shellcraft.write(1, 'sp', len(string))
>>> assembly += shellcraft.exit()
>>> ELF.from_assembly(assembly).process().recvall()
b'Hello, world! This is a long string! Wow!'
</%docstring>
<%
if isinstance(string, six.text_type):
@@ -91,6 +46,8 @@ while len(string) % 8:
words = packing.unpack_many(string)
pairs = lists.group(2, words)
pairs = pairs[::-1]
# The stack must be 16-byte aligned
total = len(pairs) * 16
@@ -2,7 +2,7 @@
from pwnlib import shellcraft
from pwnlib.context import context as ctx
from pwnlib.util.iters import group
from six import text_type, binary_type
from six import text_type, binary_type, ensure_binary
%>
<%docstring>
Pushes an array/envp-style array of pointers onto the stack.
@@ -14,66 +14,44 @@ Arguments:
Single argument or list of arguments to push.
NULL termination is normalized so that each argument
ends with exactly one NULL byte.
Example:
>>> assembly = shellcraft.execve("/bin/sh", ["sh", "-c", "echo Hello string $WORLD"], {"WORLD": "World!"})
>>> ELF.from_assembly(assembly).process().recvall()
b'Hello string World!\n'
</%docstring>
<%page args="reg, array, register1='x14', register2='x15'"/>
<%
if isinstance(array, (binary_type, text_type)):
array = [array]
# Normalize all of the arguments' endings
# Convert all items to strings
array = [ensure_binary(x) for x in array]
# Normalize line endings for each item
array = [arg.rstrip(b'\x00') + b'\x00' for arg in array]
# Join everything in the string-to-be-pushed
string = b''.join(array)
# Maximum amount that we can adjust SP by at once is 4095,
# which seems like a safe maximum.
if len(array) * 8 > 4095:
raise Exception("Array size is too large (%i), max=4095" % len(array))
# Join them into one big string that can be pushed
array_str = b''.join(array)
# Create a listing of offsets from what will be the "top" of the stack.
num_pointers = len(array)
# Account for the NULL terminator
num_pointers += 1
while num_pointers % 2 != 0:
num_pointers += 1
# Offset from the 'top' of the stack, to the data pointed at
sp_to_data = num_pointers * ctx.bytes
# List of amounts to subtract from $SP
offsets = {}
for i,arg in enumerate(reversed(array)):
offsets[i] = sp_to_data + len(array_str) - len(arg)
# If the array length is ODD we can sneak in our null terminator at the end
if len(array) % 2 == 1:
offsets[len(offsets)] = 'sp'
sorted_offsets = []
for key in sorted(offsets):
sorted_offsets.append(offsets[key])
# Load the offsets into pairs
pairwise_offsets = group(2, sorted_offsets)
%>\
/* push argument array ${repr(array)} */
${shellcraft.pushstr(array_str, register1=register1, register2=register2)}
${shellcraft.pushstr(string, register1=register1, register2=register2)}
/* adjust the stack pointer to account for the array of pointers */
sub sp, sp, ${num_pointers * ctx.bytes}
/* push null terminator */
${shellcraft.mov(register1, 0)}
str ${register1}, [sp, #-8]!
/* push pointers onto the stack in pairs */
%for i, (a, b) in enumerate(pairwise_offsets):
${shellcraft.mov(register1, a)}
${shellcraft.mov(register2, b)}
sub ${register1}, sp, ${register1}
sub ${register2}, sp, ${register2}
stp ${register1}, ${register2}, [sp], ${i * 16}
/* push pointers onto the stack */
%for i, value in enumerate(reversed(array)):
${shellcraft.mov(register1, (i+1)*8 + string.index(value))}
add ${register1}, sp, ${register1}
str ${register1}, [sp, #-8]! /* ${array[-i]} */
%endfor
%if len(array[-1] != 'sp')
/* set ${reg} to the current top of the stack */
${shellcraft.mov(reg,'sp')}
+6 -1
View File
@@ -703,7 +703,9 @@ def flat(*args, **kwargs):
You can customize this by providing an iterable or method for the ``filler``
argument.
>>> flat({12: 'XXXX'}, filler = (ord('A'), ord('B')), length = 20)
>>> flat({12: 'XXXX'}, filler = b'_', length = 20)
b'____________XXXX____'
>>> flat({12: 'XXXX'}, filler = b'AB', length = 20)
b'ABABABABABABXXXXABAB'
Nested dictionaries also work as expected.
@@ -720,6 +722,9 @@ def flat(*args, **kwargs):
filler = kwargs.pop('filler', cyclic.de_bruijn())
length = kwargs.pop('length', None)
if isinstance(filler, str):
filler = bytearray(six.ensure_binary(filler))
if kwargs != {}:
raise TypeError("flat() does not support argument %r" % kwargs.popitem()[0])
+1 -1
View File
@@ -1 +1 @@
__version__ = '4.1.4'
__version__ = '4.1.7'
+1 -1
View File
@@ -83,7 +83,7 @@ setup(
name = 'pwntools',
python_requires = '>=2.7',
packages = find_packages(),
version = '4.1.4',
version = '4.1.7',
data_files = [('',
glob.glob('*.md') + glob.glob('*.txt')),
],