#!/usr/bin/env python
from subprocess import call
try:
call(['echo', "aabbccddee".decode('hex')])
print 'Input without \\x00 works!'
except Exception as e:
print 'Input without \\x00 throws exception: ' + str(e)
try:
call(['echo', "aabbccdd00ee".decode('hex')]) # The input contains \x00
print 'Input with \\x00 works!'
except Exception as e:
print 'Input with \\x00 throws exception: ' + str(e)
Returns the following (tested with Python 2.7 on RHEL 6):
▒▒▒▒▒
Input without \x00 works!
Input with \x00 throws exception: execv() arg 2 must contain only strings
Questions:
- Is this expected behavior by
subprocess.call
or might this be a bug? - Is there any way I can pass binary data (directly) containing \x00 to another executable within a python script? It will probably work using shell=True, but I would prefer another way, if there is any.
Note:
>>> type("00".decode('hex')) <type 'str'>
Running
echo $'\x00'
directly works as expected.
EDIT
This seems to be correct behavior after more research. Due to the execve(2) semantics it is not possible to pass a string containing a null byte as argument.
See:
$ echo $'\x55\x55\x55\x00\x55\x55' UUU
However, I couldn't really find anymore info on this (second question especially, as it seems shell=True won't help either (all data after the null byte wouldn't be passed)). I leave this question open for a while, maybe someone can provide a deeper insight or share some useful resources on this.