Android证书绑定绕过研究(一)

TAG: SSL Pinning Bypass

背景

  • 随着App安全技术快速发展,越来越多的App使用SSL Pinning(证书绑定),因此需要有方案来绕过该防御措施。

  • 网上有很多脚本,适用于大部分情况,但是一遇到脚本无法使用的时候,我们便需要有逆向分析的思路。

  • 本文将从两方面入手,一方面是分析公开脚本的原理,一方面是当脚本失效时的逆向思路分享。

---- 授人以鱼不如授人以渔

逆向思路(一)

  1. 思路: 当证书校验失败时,应该会调用系统close关闭连接,因此可以trace close入手,定位校验证书的SO位置。
  2. frida-trace -U -f com.xxx.android -i close
  3. 找到 __handlers/libc.so/close.js

修改为:

/*
 * Auto-generated by Frida. Please modify to match the signature of close.
 * This stub is currently auto-generated from manpages when available.
 *
 * For full API reference, see: https://frida.re/docs/javascript-api/
 */
{
    /**
     * Called synchronously when about to call close.
     *
     * @this {object} - Object allowing you to store state for use in onLeave.
     * @param {function} log - Call this function with a string to be presented to the user.
     * @param {array} args - Function arguments represented as an array of NativePointer objects.
     * For example use args[0].readUtf8String() if the first argument is a pointer to a C string encoded as UTF-8.
     * It is also possible to modify arguments by assigning a NativePointer object to an element of this array.
     * @param {object} state - Object allowing you to keep state across function calls.
     * Only one JavaScript function will execute at a time, so do not worry about race-conditions.
     * However, do not use this to store function arguments across onEnter/onLeave, but instead
     * use "this" which is an object for keeping state local to an invocation.
     */
    onEnter(log, args, state) {
            const sockfd = args[0].toInt32();
            const socktype = Socket.type(sockfd);
            if (!socktype || socktype !== "tcp") return;
            const sockLocal = Socket.localAddress(sockfd)
            const tcpEpLocal = sockLocal && sockLocal.ip ? sockLocal : null
            const sockRemote = Socket.peerAddress(sockfd)
            const tcpEpRemote = sockRemote && sockRemote.ip ? sockRemote : null
            if (tcpEpLocal !== null) {
                log("[*] TcpEpLocal addr: " + tcpEpLocal.ip + " ,port: " + tcpEpLocal.port + " ,lr: " + this.context.lr + " ,path: " + new ModuleMap().find(ptr(this.context.lr)).path);
            }
            if (tcpEpRemote != null) {
                log("[*] TcpEpRemote addr: " + tcpEpRemote.ip + " ,port: " + tcpEpRemote.port + " ,lr: " + this.context.lr + " ,path: " + new ModuleMap().find(ptr(this.context.lr)).path);
            }
        },


        /**
         * Called synchronously when about to return from close.
         *
         * See onEnter for details.
         *
         * @this {object} - Object allowing you to access state stored in onEnter.
         * @param {function} log - Call this function with a string to be presented to the user.
         * @param {NativePointer} retval - Return value represented as a NativePointer object.
         * @param {object} state - Object allowing you to keep state across function calls.
         */
        onLeave(log, retval, state) {}
}
  1. 定位到SSL验证的SO位置后进行静态分析
  2. 静态分析关键词: verify、SSL、x509_store_st,log信息
  3. 一般分析返回值为bool、int的函数,修改其返回值即可

示例

绕过ssl pinning

var acallBackfn = {
    onEnter: function(args){
    },
    onLeave: function(retval){
        console.log("ori retval: " + retval.toInt32());
        retval.replace(0x1);
        console.log("changed retval: " + retval.toInt32());
    }
};
hook_native("libliger.so","_ZN8proxygen15SSLVerification17verifyWithMetricsEbP17x509_store_ctx_stRKNSt6__ndk112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEPNS0_31SSLFailureVerificationCallbacksEPNS0_31SSLSuccessVerificationCallbacksERKNS_15TimeUtilGenericINS3_6chrono12steady_clockEEERNS_10TraceEventE",2,acallBackfn);

逆向思路(二)

定位思路: 采用grep定位字符串位置

grep -rins "verify error" .

关键词:

  • OpenSSL
  • verify error
  • signed certificate
  • and verifier failure

参考

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值