SSL Pinning Bypass

ewillwin·2022년 12월 12일
0

Information Security

목록 보기
3/3

우회해야하는 pinning request 목록은 아래와 같다.
1. UNPINNED REQUEST
2. CONFIG FINNED REQUEST
3. OKHTTP PINNED REQUEST
4. VOLLEY PINNED REQUEST
5. TRUSTKT PINNED REQUEST
6. MANUALLY PINNED REQUEST

Java.perform(function(){
 
   console.log('');
   console.log('======');
   console.log('[#] Android Network Security Config bypass [#]');
   console.log('======');
 
   var array_list = Java.use("java.util.ArrayList");
   var ApiClient1 = Java.use('com.android.org.conscrypt.TrustManagerImpl');
   var ApiClient2 = Java.use('com.android.org.conscrypt.TrustManagerImpl');
   var ApiClient3 = Java.use('okhttp3.CertificatePinner');
   var ApiClient4 = Java.use('okhttp3.CertificatePinner');
   var SSLContext = Java.use('javax.net.ssl.SSLContext');
 
   const TrustManager = Java.registerClass({
       // Implement a custom TrustManager
       name: 'dev.asd.test.TrustManager',
       implements: [X509TrustManager],
       methods: {
           checkClientTrusted: function (chain, authType) { },
           checkServerTrusted: function (chain, authType) { },
           getAcceptedIssuers: function () { return []; }
       }
   });
 
   const TrustManagers = [TrustManager.$new()];
 
   const SSLContext_init = SSLContext.init.overload(
       '[Ljavax.net.ssl.KeyManager;', '[Ljavax.net.ssl.TrustManager;', 'java.security.SecureRandom'
   );
 
   SSLContext_init.implementation = function (keyManager, trustManager, secureRandom) {
       console.log('  --> Bypassing Trustmanager (Android < 7) request');
       SSLContext_init.call(this, keyManager, TrustManagers, secureRandom);
   };
 
   ApiClient1.checkTrustedRecursive.implementation = function(a1, a2, a3, a4, a5, a6, a7, a8){
       console.log('Bypassing SSL Pinning');
       var trusted = array_list.$new();
       return trusted;
       //return;
   };
 
   ApiClient2.verifyChain.implementation = function(a1, a2, a3, a4, a5, a6, a7, a8){
       console.log('Bypassing SSL Pinning');
       var trusted = array_list.$new();
       return trusted;
       //return;
   };
 
   ApiClient3.check.implementation = function(a1, a2, a3){
       console.log('Bypassing SSL Pinning');
       var trusted = array_list.$new();
       return trusted;
       //return;
   };
 
   ApiClient4.check$okhttp.implementation = function(a1, a2, a3){
       console.log('Bypassing SSL Pinning');
       var trusted = array_list.$new();
       return trusted;
       //return;
   };
 
 
});

위의 frida script를 통해 아래 캡처 사진에서 보이는 것처럼 1, 2, 4, 5번의 pinning request를 우회할 수 있다.

UNPINNED REQUEST, CONFIG PINNED REQUEST, VOLLEY PINNED REQUEST는 교안에 나와있던 frida script로 bypass가 가능했다.
TRUSTKIT PINNED REQUEST는 frida script에서 Trusted 값을 return 함으로써 bypass할 수 있다.

MANUALLY PINNED REQUEST
android sslpinning disable 명령어를 통해 아래와 같은 결과를 얻을 수 있다.

따라서 위의 함수들의 경로를 찾고 그것을 override 해야한다는 것을 알 수 있다.

SSLContext.init(), CertificatePinner.check(), CertificatePinner.check$okhttp(), TrustmanagerImpl.verifyChain(), TrustManagerImpl.verifyChain() 찾고, 그것을 overriding하는 방식으로 frida script를 작성하고, bypass 하였다.

profile
Software Engineer @ LG Electronics

0개의 댓글