Welcome To The World Of Shellcode

The shellcode encoder/decoder is additive. In that the encoder will minus a specific number (the key) from each byte of shellcode, then the decoder will add a specific number (again the key) to each byte in order to decode the original shellcode on the other side (interesting to watch in a debugger).

Brief Wrap Up

In the past year much has happened! I no longer work for Sense of Security, nor publish security advisories (to the public that is, usually). I’ve started a new role at Datacom TSS (datacom.com.au/tss).

At TSS, I have a large focus on true vulnerability research, where i get to pick a target and attempt to break it! I still do penetration testing/security assessments however my billable hours have been largely decreased. So far i’ve been enjoying my time and lifestyle at TSS 🙂

Exploiting The Unexploitable

Recently i discovered a vulnerability in Apache mod_isapi that when exploited provides the attacker with SYSTEM privileges to the remote host, without authentication (provided the DLL you call doesn’t require authentication – this would be rare and most likely only basic auth authetication would prevent the bug from being triggered). Below are some interesting notes about this bug.

Triggering the vulnerability:
– Send a normal request with the keep-alive flag set and a sized content-length value.
– Follow this request by a RESET packet.

Apache’s processing:
The function: ap_get_client_block() fails, and “res” becomes less than 0.

1530: while (read < cid->ecb->cbAvailable &&
1531: ((res = ap_get_client_block(r, (char*)cid->ecb->lpbData + read,
1532: cid->ecb->cbAvailable – read)) > 0)) {
1533: read += res;
1534: }

The call to unload the DLL.

1536: if (res < 0) {
1537: isapi_unload(isa, 0); // <– CALL TO UNLOAD
1538: return HTTP_INTERNAL_SERVER_ERROR;
1539: }

“yes, yes, so what?”

Now we have an “orphaned” callback pointer.

“a what?”

Exploiting the vulnerability:
Now we send another request to exploit the vulnerability. In this request we call a function published by the ISAPI module that has just been unloaded. Since the DLL is no longer in memory we will be calling invalid memory, unless we make that memory valid.

We make the memory valid by attempting to make Apache allocate user supplied data and the best way to do this that i could think of was to send a large request.

In the example proof of concept code, and demonstration video i was using an ISAPI module called “SMTPSend.dll”. Nothing fancy just a simple ISAPI module.

After unloading the DLL and sending another packet i noticed it would crash when calling “0x0074xxxx”. The proof of concept code will send a payload request that will hit above this address, from memory i think 0x007Axxxx. However with other versions of the code i was able to hit higher addresses again by increasing the size of the packet.

Disadvantages:
* Reliability just isn’t there. Most of the time, each ISAPI module will be different.
* Apache would allocate large chunks of user supplied data followed by a pile of nulls, destroying a large nopsled, and it sucks to land in the middle of them.
* DEP owns this attack since we cannot directly control EIP.

The advantage of exploiting a bugs like this is that i was able to exploit the bug and take _control_.

Before developing an exploit for this bug it was said that this bug could not be exploited by a “hacker”. 5 days later i had a working exploit.

Finally, well done to Apache for their prompt response and fix.

One of the most common bugs I find when reverse engineering is off by one bugs. While they can have devastating consequences, they can also result in minor problems that cannot be exploited.