Archive

Posts Tagged ‘pwned’

WardenMimic v20090723a

July 23rd, 2009

New build of WardenMimic. I held on to it because I got word of a new build in the near future, I wanted to give them a chance to maybe fix some of their shit. The changelog says they’ve improved their anti-detection, but my checks say otherwise. This is confirmed working on v54, but should work on previous builds too (shit, I think pretty much all of their builds are vulnerable to this particular hole).

There are still plenty more holes left though so don’t worry, I’m not taking all the fun away from Blizzard, just a bit of it.

WardenMimic v20090723a

Let the drama begin!

WoWMimic Mini-Banwave

June 6th, 2009

Lol. Can’t say you weren’t warned.

That’s all I have to say on the issue.

Author: Cypherjb Categories: Games Tags: , , , ,

More WoWMimic Detection Code

May 15th, 2009

Well, we have found yet another hole in WoWMimic that is criminally easy to abuse. Credits to Kynox and Harko for working on this with me.

This code abuses the fact that the WoWMimic idiots are only hooking VirtualQuery, and none of the lower control paths, so we can easily call VirtualQueryEx to verify that the results we get back are untainted. If we find something that has been modified we know we have a hidden page. Mimic only hides the base page, not the entire module, so at the point I’ve marked “Warden function to do hashing goes here”, you simply need to do standard hashing of  data in the page, something which Warden already does (the reason for the hook in the first place).

void FindHiddenPages()

{

std::cout << “Start!” << std::endl << std::hex;

PVOID p1 = 0, p2 = 0;

MEMORY_BASIC_INFORMATION MyMbi = { 0 };

typedef std::vector< std::pair<PVOID,PVOID> > tAddresses;

tAddresses AddressList;

tAddresses Hidden;

while (VirtualQuery(p1,&MyMbi,sizeof(MyMbi)) == sizeof(MyMbi))

{

if (MyMbi.State == MEM_COMMIT && MyMbi.AllocationBase != p2 &&

MyMbi.AllocationBase == MyMbi.BaseAddress)

{

AddressList.push_back(std::make_pair(MyMbi.AllocationBase,MyMbi.BaseAddress) );

}

p2 = MyMbi.AllocationBase;

p1 = reinterpret_cast<PVOID>(reinterpret_cast<DWORD_PTR>(p1) + MyMbi.RegionSize);

}

p1 = p2 = 0;

while (VirtualQueryEx(GetCurrentProcess(),p1,&MyMbi,sizeof(MyMbi)) == sizeof(MyMbi))

{

if (MyMbi.State == MEM_COMMIT && MyMbi.AllocationBase != p2 &&

MyMbi.AllocationBase == MyMbi.BaseAddress)

{

std::pair<PVOID,PVOID> MyAddresses(MyMbi.AllocationBase,MyMbi.BaseAddress);

const tAddresses::const_iterator iCurrent(std::find(AddressList.begin(),AddressList.end(), MyAddresses));

if (iCurrent == AddressList.end())

Hidden.push_back(MyAddresses);

}

p2 = MyMbi.AllocationBase;

p1 = reinterpret_cast<PVOID>(reinterpret_cast<DWORD_PTR>(p1) + MyMbi.RegionSize);

}

for (tAddresses::const_iterator i = Hidden.begin(); i != Hidden.end(); ++i)

{

std::cout << “Hidden page! Allocation Base: ” << i->first

<< “. Base Address: ” << i->second << “.” << std::endl;

// Warden function to do hashing goes here

}

std::cout << “End!” << std::endl << std::dec;

}

On its own, even without hashing, you still have ground for a kick at the very least because hiding memory pages is something that only malicious software normally does. Once you add hashing though you have a guarantee of no false positives so you can go ahead and ban for it.

Yet again it seems that WoWMimic just doesn’t stand up when it comes to the detection test. Don’t trust their website, this thing is trivial to detect.

In-process WoWMimic Detection

May 14th, 2009

The following is code that will detect if WoWMimic is running using fully in-process checks. That means that you can lock it down with guest mode, hide the window, etc all you want, this will still work, because we’re operating entirely inside WoW.exe’s address space.

Before we begin, huge thanks to Kynox for unpacking Melete (WoWMimic’s injected DLL).

WoWMimic needs a way for its DLL to communicate with its application component, it does this through shared memory. Here is the disassembled function responsible for setting this up. I have commented the virtualized API calls to make it apparent what is going on:

___:1002F630 ; =============== S U B R O U T I N E =======================================

___:1002F630

___:1002F630 ; Attributes: bp-based frame

___:1002F630

___:1002F630 sub_1002F630    proc near               ; CODE XREF: DllMain(x,x,x)+45p

___:1002F630

___:1002F630 var_24          = dword ptr -24h

___:1002F630 var_20          = dword ptr -20h

___:1002F630 var_1C          = dword ptr -1Ch

___:1002F630 var_10          = dword ptr -10h

___:1002F630 var_8           = dword ptr -8

___:1002F630 var_4           = dword ptr -4

___:1002F630

___:1002F630                 push    ebp

___:1002F631                 mov     ebp, esp

___:1002F633                 push    0FFFFFFFEh

___:1002F635                 push    offset dword_10070488

___:1002F63A                 push    offset __except_handler4

___:1002F63F                 mov     eax, large fs:0

___:1002F645                 push    eax

___:1002F646                 sub     esp, 14h

___:1002F649                 push    ebx

___:1002F64A                 push    esi

___:1002F64B                 push    edi

___:1002F64C                 mov     eax, dword_10072054

___:1002F651                 xor     [ebp+var_8], eax

___:1002F654                 xor     eax, ebp

___:1002F656                 push    eax

___:1002F657                 lea     eax, [ebp+var_10]

___:1002F65A                 mov     large fs:0, eax

___:1002F660                 xor     ebx, ebx

___:1002F662                 mov     [ebp+var_24], ebx

___:1002F665                 mov     [ebp+var_1C], ebx

___:1002F668                 xor     esi, esi

___:1002F66A                 mov     [ebp+var_20], esi

___:1002F66D                 mov     [ebp+var_4], ebx

___:1002F670                 push    offset a0xa0c82e ; “0xA0C82E”

___:1002F675                 push    ebx

___:1002F676                 push    2

___:1002F678                 call    near ptr 3E0000h ; OpenFileMappingW

___:1002F67D                 nop

___:1002F67E                 mov     edi, eax

___:1002F680                 mov     [ebp+var_1C], edi

___:1002F683                 cmp     edi, ebx

___:1002F685                 jz      short loc_1002F6D8

___:1002F687                 push    0Ch

___:1002F689                 push    ebx

___:1002F68A                 push    ebx

___:1002F68B                 push    2

___:1002F68D                 push    edi

___:1002F68E                 call    near ptr 3E0370h ; MapViewOfFile

___:1002F693                 nop

___:1002F694                 mov     esi, eax

___:1002F696                 mov     [ebp+var_20], esi

___:1002F699                 cmp     esi, ebx

___:1002F69B                 jz      short loc_1002F6D8

___:1002F69D                 push    ebx

___:1002F69E                 push    ebx

___:1002F69F                 mov     eax, [esi]

___:1002F6A1                 push    eax

___:1002F6A2                 push    offset loc_1002F570

___:1002F6A7                 push    ebx

___:1002F6A8                 push    ebx

___:1002F6A9                 call    near ptr 21092Eh ; CreateThread

___:1002F6AE                 nop

___:1002F6AF                 mov     dword_100730C0, eax

___:1002F6B4                 cmp     eax, ebx

___:1002F6B6                 jz      short loc_1002F6D8

___:1002F6B8                 mov     ecx, [esi+10h]

___:1002F6BB                 mov     dword_100730C4, ecx

___:1002F6C1                 mov     edx, [esi+20h]

___:1002F6C4                 mov     dword_100730C8, edx

___:1002F6CA                 mov     [ebp+var_24], 1

___:1002F6D1                 mov     [esi], ebx

___:1002F6D3                 call    sub_10058CD0

___:1002F6D8

___:1002F6D8 loc_1002F6D8:                           ; CODE XREF: sub_1002F630+55j

___:1002F6D8                                         ; sub_1002F630+6Bj …

___:1002F6D8                 mov     [ebp+var_4], 0FFFFFFFEh

___:1002F6DF                 call    sub_1002F701

___:1002F6E4                 mov     eax, [ebp+var_24]

___:1002F6E7                 mov     ecx, [ebp+var_10]

___:1002F6EA                 mov     large fs:0, ecx

___:1002F6F1                 pop     ecx

___:1002F6F2                 pop     edi

___:1002F6F3                 pop     esi

___:1002F6F4                 pop     ebx

___:1002F6F5                 mov     esp, ebp

___:1002F6F7                 pop     ebp

___:1002F6F8                 retn

___:1002F6F8 sub_1002F630    endp

The file name they have is hardcoded and doesn’t change (even across mimic versions), so it’s obvious what we can do to abuse this fact:
bool IsMimicInjected()
{
HANDLE MimicIPC = OpenFileMapping(FILE_MAP_READ,FALSE,”0xA0C82E”);
if (!MimicIPC)
return false;
// You could do even more to check here by inspecting the memory
// mapped file but that is unnecessary.
CloseHandle(MimicIPC);
return true;
}
There you have it. WoWMimic detected yet again. This time though the bar has been raised heavily, as you can no longer hide just by restricing WoW’s security descriptors.
Your move, WoWMimic.