上海ctf2017 pwn100 && pwn200
前言
尽量详细,给有需要的学弟们看看
分析的 idb 文件在这:
https://gitee.com/hac425/blog_data/tree/master/shanghaictf
pwn100
程序是一个经典的 堆管理程序,基本增删改查功能。
add
功能很正常,分配8字节的内存然后写入8字节内容。把 分配到的 heap
指针存到 table
中,然后 count++
我们调试看看,使用 add
功能然后 看看堆的内容
可以看到尽管 malloc(8)
实际会分配 0x20
字节(0x10 chunk结构 + 8 + 8 字节 对齐padding)
所以这里应该没有溢出的问题,但是注意 count
变量会索引到下一个没有使用的 table
表项。
这个程序的问题在于,在 get_last
, edit
时会直接使用 table[count]
来获取要处理的指针, 而且在 delete
时就只是简单的 count--
,而且count
是一个有符号整数。这样多次 delete
后,count
会变成 负数。
然后 通过table[count]
(*(table + count*8)
) ,这样我们就可以通过get_last
, edit
来 泄露内存和 修改内存了。
ctf
中利用漏洞的目标一般就是执行 system('sh')
,在这里我们可以通过修改 got
表中atoi
函数的指针为 system
的函数,然后在调用 atoi
函数时,就会去调用 system
函数了。为什么要选择 atoi
函数作为目标呢?
在打印程序的菜单后,会要我们输入一个选项,这就会调用这个函数,可以看到他会读取 16
字节到 nptr
, 然后传到 atoi
,如果我们把 atoi
改成system
, 然后输入 sh
, 就会执行 system('sh')
了,目标达到。
由于是这样获取内存地址: *(table + count*8)
, 所以我们需要在 table
的上面(就是地址 < table的地址) 区域找到一个 指向 got
的指针。我们可以使用 pwndbg
的 searchmem
来搜索
属于
那么现在利用的思路就很清晰了。
- 首先多次调用
delete
函数使得table + count*8
指向 这里的atoi
函数对应的地址,也就是0x400588
.
然后我们就可以通过
get_last
功能打印atoi
函数的地址,通过atoi
在libc
中的固定偏移,泄露libc
的地址。然后获取
system
函数地址,然后使用edit
修改atoi
函数的地址改成system
函数地址。然后输入sh
即可。
exp(要跑 20几分钟左右):
|
|
pwn200
就是用c++
写的程序比较难看,不过看到程序的菜单,漏洞就很清楚了。
提示的很明显了,应该是 uaf
, 那我们就重点看看与内存分配相关的位置。
首先会分配两个结构体,其中开始8字节被写入了函数的指针。
可以看到内存块的大小为 0x40
大小。通过 new(0x30)
分配得到,所以 new
和 malloc
的分配方式应该是一样的。接着往下看。
选择2
时,可以有我们提供大小,传到 new
,然后通过 read
写入内容。
free
时会调用 delete
释放掉内存块。free
之后可以看到进入了fastbin
那此时我们使用 2
号功能,连续分配两块 48
(0x30) 字节的内存,就会拿到这两块内存了。
程序中内置了getshell
函数
所以我们在拿到那两块内存后,把开始 8 字节写成 getshell-8
函数的地址就行了。(减8的原因看下图)
然后使用 1
功能,就能调用了。
exp中把 开始 8 字节改成了 0x0602D50
exp:
|
|
本站文章均原创, 转载注明来源
本文链接:http://blog.hac425.top/2017/11/05/shctf2017_pwn100_pwn200.html