Android/Androgoat

Network Intercepting

Analysis

기기에서 Burp Proxy 설정 이후 HTTP, HTTPS 버튼을 누르면 다음과 같이 Burp Suite에서 두 버튼 활성화로 인한 패킷을 확인할 수 있지만 마지막 CERTIFICATE PINNING으로는 패킷이 잡히지 않는 것을 확인할 수 있다. (Burp Proxy 설정)

 

Code

http

final class TrafficActivity$onCreate$1 implements View.OnClickListener {
    final /* synthetic */ TrafficActivity this$0;

    TrafficActivity$onCreate$1(TrafficActivity trafficActivity) {
        this.this$0 = trafficActivity;
    }

    public final void onClick(View it) {
        TrafficActivity trafficActivity = this.this$0;
        trafficActivity.run(trafficActivity.getHttpurl());
    }
}
public final String getHttpurl() {
        return this.httpurl; // "http://demo.testfire.net"
}

HTTP버튼을 누르면 run() 함수에 getHttpurl() 반환 값("http://demo.testfire.net")을 넘겨주게 된다. (HTTPS버튼의 경우도 넘겨지는 url만 다르지 나머지는 동일하다)

 

run

public final void run(String url) {
        Intrinsics.checkParameterIsNotNull(url, "url");
        try {
            Request request = new Request.Builder().url(url).build();
            Toast.makeText(this, "Request sent to " + url + " Please intercept using Proxy", 1).show();
            this.client.newCall(request).enqueue(new TrafficActivity$run$1());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

run() 함수에서는 이전 함수에서 넘어온 url을 Request.Builder를 이용하여 GET 방식의 요청을 발생하게 된다.

 

doPinning

final class TrafficActivity$doPinning$1 extends Lambda implements Function1<AnkoAsyncContext<TrafficActivity>, Unit> {
    public static final TrafficActivity$doPinning$1 INSTANCE = new TrafficActivity$doPinning$1();

    TrafficActivity$doPinning$1() {
        super(1);
    }

    public /* bridge */ /* synthetic */ Object invoke(Object obj) {
        invoke((AnkoAsyncContext<TrafficActivity>) (AnkoAsyncContext) obj);
        return Unit.INSTANCE;
    }

    public final void invoke(AnkoAsyncContext<TrafficActivity> $this$doAsync) {
        Intrinsics.checkParameterIsNotNull($this$doAsync, "$receiver");
        try {
            OkHttpClient client = new OkHttpClient.Builder().certificatePinner(new CertificatePinner.Builder().add("owasp.org", "sha256/gdU/UHClHJBFbIdeKuyHm/Lq/aQvMLyuTtcvTEE/1JQ=").add("owasp.org", "sha256/YLh1dUR9y6Kja30RrAn7JKnbQG/uEtLMkBgFF2Fuihg=").add("owasp.org", "sha256/Vjs8r4z+80wjNcr1YKepWQboSIRi63WsWXhIMN+eWys=").build()).build();
            Request.Builder builder = new Request.Builder();
            ResponseBody body = client.newCall(builder.url("https://" + "owasp.org").build()).execute().body();
            Log.v("Response", body != null ? body.string() : null);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

CERTIFICATE PINNING버튼을 누를 경우 certificatePinner를 이용하여 인증서를 고정한 후 "https://owasp.org" 요청을 보내는 것을 확인할 수 있다.

 

Exploit

Frida

코드에 고정된 인증서를 우회하기 위해서는 인증서 고정을 위해 사용하는 CertificatePinner클래스의 검증 로직을 후킹 하면 쉽게 우회할 수 있다.

후킹은 다음과 같이 check 함수를 후킹하여 진행한다.

console.log("Script loaded successfully");
Java.perform(function x() {
    console.log("java perform function");
    var CertificatePinner = Java.use('okhttp3.CertificatePinner');
    CertificatePinner.check.overload('java.lang.String','java.util.List').implementation = function (p0, p1) {
        console.log('! Intercepted okhttp3: ' + p0);
        return;
    };
});

 

코드를 실행한 후 CERTIFICATE PINNING버튼을 누르면 다음과 같이 로그와 Burp Suite에서 패킷이 잡히는 것을 확인할 수 있다.

 

Reference

'Android > Androgoat' 카테고리의 다른 글

Binary Patching  (0) 2021.09.20
Emulator Detection  (0) 2021.09.20
Root Detection  (0) 2021.09.20