일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- igoat
- 안드로이드
- CTF-d
- SQL Injection
- 파이썬
- lord of sql injection
- beebox
- elasticsearch
- otter
- Reflected XSS
- 2018
- ESXi
- ctf
- vulnhub
- Strings
- NTFS
- Suninatas
- frida
- Openstack
- kibana
- InsecureBank
- Docker
- Volatility
- 인시큐어뱅크
- XSS
- base64
- MFT
- diva
- logstash
- foremost
- Today
- Total
Information Security
SSL Pinning 우회 코드 분석 본문
SSL Pinning.apk를 jadx파일을 열어 AndroidMainfest.xml에서 package 이름을 확인했다.
PinnedSSLDemoActivity 클래스 내의 onSubmit() 메서드가 호출되었을 때, SSL Pinning 사용 체크박스에 체크가 되어 있다면 sslContext 라는 변수에 getPinnedSSLContext() 메소드의 반환 값이 저장된다. 체크가 되어 있지 않다면 기본값인 NULL이 저장된다. 이 sslContext 의 값에 따라 SSL Pinning이 적용된 암호화 통신을 할지 안 할지 결정하는 것을 알 수 있다. sslContext의 값을 결정하는 getPinnedSSLContext() 메서드의 로직을 확인해 볼 필요가 있다.
해당 메소드의 반환 값은 SSLContext 객체이고, 이 객체는 PinnedSSLContextFactory 클래스의 getSSLContext() 메서드의 반환값이다. 이 메소드의 인자로 전달되는 input 값은 load-der.crt 라는 인증서 파일을 로드한 것이다. 이 파일은 Resources 디렉토리 내에 assets 디렉토리에 존재한다.
해당 인증서 파일은 Resources 디렉토리 내에 assets 디렉토리에 존재한다. load-der.crt를 Burp Suite 인증서로 교체한 후 다시 apk 파일로 리패키징 후 컴파일 과정을 거치면 SSL Pinning 우회 과정 없이 통신 패킷을 Burp Suite로 인터셉트할 수 있지만, 이는 해당 앱이 무결성 검증을 하지 않는 경우에만 가능하다.
return문을 보니 인자값으로 전달 받은 input 값이 loadCertificate() 메소드의 인자 값으로 전달되고, 이 메소드의 반환값이 createKeyStore() 메소드의 인자 값으로, 그 반환값이 다시 createTrustManager() 메소드의 인자 값으로, 마지막으로 그 반환값이 createSSLContext() 의 인자 값으로 전달되어 반환되는 값을 최종적으로 반환하고 있다.
[안드로이드 SSL 통신 시 클라이언트 인증서 사용 순서]
1. 클라이언트 인증서 로드
2. 클라이언트 인증서를 이용하여 KeyStore 생성
3. 클라이언트 인증서를 이용하여 TrustManager 생성
4. KeyStore, TrustManager를 이용하여 SSLContext 생성
CertificateFactory 라는 클래스의 getInstance() 메소드를 통해 반환되는 인스턴스의 generateCertificate() 메소드의 인자 값으로 인증서 파일이 전달되어 반환되는 값을 리턴하고 있다. 이 CertificateFactory 클래스는 자바에서 제공하는 기본 클래스로, java.security.cert.CertificateFactory 이다. 이 로직에서 중요한 것은 인자 값으로 전달 받은 input 변수인데, 이 변수값을 조작하여 assets 내에 있는 인증서가 아닌 이전에 다운로드 받은 Burp Suite 인증서 파일로 바꿔서 SSL Pinning을 우회해 보자.
FileInputStream 클래스를 이용하여 Burp Suite 인증서를 로드한 후에 generateCertificate() 메소드의 인자 값으로 전달하였다.
두 번째로 KeyStore를 생성하기 위해 호출하는 createKeyStore() 메소드의 로직을 확인했다.
KeyStore는 인증서 증명을 위한 키 값들을 저장한 것으로, 이 로직은 그대로 사용하면 된다.
세 번째로 TrustManager를 생성하는 createTrustMangager() 메소드의 로직을 확인해 보자.
해당 메소드의 로직 동일하게 작성하면 된다.
이 메소드를 호출할 때 위에서 생성한 TrustManager 배열 객체를 전달하고, 해당 객체를 SSLContext 클래스의 init() 메소드의 두 번째 인자 값으로 전달한다.
이 init() 메소드를 재작성하여 위에서 생성한 tmf_get 변수를 인자 값으로 전달하도록 하자. 물론 위에서 TrustManager를 생성하는 코드를 작성했을 때 처럼 init() 메소드를 직접 호출해도 되지만, 재작성을 통해 다른 로직은 원래 작성되어 있던 코드대로 진행하도록 할 것이다.
Pinned SSL Demo 실행 후 SSL connection 체크 후 Submit을 하면 Connection refused 되는 것을 알 수 있다.
자바스크립트를 실행하였다.
Burp Suite에서 확인을 하면 Request 패킷이 잡히는 것을 알 수 있다.
'모바일 > Frida' 카테고리의 다른 글
SSL Pinning 우회 (0) | 2020.12.24 |
---|---|
Frida - sieve.apk BruteForce PIN (0) | 2020.12.21 |
Frida - sieve.apk 로그인 우회 (1) | 2020.12.20 |
Uncrackable1 - 암호화 (0) | 2020.12.18 |
UnCrackable - Level1 (0) | 2020.12.17 |