pipe
1 | pipe: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=d5d6c196bf2c85c2c624a610ec541382acc30bb0, for GNU/Linux 3.2.0, not stripped |
- 64位,dynamically,全开
漏洞分析
1 | case 6: |
- 往
"./ctf.sh"
中写cat flag
就可以了
入侵思路
可以先把 cat flag
写入管道,然后把 pipe_buffer
中的数据写入 "./ctf.sh"
完整 exp:
1 | from pwn import * |
manageheap
1 | GNU C Library (Ubuntu GLIBC 2.35-0ubuntu3) stable release version 2.35.\n |
1 | manageheap: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /home/yhellow/tools/glibc-all-in-one/libs/2.35-0ubuntu3_amd64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=b988b53575c5a8324331c1b492940f6098e71ace, stripped' |
- 64位,dynamically,全开
漏洞分析
1 | num = LODWORD(chunk_list[index]->num); |
- 当
i==num
时,有8字节的溢出
入侵思路
先利用8字节的溢出来修改 chunk->size,释放后获得 unsorted chunk,接下来执行一次申请操作,泄露出遗留在 chunk 中的 main_arena 和 tcache->next
然后打 tcache attack,把 IO_list_all
写入 tcachebin 中,这里有两个注意点:
- libc-2.34 及其以上版本会设置 key 值,利用如下公式就可以绕过:
1 | key = heap_base // 0x1000 |
- 劫持目标 tcachebin 之前,需要先看看 tcache head->count 的值够不够申请到
IO_list_all
(当对应 count 为“0”时,程序将不会申请该 tcachebin 上的 free chunk),比赛时就考虑漏了这个问题,导致IO_list_all
申请不出来,浪费了很长的时间
在高版本 libc 中,最终劫持控制流的手段就那么几种,比赛时我使用了 house of cat
接下来就是标准的 house of cat 了,IO 流可以如下代码进行触发:
1 | if ( !read(0, chunk_list[i]->chunk_data, 8 * LODWORD(chunk_list[i]->num)) ) |
- 当输入的
chunk_list[i]->num
为“0”时,read
就会执行失败 - 然后调用
exit
触发 house of cat
由于本题目没有沙盒,我的第一反应是直接写 one_gadget
,后来打远程时环境不对,只能用 system("/bin/sh")
当时不知道怎么控制程序的参数,幸好 house of cat 触发后直接执行了 system("aaaaaaaa")
,于是我把所有的 "aaaaaaaa"
替换为 "/bin/sh"
然后就 getshell 了
完整 exp:
1 | from pwn import * |
PS:菜鸡 pwn 手的第一个3血
badshell
1 | GNU C Library (Ubuntu GLIBC 2.31-0ubuntu9.9) stable release version 2.31.\n |
1 | badshell: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=7b723a1405c35735c73c5600c68ee2c53b2a1f33, stripped |
- 64位,dynamically,全开
入侵思路
本题目没有做出来,比赛时没有时间做了,赛后复现找不到 wp 也很头痛
cpp 的堆环境很乱,并且逆向出来也很难看,暂时没有找到漏洞点,但通过遗留在 unsorted chunk 中的 main_arena 指针,和遗留在 tcache chunk 中的 next 指针,可以完成泄露
1 | touch("1") |
但程序只要执行过一次 echo
后(必须成功写入数据),再次执行 touch
和 mkdir
都会报错
暂时只能完成泄露了,找不到漏洞点