问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

如何绕过Android网络安全配置

发布网友 发布时间:2022-05-02 12:12

我来回答

1个回答

热心网友 时间:2022-06-20 00:44

Android Nougat(Android 7)引入了一种名叫网络安全配置(Network Security Configuration)的新型安全功能,这种新功能可以允许Android开发者们在无需修改App代码的情况下自定义他们的网络安全设置。

但是这种功能将有可能影响Android移动端应用的安全测评。如果需要拦截HTTPS流量,那么就必须安装代理证书,而且还必须安装在“用户证书”之中,而默认情况下这类证书是不被信任的。

接下来,我们将给大家介绍这种新机制的运行模式,以及如何通过重新编译或运行时钩子机制来修改这种新型安全机制的默认行为。

开发者如何使用该功能

为了修改默认配置,我们需要在resources目录中创建一个XML文件来指定自定义配置信息。下面给出的是一份配置文件样本,代码给应用程序的所有HTTPS链接配置了用户证书:

<?xml version="1.0"encoding="utf-8"?>
<network-security-config>
<base-config>
<trust-anchors>
<certificates src="system"/>
<certificates src="user"/>
</trust-anchors>
</base-config>
</network-security-config>

除此之外,该文件还需要在AndroidManifest文件中进行引用,即在application标签中的android:networkSecurityConfig参数中指定:

<?xml version="1.0"encoding="utf-8"?>
<manifest ... >
<applicationandroid:networkSecurityConfig="@xml/network_security_config"
... >
...
</application>
</manifest>

渗透测试人员如何绕过该功能

重新编译

如果待测试的应用程序运行在Android 7以及更高版本的Android平台中(或者targetSdkVersion键配置为版本24或更高),应用程序很可能使用的是默认配置。因此,用户证书(例如代理CA证书)将不会被应用程序所信任。

一般来说,修改默认配置的方法是在插入了XML内容(激活证书容器)之后再对应用程序进行重新编译。那么接下来,我们就要使用apktool来对应用程序进行修改了。

首先,我们要做的就是使用apktool来对应用程序进行反编译。完成之后,我们还需要在resources目录中创建一个XML文件并修改AndroidManifest.xml文件中的相关参数(指向网络安全配置文件)。此时,我们就可以再次使用apktool来对应用程序进行重新编译,然后使用jarsigner工具来对生成的APK文件签名。

当我们使用任意证书完成对APK文件的重新签名后,我们就可以使用adb来将其安装到手机之中了。如果手机经过配置后可以通过中间代理(例如Burp Suite)来发送流量,那么只要手机系统中安装了CA证书,我们就可以拦截HTTPS流量了。

运行时钩子

但是在某些情况下,刚才所介绍的方法也许是不可行的。比如说,如果应用程序使用了shareId来跟其他应用程序共享同一ID,而我们又需要直接访问其数据的话,那么这两个应用程序必须使用同一份证书来进行签名。如果应用程序经过了重新编译和重新签名之后,那这个保护功能也就多余了,而且我们也不可能再使用开发者之前的初始证书来对修改后的APK进行签名。

对于这种场景,我们就可以使用动态构造技术了,因为这种方法可以允许我们在运行时对程序的行为进行修改而无须修改应用程序的代码。为了实现这种操作,我们需要创建一个Frida脚本来调整应用程序(目标SDK版本>=24)网络安全配置的默认行为。

android.security.net.config包实现了网络安全配置模块,其主类ManifestConfigSource可以加载XML文件中自定义的配置信息,如果resources文件不存在的话,它将会加载默认配置。相关代码如下所示:

package android.security.net.config;
public class ManifestConfigSourceimplements ConfigSource {

. . .
private ConfigSource getConfigSource() {       synchronized (mLock) {

. . .
if (mConfigResourceId != 0) {

. . .

source = newXmlConfigSource(mContext, mConfigResourceId, debugBuild, mTargetSdkVersion,mTargetSandboxVesrsion);
} else {
. . .
source = new DefaultConfigSource(usesCleartextTraffic,mTargetSdkVersion, mTargetSandboxVesrsion);
}
mConfigSource = source;           return mConfigSource;
}
}
. . .
}

DefaultConfigSource类是ManifestConfigSource类中定义的一个私类,如果没有使用XML文件来修改配置信息的话,系统将会默认使用这个类:

package android.security.net.config;
public class ManifestConfigSourceimplements ConfigSource {
...
private static final class DefaultConfigSource implements ConfigSource {       private final NetworkSecurityConfig mDefaultConfig;       public DefaultConfigSource(boolean usesCleartextTraffic, inttargetSdkVersion,                int targetSandboxVesrsion) {
mDefaultConfig =NetworkSecurityConfig.getDefaultBuilder(targetSdkVersion,
targetSandboxVesrsion)
.setCleartextTrafficPermitted(usesCleartextTraffic)
.build();
}       @Override
public NetworkSecurityConfig getDefaultConfig() {           return mDefaultConfig;
}       @Override
public Set<Pair<Domain, NetworkSecurityConfig>>getPerDomainConfigs() {           return null;
}
}
}

请大家看看这个类的构造器,它可以接收三个参数,其中一个就是应用程序的目标SDK版本。这个值可以使用getDefaultBuilder()方法来构造NetworkSecurityConfig类。在最后一段代码中,如果targetSdkVersion的值小于或等于23(Android Marshmallow,即Android 6.0),代码将会加载用户证书。

package android.security.net.config;
public final class NetworkSecurityConfig {
...
public static final Builder getDefaultBuilder(int targetSdkVersion, inttargetSandboxVesrsion) {
Builder builder = new Builder()
.setHstsEnforced(DEFAULT_HSTS_ENFORCED)                      // System certificatestore, does not bypass static pins.
.addCertificatesEntryRef(
newCertificatesEntryRef(SystemCertificateSource.getInstance(), false));              final booleancleartextTrafficPermitted = targetSandboxVesrsion < 2;
builder.setCleartextTrafficPermitted(cleartextTrafficPermitted);              // Applications targeting N andabove must opt in into trusting the user added certificate
// store.
if (targetSdkVersion <=Build.VERSION_CODES.M) {                  // User certificate store,does not bypass static pins.
builder.addCertificatesEntryRef(
newCertificatesEntryRef(UserCertificateSource.getInstance(), false));
}              return builder;
}

...

接下来,我们需要使用一个Frida脚本来挂钩DefaultConfigSource类的构造器,并修改其中的targetSdkVersion值。除此之外,这个脚本还需要挂钩getDefaultBuilder()方法来确保这个值已经被成功修改了。

Java.perform(function(){
var ANDROID_VERSION_M = 23;

var DefaultConfigSource =Java.use("android.security.net.config.ManifestConfigSource$DefaultConfigSource");
var NetworkSecurityConfig = Java.use("android.security.net.config.NetworkSecurityConfig");

DefaultConfigSource.$init.overload("boolean","int").implementation = function(usesCleartextTraffic,targetSdkVersion){
console.log("[+] Modifying DefaultConfigSource constructor");            return this.$init.overload("boolean","int").call(this, usesCleartextTraffic, ANDROID_VERSION_M);
};

DefaultConfigSource.$init.overload("boolean", "int","int").implementation = function(usesCleartextTraffic,targetSdkVersion, targetSandboxVersion){
console.log("[+]Modifying DefaultConfigSource constructor");            return this.$init.overload("boolean", "int","int").call(this, usesCleartextTraffic, ANDROID_VERSION_M,targetSandboxVersion);
};

NetworkSecurityConfig.getDefaultBuilder.overload("int").implementation= function(targetSdkVersion){
console.log("[+] getDefaultBuilder original targetSdkVersion =>" + targetSdkVersion.toString());            return this.getDefaultBuilder.overload("int").call(this, ANDROID_VERSION_M);
};

NetworkSecurityConfig.getDefaultBuilder.overload("int","int").implementation = function(targetSdkVersion,targetSandboxVersion){
console.log("[+] getDefaultBuilder original targetSdkVersion =>" + targetSdkVersion.toString());            return this.getDefaultBuilder.overload("int","int").call(this, ANDROID_VERSION_M, targetSandboxVersion);
};
});

现在,在上面给出的Frida脚本的帮助下,我们可以使用类似Burp Suite之类的HTTP代理来拦截应用程序(所有目标SDK版本>=24的应用程序)的网络流量。

$ frida -U -l ntc.js -f<package_name> --no-pause

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
钢琴谱一小段有三行怎么弹?最上是高音,然后还是高音,最后是低音?我用来... 请问跨专业考研都需要哪些方面的准备啊? 2013109期福彩双色球开奖号码 vivoy3手机如何长截屏 男友贪污也是网上追逃犯我还可以和他在一起吗 网上追逃犯罪嫌疑人住家里算是窝藏或是包庇吗 ps3海贼无双普通版有下载卡的吗? 关于PS3版海贼王无双和北斗神拳无双 PS3现在海贼无双3.55破解能玩了吗 我看网上说有破解补丁 谁能给个地址... 现在网上下载得到PS3的海贼无双。铁拳6,。高达无双3等游戏吗 Android模拟器 通过本地电脑上网 微信新版不好用,想下载旧版,原来的订阅号还有吗? 请教excel专家,怎样在单元格内加入下拉列表选项,下拉列表选项中的内容从另外工作表中提取。请教高手 花儿笑鸟儿和是哪首唱的歌曲 这首歌叫什么名 “我爱你一定爱到话花儿开了鸟儿把歌唱。。 我爱你已经爱到花都开了鸟儿大声唱。。 爱到牛郎织女。。。(。。。) 求歌名。谢谢 “我爱你,爱到花儿谢了,鸟儿把歌唱…”是哪首歌的歌词? “我爱你一定爱到花儿开了鸟儿…爱到牛郎织女为我们点头”出自哪首歌,歌词有哪些 歌词里【有我爱你爱到花都谢了鸟儿把歌唱】是什么 歌? “我一定爱你爱到海枯石烂鸟儿把歌唱”是哪首歌的歌词 我一定爱你爱到花儿谢了鸟儿把歌唱…歌名是什么 有首歌,歌词中有一句是“我爱你爱到花儿开了,鸟儿把歌唱,牛郎织女为我们点头”谁知道歌名是什么啊 我等你等到花儿开了,鸟儿把歌唱,等到牛郎织女为我们点头,这一首歌的名字叫什么啊 求歌词:我爱你爱到花儿开了鸟儿把歌唱 mysql里面 left join on 和 普通多表查询 有啥区别 我感觉区别不大 能否通俗点解释下 中行华为手表支付是什么? 篮球鞋的面料合成革与牛皮哪个更好? 合成格皮鞋有好优点比牛皮好的?小编介绍 怎么给苹果5手机设置接电话也需要输入锁屏密码? OPPO r15梦境版手机后壳摔碎了能修吗?修一下大概多少钱? 搭建Android环境后执行adb必须管理员身份运行吗? ADBOD FLASH PLAYERS安装的时候下载配置失败 如何辨别真假进口家具 手机能接电脑上网吗? 怎么玩HF跑跑``??? SOUI经常聊天的朋友+为何恋爱铃响 琼瑶写了多少小说? 公交车指什么生肖 541路公交车指什么生肖肖? 励志的诗歌散文 公交车的服务员猜一生肖? 八年级物理:第三章凸透镜成像的规律 现代励志散文诗歌 大华坐公车为什么不用付钱?答案:因为公车还停在站上,能解十二生肖的哪生肖 (脑筋急转弯)公共汽车上,两个人正在热烈的交谈,可围观的人却一句话也没听到,就是因为什么?提示,聋 谁知道励志类散文诗歌急需 急急急!!!八年级物理课程,凸透镜成像规律总结一下 宛转蛾眉马前死打一生肖 励志的散文诗集 励志诗歌散文