hackme.inndy.tw petbook writeup
TOC
本题原本有简单的方法,但是刚开始我没发现,所以用的方法比较复杂。
原题地址:https://hackme.inndy.tw/scoreboard/ 。 靶机环境是 glibc-2.23 。
源程序和相关文件下载:petbook.zip 。
更快的方法
我先介绍来自pwn大佬carlstar
的思路。
溢出点
void __fastcall user_create(char *username, char *password) |
user_create
时没有初始化pet
,可以用污染的chunk来设置pet
,从而通过下面的代码实现任意读。
int user_loop() |
之后泄露出magic之后,利用pet_rename
实现任意写。
void __cdecl pet_rename() |
笨方法
这个是我自己做的,方法比较笨。
溢出点
char *__fastcall stripnl(const char *a1) |
stripnl
字符串可以将字符串后面字节为0x0a
改为0x00
,但是该函数,没有限制长度,所以存在溢出。
void __fastcall read_data(char *buf, __int64 length) |
read_data
函数虽然为了null
截断做了很好的防护,但是当输入的字符串长度为length
,就没有办法null
截断,因为没有null
截断,我们可以读取到后面的内容。
思路
- 泄露libc
- 构造heap布局
- 劫持hook
泄露libc
New(0x160, 'hello\n') # 2 |
由于edit
函数内部用的是realloc
,所以申请的0x160
chunk就会被free
到unsorted bin
中,那么自然会有main_arena
指针残余,我们只要让输入的内容不被null
截断即可泄露出该地址,那么只需要把New
的size
设置为8
则正好。
构造heap布局
这个就比较复杂了,用到的是stripnl
函数的没有长度限制的漏洞。最终效果是chunk overlapping
。
先看看Post
的布局:
00000000 Post struc ; (sizeof=0x110, mappedto_7) |
在user_edit_post
中,会对post->title
进行stripnl
操作,而该操作会影响到post->content
指针,该指针指向heap
。
int user_edit_post() |
所以我们可以通过使用污染的chunk
来使得post->field_104
的值不为空,那么stripnl
函数便可以修改到post->content
。
当post->content
指向的heap地址的为0x.......0a..
时(点为任意十六进制),则在stripnl
操作中就会被修改为0x.......00..
。所以我们只需要提前在这个地址布置好heap结构即可。
New(0x118, 'e' * 0x118) # 4 |
上面脚本中,第9个
就是布置地址为0x.......0020
的fake chunk
的size
。
edit(5, 0xf8, '\n') |
通过上面一系列的布局之后,则使得第10个post
的content
地址则刚好为0x........a20
,受随机话影响,当地址为0x.......0a20
则会导致溢出,所以几率是1/16
。
下面是调试结果:
Breakpoint 1, 0x0000000000400c84 in stripnl () |
上面的调试信息结果已经很明显了,rdi
(第一个参数)为0xf4f834
,由于没有null
截断,最终将修改0xf4f930 + 8
上的0x0000000000f50a30
为0x0000000000f50030
(post->content指针)。
在看看0x0000000000f50030
地址的情况,由于之前我们已经布置好了栈结构,所以这里会chunk overlap
。
其布局如下:
pwndbg> x/16gx 0x0000000000f50030-0x30 |
最后就是通常的劫持hook操作。
完整脚本
受随机化影响,概率是1/16
。
##!/usr/bin/python2 |
运行实例
ex@Ex:~/test$ ./exp.sh exp.py |