This is kind of a funny one. I’m not unfamiliar with hacking, game-hacking to be more precise. This has always been a fun thing to do, now I came across something I find rather annoying. Let me explain, I wrote a small program that allocates a fixed size of memory at runtime and writes your own code in an existing process. In the end I load my module in the address space of the target process, this causes a call to DllMain with the reason argument set to DLL_PROCESS_ATTACH. I use this to run third-party code in an existing process. You might already guess this is suspicious behavior and would trigger an antivirus program way too fast. I’ve changed several games to my own needs with this technique but my antivirus doesn’t seem to like the host program at all.
I could easily whitelist the executable file but I’m more interested in why, and more important, how an antivirus program gets a trigger from my host program. Their-for I build an easy test-case to a more familiar technique of writing viruses. I used the “URLDownloadToFileA” API located in the Urlmon.dll library to fake a trojan application. The actually trojan code was written in a file named “io.exe”, which of course wasn’t a trojan but simply spammed my view with a few MessageBox’s. With my testcase set up, it was time to upload the “host” program (which would eventually load the payload from io.exe) to https://www.virustotal.com/. Lots of virus alerts were triggered and the file was marked as “unsafe”.
I took several steps in order to lay low on about any antivirus system out there.
- Load Urlmon.dll into the address space of the calling process and get the pointer to the URLDownloadToFileA API.
- Allocate a buffer space to replace the first 10 bytes at the URLDownloadToFileA API.
- Write a jmp opcode and target it correctly.
- Build an argument list that our target API needs and push them correctly onto the stack.
- Store our target in eax and call the API manually.
In our code, almost nothing pointed to the use of URLDownloadToFileA, almost… Two vital strings could be trapped fairly easy, “URLDownloadToFileA” and “Urlmon.dll”. By xor’ing both strings, that problem got off track and I didn’t have to worry about that. Another part, which would bust this method upside down, is to scan each page for known patterns. A sequence of opcodes matching known opcodes from an antivirus program’ database. But then again, rewriting the code or obfuscating at runtime would semi-avoid this detection.
I choose to run the strings through an XOR function, the string is no longer visible when debugging / decompiling the file.
void safe_api_call( ) {
// This is an XOR of "URLDownloadToFileA", just to avoid anti-virus programs picking up a suspicious string
char api[] = { 0x2D, 0x3D, 0x3E, 0x29, 0x19, 0x7, 0x16, 0x3, 0x1D, 0xC, 0x12, 0x24, 0x17, 0x29, 0x1B, 0x1, 0x13, 0x31, 0x78 };
const char key[] = "xormvp";
for ( int i = 0; i <= sizeof( api ) - 1; i++ )
api[i] ^= key[i % ( sizeof( key ) - 1 )]; // Decrypting the string at runtime
// Load "Urlmon.dll" into the address space of the calling process
HMODULE hMod = LoadLibraryA( "Urlmon.dll" );
if ( hMod == NULL )
return;
// Allocate a buffer space for the API call
unsigned char* ptr = new unsigned char[10];
DWORD ret;
VirtualProtect( ptr, 10, PAGE_EXECUTE_READWRITE, &ret ); // Change page flags for read/write access
unsigned char* ptr_url_dltofile = ( unsigned char* ) GetProcAddress( hMod, api ); // Pointer to "URLDownloadToFileA"
memcpy( ptr, ptr_url_dltofile, 0x5 );
...
}
View the full source code here: http://matvp.info/paste/view.php?id=240
I left some mistakes in there by purpose, the code posted above will probably compile but won't do what it has to do. Simply because I dislike a copy and paste behavior.
The code is a Proof of Concept (PoC) and posted for educational reason only. Thus another reason I left some important stubs out of this source code (Note: "Urlmon.dll" as plain text).
What next? With the same technique you could mask the shell execution (http://msdn.microsoft.com/en-us/library/windows/desktop/bb762153(v=vs.85).aspx) and actually run malicious code on a target pc without the antivirus program triggering a detection. Another possibility is to write code and execute it in an existing process as I illustrated in the beginning of this post.
Oh well, until next time.
Geert Van Parijs 11:20 pm on January 19, 2013 Permalink |
Well done buddy !