DLL劫持(HiJack)原理以及实现细节
2016-08-21 18:08
239 查看
Dll劫持(HiJack)原理以及实现细节
之前就说个要研究一下这个,今天自己尝试了一下,接下来就说下HiJack的原理以及如何实现,至于拿它来做什么,这个...不可描述。
原理:
这个技术的原理很简单,就是A.exe想要调用B.dll,并且使用里面的FunC函数,这样的话我们把B.Dll改名BB.Dll(有的不用,直接根据路径劫持),然后我们自己写一个B.Dll里面有一个FunC这个函数,然后我们在这个函数里加载BB.Dll,并且调用里面的FunC函数,之后我们在干一些自己的事,对于A.exe来说通常没什么异常感觉,这样我们的目的就达到了,记住此时的你,也就是B.dll的权限和内存归属都是A的,也即是你和A是一家的了,类似于代码注入之后直接修改内存一样。
原理:上面是最表面的介绍原理,接下来就在编程方面说下原理,因为WIndows上的Dll加载有一个默认的规则,就是先在主程序目录下查找B.dll,如果没有就在系统路径下找,如果还没有,就去环境变量路径里找,就因为这个我们可以轻松的在相应的位置给做劫持,然后问题就如果是实现劫持,就要知道B.Dll里面的所有函数名字以及函数参数,这个地方比较蛋疼,但是也不是绝对不可以实现,分为几种情况,首先就是公用库问题,随便看一下qq的目录:
看到那个zlib.dll了吗,他是个开源项目,我们可以直接找到源码,然后自己进行编译修改,刚刚我拿了另一个项目的zilb.dll,直接换进去,QQ正常运行了,so...,这个是一种方式,也是最省事的方式,还有一种方式比较麻烦,但是比较通用,就是我们先用CFF
Explorer进行dll的分析,把所有导出函数都拿出来,CFF Explorer是这一款软件:
安装后显示出来的那个大辣椒,得到dll导出函数时候我们可以直接用IDA去分析这个函数的参数,IDA就是上面大辣椒下面的那个程序,这两个需要自己安装,并且IDA安装的话估计比较蛋疼,直接找小伙伴要吧,还有就是有一点需要说明,IDA的话本身不能完全精准的翻译出来真正的函数参数类型,这个需要结合上下文理解,但是通常参数个数应该是对的,(而且貌似不需要真正的去模拟一定对的参数类型,好像说满足所谓的栈平衡就可以了,这个目前不理解,也不确定)。然后就是我刚刚随便写了一个DLL里面有一个函数是这样:
int Add(int a ,int b ,char c) 然后
CFF Explorer的结果是这样:
然后在IDA上进行分析结果是这样:
额...显然要结合上下文分析,逆向果真是一个耐心和悟性都要很高才能行的活,之后肯定会学习汇编和逆向相关的东西的再有就是驱动编程,这些都是好东西,但首要当前还是继续学架构和一些其他的东西吧,不管你是搞什么开发,什么方向,架构不行写出来的东西简直就是...,慢慢学一样一样来,都是好东西。
OK,接下来我就模拟实现一个Dll劫持的全过程。
需要准备的东西
A.exe(自己写的一个,直接调用dll里面Add函数)
B.Dll(这个是A调用的东西)
HiJack.Dll(劫持用的Dll)
根据使用的顺序进行编写吧,先来B.Dll
创建一个dll项目,然后添加一个类MyCode里面细节是:
MyCode.h #pragma once #ifdef TESTDLL_EXPORTS #define EXPORTS_DEMO _declspec(dllexport) #else #define EXPORTS_DEMO _declspec(dllimport) #endif extern "C" EXPORTS_DEMO int Add (int a , int b); MyCode.cpp #include "stdafx.h" #include "MyCode.h" int Add ( int a , int b) { return ( a + b ); }
然后创建使用者A.exe,就是直接调用一下
#include "stdafx.h" #include <windows.h> #include <iostream> using namespace std; typedef int (*AddFunc)(int a, int b); int main(int argc, _TCHAR* argv[]) { HMODULE hDll = LoadLibrary(L"B.dll"); if (hDll != NULL) { AddFunc add = (AddFunc)GetProcAddress(hDll, "Add"); if (add != NULL) { cout<<add(2, 3)<<endl; } FreeLibrary(hDll); } return 0; }
然后再来一个HiJack.Dll 这个里面我就直接默认调用BB.dll,BB.dll就是本身的B.dll,为了不重名真正用的时候会进行改名。(但是如果用的dll不在项目里的话就不用这样了,直接添加B.dll就行,因为dll的查找顺序是先找根目录,我们直接在根目录下放自己的就行了)。实现也是差不多,创建一个dll项目,然后有一个接口,不同的是接口的实现是我们直接载入BB.dll就行。
MyCode.h #pragma once #ifdef HIJACK_EXPORTS #define EXPORTS_DEMO _declspec(dllexport) #else #define EXPORTS_DEMO _declspec(dllimport) #endif extern "C" EXPORTS_DEMO int Add (int a , int b); MyCode.Cpp #include "stdafx.h" #include "MyCode.h" #include <iostream> #include <windows.h> using namespace std; typedef int (*AddFunc)(int a, int b); int Add ( int a , int b) { HMODULE hDll = LoadLibrary(L"BB.dll"); if (hDll != NULL) { AddFunc add = (AddFunc)GetProcAddress(hDll, "Add"); if (add != NULL) { cout<<"HiJack Success"<<endl; return add(2, 3); } FreeLibrary(hDll); } }
上面那个写完之后就可以直接把B.Dll改成BB.Dll,然后把HiJack.Dll改成B.Dll,放在一起,然后执行A.exe发现原来的B.dll被成功劫持。所有的东西都准备好了,我们来简单走一下流程加深理解。
1.首先我们分析下A.exe调用了那些DLL.
现用CFF Explorer 静态分析一次试试
额...结果只是分析出来几个系统的DLL,应该是因为我动态加载的原因或者别的吧,不过没事,
我们可以直接Procmon动态分析:
OK 动态抓到了它加载了B.dll。
2.接下来就分析B.dll的导出函数:
先CFF Explorer
找到导出函数Add,然后我们IDA分析一下B.dll
然后根据上下文分析,这个就看自己逆向能力和经验了,这个我经验不足,就不废话了,分析后确定结果是 int Add(int nA ,int nB)
2.根据分析结果实现HiJack
3.之后我们把A.exe和B.dll(改名BB.dll),HiJack(改名B.dll)放在一起,运行A看效果
注入前执行结果
注入后执行结果:
OK以上就是HiJack的基本实现,记住先找开源好弄的方式,比如那个zlib或者是导出少的dll等等,这都是简化流程,我上面说的是最最麻烦的那种情况才这么弄。然后我也看了下通常对手是如何防护HiJack的,他们的基本防护大体有两种,第一种是修改dll加载的顺序,就是直接就去系统目录加载,对方认为程序直接去修改系统目录下的dll成功率很低,而且如果装了杀软修改几乎就是不可能的,但是然并卵,因为他们实现这个功能的方式是修改注册表,...你改了,我在劫持前改回来不就得了,可爱的防护思路,还有一种比较绝的方式就是杀软的文件保护的那种方式,这个比较难破,目前不知道。而且告诉一个好消息,除了杀毒软件等特别的保护程序,很少有程序做到了dll保护和验证,因为保护涉及到的东西过于底层,代价比较大,验证的话对升级维护会造成很大麻烦。所以dll劫持目前依然可以横行装逼,让我想起了几乎给赶尽杀绝了的那个洪水DDOS攻击问题,MS已经封闭了伪造IP之后的那个sendto函数,之后会单独再好好说下这几天遇到的DDOS攻击思路和测试结果。
再补上一张被劫持后的A.exe的动态分析图片(里面可以看到A.exe加载了B.dll,但是BB.dll也被调用,HiJack.dll成功劫持了B.dll)
相关文章推荐
- 动网论坛上传文件漏洞的原理以及攻击的代码实现
- Net内存程序集通用脱壳机实现原理(二、反射以及重建方法头)
- 了解MmMapIoSpace以及MmUnmapIoSpace函数的实现原理以及实现方法
- MmMapIoSpace以及MmUnmapIoSpace,VirtualAlloc和VirtualCopy 函数的实现原理以及实现方法
- 点阵字库结构以及点阵字显示的实现原理
- 利用泛解析实现二级域名原理以及程序
- MmMapIoSpace以及MmUnmapIoSpace,VirtualAlloc和VirtualCopy 函数的实现原理以及实现方法
- [转载]蚁群算法ACO(ant colony optimization)的原理以及实现源代码
- 智能指针设计原理以及实现
- WinMain(windows程序的运行原理以及VC++的实现过程)
- 从功能实现的细节看SOA与OOA,以及SOA的优势何在
- TCP/IP原理、基础以及在Linux上的实现(转)
- 讨论 winform 引擎以及 CancelButton,OKButton 的实现原理
- 【z】蚁群算法ACO(ant colony optimization)的原理以及实现源代码
- HTTP PUSH技术原理,结合ASP.NET实现以及评述
- 动网论坛上传文件漏洞的原理以及攻击的代码实现
- 从功能实现的细节看SOA与OOA,以及SOA的优势何在
- 动网论坛上传文件漏洞的原理以及攻击的代码实现
- 点阵字库结构以及点阵字显示的实现原理
- 点阵字库结构以及点阵字显示的实现原理