Archive

Posts Tagged ‘failure’

WoWMimic v49

June 5th, 2009

WoWMimic v49 is out, a very quick bugfix release.

Nothing has changed in terms of anti-detection (so WardenMimic still works), but amusingly, they introduced a bug into their (recently removed) GetCursorPos and SetCursorPos hook subs for VEH.

They have removed a line from both that compares an internal flag to 1/0. What’s amusing about it is, they left in a conditional jump that relied on that line. That conditional jump will now fire based off the line above (a SUB instruction, which like CMP sets the ZF), and the jump will never be taken. Why is this amusing? Because its proof that the devs wrote the code using inline assemby. I was moderately sure of this before (due to the use of PUSHAD, POPAD, etc), but now we have confirmation. Not only is it totally unneeded to do all that crap in inline ASM, but it also explains that they did in fact implement the obfuscation code manually (mentioned in a previous post), obviously thinking it posed some kind of barrier.

Sorry guys, but it probably took me less time to undo it than it took you to figure it out and write it. REALLY obvious job. The call/pop trick is one of the oldest in the book, literally. C’mon. Raise the bar and give us something fun and challenging to play with. (Yeah I know, I’m asking for the world from these guys)

P.S. Still can’t figure out how to stop detection by WardenMimic?

Finding WoWMimic

May 7th, 2009

Hey, called this little snippet “WardenMimic” because it’s just mimicing what warden would have to do to detect the fail bot known as WoWMimic. Very simple example, but afaik similar to how Glider was detected (i.e. via window names and contents). A more sophisticated attack would use hashing of the remote processes memory, but that’s totally unnecessary because  WoWMimic don’t bother to obfuscate or hide anything.

Keep in mind, this was written in literally 5 minutes, a much more solid and reliable method would not be much extra work (maybe just another 5?). The code is designed to be in a DLL that is loaded by (or injected into) WoW.exe so that it is in the same context and has the same privilege level as Warden would. I made sure to load WoW via WoWMimic to ensure anything they would be doing against Warden would happen against me also, though they let you attach on the fly so I don’t think security is one of their major concerns.

Please note that I don’t have a WoWMimic sub so I just downloaded it off their site and am amusing nothing special happens if you actually run the bot that activates any window hiding or obfuscation. Let me know if this is the case and I’ll get a sub and release a new finder.

// Windows API
#include <Windows.h>
#include <io.h>
#include <fcntl.h>
#include <tchar.h>

// C++ Standard Library
#include <iostream>
#include <cstdio>
#include <vector>

// StealthLib
#include “Conditional.h”
#include “Cloaker.h”
#include “Injector.h”

// Holds windows from EnumWindows
std::vector<HWND> Windows;

// Top level window enumeration callback
BOOL CALLBACK MyEnumWindowsProc(HWND hwnd, LPARAM /*lParam*/)
{
Windows.push_back(hwnd);
return TRUE;
}

// Child level window enumeration callback
BOOL CALLBACK MyEnumChildWindowsProc(HWND hwnd, LPARAM /*lParam*/)
{
std::vector<TCHAR> Buffer(MAX_PATH);
if (GetWindowText(hwnd,&Buffer[0],MAX_PATH) &&
std::tstring(&Buffer[0]) == TEXT(”http://www.mimicusa.com”))
std::cout << “Found WoWMimic URL label!” << std::endl;
Buffer.clear();
Buffer.resize(MAX_PATH);
if (GetWindowText(hwnd,&Buffer[0],MAX_PATH) &&
std::tstring(&Buffer[0]) == TEXT(”Us Ver 3.0.0.42″))
std::cout << “Found WoWMimic version label!” << std::endl;
return TRUE;
}

// DLL entry point
BOOL WINAPI DllMain(HINSTANCE hinstDLL,
DWORD fdwReason,
LPVOID /*lpvReserved*/)
{
// Stop unreferenced param warning when __STEALTH is undefined
UNREFERENCED_PARAMETER(hinstDLL);

#ifdef __CONSOLE
// Whether to free the process’s console upon detach
static bool NeedFree = false;
#endif

// Reason for calling DllMain
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
{
#ifdef __CONSOLE
// Set up debug console
NeedFree = (AllocConsole() ? true : false);
FILE* fpOld = NULL;
freopen_s( &fpOld, “CONOUT$”, “w”, stdout );
#endif

EnumWindows(MyEnumWindowsProc,NULL);
for each (HWND Current in Windows)
{
EnumChildWindows(Current,MyEnumChildWindowsProc,NULL);
}

#ifdef __STEALTH
// Cloaker
Cloaker::Get()->AddModule(hinstDLL,true);
#endif

break;
}
case DLL_PROCESS_DETACH:
{
#ifdef __CONSOLE
// Don’t free the console if it already existed upon injection
if (NeedFree)
FreeConsole();
#endif

break;
}
}

// Success
return TRUE;
}

Sorry for the messy code. The base was taken from one of my other projects because I was too lazy to whip up the skeleton by hand. Then I just slapped in the detection stuff. There’s lots of unnecessary crap there, but you get the point.

Obviously if WoW was started as guest you could defeat remote hashing attacks or those similar, but guess what… That’s how they detected Glider! They checked whether the given access token was restricted (i.e. started with reduced privileges).

Protip: Don’t use WoWMimic. Not only is it an awful bot, its a 30 second job (literally) to write a detection routine.

How-To: Waste 10 minutes of your life

April 26th, 2009

Just had an epic fail moment I wanted to share, the type of moment where a realisation hits you like a fucking train and you just wanna kick yourself for not thinking of it.

I was working on an API hooking library (address-table based hooking) and I hook GetProcAddress mainly because I want to log indirect API calls, and partly because EAT hooking isn’t working 100% yet (due to design details which are beyond the scope of this post). I wanted to drop the hook to a lower level so I hooked LdrGetProcedureAddress because that’s the routine that GetProcAddress calls to do the actual work. I then looked at the implementation of LdrGetProcedureAddress and saw that it in turn called LdrGetProcedureAddresEx. Great, I thought, I’ll hook that. Only the hook didn’t ever get called.

Because I had previously always used code hooking I assumed that something funny was going on and that I must have screwed something up. After 10 minutes of rewriting large chunks of code to add debugging information I realised something. It’s an IAT hook, the LdrGetProcedureAddress hook works because GetProcAddress imports that function from NTDLL. LdrGetProcedureAddress however calls LdrGetProcedureAddressEx directly and NTDLL doesn’t import anything because it doesn’t have to, it’s the top of the usermode food chain (so to speak).

Obviously the only way to hook that function is with an EAT hook, so I guess now I HAVE to get that working.

*grumble*