223heap
1 | GNU C Library (Ubuntu GLIBC 2.23-0ubuntu11.3) stable release version 2.23, by Roland McGrath et al.\n |
1 | pwn: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=4ae938aabdee25f8227c57fc1a4ef180897687a3, stripped |
- 64位,dynamically,Canary,NX
漏洞分析
1 | if ( (&chunk2)[index] ) |
- UAF
入侵思路
程序有 UAF 漏洞,可以考虑打 fastbin attak,利用程序提供的 magic 功能可以实现 double free,从而实现任意堆块申请
1 | canary = __readfsqword(0x28u); |
但由于 fastbin 有 size 位的检查,因此需要错位写,将 malloc_hook 前面的指针首地址 0x7f 作为 fake chunk 的 size,从而绕过 fastbin 的检查
再次之前需要先通过切割 unsorted chunk 来制作一个位于 0x70 的 fast chunk 备用
然后可以通过 Double free 覆盖 chunk->fd 的低4位来尝试完成堆重叠(这里需要1/16的爆破,同时需要写入数据来绕过 fastbin 对 size 的检查)
成功劫持 malloc_hook 上方的某个地方之后,可以覆盖 malloc_hook 为 one_gadget
完整 exp 如下:
1 | # -*- coding:utf-8 -*- |
car_manager
1 | GNU C Library (Ubuntu GLIBC 2.31-0ubuntu9.9) stable release version 2.31.\n |
1 | car_manager: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=7c203a4e97216a548fcfd7ab2f864bcf9e0f9e27, for GNU/Linux 3.2.0, stripped |
- 64位,dynamically,全开
程序分析
由于本程序的结构较为复杂,因此可以先用一个案例来试试结构:
1 | add("a","1") |
结构体 car_list:
1 | pwndbg> telescope 0x5564327a9390-0x10 |
- car_list 用于存储 cat 结构体指针,如果超过范围就会将其释放,并重新申请更大的空间
1 | pwndbg> telescope 0x5564327a8f30 |
0x5564327a8f30-0x5564327a8f48
和0x5564327a8f50-0x5564327a8f68
有点像 basic_string- 后面的
0x5564327a8eb0
就只有两个4字节的条目
可以猜测 car 结构体的条目如下:
1 | 00000000 car struc ; (sizeof=0x68, mappedto_19) |
在函数 new_a_car 中可以验证:
1 | std::string::basic_string(car); |
漏洞分析
在释放模块中有一个疑似 UAF 的点:
1 | car_by_index = get_car_by_index(car_list, index); |
- delete 指针没有置空,但程序对 car_list 进行了特殊处理:
1 | for i in range(3): |
1 | pwndbg> telescope 0x561b2ba0a190 |
- 如果释放的 chunk 不是最后一个,其后面所有的 chunk 都会往前移动
1 | for i in range(3): |
1 | pwndbg> telescope 0x55c8ed9ee190 |
- 如果释放的 chunk 是最后一个,则不会有特殊操作
真正的 UAF 在复制模块中:
1 | std::string::basic_string(car_copy, car_src); // 复制car的make |
- 函数 copy 会直接拷贝
car->tire.data
,这样会导致两个不同的car
占据同一个tire.data
- 如果将其中一个
car
释放,就可以通过另一个car
来修改 tcache chunk
入侵思路
利用 UAF 可以快速泄露 heap_base:
1 | for i in range(5): |
泄露 heap_base 后就可以修改 tcache->next 来实现堆重叠,进而修改 chunk->size 拿到 unsorted chunk,然后泄露 libc_base
最后劫持 tcache->next 到 free_hook,并注入 “/bin/sh\x00” + system 就可以了
完整 exp 如下:
1 | # -*- coding:utf-8 -*- |
over
1 | GNU C Library (Ubuntu GLIBC 2.31-0ubuntu9.9) stable release version 2.31.\n |
1 | pwn: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=d6a2a043e8258849ba2b9c5fd02bb700a0713f20, for GNU/Linux 3.2.0, stripped |
- 64位,dynamically,全开
漏洞分析
1 | writen("some add\n"); |
- 对于 num1 和 num2 的限制不到位,因此可以覆盖函数指针 func
- 函数指针 func 在如下函数中完成初始化:
1 | int (**init_s())(const char *s) |
入侵思路
通过溢出可以覆盖函数指针,计算 puts system 之间的偏移,然后修改 puts 为 system 即可
完整 exp 如下:
1 | # -*- coding:utf-8 -*- |
artist
1 | GNU C Library (Ubuntu GLIBC 2.31-0ubuntu9.9) stable release version 2.31.\n |
1 | pwn: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=9742fe0f588e66c62439c18f22559cc96a5137df, for GNU/Linux 3.2.0, stripped |
- 64位,dynamically,全开
漏洞分析
1 | int magic() |
- 任意堆地址置空
入侵思路
具体的思路就是利用任意堆地址置空来覆盖 tcache->next 指针,从而完成堆重叠
堆重叠以后就可以修改 chunk->size 来伪造 unsorted chunk,将其释放后就可以泄露 libc_base
利用堆风水即可第二次覆盖 tcache->next 为 free_hook,即可劫持程序执行流
完整 exp 如下:
1 | # -*- coding:utf-8 -*- |