APP绕过直连、系统证书校验、代理检测、双向认证的抓包限制,进行抓包

原创 橙留香Park 2022-09-23 02:00

也许每个人出生的时候都以为这世界都是为他一个人而存在的,当他发现自己错的时候,他便开始长大

少走了弯路,也就错过了风景,无论如何,感谢经历


本篇文章遇到排版混乱的地方,可点击文末阅读原文或前往该地址:https://orangey.blog.csdn.net/article/details/126219975

更多关于Android安全的知识,可前往:https://blog.csdn.net/ananasorangey/category11955914.html

=


0x01 HTTP 直连


httpstest APP 中使用的https访问组件是okhttp3,直接访问http协议的url 即可。不需要进行任何多余的配置,只需要配置好代理,http流量会被代理软件抓到

/*
* http协议
*/

button_http_connect.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread(new Runnable() {
@RequiresApi(api = Build.VERSION_CODES.N)
@Override
public void run() {
OkHttpClient mClient = client.newBuilder().build();
Request request = new Request.Builder()
.url("http://www.vulnweb.com/")
.build();
Message message = new Message();
message.what = 1;
try (Response response = mClient.newCall(request).execute()) {
message.obj = "http connect access vulnweb.com success";
Log.d(TAG, "http connect access vulnweb.com success return code:"+response.code());
} catch (IOException e) {
message.obj = "http connect access vulnweb.com failed";
Log.d(TAG, "http connect access vulnweb.com failed");
e.printStackTrace();
}
mHandler.sendMessage(message);
}
}).start();
}
});

打开Burp,并在Android 设备中配置好代理,然后打开APP后点击【HTTP CONNECT】按钮,APP成功访问,并在显示 http connect access vulnweb.com success,Burp也成功抓到信息,如下:

0x02 HOST校验

样本APK地址:https://github.com/AndroidAppSec/vuls/releases/download/v2.1/vuls2.1.apk

对于开发者来说,在测试环境中,通常会使用自签名的证书。正常情况下是无法进行 https 通信的,于是很多开发者就会在代码中忽略证书错误。但是在上生产环境的时候,又忘记去掉相关的代码,就会出现 https 通信被中间人攻击的情况。

以下是一段典型的忽略证书错误的写法,在 TrustManager 中不做任何校验,在 HostnameVerifier 中总是返回域名正确。

// 该方法检查客户端的证书,若不信任该证书则抛出异常
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
... ...
}

// 该方法检查服务器的证书,若不信任该证书同样抛出异常
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
... ...
}

// 返回受信任的X509证书数组
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}

final HostnameVerifier hostnameVerifier = new HostnameVerifier() {@
Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
}

new Thread(new Runnable() {
@Override
public void run() {
try {
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustManagers, new SecureRandom());

URL url = new URL(baidu);
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
connection.setSSLSocketFactory(sslContext.getSocketFactory());
connection.setHostnameVerifier(hostnameVerifier);
connection.setConnectTimeout(5000);
connection.setReadTimeout(10000);
connection.connect();

int responseCode = connection.getResponseCode();
if (200 == responseCode) {
runOnUiThread(new Runnable() {@
Override
public void run() {
Toast.makeText(HttpsURLConnectionActivity.this, "请求成功", Toast.LENGTH_LONG).show();
}
});
}
connection.disconnect();
} catch (Exception e) {
e.printStackTrace();
runOnUiThread(new Runnable() {@
Override
public void run() {
Toast.makeText(HttpsURLConnectionActivity.this, "请求失败", Toast.LENGTH_LONG).show();
}
});
}
}
}).start();
}

如上代码会造成APP,在进行 https 通信与 http 通信效果无异,都会受到中间人攻击


Android7 抓包问题解决

目前在Android 7.0或以上的系统有启用了对第三方证书的限制,但在Android 7.0以下依旧可以将Fiddler/Charles/Burp的证书安装在用户的CA集中抓取https请求

将Burp或者Charles的证书作为系统级别的信任证书安装。建议重新生产burp证书并重启burp后再导出。系统级别的受信任证书以特殊格式存储在/system/etc/security/cacerts文件夹中。我们可以将Burp的证书写入此位置。

导出一个Burp/Charles证书之后,adb push到模拟器,然后修改后缀为crt直接安全,这种方式在Android 6及之前的版本可用,从Android 7.0开始,Android更改了信任用户安装的证书的默认行为,应用程序仅信任系统级CA。这样就导致安装证书后,如果尝试通过Burp或者Charlse代理访问https网站,系统会提示“该证书并非来自可信的授权中心”

对于Android 7.0 (API 24) 之后,做了些改动,使得系统安全性增加了,导致:

  • APP 默认不信任用户域的证书

    • 之前把抓包工具的ssl证书,通过【从SD卡安装】安装到受信任的凭据 -> 用户。就没用了,因为不再受信任了

    • 只信任(安装到)系统域的证书

    • 导致无法抓包https,抓出来的https的请求,都是加了密的,无法看到原文了

对此,总结出相关解决思路和方案:

  • 让系统信任抓包工具的ssl证书

    • 作为app的开发者自己:改自己的app的配置,允许https抓包(得到或本身有app的源码,把证书放到受系统信任的系统证书中去)

    • 把证书放到受系统信任的系统证书中去(root权限)

  • 绕开https不去校验

    • 借助于其他(JustTrustMe等)工具绕开https的校验(例如XPosed、太极XPosed等框架)

Android7抓包问题,解决方法:

  1. 导出Burp的证书后,使用openssl来做一些改动,最后上传到/system/etc/security/cacerts

 

root@kali:~# openssl x509 -inform DER -in cert-der.crt -out PortSwiggerCA.pem
root@kali:~# openssl x509 -inform PEM -subject_hash_old -in PortSwiggerCA.pem|head -1
root@kali:~# mv PortSwiggerCA.pem 9999.0

  1. adb传输文件报错couldn‘t create file:Read-only file system解决方法

D:\>adb shell
VOG-AL00:/ # mount -o remount -o rw /system
mount -o remount -o rw /system
VOG-AL00:/ # exit;
exit;

D:\>adb root
adbd is already running as root

D:\>adb remount
remount succeeded

D:\>adb push 9999.0 /system/etc/security/cacerts
330 KB/s (1330 bytes in 0.003s)

D:\>adb shell chmod 644 /system/etc/security/cacerts/9999.0

再次输入adb push就能正常传输文件

Android10 抓包问题解决

Android10以上需要刷入Magisk,在模块里搜索move Cert ,安装模块,重启后证书就已经被移动到系统目录(system/etc/security/cacerts),可以正常抓包了

下载地址:https://github.com/topjohnwu/Magisk


  • 为了测试域名校验,代码中存在以下校验代码:

final HostnameVerifier hostnameVerifier = new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
Log.e("NetAcitivty", hostname);
HostnameVerifier hv = HttpsURLConnection.getDefaultHostnameVerifier();
Boolean result = hv.verify("www.google.com", session);
return result;
}
};

  • 绕过Host校验的方法,只需更改Burp 的请求的Host即可,如下:

配置好Burp为代码中要校验的Host后,点击【只校验host】按钮查看效果,如下:

0x03 HTTPS 忽略证书验证

httpstest APP在对HTTPS证书验证时,可以通过代码实现信任所有证书,以okhttp网络框架为例,发起一个忽略HTTPS证书校验的请求实现如下:

/*
* https协议
* 忽略证书验证
*/

button_https_connect_without_ca.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread(new Runnable(){
@RequiresApi(api = Build.VERSION_CODES.N)
@Override
public void run() {
OkHttpClient mClient = client.newBuilder().sslSocketFactory(HttpsTrustAllCerts.createSSLSocketFactory(),new HttpsTrustAllCerts()).hostnameVerifier(new HttpsTrustAllCerts.TrustAllHostnameVerifier()).build();
Request request = new Request.Builder()
.url("https://www.baidu.com/?q=trustAllCerts")
.build();
Message message = new Message();
message.what = 1;
try (Response response = mClient.newCall(request).execute()) {
message.obj = "https connect without ca success";
Log.d(TAG, "https connect without ca success return code:"+response.code());
} catch (IOException e) {
message.obj = "https connect without ca failed";
Log.d(TAG, "https connect without ca failed");
e.printStackTrace();
}
mHandler.sendMessage(message);
}
}).start();
}
});

HttpsTrustAllCerts对象实现如下,重写checkClientTrusted、checkServerTrusted方法,使其验证逻辑为空,重写域名验证器TrustAllHostnameVerifier 的verify方法,总是返回true,达到信任所有证书的效果:

public class HttpsTrustAllCerts implements X509TrustManager {


@SuppressLint("TrustAllX509TrustManager")
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {

}

@SuppressLint("TrustAllX509TrustManager")
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { // 验证服务端证书需要重写该函数

}

@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0]; //返回长度为0的数组,相当于return null
}


public static SSLSocketFactory createSSLSocketFactory() { // SSLSocketFactory 创建器
SSLSocketFactory sSLSocketFactory = null;
try {
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, new TrustManager[]{new HttpsTrustAllCerts()},new SecureRandom());
sSLSocketFactory = sc.getSocketFactory();
} catch (Exception e) {
}
return sSLSocketFactory;
}


public static class TrustAllHostnameVerifier implements HostnameVerifier { // 域名验证器
@Override
public boolean verify(String s, SSLSession sslSession) {
return true;
}
}
}

忽略证书校验的https请求和使用http协议的请求报文一样,可以通过直接设置网络代理抓包解密明文。接下来打开Burp,并在Android 设备中配置好代理,然后打开APP后点击【HTTP CONNECT(忽略证书校验)】按钮,APP成功访问,并在显示 http connect without ca success,Burp也成功抓到信息,如下:

0x04 HTTPS 系统证书校验

httpstest APP 中使用的是okhttp3框架,okhttp3框架发起HTTPS请求时,默认就是使用的系统信任库证书链对服务端返回的证书进行验证,示例如下:

/*
* https协议
* 默认证书链校验,只信任系统CA(根证书)
*
* tips: OKHTTP默认的https请求使用系统CA验证服务端证书(Android7.0以下还信任用户证书,Android7.0开始默认只信任系统证书)
*/

button_https_connect_with_system_ca.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread(new Runnable(){
@RequiresApi(api = Build.VERSION_CODES.N)
@Override
public void run() {
Request request = new Request.Builder()
.url("https://www.baidu.com/?q=defaultCerts")
.build();
Message message = new Message();
message.what = 1;
try (Response response = client.newCall(request).execute()) {
message.obj = "https connect with system ca success";
Log.d(TAG, "https connect with system ca success return code:"+response.code());
} catch (IOException e) {
message.obj = "https connect with system ca failed";
Log.d(TAG, "https connect with system ca failed");
e.printStackTrace();
}
mHandler.sendMessage(message);
}
}).start();
}
});

设置系统代理,抓取该数据报文,会发现App报错java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.,抓包工具burp会提示certificate_unknown

上图报错的原因在于Burp拦截https流量时,会同时充当客户端和服务端。在面向App时,此时Burp充当服务端,https协议握手过程中,Burp会将自己的证书发送给App,因为App使用系统信任库里面的证书进行校验,而Burp的证书不在系统信任库中,所以导致https握手失败,报错CertPathValidatorException

根据上述分析,绕过系统证书校验的方式,只需要将抓包工具的证书安装到系统信任库里面即可正常抓包或反编译APK在\res\xml\network_security_config.xml\AndroidManifest.xml中添加如下信息后重打包APK并签名就能抓到数据:


<network-security-config>
<base-config>
<trust-anchors>

<certificates src="system" />

<certificates src="user" />
trust-anchors>
base-config>
network-security-config>

AndroidManifest.xml:

<application android:networkSecurityConfig="@xml/network_security_config">

:在Android 7.0以前,应用默认会信任系统证书和用户证书,Android 7.0开始,默认只信任系统证书,在root环境下,将证书导入系统目录的方法。只要想办法把证书弄到系统证书列表,就可以抓包解密明文数据,具体的证书安装到系统证书目录的方法,如下:

目前在Android 7.0或以上的系统有启用了对第三方证书的限制,但在Android 7.0以下依旧可以将Fiddler/Charles/Burp的证书安装在用户的CA集中抓取https请求

将Burp或者Charles的证书作为系统级别的信任证书安装。建议重新生产burp证书并重启burp后再导出。系统级别的受信任证书以特殊格式存储在/system/etc/security/cacerts文件夹中。我们可以将Burp的证书写入此位置。

导出一个Burp/Charles证书之后,adb push到模拟器,然后修改后缀为crt直接安全,这种方式在Android 6及之前的版本可用,从Android 7.0开始,Android更改了信任用户安装的证书的默认行为,应用程序仅信任系统级CA。这样就导致安装证书后,如果尝试通过Burp或者Charlse代理访问https网站,系统会提示“该证书并非来自可信的授权中心”

对于Android 7.0 (API 24) 之后,做了些改动,使得系统安全性增加了,导致:

  • APP 默认不信任用户域的证书

    • 之前把抓包工具的ssl证书,通过【从SD卡安装】安装到受信任的凭据 -> 用户。就没用了,因为不再受信任了

    • 只信任(安装到)系统域的证书

    • 导致无法抓包https,抓出来的https的请求,都是加了密的,无法看到原文了

对此,总结出相关解决思路和方案:

  • 让系统信任抓包工具的ssl证书

    • 作为app的开发者自己:改自己的app的配置,允许https抓包(得到或本身有app的源码,把证书放到受系统信任的系统证书中去)

    • 把证书放到受系统信任的系统证书中去(root权限)

  • 绕开https不去校验

    • 借助于其他(JustTrustMe等)工具绕开https的校验(例如XPosed、太极XPosed等框架)

1) Android 7抓包问题解决方法

  1. 导出Burp的证书后,使用openssl来做一些改动,最后上传到/system/etc/security/cacerts

 

root@kali:~# openssl x509 -inform DER -in cert-der.crt -out PortSwiggerCA.pem
root@kali:~# openssl x509 -inform PEM -subject_hash_old -in PortSwiggerCA.pem|head -1
root@kali:~# mv PortSwiggerCA.pem 9999.0

  1. adb传输文件报错couldn‘t create file:Read-only file system解决方法

D:\>adb shell
VOG-AL00:/ # mount -o remount -o rw /system
mount -o remount -o rw /system
VOG-AL00:/ # exit;
exit;

D:\>adb root
adbd is already running as root

D:\>adb remount
remount succeeded

D:\>adb push 9999.0 /system/etc/security/cacerts
330 KB/s (1330 bytes in 0.003s)

D:\>adb shell chmod 644 /system/etc/security/cacerts/9999.0

再次输入adb push就能正常传输文件

2)Android10 抓包问题解决方法

Android10以上需要刷入Magisk,在模块里搜索move Cert ,安装模块,重启后证书就已经被移动到系统目录(system/etc/security/cacerts),可以正常抓包了

下载地址:https://github.com/topjohnwu/Magisk

0x05 系统代理检测

TCP协议在操作系统中完全被定死了,但是http协议都是各个开发者自己实现的,很多功能实现了多少,支持哪些细节都是开发人员自己决定的

例1:除了校验HTTPS证书防止中间人抓包以外,常见的方法还有通过检测系统代理防止抓包,其原理是检测到设备开启系统代理后,APP中通过代码实现禁用代理,以OkHttp框架为例,示列代码如下:

/*
* 检测代理
* 目前仅限OkHttp发出的请求
*/

switch_check_proxy.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(isChecked){
client = new OkHttpClient().newBuilder().proxy(Proxy.NO_PROXY).build();
}else {
client = new OkHttpClient();
}
}
});
}

例2:很多APP中会设置如下检测

String property = System.getProperty("https.proxyHost");
String property = System.getProperty("https.proxyPort");
if(!TextUtils.isEmpty(property)){
return new Proxy(Proxy,Type.HTTP, new InetSockerAddress(Property, Integer.parseInt(property2)))
}

为了绕过系统代理检测,可以使用iptables对请求进行强制转发或使用Proxy Droid,ProxyDroid全局代理工具就是通过iptables实现的,所以使用ProxyDroid开启代理,可以比较有效的绕过代理检测。手机root后,使用Proxy Droid 或Postern实现强制全局代理,让ssl代理证书生效,proxy Droid可以在UpToDown,ApkHere等的地方下载

1)对ProxyDroid进⾏配置(基本配置)

  • Auto Setting不勾选,⼿动进⾏配置

    • Host:输⼊代理服务器IP

    • Port:输⼊代理服务器端⼝

  • Proxy Type选择代理服务器提供服务类型:选择HTTP

  • Auto Connect为当2G/3G/WIFI⽹络开启时,⾃动开启代理服务。不勾选,⼿动启动,以获取最⼤灵活性

  • Bypass Addresses:相当于⿊名单列表,选择排除代理的IP范围,有需要的可以⾃⼰⼿动设置

2)认证信息配置

  • Enable Authentication:如果代理服务器需要账户、密码认证,勾选

  • User:认证账户名

  • Password:认证密码

  • NTLM Authentication:NTLM/ NTLM2,Windows早期的⼀种认证⽅式,不⽤勾选

3) 特征设置

  • Global Proxy:⼀定要勾选,即为全局代理,代理所有App

  • Individual Proxy:单独代理所选App,勾选了第⼀条的不⽤管

  • Bypass Mode:勾选了代表第⼆条中所选App不代理,勾选了第⼀条的不⽤管

  • DNS Proxy:开启DNS代理。

4)通知设置

  • Ringtone:选择通知铃声

5)都设置完成后,开启Proxy Switch即可。注意:如果使⽤ProxyDroid,⽆需在系统wifi处设置代理

下载地址:https://apkpure.com/proxydroid/org.proxydroid

Postern是Android系统里一款非常流行的代理/ 虚拟专用网络管理程序,是一个Android下的全局代理工具,可以说是安卓版surge,它可以添加规则,屏蔽广告。

Postern支持的代理协议有:

  • SSH隧道

  • Shadowsocks

  • SOCKS5代理

  • HTTPS/HTTP CONNECT method隧道

  • gfw.press

下载地址:https://apkpure.com/postern/com.tunnelworkshop.postern

上面说的是要root的情况下,免root的可以使用如下Drony 或 VProxid、Postern

  • Drony

Drony 支持 App 定向的 http,https 抓包。手机上装的 app 多了,会很多数据上来,要加过滤规则,正式环境测试环境都要加连上了代理,有些普通使用的 app (非抓包 app)会没法使用,会出现经常要设置代理,关闭代理,需要又要设置(有些手机会保存代理 ip 还好,不保存的还要每次手写)

将手机上的所有流量都重定向到 drony 自身,这样 drony 就可以管理所有手机上的网络流量,然后对手机上不同 APP 的流量进行单独配置,再转发到 BurpSuite上

Drony 可以解决上述痛点,不需要手机在 wifi 里设置代理。可以通过该 app 直接指定目标 app 才走代理,对其他 app 不可见

下载地址:https://www.apkshub.com/app/org.sandroproxy.drony

  • VProxid

VProxid是Android平台上的Proxifier替代工具,VProxid允许不支持通过代理服务器工作的网络应用程序通过SOCKS或HTTP(S)代理进行操作。使用VProxid,可以轻松地将所选应用程序上的所有TCP连接隧道传输到不同的代理服务器,这意味着VProxid可以为每个应用程序设置不同的代理来抓取数据,配合Burp使用更佳

1. 通过代理服务器运行任何网络应用程序
2. 该软件不需要特殊配置;整个过程是完全透明的
3. 同时为选定的应用程序设置不同的代理
4. 通过代理服务器网关从受限网络访问Internet
5. 绕过防火墙限制
6. 通过隐藏您的IP地址来保护隐私
7. 实时查看状态,公共IP,流量等信息
8. VProxid限制
9. 不支持UDP连接
10. 不支持https代{过}{滤}理

下载地址:https://github.com/EasyLazyBean/VProxid

0x06 HTTPS 双向验证

双向验证(或称为双向认证),顾名思义就是客户端验证服务器端证书的正确性,服务器端也验证客户端的证书正确性(当服务器启用了证书双向认证之后,除了客户端去验证服务器端的证书外,服务器也同时需要验证客户端的证书,也就是会要求客户端提供自己的证书,如果没有通过验证,则会拒绝连接,如果通过验证,服务器获得用户的公钥)。所以基本原则上客户端要持有服务器端证书,服务端也要持有客户端的证书,对于Android APP来说打包发布的时候既要内置一个服务端证书也要生成一个客户端证书给服务器存储起来。这种双向认证非常可以做到非常高的安全性,但是同时服务端要想保持所有服务端的证书比较困难,因此这种方式只适用于某些点对点的高安全性需求的通信场合,对于Android APP来说可能是某类高机密性的内网业务才会使用这种双向HTTPS认证

6.1 单向认证流程

单向认证流程中,服务器端保存着公钥证书和私钥两个文件,整个握手过程如下:

  1. 客户端发起建立HTTPS连接请求,将SSL协议版本的信息发送给服务器端

  2. 服务器端将本机的公钥证书(server.crt)发送给客户端

  3. 客户端读取公钥证书(server.crt),取出了服务端公钥

  4. 客户端生成一个随机数(密钥R),用刚才得到的服务器公钥去加密这个随机数形成密文,发送给服务端

  5. 服务端用自己的私钥(server.key)去解密这个密文,得到了密钥R

  6. 服务端和客户端在后续通讯过程中就使用这个密钥R进行通信了

6.2 双向认证流程

  1. 客户端发起建立HTTPS连接请求,将SSL协议版本的信息发送给服务端

  2. 服务器端将本机的公钥证书(server.crt)发送给客户端

  3. 客户端读取公钥证书(server.crt),取出了服务端公钥

  4. 客户端将客户端公钥证书(client.crt)发送给服务器端

  5. 服务器端使用根证书(root.crt)解密客户端公钥证书,拿到客户端公钥

  6. 客户端发送自己支持的加密方案给服务器端

  7. 服务器端根据自己和客户端的能力,选择一个双方都能接受的加密方案,使用客户端的公钥加密999后发送给客户端

  8. 客户端使用自己的私钥解密加密方案,生成一个随机数R,使用服务器公钥加密后传给服务器端

  9. 服务端用自己的私钥去解密这个密文,得到了密钥R

  10. 服务端和客户端在后续通讯过程中就使用这个密钥R进行通信了

6.3 HTTPS 单向验证/HTTPS 双向验证的区别

单向验证过程中,客户端会验证自己访问的服务器,服务器对来访的客户端身份不做任何限制。如果服务器需要限制客户端的身份,则可以选择开启服务端验证,这就是双向验证。从这个过程中我们不难发现,使用单向验证还是双向验证,是服务器决定的。

一般而言,我们的服务器都是对所有客户端开放的,所以服务器默认都是使用单向验证。如果你使用的是Tomcat服务器,在配置文件server.xml中,配置Connector节点的clientAuth属性即可。若为true,则使用双向验证,若为false,则使用单向验证。如果你的服务,只允许特定的客户端访问,那就需要使用双向验证了。

双向验证基本过程与单向验证相同,不同在于:

1)第二步服务器第一次回应客户端的SeverHello消息中,会要求客户端提供“客户端的证书”

2)第三步客户端验证完服务器证书后的回应内容中,会增加两个信息:

  • 客户端的证书

  • 客户端证书验证消息(CertificateVerify message):客户端将之前所有收到的和发送的消息组合起来,并用hash算法得到一个hash值,然后用客户端密钥库的私钥对这个hash进行签名,这个签名就是CertificateVerify message

3)服务器收到客户端证书后:

  • 确认这个证书是否在自己的信任库中(当然也会校验是否过期等信息),如果验证不通过则会拒绝连接

  • 用客户端证书中的公钥去验证收到的证书验证消息中的签名。作用是为了确认证书确实是客户端的

所以,在双向验证中,客户端需要用到密钥库,保存自己的私钥和证书,并且证书需要提前发给服务器,由服务器放到它的信任库中

6.4 HTTPS 单向验证/HTTPS 双向验证的总结

HTTPS 单向验证:

  • 如果是你客户端,你需要拿到服务器的证书,并放到你的信任库中

  • 如果是服务端,你要生成私钥和证书,并将这两个放到你的密钥库中,并且将证书发给所有客户端。

HTTPS 双向验证:

  • 如果你是客户端,你要生成客户端的私钥和证书,将它们放到密钥库中,并将证书发给服务端,同时,在信任库中导入服务端的证书

  • 如果你是服务端,除了在密钥库中保存服务器的私钥和证书,还要在信任库中导入客户端的证书

6.5 HTTPS 双向验证实例


补充知识:如果想自己生成证书的话,可以通过以下命令生成证书:

  • 生成自签名服务器端证书:

openssl genrsa -out server-key.key 2048
openssl req -new -out server-req.csr -key server-key.key
openssl x509 -req -in server-req.csr -out server-cert.cer -signkey server-key.key -CAcreateserial -days 3650

  • 生成自签名客户端证书:

openssl genrsa -out client-key.key 2048
openssl req -new -out client-req.csr -key client-key.key
openssl x509 -req -in client-req.csr -out client-cert.cer -signkey client-key.key -CAcreateserial -days 3650

生成客户端带密码的p12证书(双向认证的话,浏览器访问时候要导入该证书才行;可能某些Android系统版本请求的时候需要把它转成bks来请求双向认证,或某些设备用p12格式):

openssl pkcs12 -export -clcerts -in client-cert.cer -inkey client-key.key -out client.p12

需要使用的证书都在源码certs目录,对应证书密码如下:

  • 客户端证书client.p12密码:clientpassword

  • 服务端证书server密码:serverpassword


APP解密的代码逻辑,一般步骤如下:

  • 客户端发送数据包

  • 去从app中读取这个证书文件,密码是以硬编码形式放在了代码中

  • 寻找到硬编码形式的这个代码,然后利用这个代码中的密码字段去解密证书文件,从中读取以后,再进行解密并回传给服务器端进行确认

  • 由此可寻找证书名称来获得证书密码

证书后缀名一般为:

  • .p12

  • .bks

  • .pfx

SSL双向校验一般都将证书放到/asset目录下, 也就是app的资源目录下, 也有可能放在/res/raw目录下,如果都不再就使用*.p12、*.bks、.pfx来快速定位位置

反编译APK,通过关键词"PKCS12"能够定位到加载证书的位置,获得证书密码:clientpassword

或使用IDA加载dex文件,然后在String窗口搜索证书的名称,搜索后进入对应的类进行查找;有些APP为了安全性会把证书密码放到native层保护,如果想知道密码就要去找到对应的函数,查看具体加载的是哪个so文件(利用IDA工具)

6.5.1 实验开始之前

在开始之前,我们通过PC 浏览器来验证一下概念,如下步骤:

  • 创建Python服务端代码,文件名保存为server_https.py

import os
import sys
import ssl
from http.server import HTTPServer, BaseHTTPRequestHandler

#服务端证书和私钥
serverCerts = "D:\\t\\httpstest-master\\certs\\server-cert.cer"
serverKey = "D:\\t\\httpstest-master\\certs\\server-key.key"
#客户端证书
clientCerts = "D:\\t\\httpstest-master\\certs\\client-cert.cer"

class RequestHandler(BaseHTTPRequestHandler):
def _writeheaders(self):
self.send_response(200)
self.send_header('Content-type','text/plain')
self.end_headers()
def do_GET(self):
self._writeheaders()
self.wfile.write("OK".encode("utf-8"))

def main():
if (len(sys.argv) != 2):
port = 443
else:
port = sys.argv[1]
server_address = ("0.0.0.0", int(port))
server = HTTPServer(server_address, RequestHandler)
#双向校验
server.socket = ssl.wrap_socket(server.socket, certfile = serverCerts, server_side = True,
keyfile = serverKey,
cert_reqs = ssl.CERT_REQUIRED,
ca_certs = clientCerts,
do_handshake_on_connect = False
)
print("Starting server, listen at: %s:%s" % server_address)
server.serve_forever()

if __name__ == "__main__":
main()

  • 物理机启动该python脚本:

python3 server_https.py

  • 虚拟机Host文件需配置一下:

格式:物理机的IP www.test.com
192.168.66.55 www.test.com

  • 将httpstest-master\certs 下的client.p12 拷贝到虚拟机并安装:

  • 输入我们已知道的密码:clientpassword

  • 最后打开浏览器访问地址:https://www.test.com

从上看到,访问test.com成功会返回OK字样的空白页,也输出ERROR错误,但还是访问成功了,报错的错误原因是证书为自签名证书,客户端并不想认可该证书。只需要手动确认即可打开对应的内容

 

6.5.2 实验正式开启

1)需要做一些简单的配置:

  • 修改Android模拟器中的 hosts,将 www.test.com 域名定向到正确IP(之前用的哪个Python脚本启动的服务端机器的IP)

adb root
adb remount
adb pull /system/etc/hosts
adb push hosts /system/etc/hosts
adb shell
echo -e \\n >> /system/etc/hosts

  • 本地PC未开启代理软件

  • APP 通过frida hook 模式启动

client app包含server-cert.cer 对服务端证书PIN,这个过程需要验证服务端证书的签发单位是否为合法CA Issuer,但是我们的证书是自签名的,所以就算是不使用代理还是不能通过SSL PINNING,大概率是报错:

Caused by: java.security.cert.CertificateException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.

APP 通过frida hook 模式启动:

D:>adb shell
root@VOG-AL00:/ # cd /data/local/tmp
root@VOG-AL00:/data/local/tmp # ./frida-server-15.1.21-android-x86

JS脚本:

/* Android ssl certificate pinning bypass script for various methods

Run with:
frida -U -f [APP_ID] -l fridascript.js --no-pause
*/

setTimeout(function() {
Java.perform(function () {
// 绕过OpenSSLSocketImpl Conscrypt
var OpenSSLSocketImpl = Java.use('com.android.org.conscrypt.OpenSSLSocketImpl');
OpenSSLSocketImpl.verifyCertificateChain.implementation = function (certRefs, JavaObject, authMethod) {
console.log('[+] Bypassing OpenSSLSocketImpl Conscrypt');
};

});
}, 0);

最后运行启动APP

frida -U -f com.example.httpstest -l D:\t\fridascript.js --no-paus

2)都完成后,我们来查看查看当前APP 包名

adb shell "dumpsys window | grep mCurrentFocus"

3)Frida 启动app,Android无配置抓包代理的情况下,点击【HTTPS双向验证】按钮,可以看到收到了一个请求,但此处我点击按钮后,会闪退,大家不用管,可能是我打包APK的时候出了一些问题

frida -U -f com.example.httpstest -l D:\t\fridascript.js --no-paus

4)接下来配置抓包代理,然后用Burp直接抓包,请求是抓到了,但并未返回信息,Burp能抓包HTTPS协议报文的原理是: Burp在中间即充当客户端,又充当服务端。在Burp冒充客户端时,因为服务端要求APP发送客户端证书进行验证,而burp没有客户端证书,所以导致握手失败(双向验证):

5)此时,BurpSuite需要给代理软件加客户端证书,该证书在前面的哪个已经说过了,解压缩APK里面查找,加密的密码反编译或IDA动态调试获取密码,然后将客户端证书安装给Burp,如下:

 

选择client.p12证书文件,证书文件密码为:clientpassword

  

接下来,再次重复之前的步骤,再Frida 打开APP以及设置Android Burp代理,可以成功的发送请求并返回信息,结果如下:

参考链接

https://www.jianshu.com/p/1546e606028b

https://blog.csdn.net/lgxzzz/article/details/124645489

https://mp.weixin.qq.com/s/A-bPf6uNGiEQVu-dFvHnVw

https://ch3nye.top/Android-HTTPS认证的N种方式和对抗方法总结/


你以为你有很多路可以选择,其实你只有一条路可以走



橙留香Park 橙留香来自一位三流剑客之乡,担任威胁猎手,脑子不会转弯,属于安全特学脑。橙留香同学[小菜鸟],定期分享从零入门车联网安全(包括基础知识储备)技术。只为你呈现有价值的信息,专注于车联网安全领域之Android终端反入侵技术研究。
评论
  • 80,000人到访的国际大展上,艾迈斯欧司朗有哪些亮点?感未来,光无限。近日,在慕尼黑electronica 2024现场,ams OSRAM通过多款创新DEMO展示,以及数场前瞻洞察分享,全面展示自身融合传感器、发射器及集成电路技术,精准捕捉并呈现环境信息的卓越能力。同时,ams OSRAM通过展会期间与客户、用户等行业人士,以及媒体朋友的深度交流,向业界传达其以光电技术为笔、以创新为墨,书写智能未来的深度思考。electronica 2024electronica 2024构建了一个高度国际
    艾迈斯欧司朗 2025-01-16 20:45 177浏览
  • 实用性高值得收藏!! (时源芯微)时源专注于EMC整改与服务,配备完整器件 TVS全称Transient Voltage Suppre,亦称TVS管、瞬态抑制二极管等,有单向和双向之分。单向TVS 一般应用于直流供电电路,双向TVS 应用于电压交变的电路。在直流电路的应用中,TVS被并联接入电路中。在电路处于正常运行状态时,TVS会保持截止状态,从而不对电路的正常工作产生任何影响。然而,一旦电路中出现异常的过电压,并且这个电压达到TVS的击穿阈值时,TVS的状态就会
    时源芯微 2025-01-16 14:23 185浏览
  •  光伏及击穿,都可视之为 复合的逆过程,但是,复合、光伏与击穿,不单是进程的方向相反,偏置状态也不一样,复合的工况,是正偏,光伏是零偏,击穿与漂移则是反偏,光伏的能源是外来的,而击穿消耗的是结区自身和电源的能量,漂移的载流子是 客席载流子,须借外延层才能引入,客席载流子 不受反偏PN结的空乏区阻碍,能漂不能漂,只取决于反偏PN结是否处于外延层的「射程」范围,而穿通的成因,则是因耗尽层的过度扩张,致使跟 端子、外延层或其他空乏区 碰触,当耗尽层融通,耐压 (反向阻断能力) 即告彻底丧失,
    MrCU204 2025-01-17 11:30 143浏览
  • 一个易用且轻量化的UI可以大大提高用户的使用效率和满意度——通过快速启动、直观操作和及时反馈,帮助用户快速上手并高效完成任务;轻量化设计则可以减少资源占用,提升启动和运行速度,增强产品竞争力。LVGL(Light and Versatile Graphics Library)是一个免费开源的图形库,专为嵌入式系统设计。它以轻量级、高效和易于使用而著称,支持多种屏幕分辨率和硬件配置,并提供了丰富的GUI组件,能够帮助开发者轻松构建出美观且功能强大的用户界面。近期,飞凌嵌入式为基于NXP i.MX9
    飞凌嵌入式 2025-01-16 13:15 211浏览
  • 本文介绍瑞芯微开发板/主板Android配置APK默认开启性能模式方法,开启性能模式后,APK的CPU使用优先级会有所提高。触觉智能RK3562开发板演示,搭载4核A53处理器,主频高达2.0GHz;内置独立1Tops算力NPU,可应用于物联网网关、平板电脑、智能家居、教育电子、工业显示与控制等行业。源码修改修改源码根目录下文件device/rockchip/rk3562/package_performance.xml并添加以下内容,注意"+"号为添加内容,"com.tencent.mm"为AP
    Industio_触觉智能 2025-01-17 14:09 109浏览
  • 现在为止,我们已经完成了Purple Pi OH主板的串口调试和部分配件的连接,接下来,让我们趁热打铁,完成剩余配件的连接!注:配件连接前请断开主板所有供电,避免敏感电路损坏!1.1 耳机接口主板有一路OTMP 标准四节耳机座J6,具备进行音频输出及录音功能,接入耳机后声音将优先从耳机输出,如下图所示:1.21.2 相机接口MIPI CSI 接口如上图所示,支持OV5648 和OV8858 摄像头模组。接入摄像头模组后,使用系统相机软件打开相机拍照和录像,如下图所示:1.3 以太网接口主板有一路
    Industio_触觉智能 2025-01-20 11:04 97浏览
  • 2024年是很平淡的一年,能保住饭碗就是万幸了,公司业绩不好,跳槽又不敢跳,还有一个原因就是老板对我们这些员工还是很好的,碍于人情也不能在公司困难时去雪上加霜。在工作其间遇到的大问题没有,小问题还是有不少,这里就举一两个来说一下。第一个就是,先看下下面的这个封装,你能猜出它的引脚间距是多少吗?这种排线座比较常规的是0.6mm间距(即排线是0.3mm间距)的,而这个规格也是我们用得最多的,所以我们按惯性思维来看的话,就会认为这个座子就是0.6mm间距的,这样往往就不会去细看规格书了,所以这次的运气
    wuliangu 2025-01-21 00:15 17浏览
  • 随着消费者对汽车驾乘体验的要求不断攀升,汽车照明系统作为确保道路安全、提升驾驶体验以及实现车辆与环境交互的重要组成,日益受到业界的高度重视。近日,2024 DVN(上海)国际汽车照明研讨会圆满落幕。作为照明与传感创新的全球领导者,艾迈斯欧司朗受邀参与主题演讲,并现场展示了其多项前沿技术。本届研讨会汇聚来自全球各地400余名汽车、照明、光源及Tier 2供应商的专业人士及专家共聚一堂。在研讨会第一环节中,艾迈斯欧司朗系统解决方案工程副总裁 Joachim Reill以深厚的专业素养,主持该环节多位
    艾迈斯欧司朗 2025-01-16 20:51 136浏览
  • Ubuntu20.04默认情况下为root账号自动登录,本文介绍如何取消root账号自动登录,改为通过输入账号密码登录,使用触觉智能EVB3568鸿蒙开发板演示,搭载瑞芯微RK3568,四核A55处理器,主频2.0Ghz,1T算力NPU;支持OpenHarmony5.0及Linux、Android等操作系统,接口丰富,开发评估快人一步!添加新账号1、使用adduser命令来添加新用户,用户名以industio为例,系统会提示设置密码以及其他信息,您可以根据需要填写或跳过,命令如下:root@id
    Industio_触觉智能 2025-01-17 14:14 68浏览
  • 百佳泰特为您整理2025年1月各大Logo的最新规格信息,本月有更新信息的logo有HDMI、Wi-Fi、Bluetooth、DisplayHDR、ClearMR、Intel EVO。HDMI®▶ 2025年1月6日,HDMI Forum, Inc. 宣布即将发布HDMI规范2.2版本。新规范将支持更高的分辨率和刷新率,并提供更多高质量选项。更快的96Gbps 带宽可满足数据密集型沉浸式和虚拟应用对传输的要求,如 AR/VR/MR、空间现实和光场显示,以及各种商业应用,如大型数字标牌、医疗成像和
    百佳泰测试实验室 2025-01-16 15:41 188浏览
  • 随着智慧科技的快速发展,智能显示器的生态圈应用变得越来越丰富多元,智能显示器不仅仅是传统的显示设备,透过结合人工智能(AI)和语音助理,它还可以成为家庭、办公室和商业环境中的核心互动接口。提供多元且个性化的服务,如智能家居控制、影音串流拨放、实时信息显示等,极大提升了使用体验。此外,智能家居系统的整合能力也不容小觑,透过智能装置之间的无缝连接,形成了强大的多元应用生态圈。企业也利用智能显示器进行会议展示和多方远程合作,大大提高效率和互动性。Smart Display Ecosystem示意图,作
    百佳泰测试实验室 2025-01-16 15:37 191浏览
  • 电竞鼠标应用环境与客户需求电竞行业近年来发展迅速,「鼠标延迟」已成为决定游戏体验与比赛结果的关键因素。从技术角度来看,传统鼠标的延迟大约为20毫秒,入门级电竞鼠标通常为5毫秒,而高阶电竞鼠标的延迟可降低至仅2毫秒。这些差异看似微小,但在竞技激烈的游戏中,尤其在对反应和速度要求极高的场景中,每一毫秒的优化都可能带来致胜的优势。电竞比赛的普及促使玩家更加渴望降低鼠标延迟以提升竞技表现。他们希望通过精确的测试,了解不同操作系统与设定对延迟的具体影响,并寻求最佳配置方案来获得竞技优势。这样的需求推动市场
    百佳泰测试实验室 2025-01-16 15:45 284浏览
  • 日前,商务部等部门办公厅印发《手机、平板、智能手表(手环)购新补贴实施方案》明确,个人消费者购买手机、平板、智能手表(手环)3类数码产品(单件销售价格不超过6000元),可享受购新补贴。每人每类可补贴1件,每件补贴比例为减去生产、流通环节及移动运营商所有优惠后最终销售价格的15%,每件最高不超过500元。目前,京东已经做好了承接手机、平板等数码产品国补优惠的落地准备工作,未来随着各省市关于手机、平板等品类的国补开启,京东将第一时间率先上线,满足消费者的换新升级需求。为保障国补的真实有效发放,基于
    华尔街科技眼 2025-01-17 10:44 194浏览
我要评论
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦