bt365软件下载

HTTPS SSL Pinning (SSL证书锁定) 绕过:如何通过修改应用、操作系统或网络流量来绕过证书锁定?

HTTPS SSL Pinning (SSL证书锁定) 绕过:如何通过修改应用、操作系统或网络流量来绕过证书锁定?

各位观众老爷们,大家好!我是今天的主讲人,一个在代码堆里摸爬滚打多年的老码农。今天咱们来聊点刺激的——HTTPS SSL Pinning的绕过。

首先声明,咱们今天讨论的是技术,目的是了解安全机制,不是教唆大家去干坏事!学技术是为了更好的保护自己,可别用来搞破坏啊!

SSL Pinning 是个啥?

简单来说,SSL Pinning就像给你的App加了个“白名单”。它会把服务器的SSL证书(或者证书的公钥、哈希)直接“钉”在你的App代码里。这样,App只会信任与这个“白名单”里的证书匹配的服务器。

为啥要这么做呢?因为普通的HTTPS连接,App会信任任何经过可信CA(证书颁发机构)签发的证书。但CA也可能被攻破,或者被某些邪恶势力控制,从而签发假的证书。有了Pinning,即使CA被攻破,攻击者也无法用假证书欺骗你的App。

绕过Pinning,为啥这么难?

Pinning把信任锚点从整个CA体系缩小到了特定的证书,大大提高了安全性。想要绕过它,意味着你需要找到方法让App信任一个非“白名单”里的证书,或者直接修改App的行为,让它忽略Pinning的检查。

那么,如何“优雅”地绕过它呢?(注意,是“优雅”,不是“暴力破解”)

绕过SSL Pinning的方法有很多,咱们可以从不同的角度入手:

一、修改App(难度系数:看情况)

这是最直接,也是最“脏”的方法。但如果能拿到App的源码,或者能够反编译App并修改它的代码,那就可以为所欲为了。

反编译App:

首先,我们需要拿到App的安装包(比如.apk文件,如果是iOS,就是.ipa文件)。然后,使用反编译工具(比如apktool、dex2jar + jd-gui,或者Hopper Disassembler、IDA Pro)把App的代码反编译成可读的Java代码(或者汇编代码)。

# 反编译apk

apktool d your_app.apk

反编译出来的代码通常是混淆过的,阅读起来比较困难,但我们可以通过一些技巧来找到关键的代码。

定位Pinning代码:

Pinning通常会在网络请求的代码中实现。我们可以搜索一些关键词,比如SSLContext、TrustManager、HostnameVerifier、Certificate、pinning等,来找到相关的代码。

在Android中,OkHttp、Retrofit、Volley等网络库都可能被使用,Pinning的实现方式也会有所不同。

OkHttp: OkHttp使用CertificatePinner类来实现Pinning。

// 示例代码(可能混淆过)

CertificatePinner certificatePinner = new CertificatePinner.Builder()

.add("example.com", "sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=")

.build();

OkHttpClient client = new OkHttpClient.Builder()

.certificatePinner(certificatePinner)

.build();

TrustManager: 有些App会自己实现TrustManager来验证证书。

// 示例代码(可能混淆过)

TrustManager[] trustAllCerts = new TrustManager[] {

new X509TrustManager() {

@Override

public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {

}

@Override

public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {

// Pinning 逻辑

// ...

}

@Override

public java.security.cert.X509Certificate[] getAcceptedIssuers() {

return new java.security.cert.X509Certificate[0];

}

}

};

SSLContext sslContext = SSLContext.getInstance("TLS");

sslContext.init(null, trustAllCerts, new java.security.SecureRandom());

修改Pinning代码:

找到Pinning的代码后,就可以开始修改了。

禁用Pinning: 最简单粗暴的方法就是直接注释掉Pinning相关的代码,或者修改条件判断,让Pinning永远不生效。

添加自定义证书: 可以修改代码,让App信任我们提供的证书,或者信任所有证书。

// 示例代码(修改TrustManager,信任所有证书)

TrustManager[] trustAllCerts = new TrustManager[] {

new X509TrustManager() {

@Override

public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {

}

@Override

public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {

// 信任所有证书

}

@Override

public java.security.cert.X509Certificate[] getAcceptedIssuers() {

return new java.security.cert.X509Certificate[0];

}

}

};

SSLContext sslContext = SSLContext.getInstance("TLS");

sslContext.init(null, trustAllCerts, new java.security.SecureRandom());

OkHttpClient client = new OkHttpClient.Builder()

.sslSocketFactory(sslContext.getSocketFactory(), (X509TrustManager)trustAllCerts[0])

.hostnameVerifier((hostname, session) -> true) // 信任所有hostname

.build();

重新打包App:

修改完代码后,需要重新编译并打包App。

# 重新编译apk

apktool b your_app

# 签名apk (需要keystore)

jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore your_keystore.jks your_app.apk your_alias

重新打包的App需要签名才能安装到设备上。

二、修改操作系统(难度系数:高)

这种方法需要在操作系统层面修改证书信任链,让操作系统信任我们提供的证书。这种方法比较通用,可以绕过大多数App的Pinning。

安装自定义CA证书:

我们可以自己创建一个CA证书,然后把这个证书安装到操作系统的受信任根证书列表中。这样,任何由这个CA签发的证书都会被操作系统信任。

Android: 可以通过Settings -> Security -> Install from SD card来安装证书。

iOS: 可以通过AirDrop或者邮件把证书发送到设备上,然后按照提示安装。

使用Frida Hook:

Frida是一个动态代码插桩工具,可以让我们在运行时修改App的行为。我们可以使用Frida来Hook SSL/TLS相关的函数,修改证书验证的逻辑。

# Frida 脚本 (Python)

import frida

import sys

def on_message(message, data):

if message['type'] == 'send':

print("[*] {0}".format(message['payload']))

else:

print(message)

def main():

package_name = "your.app.package.name" # 替换成你的App包名

try:

device = frida.get_usb_device(timeout=10)

session = device.attach(package_name)

except frida.TimedOutError:

print("[-] Could not connect to the device. Is USB debugging enabled?")

sys.exit(1)

except frida.ProcessNotFoundError:

print("[-] The app is not running. Please start it.")

sys.exit(1)

script = session.create_script("""

// Hook X509TrustManager.checkServerTrusted

Java.perform(function () {

var X509TrustManager = Java.use('javax.net.ssl.X509TrustManager');

X509TrustManager.checkServerTrusted.implementation = function (chain, authType) {

console.log('[+] Bypassing TrustManager checkServerTrusted()');

return; // Trust everything!

};

// Hook CertificatePinner.check

var CertificatePinner = Java.use('okhttp3.CertificatePinner');

CertificatePinner.check.implementation = function (hostname, peerCertificates) {

console.log('[+] Bypassing CertificatePinner check()');

return; // Bypass CertificatePinner!

};

//Hook HostnameVerifier.verify

var HostnameVerifier = Java.use('javax.net.ssl.HostnameVerifier');

HostnameVerifier.verify.implementation = function(hostname, session){

console.log('[+] Bypassing HostnameVerifier verify()');

return true; // Trust all hostnames!

}

});

""")

script.on('message', on_message)

script.load()

sys.stdin.read()

if __name__ == '__main__':

main()

这个Frida脚本会Hook X509TrustManager.checkServerTrusted()、CertificatePinner.check()和HostnameVerifier.verify()函数,让它们直接返回,从而绕过证书验证。

三、修改网络流量(难度系数:中)

这种方法通过拦截和修改App的网络流量,来绕过Pinning。

使用代理工具:

我们可以使用一些代理工具(比如Charles、Burp Suite、Fiddler)来拦截App的网络流量。这些工具可以让我们查看App发送和接收的数据,甚至可以修改这些数据。

配置代理: 需要在App或者操作系统中配置代理,让App的网络流量经过代理工具。

安装代理证书: 代理工具会生成一个自签名证书,需要把这个证书安装到App或者操作系统的受信任根证书列表中。

修改SNI:

SNI(Server Name Indication)是TLS协议的一个扩展,用于在客户端与服务器建立连接时,告诉服务器客户端要访问的域名。有些App会根据SNI来判断是否需要进行Pinning。

我们可以修改SNI,让App认为我们访问的是一个不需要Pinning的域名,从而绕过Pinning。

使用Burp Suite: 在Burp Suite中,可以配置拦截规则,修改SNI的值。

中间人攻击(MITM):

我们可以使用代理工具,进行中间人攻击。

拦截HTTPS流量: 代理工具会拦截App的HTTPS流量,然后使用自己的证书与App建立连接。

修改流量: 可以修改App发送和接收的数据,甚至可以伪造服务器的响应。

各种方法的对比:

方法

优点

缺点

难度系数

修改App

最直接,效果最好

需要反编译App,代码混淆,重新打包,可能破坏App的功能,容易被检测

看情况

修改操作系统

通用性强,可以绕过大多数App的Pinning

需要root权限或者越狱,风险较高,可能影响系统稳定性

修改网络流量

不需要修改App或者操作系统,相对安全

需要配置代理,只能拦截和修改网络流量,可能被检测

一些注意事项:

代码混淆: 大多数App都会对代码进行混淆,增加了反编译和修改的难度。

反调试: 一些App会加入反调试机制,防止被调试和修改。

完整性校验: 一些App会对自身进行完整性校验,防止被篡改。

Pinning方式: Pinning的实现方式有很多种,需要根据具体情况选择合适的绕过方法。

安全检测: 一些App会检测是否存在代理或者Hook,如果检测到,可能会阻止App运行或者限制某些功能。

总结:

SSL Pinning是一种有效的安全机制,可以防止中间人攻击。但是,没有绝对的安全,只要有足够的时间和资源,任何安全机制都有可能被绕过。

绕过SSL Pinning的方法有很多,每种方法都有其优缺点。选择哪种方法取决于具体情况,比如App的复杂程度、Pinning的实现方式、以及我们掌握的工具和技术。

希望今天的讲座能让大家对SSL Pinning和绕过方法有更深入的了解。记住,技术是把双刃剑,要用它来保护自己,而不是伤害别人!

最后,祝大家代码无Bug,生活愉快!咱们下次再见!

相关推荐