array(5) { ["chapterid"]=> string(8) "49409217" ["articleid"]=> string(7) "7300050" ["chaptername"]=> string(8) "第24章" ["content"]=> string(3508) "SSRF打通。通过内网请求访问了云存储的元数据接口,拿到flag。

整个过程三十五分钟。

林墨靠回椅背,活动了一下脖子。颈椎咔嗒响了一声。他看了一眼时间——八点三十五。其他人还在做第一道题。

他把题目标记为"已解",打开下一道——五星的SSRF链,留到下午。然后端起桌上那杯已经凉了的豆浆喝了一口。豆浆是苏晚晴早上从食堂带的,一人一杯。纸杯上的食堂logo被他的手指蹭得模糊了。

在他左侧三个工位之外,赵一鸣正在跟一道五星的堆利用题搏斗。

赵一鸣没听林墨的话——做完三星题后直接跳到了五星。

三星题他用了八分钟,太简单了。他觉得不够刺激。

五星题是一道堆利用。简单说,就是通过操纵程序管理内存的方式来劫持程序的执行流程——让它跑你想让它跑的代码,而不是它本来该跑的代码。靶场是一个用C语言写的笔记管理程序,功能很简单:创建笔记、编辑笔记、删除笔记。每个笔记在内存里占一块空间,叫"堆块"。

漏洞出在编辑功能上:用户输入新内容时,程序不检查长度。如果你输入的内容比笔记原来的大小还长,多出来的部分就会溢出到旁边那块内存里,覆盖掉隔壁的数据。这就是"堆溢出"——像往一个小杯子里倒太多水,水漫到了旁边的杯子。

赵一鸣读完源码,开始构思攻击链。思路是:先利用堆溢出修改相邻堆块的大小信息,让两个堆块在内存里重叠;然后通过重叠区域,控制一个已经被释放的堆块的指针——这相当于拿到了一把"任意地址写"的钥匙,可以在程序的内存里任何位置写入任何数据。

有了这把钥匙,理论上就能让程序跳转到他想执行的代码。但问题是——往哪跳?

他查了一下靶场系统的glibc版本。glibc是Linux系统的核心库,负责内存分配、文件操作这些基础功能。版本号决定了哪些攻击手法能用、哪些不能用。

2.34。

他的手停在键盘上。

2.34是个分水岭。之前的版本里,glibc有三个特殊的"钩子"函数——你可以把它们想象成三把万能钥匙。只要覆盖其中一个,叫`__free_hook`,把它指向系统命令函数,然后释放一个内容是"/bin/sh"的堆块,程序就会弹出命令行——你拿到了系统的控制权。

但2.34把这三把万能钥匙全删了。彻底堵死。赵一鸣之前练过的所有利用手法,有一半是建立在这三把钥匙上的。

"操。"他低声骂了一句。

盯着屏幕想了三十秒,开始换思路。没有万能钥匙,就得找别的入口。他想到了FSOP——不攻击内存分配机制,转而攻击程序的文件处理系统。程序每次往屏幕上输出文字时,都要经过一个叫"标准输出"的结构体。这个结构体里有一张函数表,记录着"输出文字时该调用哪个函数"。如果能伪造这张表,让程序以为该调用的函数变成了他想执行的代码——下次程序刷新输出时,就会跳转到他的代码。

这条路更绕,更复杂,但不是没走过。他以前在2.31版本的glibc上做过类似的题。

前四十分钟进展顺利。堆块重叠构造完成,任意地址写的钥匙也拿到了。他可以在程序内存的任何位置写入任何数据——这是堆利用里最强大的能力。" ["create_time"]=> string(10) "1785963703" }