首页
社区
课程
招聘
[原创]阐述一个利用Win32函数钩子防堆栈溢出的函数调用栈检测法
2008-7-5 13:31 14807

[原创]阐述一个利用Win32函数钩子防堆栈溢出的函数调用栈检测法

2008-7-5 13:31
14807
对Flash的溢出网马有痛恨的感觉,这个溢出太恶心了,所以公布一种切实可行的网页防漏防堆栈溢出的检测及防御技术

一、所用的的关键技术:
  1.  Win32 函数钩子(用Inline Hook比较牢靠)
  2.  简单的Win32 汇编语言编写
3. 了解Call 指令及Ret指令的函数调用栈的变化  

二、原理 :
当函数被调用时,在函数的入口是可以准确获取到调用该函数的原EIP地址,即调用起始地址,这个地址被 ret 指令作为返回地址用,这点就是被堆栈溢出病毒木马所利用的关键
而我们要做的就是在关键的一些系统函数入口处下钩子并对调用栈中函数的返回地址进行检测,如果发现该返回地址处于程序的堆栈地址空间,那么我们就可以很明确的知道有代码正在堆栈中执行,也就是说当前程序已经发生了堆栈溢出

三、所要下勾子的函数
VirtualProtect
  VirtualProtectEx
  NtProtectVirtualMemory
另外是所有创建进程及加载PE相关的函数
对以上所说的函数进行Inline Hook并在入口检测返回地址是否是当前堆栈中的地址就可以实现对网页的堆栈溢出攻击的防御

四、对系统Dll下完钩子后,别忘了用VirtualProtect将属性改回PAGE_EXECUTE_READ

    希望本技术能提升大多数网页防漏软件的功能及系统的安全,渴望回到远古流传的没有病毒的网络时代

  转贴请注明出处,别忘了这个技术源自一个普通中国人的想法

                                                                                             作者 :  antime zhang
      
       2008-7-5   上海山丽网安

最后BS 下国内某著名的杀毒软件产商,难道你就是这样对待同样做安全的其他软件产商的吗,你太强了,我佩服,佩服呀。。。。。。 哈哈

看看这图片


[培训]《安卓高级研修班(网课)》月薪三万计划,掌 握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

上传的附件:
收藏
点赞0
打赏
分享
最新回复 (32)
雪    币: 563
活跃值: (95)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
lixupeng 2008-7-5 13:43
2
0
看来误报很严重啊
雪    币: 10
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
gesily 2008-7-5 14:10
3
0
貌似是个不错的想法,不知道有没有实现的代码,发出来共享下。
雪    币: 1946
活跃值: (238)
能力值: (RANK:330 )
在线值:
发帖
回帖
粉丝
Bughoho 8 2008-7-5 14:32
4
0
向瑞星同志学习
雪    币: 207
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
lunglungyu 1 2008-7-5 15:06
5
0
瑞* 实在是敢作敢为
学习.
雪    币: 185
活跃值: (405)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
fireworld 2008-7-5 22:12
6
0
[QUOTE=;]...[/QUOTE]
只是可疑罢了~软件不是人 没这么智能吧
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
commport 2008-7-7 13:08
7
0
只是可疑罢了~软件不是人 没这么智能吧

呵呵,

再看看我2004年写的一个安全小工具,使用的是现在流行的HIPS理念
装上瑞星就把它当木马病毒杀了,看来有人没有分析就添加病毒库了
http://www.raslab.net/download/AntiVirus1.0.exe
雪    币: 375
活跃值: (12)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
xPLK 3 2008-7-8 13:18
8
0
刚才理解错了,不好意思。

我觉得,Inline也未必保险,ShellCode可以找个地方执行原始指令再跳到回原函数继续执行。。。
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
commport 2008-7-8 19:13
9
0
8楼

找一个esp也不是吃菜一样,随便夹都是,你还想把shellcode控制着当弹簧吗
虽说这种可能性是存在的,但在现实世界就....,呵呵 , 你可以花几年试试看
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
commport 2008-7-8 19:18
10
0
在stdcall类型的vc代码钩子函数中使用下面代码就可以了

_asm
{
     add ebp,4;
     mov eax,[ebp];
     sub ebp,4;
}

然后你再把eax值 mov到你的变量中去,就得到函数返回地址了
雪    币: 722
活跃值: (123)
能力值: ( LV12,RANK:300 )
在线值:
发帖
回帖
粉丝
轩辕小聪 7 2008-7-8 20:48
11
0
既然提到了flash网马,我记得楼主看过我的帖子呀,难道楼主没注意?事实是,那个Flash网马使用的shellcode,就正好绕过了楼主所提到的检测。
【原创】flash漏洞所用shellcode的分析中,提到shellcode调用LoadLibraryA的实现方式:

以下是我的帖子中的内容:
***********************************
接着是使用LoadLibraryA加载urlmon.dll并取得URLDownloadToFileA函数的地址。值得一提的是这里不是直接call而是用在子函数里用先push返回地址再jmp的方式。

00407069    6A 01           push    1
0040706B    59              pop     ecx
0040706C    68 6F6E0000     push    6E6F
00407071    68 75726C6D     push    6D6C7275
00407076    54              push    esp                                              ; 'urlmon'
00407077    8B06            mov     eax, dword ptr [esi]                             ; LoadLibraryA
00407079    E8 10010000     call    0040718E                                         ; (13)为了对付溢出检查,采用kernel32.dll中搜到的retn地址作为返回地址,调用LoadLibraryA。

0040718E    8B56 30         mov     edx, dword ptr [esi+30]                          ; (14)
00407191    41              inc     ecx
00407192    5B              pop     ebx
00407193    52              push    edx                                             
00407194    03E1            add     esp, ecx
00407196    03E1            add     esp, ecx
00407198    03E1            add     esp, ecx
0040719A    03E1            add     esp, ecx
0040719C    83EC 04         sub     esp, 4
0040719F    5A              pop     edx
004071A0    53              push    ebx
004071A1    8BDA            mov     ebx, edx
004071A3  ^ E2 F7           loopd   short 0040719C
004071A5    52              push    edx                                              ; 返回地址入栈,这里刚好是一个retn命令
004071A6    FFE0            jmp     eax                                              ; jmp进API函数开头
***********************************

这里shellcode就从kernel32.dll中搜索到了一个retn的地址,然后在调用LoadLibraryA的时候,采用先push这个地址,再jmp到API函数中的方法,完成一个等效的call。而且这时候,进入LoadLibraryA时堆栈的返回地址是在kernel32.dll中,而不是在堆栈中,因此就绕过了这种检测。

另外,这种思想卡巴斯基早就用了,而且这种绕过的方法也早就公开了,网上随便一搜,就看到安焦的文章:
http://www.xfocus.net/articles/200708/936.html
这篇文章不但讨论了卡巴斯基使用的这种方法(也就是楼主所提的这种方法)的缺点,还提出了更进一步结合对shellcode特征码的搜索来检测的思想。
雪    币: 375
活跃值: (12)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
xPLK 3 2008-7-8 21:09
12
0
不用我解释了吧~

还花几年~

雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
commport 2008-7-8 22:16
13
0
调用完LoadLibrary后又返回到栈上,然后再来URLDownloadToFileA跳转??
雪    币: 339
活跃值: (1510)
能力值: ( LV13,RANK:970 )
在线值:
发帖
回帖
粉丝
nbw 24 2008-7-8 22:23
14
0
是不是老纳同事?
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
commport 2008-7-8 22:37
15
0
11  楼的跳过了几重检测?
一重还是多重调用栈检测?
如果真要做溢出检测,估计我会写3重调用栈检测
雪    币: 375
活跃值: (12)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
xPLK 3 2008-7-8 23:16
16
0
[QUOTE=commport;477943]在stdcall类型的vc代码钩子函数中使用下面代码就可以了

_asm
{
     add ebp,4;
     mov eax,[ebp];
     sub ebp,4;
}

然后你再把eax值 mov到你的变量中去,就得到函数返回地址了[/QUOTE]

我的意思是:你不一能Hook到。
你Patch掉的指令可以去另外的地方执行。
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
commport 2008-7-9 00:53
17
0
Windows 是一层一层的函数往下调用
你就是到了sysenter指令进入内核之后,我们也可以同样的用调用栈还原之上的几个函数层的调用
并在函数的返回地址前后做检测
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
commport 2008-7-9 00:55
18
0
而抓住溢出攻击必然会有破坏动作,如下载文件,执行有恶意的函数等等行为,我们就可以通过类似于后续的它的操作去确认这个溢出的发生
雪    币: 375
活跃值: (12)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
xPLK 3 2008-7-9 09:59
19
0
无论怎样,你检测的基础是Hook。一旦被绕过或者是被欺骗(例如那个Flash的网马),一切都是0了。

见你挺能说的
放bin吧~

那样多好玩~~
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
commport 2008-7-9 11:32
20
0
看来又有人开始怀疑我的编码及设计能力了
呵呵
有意思
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
commport 2008-7-10 00:01
21
0
Flash 网马无敌了吗?
国内很多都可以拦住了,来试试这个

来看看2008年3月10日放出来的网页防漏工具

www.raslab.net/download/AntiSysLeak.zip

绝对的bin安装包
雪    币: 722
活跃值: (123)
能力值: ( LV12,RANK:300 )
在线值:
发帖
回帖
粉丝
轩辕小聪 7 2008-7-10 14:02
22
0
现在不是在讨论flash网马是不是无敌,flash网马只是一个举例,说明用来绕过这种栈溢出检测的方法已经被用在shellcode中了。
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
commport 2008-7-10 23:00
23
0
再往深处想想,有些检测是可以有算法行为库来实现的,为什么?

因为执行的操作很特别,肯定能找到行为的

硬件防溢出需要cpu支持,当前使用的这种防溢出方法可能全部使用jmp绕过

jmp esp等指令特征可能会误检测,

行为的方法虽然好,却没办法及时检测出溢出,

PAGE_GUARD 方法又只能对付HeapAlloc出来的堆

难道真没有更好的办法了吗?
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
commport 2008-7-11 11:44
24
0
有了新的方法了

函数调用行为分析法

为了防止新方法又被图谋不轨的人太明了,我这里就不公布了
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
www 2008-7-27 11:24
25
0
貌似是个不错的想法,不知道有没有实现的代码,发出来共享下。
游客
登录 | 注册 方可回帖
返回