2026软件安全赛半决赛PWN Robo_admin WP fix&break
字数 4170
更新时间 2026-04-22 13:35:36

2026软件安全赛半决赛PWN题目“Robo_admin”分析与利用教学

1. 题目概览

本题是一个CTF PWN(二进制利用)挑战,名为“Robo_admin”。选手需要利用一个管理员功能中的安全漏洞,最终目标是获取系统权限。题目主要涉及两种利用场景:“Break”(攻破)和“Fix”(修复),其中“Break”是利用现有漏洞获取权限的标准解法,而“Fix”是题目要求的一种变体,侧重于绕过额外的安全限制。

2. 漏洞原理与利用过程详解 (Break)

2.1 初始权限获取:格式化字符串漏洞

程序存在一个关键的 set_notice 函数,用于更新一个公告。函数内部逻辑如下:

  1. 读取用户输入到缓冲区 s 中,最大长度为 0x200 字节。
  2. 检查输入中是否包含非法字符 %$。如果包含,则输出错误信息并退出。
  3. 如果通过非法字符检查,输入会被送入一个名为 str 的函数进行处理。
  4. 处理后的内容被复制到全局缓冲区 s__1 中,并设置一个更新成功标志。

漏洞点:尽管程序在原始输入中过滤了 %$,但 str 函数实际上是一个转义/解码函数。经过逆向分析,该函数的作用是将形如 \x25 的ASCII码转义序列转换成对应的字符(如 \x25 -> %)。这意味着攻击者可以通过输入 \x25 来绕过对 % 的检查,从而在解码后的字符串中嵌入 % 符号,触发格式化字符串漏洞。

利用步骤

  1. 通过输入 \x25\x24 等转义序列,在解码后的公告字符串中构造一个包含 %p 等格式化占位符的payload。
  2. 程序在输出这个公告时,会执行格式化字符串漏洞,泄漏栈上的敏感数据。
  3. 在提供的Write-up(WP)中,利用此漏洞泄漏出了两个关键值:passwd1passwd2。这两个值与一个固定的 token 一起,用于通过管理员身份验证,进入 admin_function

2.2 堆利用:Off-by-one 与 House of Some

成功进入 admin_function 后,题目提供了一个堆管理器,具有常见的添加、编辑、查询、列出、删除任务(堆块)的功能。

漏洞点edit 函数存在一个Off-by-one溢出漏洞。在编辑堆块描述时,可以写入比堆块描述长度多一个字节的数据,导致覆盖下一个堆块的 size 字段的最低字节。

利用链构造

  1. 堆布局与塑形
    • 创建多个不同大小的堆块(索引0-6)。
    • 利用 edit 函数的Off-by-one漏洞,修改特定堆块的 size 字段,例如将 0x111 改为 0x161,目的是在后续操作中造成堆块重叠(overlapping chunks)。
  2. 触发Unlink并泄露地址
    • 通过精心设计的释放(delete)和重新申请(add)操作,触发 unlink 操作,从而在合并或分割堆块的过程中,让某个堆块的内容区域包含一个 main_arena 中的地址(即libc地址)。
    • 通过 query 功能读取这个堆块的内容,即可计算出 libc 的基地址。
    • 类似的技巧可以用于泄露堆(heap)的起始地址。
  3. House of Some 利用
    • 这是本题利用链的核心。House of Some 是一种针对高版本glibc(2.35及以上)的堆利用技术,通过伪造 _IO_2_1_stderr 或相关 _IO_FILE 结构体,最终目的是劫持程序控制流。
    • 利用堆块重叠,在一个可控的堆块(例如索引5)中写入一段 shellcode(用于后续执行)。
    • 在另一个堆块中构造一个伪造的 _IO_FILE 结构体(HouseOfSome 模板),并利用堆漏洞修改 tcachefastbinfd 指针,使其指向一个关键位置——_IO_list_all 符号。这是一个全局指针,指向 _IO_2_1_stderr 链表的头部。
    • 当程序下一次调用类似 exit 的函数,或触发 abort 时,会遍历 _IO_list_all 链表并调用其中 _IO_FILE 结构体的虚函数。通过将 _IO_list_all 指向我们伪造的 _IO_FILE 结构体,可以控制程序执行流。
  4. 最终利用
    • 在提供的WP中,利用 House of Some 将控制流导向一个ROP链。
    • ROP链调用 mprotect 将存放 shellcode 的堆内存区域设置为可执行(PROT_EXEC)。
    • 最后跳转到 shellcode 执行。
    • shellcode 的功能是:调用 openat2 系统调用打开 ./flag 文件,然后通过 readvwritev 系统调用将文件内容读取并输出。

3. 修复绕过分析 (Fix)

“Fix”部分要求参赛者修复漏洞,但WP作者展示的是另一种理解:题目本身可能要求攻击者去绕过新增的过滤。

新增的安全检查
set_notice 函数中,原始的检查是在解码前检查输入是否包含 %$。而“Fix”可能在代码的 .eh_frame 节(通常是异常处理或编译器生成的数据)中增加了一段补丁代码。这段补丁代码的逻辑是:

  1. 在调用 str 解码函数之后,再次检查解码后的缓冲区([rbp-310h])中是否包含 %(ASCII 0x25)或 $(ASCII 0x24)。
  2. 如果包含,则输出错误信息 [X] decoded input contains illegal chars 并退出。

绕过方法
尽管补丁增加了解码后的检查,但最初的利用方法依然有效。因为攻击者输入的是 \x25\x24 这样的转义序列。str 解码函数会正确地将它们转换为 %$ 字符。所以,解码后的缓冲区确实包含了非法字符。但是,关键在于触发漏洞的时机
格式化字符串漏洞的触发,发生在程序输出公告 s__1 的时候。而解码后的检查,发生在 str 函数执行之后、数据复制到 s__1之前。如果检查失败,程序会直接跳到错误处理并返回,不会执行 memcpy(s__1, src, ...)。因此,s__1 中的内容不会被更新,也就不会触发漏洞。

然而,WP作者指出,他们在实际挑战中“一开始没审题”,以为“Fix”是要去修复 off-by-one 漏洞。后来重新读题才发现,题目的真正意图是让选手绕过这个新增的过滤。WP中并未给出绕过这个“解码后检查”的具体方法,但留下了一个“嘻嘻收工~”的评论,暗示可能发现了检查逻辑的缺陷或另一种无需更新 s__1 即可触发漏洞的路径(例如,检查的缓冲区与最终输出的缓冲区可能不是同一个?文中未明确说明)。这通常是CTF比赛中需要选手自行探索的关键点。

4. 关键知识点总结

  1. 绕过字符过滤:通过输入ASCII码转义序列(如 \x25 代表 %)来绕过对特定字符的字符串检查,是Web安全和二进制安全中常见的绕过技巧。
  2. 格式化字符串漏洞:允许攻击者读取栈内存(泄露地址)或向任意地址写入数据。本题中用于泄露密码,完成身份验证。
  3. 堆利用基础
    • Off-by-one:单字节溢出,可用于精细地修改堆块元数据,是构造堆块重叠的常见入口点。
    • 堆布局与塑形:通过有顺序地申请和释放不同大小的堆块,来控制堆内存的布局,为后续利用创造条件。
    • 地址泄露:利用堆管理器的行为(如 unlink)将libc或堆地址放入用户数据区,再通过输出功能读取。
  4. 高级堆利用技术 - House of Some:适用于现代glibc(>=2.35),利用了 _IO_FILE 结构体在程序异常退出时的处理流程。其核心是伪造一个 _IO_FILE 结构体,并利用堆漏洞劫持 _IO_list_all 指针,从而在调用 _IO_overflow 等虚函数时获取控制流。这是一种结合了堆漏洞和IO流利用的复杂技术。
  5. 利用链构造:真实的漏洞利用往往是一个复杂的多阶段链条。本题的链条为:格式化字符串泄露 -> 身份验证 -> 堆溢出制造重叠 -> 泄露libc/heap地址 -> 布置shellcode -> House of Some劫持 _IO_list_all -> ROP链调整内存权限 -> 执行shellcode读取flag
  6. Shellcode编写:在限制环境下(如缺少 open 系统调用),使用 openat2 等替代系统调用来打开文件,并使用 readv/writev 进行读写。

5. 教学启示

  1. 代码审计要全面:不能只看表面过滤。set_notice 函数在解码前和解码后都可能存在检查点,需要追踪整个数据处理流程。
  2. 理解漏洞本质:格式化字符串漏洞的本质是用户控制了格式字符串参数。无论过滤发生在解码前还是解码后,只要最终传递给 printf 类函数的字符串是用户可控的并包含 %,就可能触发。
  3. 现代缓解机制的绕过:随着ASLR、NX、Stack Canaries、FULL RELRO以及glibc引入 tcache 等机制的普及,传统的栈溢出和简单堆利用变得困难。像 House of Some 这类技术,展示了攻击者如何利用程序中更复杂的组件(如IO流)在防护齐全的环境下实现利用。
  4. 工具与脚本的重要性:WP中使用了 pwntoolsLibcSearcher、自定义的 HouseOfSome 类等工具,自动化了地址计算、payload生成、交互等过程。在复杂的漏洞利用中,编写可靠的漏洞利用脚本(Exp)是必不可少的技能。

通过深入分析本题,可以系统性地学习从简单的字符过滤绕过,到复杂的现代堆利用技术组合的完整攻击面。

相似文章
相似文章
 全屏