首页
社区
课程
招聘
Asis 2016 b00ks (off by one利用)
发表于: 2018-8-28 12:34 24605

Asis 2016 b00ks (off by one利用)

2018-8-28 12:34
24605

记pwn萌新解题的辛酸历程,写的尽量详细,让和我一样的小菜鸡都能看的明白清楚。


参考前辈的文章  
 https://cq674350529.github.io/2018/06/05/asis-ctf-2016-pwn-b00ks/   
https://bbs.pediy.com/thread-225611.htm  
写的非常清楚明白

首先用checksec查看一下b00ks文件的保护,发现开启了PIE,Full RELRO。

为了调试的时候方便,暂时关闭系统的地址随机化功能  echo 0 > /proc/sys/kernel/randomize_va_space

然后用ida打开分析程序的具体功能。

b00ks是常见的图书管理系统,功能如下:


off_by_one的漏洞位于如下函数:


当输入author name的时候,如果输入的字符串长度为32时,会溢出一个字节‘\00’。实际想内存中写入了33个字符。

分析create函数中如下代码


可知book_struct的结构如下:
struct book_struct
{
int id;
void * book_name;
void *book_description;
int description_size;
}
大小为32个字节。

并且book_struct的同意存放在一个静态的数组中管理global_struct_array中,以及author存放的地址也是一个静态的地址。


可知offset_book_strcut - offset_author_name = 0x20,恰好和之前分析的author_name输入时的off_by_one漏洞所需的字符串长度吻合。

因此,我们可以知道当author_name的长度为32B时,结束符‘/00’会溢出到global_struct_array的第一个数组元素当中去,然后如果我们create一个book之后,'\00'结束符会被覆盖掉,因此打印author_name的时候可以将global_struct_array的第一个元素泄露出来,即泄露出addr_book1。

调试程序看一下具体效果,因为我们不知道程序加载的基址,所以调试的时候下断点不方便,因此通过如下办法获取程序加载的基址(因为我们调试的时候为了方便已经禁用了PIE,所以多次加载程序的基址不变):
首先gdb b00ks,然后r运行程序。

程序启动之后,通过 cat /proc/pid/maps获取程序的内存信息,可知程序加载的基址为0x555555554000。因此之后设置断点时  基址+ida地址  = 实际运行的地址。

当输入author_name = 'a'*32后,查看内存信息如下:
x/10xg 0x555555554000+0x202040
溢出的'\00'的位置如图中标注所示

在create一个book_struct之后,内存信息如下所示,可以看到author_name的结束符被覆盖,通过打印author_name的信息可以将addr_book1的信息泄露。

然后在继续create book2,通过查看内存地址信息,可以知道addr_book2-addr_book1=0x30。因此exp的时候可以通过泄露addr_book1来得到addr_book2的信息。

然后在运用change_author_name的功能,重新溢出一个字节‘\00',然后global_struct_array中的第一个元素的地址改变,我们可以通过为book1_description申请大一点的空间,来使的被修改后 global_struct_array中的第一个元素的地址指向book1_description内的地址,然后我们可以在相应的地址重新伪造一个book1_struct。因为有print description以及edit description的功能,所以我们通过伪造book1_struct的description使其指向任意地址,通过打印或者edit来实现任意地址的读写。


change_author_name来实现溢出'\00',可以看到global_struct_array中的第一个元素地址由0x0000555555758160被改为0x0000555555758100,即指向了我们伪造的book1_struct。然后我们伪造的struct结构如下:
{

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2019-10-30 22:55 被Seclusion编辑 ,原因:
上传的附件:
收藏
免费 5
支持
分享
最新回复 (14)
雪    币: 2277
活跃值: (46)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
这篇终于能看懂了,膜dalao
2019-7-23 12:45
0
雪    币: 522
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
找到基地址以后下断点是要退出gdb以后再下断点吗?
2019-8-3 10:43
0
雪    币: 197
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
4
看懂一点点,自己始终是不够啊
2019-8-6 18:26
0
雪    币: 61
活跃值: (2390)
能力值: ( LV9,RANK:260 )
在线值:
发帖
回帖
粉丝
5
久久归 找到基地址以后下断点是要退出gdb以后再下断点吗?
嗯嗯 下断点就要重新下了 
2019-8-15 21:23
0
雪    币: 61
活跃值: (2390)
能力值: ( LV9,RANK:260 )
在线值:
发帖
回帖
粉丝
6
出嘿29398636 看懂一点点,自己始终是不够啊
加油 慢慢来 都是这么过来的
2019-8-15 21:25
0
雪    币: 177
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
请问如果不禁止PIE,怎样查找author在内存中的位置呢?
2019-9-15 01:22
0
雪    币: 61
活跃值: (2390)
能力值: ( LV9,RANK:260 )
在线值:
发帖
回帖
粉丝
8
零零七Robot 请问如果不禁止PIE,怎样查找author在内存中的位置呢?
我记不太清楚了,大概通过计算就可以。程序基址+相对偏移。
2019-9-15 08:52
0
雪    币: 177
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
已解决,用gdb查找字符在内存中位置即可
2019-9-16 17:24
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
10
师傅您好,我想请问一下在exp的第87行, mmap_addr: 0x7ffff7fb7010是怎么获得的?在vmmap中我找不到相关信息啊
2020-11-9 03:25
0
雪    币: 61
活跃值: (2390)
能力值: ( LV9,RANK:260 )
在线值:
发帖
回帖
粉丝
11
mb_hsppmskk 师傅您好,我想请问一下在exp的第87行, mmap_addr: 0x7ffff7fb7010是怎么获得的?在vmmap中我找不到相关信息啊
本地gdb调试的时候 p/x &mmap 查看mmap函数地址
2020-11-9 14:33
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
12
iddm 本地gdb调试的时候 p/x &mmap 查看mmap函数地址[em_76]
弱弱的再请教一下, 如果按照正常的做题开启ASLR的情况下, 又该如何获得这个地址呢...我现在关闭ASLR成功了, 但是开启ASLR又无法获得这个libcbase了, 毕竟它mmap函数地址也一直在改变啊
2020-11-11 02:35
0
雪    币: 61
活跃值: (2390)
能力值: ( LV9,RANK:260 )
在线值:
发帖
回帖
粉丝
13
mb_hsppmskk 弱弱的再请教一下, 如果按照正常的做题开启ASLR的情况下, 又该如何获得这个地址呢...我现在关闭ASLR成功了, 但是开启ASLR又无法获得这个libcbase了, 毕竟它mmap函数地址也一直在 ...
函数地址的偏移是固定的,泄露出一个函数地址以后,通过偏移就可以计算出所有函数的地址了。
你不理解的话,可以开启ALSR然后gdb调试,计算一下泄露的libc地址和libc基地址之间的偏移就懂了。
2020-11-11 18:14
0
雪    币: 6008
活跃值: (2590)
能力值: ( LV9,RANK:250 )
在线值:
发帖
回帖
粉丝
14
大佬,我book2开的0x21000结果泄漏出来,mmap在libc上面
2022-11-15 23:34
0
雪    币: 7
活跃值: (75)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
请教一下大佬,这个打本地我可以调试偏移,如果打远程得到那块mmap分配的地址后,但是远程不能调试该怎么计算偏移?
1天前
0
游客
登录 | 注册 方可回帖
返回
//