关于最近的 Typecho 安全漏洞

已经跟报告漏洞的相关方讨论过这个事情,大家的初心还都是技术层面的交流,之前在流程上由于沟通不畅造成了一些误解,现在误解已经消除,大家也不要恶意去揣测他人的意图,让我们把焦点放在技术本身。我们也一致表达了在安全层面加强合作的意向。

作为开发者其实不太想写这种针对性的回复文章。一般针对安全问题,如果有人报告我都是在第一时间提交修复。但这两天很多关心 Typecho 的朋友通过各种渠道向我询问最新爆出来的两个严重的安全漏洞,我看了网络上的分析文章,前面技术性的分析我在后面做回复。但是文中某些技术细节之外的无端猜测,是促使我写这篇文章的理由。

原文链接:
https://mp.weixin.qq.com/s/IE9g6OqfzAZVjtag-M_W6Q

修复方法

这一点是你务必要知道的,为了你的站点安全,你可以先暂时删除掉根目录下掉 install.php 文件,或者你也可以直接升级到最新的 Beta 版
注意在升级的时候也要覆盖 install.php 文件。

关于 XMLRPC 漏洞

第一个漏洞是 XMLRPC 里的 Pingback 协议,很多人可能不知道 Pingback 协议是干嘛的。我在这里简单解释下,这个协议诞生在 Web 2.0 概念诞生之初,由于在互联网世界各个博客站点之间是独立的存在,而它们之间又经常存在互相引用的情况。作为一个原创博主,我是无法知道我这篇文章被哪些站点引用过的,因此 Pingback 协议就是为了解决这个问题存在的。

当你在写的文章发表后,如果文中引用了某个链接,系统会自动向那个链接发一个 PING,告诉对方我引用了这篇文章,地址是: xxx。对方收到这个 PING 以后会根据你给的原文地址回去检验一下是否存在这个引用,这就是一次 BACK。检验完以后,会把这次引用记录下来,大家经常在 Typecho 或者 WordPress 之类博客评论列表里看到的引用记录,就是这么来的。

而造成这个漏洞的关键就在于这个 BACK 过程。系统回访的时候会调用网络接口(在 Typecho 里还对 CURL 做了基于 Socks 的 fallback),而当时的代码没有对回访的 URL 做验证,结果本意是让这个网络接口去访问 http 或者 https 的地址,但由于没做验证,导致它可以被用来访问任何协议,这就为攻击者创造了便利条件。

这个漏洞已经在上个月得到了修复,我们对访问的协议和地址都做了双重验证,只限于访问 http 或者 https 协议,并且限制了它的访问范围,不能用于访问内网或者本机的地址,而且还针对今后可能普及的 IPV6 做了预防。

关于 install.php 漏洞

这个漏洞本质其实比上一个漏洞更简单,原文的分析有点绕,其实只看最开始的部分就可以了,一句话解释就是 install.php 本身对安装状态验证存在漏洞,导致了可以绕过它向系统写入一些非法代码。

下面解释三个大家最关心的问题

为什么要用 Cookie 传递配置信息?

首先安装的过程会分很多步骤,而且每一步都要验证后再跳转到下一步。具体到填写配置信息的这一步,我们在你填写完以后会验证你的配置信息是否合法,比如数据库连接是否正确等等,这些信息是通过 HTTP POST 传递到 PHP 的。当这一步做完验证后,并写入相应信息后(也有可能不写入,比如 GAE 之类的容器环境,根本没有可写的环境),再 Location 跳转到下一步,也就是去写入初始数据。

熟悉一点编程的朋友,请回答我一个问题。如何在两个 GET 请求间传递配置数据?用 querystring?太丑陋了吧。用 session?对不起,很多主机都没有配好 session。用临时文件?不好意思,就像上面说的,很多运行环境根本没有可写的权限。用数据库?不行,数据表是在下一步的时候才建的。

所以我最后就用了 Cookie 来传递数据,这样你的安装过程会显得比较干净。

我个人认为,原文作者认为这可能是个后门之类的原因就在于,我对 Cookie 做了个 base64 的编码,这是黑客最爱的做事风格,把不可告人的代码隐藏在无意义的 base64 编码下面。

但是,我用 base64 只是为了避免可能存在的 Cookie 编码问题,这样一种很正常的思路,给它预设不好的前提后,往往会得出令人不快的结论。

为什么要在最后一步取出 Cookie?

原文作者指出他不明白为什么这里要有这段代码
https://github.com/typecho/typecho/blob/242fc1a4cb3d6076505f851fdcd9c1bbf3e431a5/install.php#L230

                <?php else : ?>
                    <?php
                    $config = unserialize(base64_decode(Typecho_Cookie::get('__typecho_config')));
                    Typecho_Cookie::delete('__typecho_config');
                    $db = new Typecho_Db($config['adapter'], $config['prefix']);
                    $db->addServer($config, Typecho_Db::READ | Typecho_Db::WRITE);
                    Typecho_Db::set($db);
                    ?>

如果你不联系上下文,当然不知道为什么要有这段代码。

首先解释为什么要在这一步连接数据库,因为这段代码看起来就是这个作用。初一看这一步好像跟数据库没什么关系,该写入的数据上一步已经写完了,这一步就是告诉用户安装成功

但是我们的目光再往下移
https://github.com/typecho/typecho/blob/242fc1a4cb3d6076505f851fdcd9c1bbf3e431a5/install.php#L258

                    <?php
                        if (isset($_REQUEST['user']) && isset($_REQUEST['password'])) {
                            $loginUrl = _u() . '/index.php/action/login?name=' . urlencode(_r('user')) . '&password='
                            . urlencode(_r('password')) . '&referer=' . _u() . '/admin/index.php';
                            $loginUrl = Typecho_Widget::widget('Widget_Security')->getTokenUrl($loginUrl);
                        } else {
                            $loginUrl = _u() . '/admin/index.php';
                        }
                    ?>

这是一段生成快速登录链接的代码,方便你在安装完成不需要输入密码直接进入后台,请关注 Typecho_Widget::widget('Widget_Security')->getTokenUrl($loginUrl) 这一段代码。

在 Typecho 0.9 里面,我们加入了防跨站模块,而它的核心就是在每次提交的时候加入一个 Token 供系统验证。而这个 Token 的生成是需要加盐 salt 的,而每个站点的 salt 都是在安装的时候写入到数据库中的随机字符串。

所以看到了么?生成一个合法的后台 URL 是需要数据库连接的。

然后再解释为什么要从 Cookie 里取数据,我们不是已经创建了 config.inc.php 文件了么?但是由于 config.inc.php 里定义的常量以及一些初始化动作,会与 install.php 头部的代码有所冲突。所以,我们无法在 install.php 去直接 require 它(这一点已经在新版里解决,我在这里只是解释当时那么做的理由)。因此,我们又要初始化数据库,就只能从 Cookie 里读取信息并解码了。

为什么不删除 install.php?

首先,删除 install.php 意味着需要给根目录赋予额外的写入权限,这本身就会造成安全问题。其次,很多容器环境,比如 GAE SAE BAE 之类的,代码是基于版本控制管理的,根本不可能让你去更改文件。那安装完成后提醒用户修改删除可以吗?首先,这么做没有技术问题,但我认为安装完以后再去删除,是一件很麻烦的事情,在保证没有漏洞的前提下,应该做到安装后即可使用,当然用户也可以自行去删除 install.php。

写在最后

首先,我欢迎任何以技术为目的质疑和交流,Typecho 这个项目也是依靠大家的力量一点点完善起来的。其次,我希望仅仅将这种质疑局限在技术本身,毕竟取一个吸引眼球的标题,最后再加一些揣测,又有多少人会真的去细思呢?大多数人都是会被带着节奏,而接受预设立场,这一点不利于问题的解决。

所以你们看,即使我认真写了这么多,仔细去看去分析的人估计也不会有多少。

Typecho 的社区个性一直是低调踏实,我们会认真对待每一项改进的提议。我想向那些因为此次软件漏洞可能造成损失的用户,表达歉意。

新的正式版,会在本周放出。

已有 37 条评论

  1. Bestony Bestony

    期待新版!终于要发新的正式版了。什么时候有空还在sf.gg开live啊?

  2. 李军博客 李军博客

    这下真相大白了

  3. 囧

    支持作者,国内就爱内斗,到时候都没人写了看网络怎么个样子。

  4. 飞翔的企鹅 飞翔的企鹅

    最近看了这个漏洞,总是对为什么不删除install.php有疑惑,这篇文章解答了我的问题,十分感谢

  5. 轻歌 轻歌

    关于最后一点,我做个建议,就是先尝试自动删除,如果无法删除,再通知用户手动删除。

    1. joyqi joyqi

      我会认真考虑这个建议,当然还需要兼容到不同的运行环境

      1. Silver Silver

        另一个参考方案,不删除install.php无法进入系统。这也是其他一些软件使用的方法。

  6. 你好 你好

    正式版终于要来了吗 等了好几年

  7. 某人 某人

    群主加一下我的联系方式吧

  8. 渐行渐远 渐行渐远

    支持typecho!

  9. 某人 某人

    当时是尝试联系过你,只是没有找到你的联系方式

  10. pingback R11; 眼望四周阳光照

    [...]关于最近的 Typecho 安全漏洞 – JoyQi’s Homepage[...]

  11. what is pingback in wordpress? R11; 眼望四周阳光照

    [...]关于最近的 Typecho 安全漏洞 – JoyQi’s Homepage[...]

  12. Coink Coink

    看到一些文章说230行的代码没有存在的意义,然后以阴谋论揣测,接着许多人附和,将其作为谈资。目睹了多次类似事件之后,感触颇多,希望更多的人能独立去思考,而不是随声附和,不加核实的传播消息。也感谢作者对于Cookie和install.php的解惑。

  13. lepture lepture

    既然喚作「先知安全技术社区」,居然是直接公開安全問題,而不是第一時間發郵件給作者,我不知其何以稱「安全技术社区」的。

    1. 1 1

      事情从头到尾了解清楚再喷好嘛,一口一个被带节奏,自己被带节奏了都乐呵的跟个傻逼一样,先知是最后发的,github有人通知作者,官网版本也更新之后,才放出来的。

  14. Jrotty Jrotty

    加油,终于要更新了哈,被bug逼的哈哈哈

  15. wsy wsy

    有人总想搞大新闻……

  16. Typecho 开发者:关于最近的 Typecho 安全漏洞 R11; 安百科技

    [...]作者:joyqi[...]

  17. 陈宇恒 陈宇恒

    我的博客被黑成了澳门赌场我才知道这个漏洞,幸好数据库没事。
    期待新版本!

  18. 姬长信 姬长信

    安装时手动删除了

  19. 阿宅 阿宅

    虽然目前不用typecho,不过一直都很喜欢这种简单明快高效的博客程序,感谢付出

  20. Silver Silver

    原文更多的是对漏洞PoC、构造ROP链的分析,而非对漏洞的分析,因为这个漏洞本身并不复杂。原文作者不知道install.php里那段代码的意义也很正常,因为打你机器的时候只要能打过去就行了,不会在乎那么多。怀疑是后门完全可以理解,xcodeghost尸骨未寒……

  21. helo helo

    太好了

  22. YIem YIem

    之前看到了没有当一回事,我的破博客今天晚上八点被搞了一波。。。

  23. minuo minuo

    大哥,更新周期的确是有点长了。

  24. 谈谈近期Typecho 的漏洞exploit及预防措施 | 土豆不好吃

    [...]joyqi[...]

  25. Typecho漏洞利用工具首发,半分钟完成渗透 R11; 安百科技

    [...]10月27日官方关于该漏洞给出的说明请看《关于最近的 Typecho 安全漏洞》。[...]

  26. Sakura Sakura

    刚刚才知道真的有这个漏洞

  27. Xman's Blog
  28. Typecho漏洞利用工具首发,半分钟完成渗透测试 | 安全渗透军火库|SHENTOU.ORG

    [...]10月27日官方关于该漏洞给出的说明请看《关于最近的 Typecho 安全漏洞》。[...]

  29. Typecho SSRF漏洞分析与利用 - SecPulse.COM | 安全脉搏
  30. tttt tttt

    可以把install.php文件的内容删除掉, 这样就算留个空文件也没什么影响了

  31. 林海草原 林海草原

    我之前遇到过一个软件专业的人。他说,只要软件在,bug永远在,除非软件停用了,bug也就没了。作者的态度很积极,而且我在github提交的bug很快也修复了,这是其他程序之所不能及的。作者加油!

  32. sailor sailor

    使用Typecho,一直因为其简洁的特性。

    看到好多Typecho新用户对作者抱怨更新太慢,功能太少,其实我觉得这样就别用Typecho了,求你们不要把Typecho变成Wordpress。需要主题多,插件丰富,功能强大的直接转Wordpress就好了啊?

    对于安全问题,作者第一时间修复,这就够了,感谢作者的付出。

  33. Typecho SSRF漏洞分析与利用 R11; 安百科技
  34. 明远网络工作室 明远网络工作室

    支持typecho 很简洁