博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[转载]DLL劫持生成器 源码开放(纯WINDOWS SDK)+ 实例分析
阅读量:6974 次
发布时间:2019-06-27

本文共 3092 字,大约阅读时间需要 10 分钟。

 本菜最近学习了什么DLL注入啊,hook啊(r3)的相关技术,觉得很好玩,于是深入发现还有DLL劫持这种东西觉得挺好玩的,加上最近看到各种木马分析报告中都还有发现有利用白加黑的现象。于是自己想找几个来玩玩,但是一个一个手动测试麻烦啊,于是想写个工具来测试目标是否存在DLL劫持漏洞的可能,于是就产生了写个工具的想法,上网一看,原来十年前都有大神写出来了,不过感觉有点麻烦,好多选项不知道干嘛的,加上本人只学了汇编和C,C++不太懂,平常都是做WINDOWS C编程,所以参考那位前辈的生成的代码改进成自己的,无奈不懂MFC ,他的源码我就没看,反正没事做,当作练练手,过程还真学了不少东西。可能有人说python三下五除二就出来。都说了无聊练习了,,,

  PS:本工具只生成常规的winowds调用方式的DLL代码,还添加了列出目标进程存在DLL劫持可能性的DLL。
  方便大家用来测试(sha)软(ren)件(fang)安(huo)全
  大神不喜勿喷啊,有错误的或者需要改进的还望指出。
0x00 工具简介
        名称:FakeLib
        开发环境:VS 2013 、 win10 x64
        开发语言:C  (纯windows sdk)
        作者:josegh
0x01 功能和使用
有两种模式:
  1.1 和aHeadLib一样,选择目标DLL直接生成这里我只生成常用的调用方式代码。
图 1-1
  1.2 通过查看进程列表,选择一个你感兴趣的进程,然后列出其加载的且不在系统
注册表KnownDlls中的DLL,然后选择一个目标来生成代码。
    1.2.1 选择侦察模式
图 1-2
     1.2.2 选择你感兴趣的进程
图 1-3
    1.2.3 选择目标DLL 生成代码
图 1-4
0x02 实际测试
  2.1 测试获取主进程函数调用参数和返回值。这里我自己写了一个测试程序
            
    2.1.1  正常 normal.dll,它导出一个函数

1
2
3
4
5
6
EXPORT DWORD add(DWORD a, DWORD b)
{
             
DWORD dwret = 0;
             
dwret = a + b;
            
return 
dwret;
}

    
    2.1.2 一个正常的loader,去调用normal.dll的add函数

1
2
3
4
5
6
7
8
9
10
11
DWORD dwResult = 0;
        
DWORD a = 5, b = 6;
        
add = (DWORD)GetProcAddress(hDll, 
"add"
);
        
if 
(add != NULL)
        
{
            
dwResult = add(a, b);
            
printf_s(
"loader:%d + %d = %d\n\n"
, a, b, dwResult);
        
}
        
else
            
printf_s(
"loader:获取导出函数地址失败\n\n"
);
        
printf_s(
"loader:重新获取控制权\n\n"
);

    2.1.3 用FakeLib工具去生成一个用来劫持的DLL利用代码
图 2-1
    2.1.4 重点部分在生成的代码中添加获取参数和返回值的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
void showArg(DWORD a, DWORD b)
{
        
printf_s(
"fake_dll:截取到参数:a:%d  b:%d\n\n"
, a, b);
        
return
;
}
void showRet(DWORD dwret)
{
        
printf_s(
"fake_dll:截取到返回值:%d\n\n "
, dwret);
        
return
;
}
///
//
导出函数 1
DWORD c, d, dwret;  
//
参数 a b,返回值dwret 在这里声明是为了不影响函数内部的堆栈
ALCDECL Fake_add()
{
//
以下注释经过OD调试得出 编译环境:win10 x64 vs2013,
        
//
一般情况下在这里为所欲为   注意堆栈平衡
     
        
__asm
        
{
            
push eax                
//
保存eax 以防目标函数用来做参数
            
mov eax, [esp +0x08]    
//
获取参数a
            
mov c,eax               
            
mov eax, [esp + 0x0C] 
//
获取参数b
            
mov d,eax
            
pop eax                 
//
恢eax
        
}
        
showArg(c, d);                                         
//
为什么不直接
printf
?
printf
是由调用者维护堆栈平衡,而我们现在这里的函数是naked声明的
                                                                 
//
不对自动维护堆栈,需要我们,为了方便,我们直接把它放到一个会维护堆栈平衡的函数里边执行
//
下边的同理
        
GetAddress(
"add"
); 
//
此时栈订保持的是返回地址,因为我们前面没有破坏堆栈
        
__asm pop dwRetaddress[1]                      
//
弹出来,下面菜可以用call,为什么用call?因为如果用直接jmp的话 想获取执行返回值有点困难
        
__asm call eax                                 
//
把返回地址入栈,这时候就相当于原来的返回地址被我们call的下一条指令地址入栈,这样真实函数返回后我们重新夺回控制权
        
//
一般情况下在这里继续为所欲为  注意堆栈平衡
        
__asm push eax      
//
保存返回值
        
__asm mov dwret ,eax
        
showRet(dwret);
        
__asm pop eax
        
__asm jmp dword ptr dwRetaddress[1]         
//
跳回原函数
}
///

  现在我们把它改名为 normal_dll.dll 放到loader目录下,执行loader的效果:
(此前你需要把之前正常的normal_dll.dll换个名字 如normal_dll_hide.dll)
图 2-1
  loader执行结果
图 2-3 执行结果
    可以看到先是我们的dll获取到返回结果。
  2.2
    略
    大家可以参考: http://www.freebuf.com/articles/78807.html
                        http://drops.wooyun.org/tips/13238#!
    乌云上也有许多例子,大家可以自己去写个测试程序,或者直接找实际的应用来测试
0x03 总结
  如果只是方便自己,我也许不会把工具的代码写得工整(自认为算是最工整的一次 - -),也不会去写界面程序。开始写导出函数的时候用的是常规的dllexport,运行的时候发现问题有点多,用OD调试发现原因是堆栈问题(菜得抠脚啊),都打算用生成汇编的算了,后面才发现有naked这种玩意,于是本着能用c就用用c的原则,最后还是选择生成c代码的方式。也算是涨姿势了。还有一点点小功能没添加,比如刷新什么的。
  还有,感觉自己菜得抠脚啊,有没有大神指点指点
0x04 使用注意
  有时候不能列出目标DLL,应该是权限问题。
源代码:

上传的附件:
  • (17.14kb,49次下载)
  • (15.21kb,26次下载)
  • (50.06kb,26次下载)
  • (62.72kb,33次下载)
  • (12.07kb,21次下载)
  • (5.42kb,129次下载)
  • (10.51kb,20次下载)
  • (6.09kb,36次下载)
  • (2.41kb,1309次下载)
  • (36.64kb,1611次下载)

转载地址:http://awrsl.baihongyu.com/

你可能感兴趣的文章
SQL server 2000常用字符串长度总结
查看>>
征服Perl——哈希——里程碑M7
查看>>
遇到女神应该使用什么样的暗恋思维
查看>>
HA(heartbeat)主备模式实现lvs群集的高可用性
查看>>
mtr路由监控
查看>>
容器编排 Docker Compose
查看>>
KVM 使用virtio驱动Windows server 虚拟机
查看>>
我的Oracle 9i学习日志(15)-- 表的管理
查看>>
mysql5.7更改密码
查看>>
adb无线网络调试
查看>>
Nginx+Keepalived搭建高可用负载均衡集群
查看>>
防火墙示例-用简单规则集保护网络
查看>>
记一次开发过程中的思维转换
查看>>
8. Accordion模拟菜单,Accordion动态绑定数据,模拟菜单点击
查看>>
基于Spring源码分析AOP的实现机制
查看>>
Windows Server 2016 Hyper-v Nested Virtualization
查看>>
30种图像动画特效算法(C#多线程版)(中)
查看>>
在VMware虚拟机中安装Linux/ubuntu系统(图文)
查看>>
WCF开发常见问题:“There is already a listener on IP endpoint 0.0.0.0:4503”
查看>>
现在还有perlmonks网站这样的网站?!
查看>>