抓包对抗原理与案例

news2025/2/24 1:28:05

服务端校验客户端

案例:爱奇艺

图片

平时我们碰到的HTTP和HTTPS都在应用层,SOCKS在会话层,TCP和UDP在传输层,IP在网络层。

HTTP未加密主要有这些不足

  • 通信使用明文(不加密),内容可能会被窃听

  • 不验证通信方的身份,因此有可能遭遇伪装  DNS劫持->GFW翻墙

  • 无法证明报文的完整性,所以有可能已遭篡改 运营商劫持->弹窗广告

HTTP+加密+认证+完整性保护=HTTPS,是身披SSL的HTTP。

通信加密:HTTP协议中没有加密机制,但可以通过和SSL( Secure Socket Layer,安全套接层)或TLS( Transport Layer Security,安全层传输协议)的组合使用,加密HTTP的通信内容。用SSL建立安全通信线路之后,就可以在这条线路上进行HTTP通信了。与SSL组合使用的HTTP被称为Https(HTTP Secure,超文本传输安全协议)

内容加密:客户端需要对HTTP报文内容进行加密处理后再发送请求。为了做到有效的内容加密,前提是要求客户端和服务器同时具备加密和解密机制。有一点必须引起注意,由于该方式不同于SSL或TLS将整个通信线路加密处理,所以内容仍有被篡改的风险。

如下图:

  1. 客户端发起https请求将SSL协议给服务端

  2. 服务端从CA机构申请一份CA证书(包括服务端公钥和签名)给客户端

  3. 客户端读取CA证书明文信息,采用同样hash函数计算拿到信息摘要,用系统自带的CA证书的公钥解密签名(签名由CA的私钥加密),对比证书中的信息摘要,一致则可信,再取出服务端的公钥去加密客户端生成随机数作为秘钥生成密文发给服务端

  4. 服务端用自己私钥解密拿到秘钥随机数

  5. 以上是非对称加密过程,后续服务端和客户端通讯过程就是通过该密钥进行通讯,整个过程都是对称加密了。

图片

对称加密 :加密和解密数据使用同一个密钥。这种加密方式的特点是速度很快,常见对称加密的算法有 AES;

非对称加密:加密和解密使用不同的密钥,这两个密钥形成有且仅有唯一的配对,叫公钥和私钥。数据用公钥加密后必须用私钥解密,数据用私钥加密后必须用公钥解密。一般来说私钥自己保留好,把公钥公开给别人(一般公钥不会单独出现,而是会写进证书中),让别人拿自己的公钥加密数据后发给自己,这样只有自己才能解密。这种加密方式的特点是速度慢,CPU 开销大,常见非对称加密算法有 RSA。

Charles,Fiddler,BurpSuite代理都是通过给wifi设置http代理的方式进行抓包,HTTPS是包裹在SSL协议里的HTTP,APP-Charles客户端校验服务端,Charles-服务器是服务端校验客户端,不使用charles证书校验失败所有https请求报错400 Bad Request,No required SSL certificate was sent。使用了服务端的证书访问服务端校验客户端的请求原理就是中间人攻击,而中间人攻击的关键就是截获服务器返回的证书并伪造证书发送给客户端骗取信任,所以在应用层拦截抓包,所以会被很轻易的检测到和绕过的。

图片

public static boolean isWifiProxy(Context context) {
    final boolean IS_ICS_OR_LATER = Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH;
    String proxyAddress;
    int proxyPort;
    if (IS_ICS_OR_LATER) {
        proxyAddress = System.getProperty("http.proxyHost");    //获取代理主机
        String portStr = System.getProperty("http.proxyPort");  //获取代理端口
        proxyPort = Integer.parseInt((portStr != null ? portStr : "-1"));
    } else {
        proxyAddress = android.net.Proxy.getHost(context);
        proxyPort = android.net.Proxy.getPort(context);
    }
   Log.i("代理信息","proxyAddress :"+proxyAddress + "prot : " proxyPort")
   return (!TextUtils.isEmpty(proxyAddress)) && (proxyPort != -1);
}

这两个API来查看当前系统是否挂了http代理,或者发起请求时OkHttpClient okHttpClient = new OkHttpClient.Builder(). proxy(Proxy.NO_PROXY). build();直接设置禁止代理,会很轻松的让你的抓包失效。

趣充:设置no proxy防抓包,校验到直接强退APP,我们通过hook将这个函数替换掉即可。

function replaceKill(){
 // 替换掉崩掉时的内容,打印崩掉时的参数和pid,不执行崩掉的逻辑,让程序不要崩
    console.log("Preventing from killing ...")
    var kill_addr = Module.findExportByName("libc.so", "kill");
    // var kill = new NativeFunction(kill_addr,"int",['int','int']);
    Interceptor.replace(kill_addr,new NativeCallback(function(arg0,arg1){
        console.log("arg0=> ",arg0)
        console.log("arg1=> ",arg1)

    },"int",['int','int']))
}

function main(){
    replaceKill()
}
setImmediate(main);

所以我们需要换一种方式来设置代理postern,本质在tcp的传输层抓包。就是设置vpn代理,vpn是属于网络层的,设置了vpn后,你的手机上ifconfig后会多一个接口,等于加了一个虚拟网卡,所有的流量都会从这走。应用层和传输层的请求都可以拿到,还不会被上面提及的两个api所检测。

图片

ip route show table 0|grep default  手机路由表第一条降维打击网络层,任何api都必须经过路由解析http。

图片

不过App依旧可以通过判断java.net.NetworkInterface.getName()是否等于tun0ppp0 或者 android.net.ConnectivityManager.getNetworkCapabilities来判断是否存在VPN抓包,可以通过grep -ril "vpn"反编译后的dex中找到所有关于vpn的函数。

通过objection hook以上的类方法

图片

图片

“```
function hook_vpn() {
    Java.perform(function () {
        var String = Java.use(“java.lang.String”);
        var NetworkInterface = Java.use(“java.net.NetworkInterface”);
        NetworkInterface.getName.implementation = funciont() {
            var name = this.getName();
            console.log("name: " + name);
            if (name == “tun0”) {
                var result = String.$new(“rmnet_data0”)
                console.log(“hook result:” + result)
                return result;
            } else {
                return name;
            }
        }
        var ConnectivityManager = Java.use(“android.net.ConnectivityManager”)
        ConnectivityManager.getNetworkCapabilities.implementation = function (args) {
            var result = this.getNetworkCapabilities(args);
            console.log("vpn result: " + result)
            return null
        }
    })
}

setImmediate(hook_vpn);


将检测抓包的函数给hook掉不就拦不住我抓包的步伐了嘛!

”

不过回过头来,为什么客户端这么容易被欺骗呢?原因就是过于依赖证书的校验合法性!市面上大部分的应用在校验证书是否过期,服务器证书域名与服务器实际域名是否匹配,证书链的完整校验都做的不够好,即使在完整校验了整个证书链体系时,中间人攻击依旧可以在终端手动添加信任根证书的方式发送请求,这也正是抓包软件在抓取HTTPS协议数据前,要求在终端安装证书的原因,确保证书通过客户端的证书链校验。以下可以将证书放到根目录,获取最高权限。

安卓8

cd /data/misc/user/0/cacerts-added/
mount -o remount,rw /
mount -o remount,rw /system
chmod 777 *
cp * /etc/security/cacerts/
mount -o remount,ro /
mount -o remount,ro /system

安卓7

cd /data/misc/user/0/cacerts-added/
mount -o rw,remount /system
mount -o rw,remount /
chmod 777 *
cp * /etc/security/cacerts/
mount -o ro,remount /system
mount -o ro,remount /

安卓10

Move_Certificates-v1.9  直接面具插件安排,重启即可

客户端校验服务端

那么FaceBook/Twitter这些大厂是如何做到防止Charles/Fiddler等抓包工具中间人攻击的呢?SSL-Pinning!原理是HTTPS建立时与服务端返回的证书比对一致性,进而识别出中间人攻击后直接在客户端侧中止连接。

证书锁定:开发时就将服务端证书一块打包到客户端里,不接受操作系统或浏览器内置的CA根证书对应的任何证书,通过这种授权方式,保障了APP与服务端通信的唯一性和安全性。但是CA签发证书都存在有效期问题,所以缺点是在证书续期后需要将证书重新内置到APP中。

公钥锁定:提取证书中的公钥并内置到客户端中,通过与服务器对比公钥值来验证连接的正确性。制作证书密钥时,公钥在证书的续期前后都可以保持不变(即密钥对不变),所以可以避免证书有效期问题,一般推荐这种做法。

不过由于客户端会做两个证书间的一次性校验,那么就通过hook的方式将此次校验的结果返回true或者干脆不让其做校验,或者Xposed安装JustTrustMe插件,该插件将各种已知的HTTP请求库中用于校验证书的API进行hook并不论是否可信证书都返回正常状态。

objection -g com.ophone.reader.ui explore   咪咕阅读
android sslpinning disable  需要在启动时运行
objection -g com.ophone.reader.ui explore -s "android sslpinning disable"  登录页面触发解绑定,如果崩溃

git clone https://github.com/WooyunDota/DroidSSLUnpinning.git frida -U -f com.ninemax.ncsearchnew -l ObjectionUnpinningPlus/hooks.js --no-pause

Java.perform(function() {
    var array_list = Java.use("java.util.ArrayList");
    var ApiClient = Java.use('com.android.org.conscrypt.TrustManagerImpl');

    ApiClient.checkTrustedRecursive.implementation = function(a1, a2, a3, a4, a5, a6) {
        // console.log('Bypassing SSL Pinning');
        var k = array_list.$new();
        return k; 
        }
}, 0);
//过证书绑定 ssl pinning 对证书在代码中进行额外校验,
function hook_ssl() {
    // hook ssl 调用栈
    Java.perform(function() {
        var ClassName = "com.android.org.conscrypt.Platform";
        var Platform = Java.use(ClassName);
        var targetMethod = "checkServerTrusted";
        var len = Platform[targetMethod].overloads.length;
        console.log(len);
        for(var i = 0; i<len; ++i) {
            Platform[targetMethod].overloads[i].implementation = function () {
                console.log("class:", ClassName, "target:", targetMethod, "i:", i, arguments);
                printStack(ClassName + "." + targetMethod);
            }
        }
    });
}

双向校验

客户端和服务端同时检验数据的加密和解密

  1. 客户端发起HTTPS请求,将SSL协议信息发送给服务端。

  2. 服务端去CA机构申请来一份CA证书,在前面提过,证书里面有服务端公钥和签名。将CA证书发送给客户端

  3. 客户端发送自己的客户端证书给服务端,证书里面有客户端的公钥,并发送支持的对称加密方案给服务端,供其选择

  4. 服务端选择完加密方案后,按照加密方案完成刚才得到的公钥去加密

  5. 客户端用自己的私钥去解密选好的加密方案,客户端生成一个随机数(密钥),用刚才等到的服务端公钥去加密这个随机数形成密文,发送给服务端。

  6. 服务端和客户端在后续通讯过程中就使用这个密钥进行通信了。和之前的非对称加密不同,这里开始就是一种对称加密的方式

Soul

Charles

soul在登录时报错400 No required SSL certificate was sent,缺少证书,需要在charles中安装客户端证书获取服务器信任。

图片

Frida

Socket本质:收发包的接口,一条跑着RAW DATA的通道,纯binary,为了方便使用TCPUDP而抽象出来作为网络中连接的两端。应用领域SSL+HTTP,SMPT/POP/IMAP,Protobuf等。Socket是传输控制层接口,WebSocket是应用层协议用来创建一种双向通信(全双工)的协议 ,来弥补HTTP协议在持久通信能力上的不足。

常用frida抓包,详情见某摩托的逆向分析

git clone https://github.com/siyujie/OkHttpLogger-Frida.git
 adb push okhttpfind.dex /data/local/tmp
 frida -U -l okhttp_poker.js -f com.motoband --no-pause  
    find() 查看是否使用okhttp并查看混淆结果,将Find Result下的内容复制到okhttp_poker.js开头,替换原有混淆类名
 hold()
git clone https://github.com/BigFaceCat2017/frida_ssl_logger.git
 解决IP的问题;
 适配Windows;
 andriod高版本适配;
 iOS/macOS适配;
 自实现ssl的适配;
 适配socket的监控
 新增对IP/dns的监控
 新增对应用列表的显示
 python ssl_logger.py -U -f com.qiyi.video >> iqiyi.txt
 python ssl_logger.py  -U -v com.iqiyi.video -p iqiyi.pcap
git clone https://github.com/r0ysue/r0capture.git
    仅限安卓平台,测试安卓7、8、9、10、11、12 可用 ;
 无视所有证书校验或绑定,不用考虑任何证书的事情;
 通杀TCP/IP四层模型中的应用层中的全部协议;
 通杀协议包括:Http,WebSocket,Ftp,Xmpp,Imap,Smtp,Protobuf等等、以及它们的SSL版本;
 通杀所有应用层框架,包括HttpUrlConnection、Okhttp1/3/4、Retrofit/Volley等等;
 无视加固,不管是整体壳还是二代壳或VMP,不用考虑加固的事情;
 frida -U -f com.motoband -l script.js --no-pause -o motoband.txt
 python r0capture.py -U -f  com.motoband -v
 python r0capture.py -U -f  com.motoband -v -p motoband.pcap
 python r0capture.py -U -f com.motoband -v >>motoband.txt 

Hook Socket

function hook_socket(){
    Java.perform(function(){
        console.log("hook_socket;")
        

        Java.use("java.net.SocketOutputStream").write.overload('[B', 'int', 'int').implementation = function(bytearry,int1,int2){
            var result = this.write(bytearry,int1,int2);
            console.log("HTTP write result,bytearry,int1,int2=>",result,bytearry,int1,int2)
            var ByteString = Java.use("com.android.okhttp.okio.ByteString");
            console.log("bytearray contents=>", ByteString.of(bytearry).hex())
            return result;
        }
        

        Java.use("java.net.SocketInputStream").read.overload('[B', 'int', 'int').implementation = function(bytearry,int1,int2){
            var result = this.read(bytearry,int1,int2);
            console.log("HTTP read result,bytearry,int1,int2=>",result,bytearry,int1,int2)
            var ByteString = Java.use("com.android.okhttp.okio.ByteString");
            console.log("bytearray contents=>", ByteString.of(bytearry).hex())
            return result;
        }

    })
}


function hook_SSLsocketandroid8(){
    Java.perform(function(){
        console.log("hook_SSLsocket")
        
        Java.use("com.android.org.conscrypt.ConscryptFileDescriptorSocket$SSLOutputStream").write.overload('[B', 'int', 'int').implementation = function(bytearry,int1,int2){
            var result = this.write(bytearry,int1,int2);
            console.log("HTTPS write result,bytearry,int1,int2=>",result,bytearry,int1,int2)
            var ByteString = Java.use("com.android.okhttp.okio.ByteString");
            console.log("bytearray contents=>", ByteString.of(bytearry).hex())
            return result;
        }
        

        
        Java.use("com.android.org.conscrypt.ConscryptFileDescriptorSocket$SSLInputStream").read.overload('[B', 'int', 'int').implementation = function(bytearry,int1,int2){
            var result = this.read(bytearry,int1,int2);
            console.log("HTTPS read result,bytearry,int1,int2=>",result,bytearry,int1,int2)
            var ByteString = Java.use("com.android.okhttp.okio.ByteString");
            console.log("bytearray contents=>", ByteString.of(bytearry).hex())
            return result;
        }
        

    })
}


function hook_SSLsocket2android10(){
    Java.perform(function(){
        console.log(" hook_SSLsocket2")
        var ByteString = Java.use("com.android.okhttp.okio.ByteString");
        Java.use("com.android.org.conscrypt.NativeCrypto").SSL_write.implementation = function(long,NS,fd,NC,bytearray,int1,int2,int3){
            var result = this .SSL_write(long,NS,fd,NC,bytearray,int1,int2,int3);
            console.log("SSL_write(long,NS,fd,NC,bytearray,int1,int2,int3),result=>",long,NS,fd,NC,bytearray,int1,int2,int3,result)
            console.log(ByteString.of(bytearray).hex());
            return result;
        }
        Java.use("com.android.org.conscrypt.NativeCrypto").SSL_read.implementation = function(long,NS,fd,NC,bytearray,int1,int2,int3){
            var result = this .SSL_read(long,NS,fd,NC,bytearray,int1,int2,int3);
            console.log("SSL_read(long,NS,fd,NC,bytearray,int1,int2,int3),result=>",long,NS,fd,NC,bytearray,int1,int2,int3,result)
            console.log(ByteString.of(bytearray).hex());
            return result;
        }      
    })
}

function main(){
    console.log("Main")
    hook_socket();
    hook_SSLsocketandroid8();
    //hook_SSLsocket2android10();
}
setImmediate(main)

Hook KeyStore

function printStack(str_tag)
 {
    var Exception=  Java.use("java.lang.Exception");
    var ins = Exception.$new("Exception");
    var straces = ins.getStackTrace();

    if (undefined == straces || null  == straces)
    {
        return;
    }

    console.log("==" + str_tag + " Stack strat ===");
    console.log("");

    for (var i = 0; i < straces.length; i++)
    {
        var str = "   " + straces[i].toString();
        console.log(str);
    }

    console.log("");
    console.log("===" + str_tag + " Stack end ===\r\n");
    Exception.$dispose();
 }
//过客户端校验服务器
function hook_KeyStore_load() {
 // hook证书 自吐证书密码和内容保存在sdcard中
    Java.perform(function () {
        var ByteString = Java.use("com.android.okhttp.okio.ByteString");
        var myArray=new Array(1024);
        var i = 0
        for (i = 0; i < myArray.length; i++) {
            myArray[i]= 0x0;
         }
        var buffer = Java.array('byte',myArray);
        
        var StringClass = Java.use("java.lang.String");
        var KeyStore = Java.use("java.security.KeyStore");
        KeyStore.load.overload('java.security.KeyStore$LoadStoreParameter').implementation = function (arg0) {
            console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new()));

            console.log("KeyStore.load1:", arg0);
            this.load(arg0);
        };
        KeyStore.load.overload('java.io.InputStream', '[C').implementation = function (arg0, arg1) {
            console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new()));

            console.log("KeyStore.load2:", arg0, arg1 ? StringClass.$new(arg1) : null);
            if (arg0){
                var file =  Java.use("java.io.File").$new("/sdcard/Download"+ String(arg0)+".p12");
                var out = Java.use("java.io.FileOutputStream").$new(file);
                var r;
                while( (r = arg0.read(buffer)) > 0){
                    out.write(buffer,0,r)
                }
                console.log("save success!")
                out.close()
            }
            this.load(arg0, arg1);
        };

        console.log("hook_KeyStore_load...");
    });
}
//过证书绑定 ssl pinning 对证书在代码中进行额外校验,
function hook_ssl() {
    // hook ssl 调用栈
    Java.perform(function() {
        var ClassName = "com.android.org.conscrypt.Platform";
        var Platform = Java.use(ClassName);
        var targetMethod = "checkServerTrusted";
        var len = Platform[targetMethod].overloads.length;
        console.log(len);
        for(var i = 0; i<len; ++i) {
            Platform[targetMethod].overloads[i].implementation = function () {
                console.log("class:", ClassName, "target:", targetMethod, "i:", i, arguments);
                printStack(ClassName + "." + targetMethod);
            }
        }
    });
}

开启hook

frida -U -f cn.soulapp.android -l ssl.js  通过attach进行hook公钥加解密的框架层api,打印密码用于解开证书用
%resume  重新启动
frida -U -f cn.soulapp.android -l ssl.js  --no-pause  通过spawn进行hook,证书公钥发送给服务器,从服务器获取session用私钥进行解密的api进行hook,属于自吐,查看terminal中的密码 }%2R+\OSsjpP!w%X

抓包

7z x soul_channel_soul.apk
tree -NCfhl|grep -i p12 找到证书位置tree -NCfhl|grep -i bks
或者objection -g cn.soulapp.android explore  如果报错查看frida的客户端和服务端版本是否匹配
android hooking watch class_method java.io.File$init --dump-args 如果找不到文件
exit并干掉app后
objection -g cn.soulapp.android explore --start-command "android hooking watch class_method java.io.File$init --dump-args"
du -h assets/client.p12
file assets/client.p12
thunar .  在windows上找到后双击导入私钥需要密码即刚才hook到的}%2R+\OSsjpP!w%X  该证书的内容即可以全部显示

安装证书

导入charles - Proxy- SSL Proxying Settings 添加客户端证书

图片

图片

图片

启动ssl抓包,Charles将对任意服务器发送该客户端证书,意味着用app访问所有的服务器,后续关闭客户端证书的soulapp.cn,否则会误认为请求来自于soul, 测试登录

图片

图片

图片

趣充

frida -U -f com.whwy.equchong -l hook_keystore.js --no-pause -o quchong.txt  证书位置和密钥在KeyStore.load2后的/sdcard/Download

将p12证书拷贝出来,下载kse_5.4.4_all.deb,dpkg -i kse_2.4.4_all.deb,启动keystore explore打开p12证书,输入密码即可查看证书内容

右键-export-export key pair-输入密码 保存为p12,设置密码123456

charles-SSL Proxying Settings-Client Certificate-Import P12-导入导出的p12证书,密码为123456,Host Port配*表示所有发出去的包都用这个证书

启动Postern,配置charles抓包,重新注册获取验证码,依旧拿不到结果是,查看socket后的端口9443,在charles中配置9443端口,即可拿到完整加密请求结果

图片

图片

滴答

启动charles抓包,发送验证码,查看OverView

证书绑定校验失败:Client closed the connection before a request was made.Possibly the SSL certificate was rejected.You may need to configure your browser or application to trust the Charles Root Certificate.See SSL Proxyinf in the Help menu.

Android SSL证书设置和锁定(SSL/TLS Pinning)查看安卓设置-加密与凭据-信任的凭据

frida -U -f cn.ticktick.task -l quchong.js --no-pause  执行hook_ssl() 失败

objection -g cn.ticktick.task explore -s “android sslpinning disable”  失败

git clone https://github.com/WooyunDota/DroidSSLUnpinning.git

frida -U -f cn.ticktick.task -l hooks.js --no-pause  失败

objection -g cn.ticktick.task explore -s "android hooking watch class_method java.io.File.$init --dump-args --dump-backtrace --dump-return"  打开证书文件就初始化这个文件,hook该类,发送验证码
plugin wallbreaker classdump z1.g
plugin wallbreaker objectsearch z1.g 
plugin wallbreaker objectdump --fullname 0x24e6

图片

图片

cd OkHttpLogger-Frida && frida -U -f cn.ticktick.task -l okhttp_poker.js 
%resume
find()  失败则不是ok3混淆,那么就是ok1

https://square.github.io/okhttp/4.x/okhttp/okhttp3/-certificate-pinner/

图片

android hooking list class_methods z1.g  其中有z1.g.a,在CertificatePinner中被混淆的
function killCertificatePinner(){
    Java.perform(function(){
        console.log(Beginning killCertificatePinner !...)
        Java.use(z1.g).a.implementation = function(str,list){
            console.log(called z1.g.a ~)
            return ;
        }
    })
}
frida -U -f cn.ticktick.task -l quchong.js --no-pause  发送注册短信过掉z1.g.a的ok1中的证书

多重证书绑定

咪咕视频

登录抓包,SSL handshake with client failed: An unknown issue occurred processing the certificate (certificate_unknown)从抓包发现证书 绑定,可能客户端只信任信任的公钥签名,不信任就不允许,停止客户端访问的证书绑定。客户端发了,我们已经绕过了校验,把自己公钥发给charles,charles用自己私钥解开客户端的公钥发现不正常的结果。

dumpsys activity top  查看包名 com.ophone.reader.ui
objection -g com.ophone.reader.ui explore
android sslpinning disable  需要在启动时运行
objection -g com.ophone.reader.ui explore -s "android sslpinning disable"  在点我登录页面触发解绑定,如果崩溃
objection -g com.ophone.reader.ui explore  在点我登录时开始漫游
android sslpinning disable   解绑定后再获取验证码,再抓包

证书绑定的逻辑没有hook掉:“at com.bangcle.andjni.JniLib.cL(Native Method)” → 只有逆代码来过证书绑定

python r0capture.py -U com.ophone.reader.ui -v -p migu.pcap  关闭postern抓包,获取验证码没有更新log,说明没有一些底层的框架

通过wireshark查看migu.pcap结果,发现也没有关键性信息,抓包也抓不到。

python r0capture.py -U -f com.ophone.reader.ui -v  尝试导出证书
frida -U -f com.ophone.reader.ui -l script.js --no-pause
adb shell 查看sdcard/Download下的证书
adb pull /sdcard/Download/ophone 下的证书导入到Charles的SSL Proxying Settings中,打开postern抓包
objection -g com.ophone.reader.ui explore  在点我登录时开始漫游
android sslpinning disable   解绑定后再获取验证码抓包即可获取passport.migu.cn:8443的包信息

SSL handshake with server failed - Remote host terminated the handshake The remote SSL server rejected the connection. The server may require a specific certificate or cipher not supported by Charles.

过客户端证书后发现更多证书绑定,Frida.Android.Practice

objection -g com.ophone.reader.ui explore -s "android sslpinning disable"

git clone https://github.com/WooyunDota/DroidSSLUnpinning.git

frida -U -f com.ophone.reader.ui -l hooks.js --no-pause   抓发送验证码包依旧有请求失败

FRIDA 使用经验交流分享,git clone https://github.com/deathmemory/FridaContainer.git

cd utils/android
frida -U -f com.ophone.reader.ui -l multi_unpinning.js --no-pause
objection -g com.ophone.reader.ui explore -s "android hooking watch class_method java.io.File.\$init --dump-args --dump-backtrace --dump-return"  查看证书
frida -U -f com.ophone.reader.ui -l trace.js --no-pause -o ophone.txt 修改trace.js中traceClass("java.io.File"),在traceClass中修改targets=[]只trace init方法,在traceMethod中打开调用栈android.util.log,发送验证码后查看文件,搜索cacert查看调用栈

图片

北京银行

python r0capture.py -U -f com.bankofbeijing.mobilebanking -v
./hluda-server-14.2.1-android-arm64
frida -U -f com.bankofbeijing.mobilebanking -l script.js --no-pause -o bjbank.txt
frida -U -f com.bankofbeijing.mobilebanking -l trace.js --no-pause -o bjbank2.txt  打开traceClass("java.security.KeyStore$PrivateKeyEntry")

加固厂商自定义开发的证书绑定对抗很难被攻克。终极解决方案就是修改安卓底层aosp源码,将发送请求时打印log后,重编译成镜像刷机,比如项目crypto_filter_aosp,让整个系统都变成一个抓包工具,当然不排除部分加固厂商会校验系统是否aosp,当然我们依旧可以通过hook等方案修改系统类型,攻防之道,道高一尺,魔高一丈。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/193999.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2月2日 读书笔记

段的起始地址用32位来表示&#xff0c;被称为段的基址&#xff0c;在本书中被分成了3段&#xff0c;分别为2字节、1字节、1字节。之所以这么做&#xff0c;主要是为了与80286时代的程序兼容。有了这样的规格&#xff0c;80286用的操作系统&#xff0c;也可以不用修改就在386以后…

不忘初心,勇攀高峰!低代码公司流辰信息紧抓机遇,努力超前冲!

在数字化发展趋势越来越激烈的当下&#xff0c;市场变得风云变幻&#xff0c;作为一家致力于提升企业办公自动化效率的低代码公司平台服务商&#xff0c;流辰信息矢志不渝&#xff0c;不忘初心&#xff0c;紧跟时代发展潮流&#xff0c;坚持围绕客户需求研发创新&#xff0c;提…

马哥架构第4周课程作业

docker应用一. docker常用命令博客1.1 Docker安装及基础命令介绍1.1.1 Docker 安装准备1.1.2 安装和删除方法1.1.2.1 Ubuntu 安装和删除Docker1.1.2.2 CentOS 安装和删除Docker1.1.2.3 Linux 二进制安装1.1.2.4 安装 podman1.1.2.5 在不同系统上实现一键安装 docker 脚本1.1.2.…

HBase入门概念

文章目录HBase存储结构数据模型table 逻辑结构切分存储table 物理结构架构 todo使用DDLDMLphoenixHBase nosql &#xff08;k&#xff0c;v&#xff09; 以HDFS为基础存储数据 存储结构 数据模型 nameSpace&#xff1a; 命名空间table&#xff1a; 表&#xff08;需要声明…

浅谈C/S和B/S架构的工作原理及优缺点

C/S架构 一、C/S架构及其背景 C/S架构是一种比较早的软件架构&#xff0c;主要应用于局域网内。在这之前经历了集中计算模式&#xff0c;随着计算机网络的进步与发展&#xff0c;尤其是可视化工具的应用&#xff0c;出现过两层C/S和三层C/S架构&#xff0c;不过一直很流行也比…

蓝桥杯刷题019——观光公交(贪心)

题目描述 风景迷人的小城 Y 市&#xff0c;拥有 n 个美丽的景点。由于慕名而来的游客越来越多&#xff0c;Y 市特意安排了一辆观光公交车&#xff0c;为游客提供更便捷的交通服务。观光公交车在第 0 分钟出现在 1 号景点&#xff0c;随后依次前往 2、3、4……n 号景点。从第 i …

使用Workbook读取表格问题总结

使用Workbook读取表格问题总结一、Workbook类型二、问题总结1.SXSSFWorkbook为什么我Create了一万行Row但是却获取不到&#xff1f;2.读取表格一、Workbook类型 Workbook分三种类型&#xff1a; 1.HSSFWorkbook 用于Excel2003版及更早版本(扩展名为.xls)的导出&#xff1b; 2.…

苹果手机备忘录密码忘记了怎么办?快速解锁,亲测有效

很多小伙伴喜欢使用苹果手机的备忘录来记录重要的事情&#xff0c;并且还会给备忘录设置密码。可是使用的时间长了&#xff0c;就忘记了自己备忘录密码了。苹果手机备忘录密码忘记了怎么办&#xff1f;别担心&#xff0c;今天小编分享一个亲测有效的方法&#xff0c;快来看看吧…

纳瓦电子前向77GHz毫米波雷达获国内新能源头部车企定点!

伴随着中国自主品牌新车搭载ADAS功能的高速增长&#xff0c;中国本土毫米波雷达供应商迎来了前所未有的机遇期。 高工智能汽车研究院监测数据显示&#xff0c;今年1-11月中国市场&#xff08;不含进出口&#xff09;乘用车前装标配搭载前向毫米波雷达交付上险755.53万颗&#…

一站式开发平台 赋能办公全场景

近几年&#xff0c;数字化办公迎来了新的机遇&#xff0c;根据亿欧智库《2022中国数字化办公市场研究报告》推算&#xff0c;数字化办公2021年的市场规模达到973.89亿元&#xff0c;至2025年将达到1768.16亿元&#xff0c;整体增速保持平稳&#xff0c;2018-2025年的CAGR为15.8…

写IB EE(Extended Essay)时容易犯的五大错误

EE的重要性无需多言&#xff0c;EE和TOK一共占IB45分总分的3分&#xff0c;其中一门拿到E的话&#xff0c;就会fail&#xff0c;拿不到IB的diploma。虽说和学校老师会有meeting讨论的机会&#xff0c;但时间有限&#xff0c;提供的精准指导也有限。EE的要求很严谨&#xff0c;很…

基于java SSM springboot动物检疫信息管理系统设计和实现

基于java SSM springboot动物检疫信息管理系统设计和实现 博主介绍&#xff1a;5年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 超级帅帅吴 Java毕设项目精品实战案例《500套》 欢迎点赞 收藏 ⭐留言 文末获…

Java集合(八)Map接口

我们来查看Map接口&#xff1a; 里面的k-v和set集合的不同之处在于&#xff1a;key仍然是一个对象&#xff0c;但是对于set来说value是一个常量&#xff0c; private static final Object PRESENT new Object(); set里面的value放的是 静态性质的PRESENT。 而map的value是自…

Issue—C#—ssl相关错误

报错&#xff1a;.net 6 : {"MessageTemplate": "An unhandled exception has occurred while executing the request.""Exception": "System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exc…

函数(基础)

目录 一、字符串函数 &#xff08;一&#xff09;常用的字符串函数 &#xff08;二&#xff09;举例 1. concat&#xff08;拼接&#xff09; 2. Lower(大写变小写) 3. upper(小写变大写) 4. lpad(左填充) 5. rpad(右填充) 6. trim(去掉前后空格) 7. ltrim(去掉左边…

Linux-远程管理命令

1.关机/重启序号命令对应英文作用01shutdown 选项 时间shutdown关机/重新启动1.1shutdownshutdown命令可以安全关闭或者重新启动系统选项含义-r重新启动提示&#xff1a;不指定选项和参数&#xff0c;默认表示1分钟之后关闭电脑远程维护服务器时&#xff0c;最好不要关闭系统&a…

Centos7 U盘 安装

目录 一 描述环境 二 下载镜像 2.1 阿里云下载地址: 2.2 Centos 下载&#xff1a; 三 制作U盘启动盘 3.1 下载软碟通 最新UltraISO官方免费下载 - UltraISO软碟通中文官方网站下载https://cn.ultraiso.net/xiazai.html 3.2 傻瓜安装即可&#xff08;不赘述&#xff09; 3.3…

怎么移除css的hover事件

移除css hover事件的方法&#xff1a;1、&#xff1b;通过“$("a").hover(function(){ alert(mouseover); }, function(){ alert(mouseout); })”方法绑定hover事件&#xff1b;2、通过“$(a).off(mouseenter).unbind(mouseleave);”方法取消绑定的hover事件即可。 j…

Filesystem closed报错问题处理

使用HDFS的时候 final Configuration conf new Configuration(); final FileSystem fs FileSystem.get(URI.create(hdfsFile), conf); final Path path new Path(hdfsFile); if (fs.exists(path)) {final FSDataInputStream is fs.open(path);final FileStatus stat fs.g…

一文细说OpenCL框架

说明&#xff1a; 子曾经曰过&#xff1a;不懂Middleware的系统软件工程师&#xff0c;不是一个好码农&#xff1b; 1. 介绍 OpenCL(Open Computing Language&#xff0c;开放计算语言&#xff09;&#xff1a;从软件视角看&#xff0c;它是用于异构平台编程的框架&#xff1b…