我正在调查 arm64 上的格式字符串漏洞(与 musl libc 相关联),并且在调试输出时遇到了一些奇怪的行为。
从反编译来看,该程序存在一个经典的格式化字符串漏洞,归结为:
fprintf(stdout, user_controlled_data);
使用重复的格式说明符(例如%p%p%p%p),我可以通过包含数千个这样的字符来转储大量内存。这按预期工作。
当我尝试直接参数访问时出现问题。出于某种原因,%1$p有效但无效%2$p,但 3 到 12 次有效,之后我尝试的一切都失败了。通过“失败”,我的意思是不打印任何值,除了在代码中自动添加到我的字符串中的换行符以某种方式被吃掉了。在调试器中,fprintf返回 -1,并errno设置为 0x16,我认为这是 EINVAL。
对于这个特定场景,我需要能够读取/写入数千个特定堆栈偏移量。但是我无法打印它来确认,因为直接参数访问不起作用。我可以通过使用重复字符来查看目标参数,但由于其他限制,我需要直接参数才能继续工作。
现在,我明白这是在“未定义的行为”领域,但我在系统上编译了一个易受攻击的测试二进制文件(与 Glibc 静态链接,我可能应该尝试对抗 musl),它按预期工作,没有问题(例如%9000$p打印一些东西)。
有什么会导致这种行为,还是我遗漏了什么?如果需要,我可以提供更多信息。