我喜欢在不寻常的地方寻找灵感。几年前的夏天,一位朋友分享了一个关于 apt-get 启动 Dwarf Fortress (!) 的故事的链接,当时他们试图升级软件包或类似的东西。普遍的共识是,它涉及一些打算调用 df(如 /usr/bin/df,盒子上的命令)并获取游戏而不是“磁盘空闲”信息的东西。这是你读到它并只是呻吟的事情之一,但你没有深入研究,因为它没有直接咬你,你有自己的问题。
我给了它我通常的眼球,因为它完全属于“运行子进程以在库调用时获取信息”的桶。它还有一个额外的装饰,即使用在 PATH 中查看的东西,因此可能会误导以某种方式运行错误的东西。
这次聊天引出了一个不可避免的话题,当时有人写了一个卸载程序,做了类似“rm -rf $THING/”之类的操作,有时 $THING 会是空的,所以有趣的事情发生了。这通常使我们陷入“事情怎么会出错”的心态,以及“如果你想这样做,他们怎么能*被制造*出错”。 PATH 开始发挥作用的事实建议 system() 或 popen(),两者都通过 shell 运行,因此引入了注入您自己的命令的可能性。
因此,我们面前有一棵大型企业源代码树。除了其他内容之外,它还包含大量 C++ 和 C 代码。多年来,所有人都在编写代码,是否有人设法犯了同样的错误?用 grep 来表示 popen 并不难,所以我们做到了。三分钟后,我们发现了这个在整个机队上运行的“网络助手”服务,它是做什么的?
文件* 输出 = popen(command.c_str(), "r");
嗯,这很有趣。这是什么?它正在监听网络,并接受 RPC?它会为我们运行 traceroute 和 ping 吗?它需要像“目的地”这样的参数吗?所以,我们所要做的就是找到一个运行它的主机,制造一个目标包括一点奖励的 RPC,比如“127.0.0.1; touch /tmp/0wned”,然后启动它。
它愉快地运行 touch 并将文件放到 /tmp 中,从而证明我们可以让它以该用户的身份执行我们想要的任何事情。哦,是的,该文件归 root 所有,因为这个东西是以 root 身份运行的。分数!根到任何你想要的地方!
有了这个,我们现在有一个安全事件要处理。在那个特定的日子里,通常的安全窥视员正在忙着那天早上坏掉的其他东西。事实证明,这个“功能”已经在 prod 中运行了一年,所以让它再冷却几个小时并没有太大变化。我们让他们把火扑灭,然后把下一个满是“胜利”的燃烧垃圾箱递给他们。
因此,不知何故,与 Ask Ubuntu 上的某些内容相关联的 reddit 帖子的分享变成了一种在公司的任何机器上获取 root 的方式。这就是会发生的那种自由联想的事情。美好时光。