Partial_RELRO_got it
本文最后更新于 2024年10月9日 上午
Partial_RELRO_got it
RELRO
RELRO保护有三种形式
Partial_RELRO
一些段(包括.dynamic,.got等)在初始化后会被标记为只读,并没有包括got表,简单来说就是got可写
Full RELRO
除了Partial RELRO,延迟绑定将被禁止,所有的导入符号将在开始时被解析,.got.plt段会被完全初始化为目标函数的最终地址,并被mprotect标记为只读,但其实.got.plt会被直接合并到.got,也就看不到这段了。另外link_map和_dl_runtime_reolve的地址也不会被装入。简单来说就是所有段不可写
not RELRO
没有开启保护,所有段基本都可写
题目_MoeCTF_Got_it
这个题目被设计的很巧妙,我们来分析一下
vlun函数
这个函数很简单,输入三个不同的数执行不同的程序
当输入的数是3时,说会给我们一个礼物,这确实是一个礼物,是后面的解题的关键
calc函数
这是一个简单的计算器函数,一开始输入要对哪一个仓库进行操作,但是没有输入限制,存在溢出漏洞,我们可以溢出save区域的地方进行操作
并且v3的数据类型是__int64,是一个非常大的数据类型,再结合上面vuln函数中有一个puts(save),那么思路就很明显了,就是把puts的got表该有system,在save中输入/bin/sh
错误思路
可以看到save距离got表的距离并不远,我一开始想直接输入负数,往上溢出,但后来发现不行,可能与scanf读入的是无符号数有关
save距离puts_got表的距离是-16()(0x4080-0x4000)/8)
那我们输入试试
可以看到now_save存入了0x555d55558000
但是put_got表的位置是0x555555558000,很明显是失败了
正解
改写got表
既然不能往上溢出那就只能往下了
我们知道计算机的原理是把要操作的位置的地址存入now_save中,再进行操作
而now_save刚好就在save的下方,那么,如果我们在now_save的位置存入now_save的地址,那不久可以对now_save的内容进行加减乘除了吗?now_save到puts_got表的距离是固定的,也就是说我们可以通过加减,从而让now_save的内容从它本身变成puts_got表的地址
1 |
|
可以看到此时now_save存的是他本身的地址
这时存的已经是puts_got表的地址了
那么我们再来一次就可以把puts_got表的内容改成system的libc地址
这里的知识点是libc里函数之间的偏移是固定的,知道一个地址就可以通过加上某个偏移得到另一个地址
1 |
|
可以看到此时puts_got表指向的地址已经变成了system
输入/bin/sh
这一步较为简单,唯一要注意的就是这是个小端程序,字符串要反着输入
1 |
|
我个人推荐这一步可以放在改got表的前面进行
最后在返回vuln函数的puts(save)即可getshell
exp
1 |
|