前一段时间,公司某位实习生在做FOFA的协议分析的时候,问了我一个问题:这么多协议,FOFA如何取选择做哪些以及做到什么效果呢?我觉得这个问题挺好的,但这又是一个没有标准答案的问题,因为绝大多数人对于你有没有某个协议或者好不好是完全无感的,那么大家怎么知道做了有价值呢?
我们经常说“利他主义”,但是这种“利他”是一种极端自我感觉良好,在我看来,做不好“利我”就谈不上做好“利他”。因为一旦我们从利他角度来讨论问题,就比较容易进入“我不是用户”的视角,这在科技型产品型的团队是一个非常要命的红线问题。你不了解“他”是谁在什么场景有什么问题,这辈子瞎琢磨,是很难做出用户想要的效果的。
那一周的周末,我在研究AI结合类似jev这样的决策模型能做什么,我看到有人用它来做《街头霸王》街机的通关视频,又看到有人用来做《我的世界》的打末影龙的视频,感觉都挺有意思的。我并不玩minecraft,不过我小孩玩,我就拿它来验证一下decisions模型的效果找找体感。在小孩的推荐下,采用fabric 1.20.1经典版本,我让AI搭建了一台云上的minecraft的游戏服务器,再用客户端连接上去(因为需要ai控制一个玩家,另一个玩家做观察,所以不能单机模式)。搭建好AI框架后,我就给他指令让他制造一个“铁巨人农场”(实话说我并不知道是做什么的)。
我家娃在做作业,我在旁边跑AI,盯着它看了一个小时,就看着它走来走去砍来砍去,忙的不亦乐乎,看着看着我就有点困了,就跟小朋友说我去睡个觉,起来再看有没有做出来。
等我醒来的时候,我就听到霹雳吧啦的声音,我还以为是小朋友在偷玩电脑,他说是我的AI出问题了,全部都是岩浆,满屏幕的“凋灵”,还有核爆的标志,里面的Steve已经死了很多轮了……画面是如下这样的。画面下方,我们的 AI 玩家正在就义。这是他当天第 156 次死亡,凶器是凋灵。等救援结束时,这个数字停在了 175。


我第一反应是AI出问题了,自动刷装备的工具没有就算了,怎么还抑郁到自残呢?后来我看到了图片中的文本“trollled! by xxx xxx discord.gg/xxxx”,作为网络安全的从业人员,这种敏感度还是有的:应该是被黑了。这时候我的好奇心被点燃:怎么进来的?
赶紧翻服务器日志,翻出当天下午的两条登录记录: 15:35:56,某 IP 登录了 "xiaozhi"——我们另一个机器人的名字; 15:49:58,同一 IP 登录了 "Steve"。 IP 归属地:俄罗斯伏尔加格勒(88.87.xx.xx),一座以坚韧不拔著称的城市。这份坚韧,在冒充者拿着白捡的 OP开始,全部倾注在了六十二分钟的行为艺术上:
- 用 /team 把自己的名字改成一行 discord 广告;- 在屏幕侧边栏刷出巨幅字符画:"trolled! by …"(就是截图里那片紫色,打了码的部分);- 在世界里盖了一幅巨型像素涂鸦;- 召唤凋灵天团,专职追杀我们的 AI;- 顺手改了世界出生点,动机不明,大概是想给作品引流。
简单来说:离线模式(offline-mode)、全网开放、机器人有 OP,放到一起,似乎就是一个招引行为艺术的门牌。但是没有这么简单,即便我是离线模式,我是全网开放,他怎么能够登陆我的Steve和xiaozhi账号呢?Steve是个默认的烂大街的名称,那么xiaozhi呢?它可是中文拼音,一帮人不会这么去碰撞吧?
找了一些材料,大概就拼凑出了完整的故事:冒充者需要密码吗?不需要。原版 Minecraft 服务端根本没有"登录密码"这个概念。正常世界里,身份认证外包给 Mojang 官方会话服务器——开启正版验证(online-mode)时,客户端要先向官方证明"我是本人",服务器再和官方核对。我们为了机器人方便,把这道验证关了。
关掉之后,"你是谁"取决于一次纯数学运算:
UUID = MD5("OfflinePlayer:" + 用户名)这串 UUID 决定了你的一切:背包、家、以及最关键的——管理员权限(服务器的 ops.json 按 UUID 认人)。看出问题了吗?这是确定性函数:**名字相同,UUID 必然相同;UUID 相同,权限必然相同。**冒充不需要任何黑客技术,只需要在登录框里输入五个字母:S-t-e-v-e。 我们当场验证:手动算了一遍 MD5("OfflinePlayer:Steve"),和服务器 ops.json 里那串 UUID 对了一遍——一字不差。那一刻的心情,就像出门旅游十年,回家才发现钥匙一直在门口垫子下面,而全世界每一本《入室指南》的第一页都印着"先翻垫子"。
也就是说,只要攻击者知道用户名,那么就可以正常登录任何offline-mode的minecraft服务器。很扯,但是,好吧,那攻击者怎么知道minecraft的用户名呢?
FOFA是干这个的啊,我们很早就支持minecraft协议,随便哪一台就能看到,比如长这样的:

这里面的协议字段并没有能够看到当前正在运行了player name。
后来定位发现,Minecraft 协议有个"服务器列表查询",任何人不用登录、不用密码,敲一个查询包,服务器就会热情汇报自己的 MOTD、版本和当前在线玩家名单。第二,这和游戏版本无关——任何版本的离线服务器都长这样,这是模式的设计,不是版本的漏洞。而正是因为FOFA上线这个协议版本很早,pre-1.7 legacy ping还有用,只是数据字段少,用最新1.7+(2013 年至今)的现代 SLP的响应就有这个字段了,同时还增加了icon的图标。
后来的事情就比较简单了,提issue让同事们更新一下,最新的FOFA中minecraft协议的显示就是这样了:

于此同时,AI中间告诉我说为了控制游戏玩家,它是通过source-rcon协议来进行的,于是FOFA又增加了这个协议的详细字段信息,效果如下:

这两件事落实后,我的心里踏实多了。我已经忘记了当初为什么要去用ai控制minecraft了,我记住的事情是,我们又让FOFA的协议识别能力更强大了一点。可能对这个世界上99.9%的人来说,大家并不会关注世界上有一种协议叫minecraft,也不知道有一种协议叫rcon,更不知道offline-mode下,会有一堆的人盯着这批服务器,但是对于另外的那一部分喜爱minecraft的玩家来说,遇到行为艺术是他成长过程中的必经之路。当他们遇到这些问题的时候,就能够通过FOFA快速了解发生了什么。
之所以FOFA还在这持续运营着,就是因为几乎每隔一段时间,我们都能遇到几次类似于这次事件的故事。有时候是爆发了一次热点漏洞(比如php2shell的漏洞),有时候是一次爆款产品(比如帕鲁游戏),有时候是一种APT情报的追踪拓线,或者单纯的是一次商业产品的调研。我们并不能预知未来会发生什么,但是我们知道的是只要把公开的数据整理清楚了,这就是一个高价值的宝矿,它必然会给特定的用户特定的价值。最最重要的,我觉得是FOFA这个产品我们开发起来很好玩,能满足我们的好奇心,也能把我们的好奇心传递给我们的用户,当大家一起玩起来的时候,成就感就起来了。
类似这样的故事我们还有很多,最近这几天也是在处理一系列相关的事情,不断涌入的好奇心促使着我们去寻找更深层次的答案,以前可能要摸索个几个月时间方能有所收获,现在有了AI,我们就可以在一两天甚至实时的就能找到答案。所以技术的门槛很快就迈过去了,人类的作用就是找到需要解决的问题,就是去发挥创意。
最后,给geekcon致敬,这是国内网络安全技术的天花板。火眼金睛没有否决权就是一种眼病,我希望未来不说否决权,只要大家能正视网络安全,不要用公关手段对付技术问题,平等尊重就好了。毕竟大家的好奇心是有利于社会的安全发展的,现在成一件事需要大家共同支持,坏一件事真的只需要拆一块小积木,信任就轰然崩塌,网络安全最后还是由国家来买单。
声明:本文来自赵武的自留地,版权归作者所有。文章内容仅代表作者独立观点,不代表安全内参立场,转载目的在于传递更多信息。如有侵权,请联系 anquanneican@163.com。