近期,作者通过测试Facebook安卓应用APP,发现可以利用其群组的文件下载功能实现针对Facebook安卓应用的任意代码执行(ACE)。

漏洞发现

作者在测试Facebook群组文件的下载功能时发现,其有两种文件下载机制。如果用户直接从群组帖子中下载文件,那么将通过内置名为DownloadManager的安卓服务下载,据我所知,这是一种安全的文件下载方法。如果用户要从群组的文件标签( Files Tab)中下载文件,那么Facebook安卓应用将会获取文件,然后将其无过滤措施地保存到下载目录中。以下是存在漏洞的修复后的代码片段,修复前的代码没有以下灰色的代码行:

路径遍历 

理所当然的是,第二种下载方法存在漏洞。虽然Facebook在上传文件时采取的一系列的安全措施,但却很容易被绕过。简而言之,Facebook安卓应用用户从Facebook群组文件标签中下载的文件会被存储到用户手机中的目录/sdcard/Downloads/FILE_NAME,这其中由于未对文件名FILE_NAME做过滤处理,导致此处存在目录遍历漏洞。之后,我马上想到的是,能否用路径遍历的方式重写覆盖掉程序的原本库来实现代码执行。

接下来,我用Burp代理拦截了文件上传的请求包,然后把其文件名更改为 ../../../sdcard/PoC,再进行上传:

不幸的是,由于Facebook服务端的安全措施,我构造的这个路径遍历Payload文件被删了,并且其它样式的Payload也不奏效,不能实现往/sdcard目录写文件的目的。

绕过安全措施

经过多次的Payload构造,也很难绕过安全过滤措施,最后,我回到了Facebook安卓应用本身,在添加文件处终有发现!

从这个添加文件功能处,首先,我发现可以从Facebook安卓应用中上传文件。因此,接下来我从手机中设置Burp代理,拦截捕获文件上传请求,把其中的文件名filename更改为../../../sdcard/PoC,之后,Payload文件成功被上传到了/sdcard目录,且文件名处的路径构造也是有效的。

然后,我尝试在群组发贴中来下载该文件,但是Facebook安卓应用的DownloadManger服务是安全的,无法找到破绽。还是在文件标签处(Files Tab)来做测试吧,首先,要明确我可以把文件上传到/sdcard/PoC目录。那就像之前考虑的那样,先来个路径遍历,再来个对原生库的覆盖重写试试。

漏洞利用

为此,我又创建了一个安卓原生库代码(Native Development Kit)来生成原生库,我把我的恶意测试代码放到了JNI_OnLoad函数中,以便加载库文件时可以对其进行调用。如下:

#include <jni.h>
#include <string>
#include <stdlib.h>
JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
    system(“id > /data/data/com.facebook.katana/PoC”);
    return JNI_VERSION_1_6;
}

通过对上述恶意原生库的生成构建,再把它用前述路径遍历+重写覆盖的方法上传到Facebook安卓应用服务端中。

/../../../../../data/data/com.facebook.katana/lib-xzs/libbreakpad.so

最终,以这种重写覆盖的方式可成功实现任意代码执行。

漏洞上报和处理进程

2020.4.29  漏洞提交
2020.4.29  Facebook安全团队成功复现
2020.4.29  漏洞分类
2020.6.16  漏洞修复
2020.7.15  Facebook奖励了我$10,000

关于赏金的讨论

当我公布该漏洞之后,Twitter上有一些网友说Facebook的赏金给少了,于是,我就试图和Facebook安全团队进行一些讨论。但他们说这个赏金数额是非常公平合理的,不管了,那就这样吧,反正漏洞已上报了。也许没报之前还有讨价还价的余地。

参考来源

medium

本文作者:clouds, 转自FreeBuf