If ESP directly points to the shellcode we can overwrite EIP with call esp instruction.
Let’s edit our exploit which was used in the previous article.
We need to replace \x3a\xf2\xaa\x01 address which points to the JMP ESP instruction to the address of CALL ESP instruction.
Let’s find it first.
The opcode of call esp is:
# rasm2 -a x86 "call esp"
We will use kernel32.dll and the next address: 0x7c868667.
So now let’s change our exploit:
The value of EIP now should change. Let’s check it.
What if none of the registers points to the shellcode, but our shellcode can be found at ESP + 8?
We can use pop ret technique.
Let’s simulate this case in our example.
We should add 4 + 8 random bytes before our shellcode (4 bytes because in this application ESP normally points to the 5th byte of the shellcode and 8 bytes because we should simulate situation when our shellcode starts at ESP+8)
"\x77\xc1\xa3\xb4\xd5\x55\x11\xff" - just random bytes added before shellcode. That’s how exploit now looks like:
Now we will look in Immunity debugger what happens after our application crashes.
That’s what we wanted to do: there is 8 random bytes before our shellcode. So now to jump directly to the shellcode we will use pop ret technique.
As there are eight bytes before shellcode we need to find (for example): pop eax pop ebx ret opcodes.
~# rasm2 -a x86 "pop eax"
~# rasm2 -a x86 "pop ebx"
~# rasm2 -a x86 "ret"
Now we need to find this sequence in one of dll’s: 585bc3!mona find -s “\x58\x5b\xc3"
This sequence was found at the next address: 0x01b17f03
In our exploit we need to write this sequence in EIP, after that pop instruction will pop 4 bytes from the stack, then another pop instruction will pop next 4 bytes and then ret instruction will put jmp esp instruction from the stack and put it into EIP.
So our attack string in exploit will look like:
attack = "A" * 26064 + "\x03\x7f\xb1\x01" + before_esp + random_bytes + "\x7c\x86\x86\x67" + "\x90" * 25 + shellcode
\x03\x7f\xb1\x01 - address of pop pop ret\x67\x86\x86\x7c - address of jmp esp - NOT in reverse order as in the previous example, case we will take it from the stack!
The full exploit:
push return is very similar with call[reg]. If one of the registers now directly pointing to the shellcode, it is possible to push the address of this register to the stack and then to make return which will take address from the stack and jump to it.
This can be useful when jmp[reg] is not available for example.
Let’s find opcodes for push esp and ret.
~# rasm2 -a x86 "push esp"
~# rasm2 -a x86 "ret"
Now we should find the address where they can be located:
!mona find -s “\x54\xc3"
And that’s it:
We will try this address: 0x77f6c62b.
Let’s modify our exploit, to make esp pointing directly to our shellcode (beginning with NOPs).
And it works!
If our shellcode for example can be found at ESP + 7 we can simply use jmp[exp+7] instruction.