mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
113 lines
8.9 KiB
Markdown
113 lines
8.9 KiB
Markdown
# 생체 인증 우회 (안드로이드)
|
||
|
||
{{#include ../../banners/hacktricks-training.md}}
|
||
|
||
## **방법 1 – 암호화 객체 사용 없이 우회하기**
|
||
|
||
여기서 초점은 인증 과정에서 중요한 _onAuthenticationSucceeded_ 콜백에 있습니다. WithSecure의 연구자들은 NULL _CryptoObject_를 _onAuthenticationSucceeded(...)_에서 우회할 수 있는 [Frida 스크립트](https://github.com/WithSecureLABS/android-keystore-audit/blob/master/frida-scripts/fingerprint-bypass.js)를 개발했습니다. 이 스크립트는 메서드 호출 시 지문 인증을 자동으로 우회하도록 강제합니다. 아래는 안드로이드 지문 컨텍스트에서 우회를 보여주는 간단한 코드 조각이며, 전체 애플리케이션은 [GitHub](https://github.com/St3v3nsS/InsecureBanking)에서 확인할 수 있습니다.
|
||
```javascript
|
||
biometricPrompt = new BiometricPrompt(this, executor, new BiometricPrompt.AuthenticationCallback() {
|
||
@Override
|
||
public void onAuthenticationSucceeded(@NonNull BiometricPrompt.AuthenticationResult result) {
|
||
Toast.makeText(MainActivity.this,"Success",Toast.LENGTH_LONG).show();
|
||
}
|
||
});
|
||
```
|
||
Frida 스크립트를 실행하는 명령:
|
||
```bash
|
||
frida -U -f com.generic.insecurebankingfingerprint --no-pause -l fingerprint-bypass.js
|
||
```
|
||
## **Method 2 – Exception Handling Approach**
|
||
|
||
Another [Frida script](https://github.com/WithSecureLABS/android-keystore-audit/blob/master/frida-scripts/fingerprint-bypass-via-exception-handling.js) by WithSecure addresses bypassing insecure crypto object usage. The script invokes _onAuthenticationSucceeded_ with a _CryptoObject_ that hasn't been authorized by a fingerprint. If the application tries to use a different cipher object, it will trigger an exception. The script prepares to invoke _onAuthenticationSucceeded_ and handle the _javax.crypto.IllegalBlockSizeException_ in the _Cipher_ class, ensuring subsequent objects used by the application are encrypted with the new key.
|
||
|
||
Frida 스크립트를 실행하는 명령:
|
||
```bash
|
||
frida -U -f com.generic.insecurebankingfingerprint --no-pause -l fingerprint-bypass-via-exception-handling.js
|
||
```
|
||
지문 화면에 도달하고 `authenticate()`가 시작되면, Frida 콘솔에 `bypass()`를 입력하여 우회 기능을 활성화합니다:
|
||
```
|
||
Spawning com.generic.insecurebankingfingerprint...
|
||
[Android Emulator 5554::com.generic.insecurebankingfingerprint]-> Hooking BiometricPrompt.authenticate()...
|
||
Hooking BiometricPrompt.authenticate2()...
|
||
Hooking FingerprintManager.authenticate()...
|
||
[Android Emulator 5554::com.generic.insecurebankingfingerprint]-> bypass()
|
||
```
|
||
## **Method 3 – Instrumentation Frameworks**
|
||
|
||
Instrumentation frameworks like Xposed or Frida는 런타임에 애플리케이션 메서드에 훅을 걸기 위해 사용될 수 있습니다. 지문 인증의 경우, 이러한 프레임워크는:
|
||
|
||
1. **인증 콜백 모의**: `BiometricPrompt.AuthenticationCallback`의 `onAuthenticationSucceeded`, `onAuthenticationFailed`, 또는 `onAuthenticationError` 메서드에 훅을 걸어 지문 인증 프로세스의 결과를 제어할 수 있습니다.
|
||
2. **SSL 핀닝 우회**: 이는 공격자가 클라이언트와 서버 간의 트래픽을 가로채고 수정할 수 있게 하여, 인증 프로세스를 변경하거나 민감한 데이터를 탈취할 수 있습니다.
|
||
|
||
Frida의 예제 명령:
|
||
```bash
|
||
frida -U -l script-to-bypass-authentication.js --no-pause -f com.generic.in
|
||
```
|
||
## **Method 4 – 리버스 엔지니어링 및 코드 수정**
|
||
|
||
리버스 엔지니어링 도구인 `APKTool`, `dex2jar`, 및 `JD-GUI`를 사용하여 Android 애플리케이션을 디컴파일하고, 소스 코드를 읽고, 인증 메커니즘을 이해할 수 있습니다. 일반적인 단계는 다음과 같습니다:
|
||
|
||
1. **APK 디컴파일**: APK 파일을 더 인간이 읽기 쉬운 형식(예: Java 코드)으로 변환합니다.
|
||
2. **코드 분석**: 지문 인증의 구현을 찾아보고 잠재적인 약점(예: 대체 메커니즘 또는 부적절한 검증 검사)을 식별합니다.
|
||
3. **APK 재컴파일**: 지문 인증을 우회하도록 코드를 수정한 후, 애플리케이션을 재컴파일하고 서명한 다음 테스트를 위해 장치에 설치합니다.
|
||
|
||
## **Method 5 – 사용자 정의 인증 도구 사용**
|
||
|
||
인증 메커니즘을 테스트하고 우회하도록 설계된 전문 도구와 스크립트가 있습니다. 예를 들어:
|
||
|
||
1. **MAGISK 모듈**: MAGISK는 사용자가 장치를 루팅하고 지문을 포함한 하드웨어 수준 정보를 수정하거나 스푸핑할 수 있는 모듈을 추가할 수 있게 해주는 Android 도구입니다.
|
||
2. **사용자 정의 스크립트**: Android Debug Bridge (ADB)와 상호작용하거나 애플리케이션의 백엔드와 직접 상호작용하여 지문 인증을 시뮬레이션하거나 우회하는 스크립트를 작성할 수 있습니다.
|
||
|
||
---
|
||
|
||
## **Method 6 – `BiometricPrompt`(API 28-34)를 위한 유니버설 Frida 훅**
|
||
|
||
2023년, **Universal-Android-Biometric-Bypass**라는 커뮤니티 Frida 스크립트가 CodeShare에 등장했습니다. 이 스크립트는 `BiometricPrompt.authenticate()`의 모든 오버로드와 레거시 `FingerprintManager.authenticate()`를 훅킹하고, **null `CryptoObject`를 포함하는 조작된 `AuthenticationResult`**로 `onAuthenticationSucceeded()`를 직접 트리거합니다. API 레벨에 동적으로 적응하기 때문에, 대상 애플리케이션이 반환된 `CryptoObject`에 대해 **암호화 검사를 수행하지 않는 경우** Android 14(API 34)에서도 여전히 작동합니다.
|
||
```bash
|
||
# Install the script from CodeShare and run it against the target package
|
||
frida -U -f com.target.app --no-pause -l universal-android-biometric-bypass.js
|
||
```
|
||
Key ideas
|
||
* 모든 작업은 사용자 공간에서 발생합니다 – 커널 익스플로잇이나 루트 권한이 필요하지 않습니다.
|
||
* 공격은 UI에 완전히 침묵을 유지합니다: 시스템 생체 인식 대화 상자가 나타나지 않습니다.
|
||
* 완화: **민감한 기능을 잠금 해제하기 전에 항상 `result.cryptoObject`와 그 암호/서명을 확인하십시오**.
|
||
|
||
## **Method 7 – Downgrade / Fallback Manipulation**
|
||
|
||
Android 11부터 개발자는 `setAllowedAuthenticators()` (또는 이전의 `setDeviceCredentialAllowed()`)를 통해 허용되는 인증기를 지정할 수 있습니다. **런타임 후킹** 공격은 `allowedAuthenticators` 비트 필드를 더 약한 `BIOMETRIC_WEAK | DEVICE_CREDENTIAL` 값으로 강제할 수 있습니다:
|
||
```javascript
|
||
// Frida one-liner – replace strong-only policy with weak/device-credential
|
||
var PromptInfoBuilder = Java.use('androidx.biometric.BiometricPrompt$PromptInfo$Builder');
|
||
PromptInfoBuilder.setAllowedAuthenticators.implementation = function(flags){
|
||
return this.setAllowedAuthenticators(0x0002 | 0x8000); // BIOMETRIC_WEAK | DEVICE_CREDENTIAL
|
||
};
|
||
```
|
||
앱이 반환된 `AuthenticationResult`를 **검증하지** 않는 경우, 공격자는 단순히 _PIN/Pattern_ 대체 버튼을 누르거나 새로운 약한 생체 인식을 등록하여 접근할 수 있습니다.
|
||
|
||
## **방법 8 – 공급업체 / 커널 수준 CVE**
|
||
|
||
안드로이드 보안 게시판을 주의 깊게 살펴보세요: 최근 커널 측 버그 몇 가지가 지문 HAL을 통해 로컬 권한 상승을 허용하고 **센서 파이프라인을 비활성화하거나 우회**할 수 있습니다. 예시는 다음과 같습니다:
|
||
|
||
* **CVE-2023-20995** – 사용자 상호작용 없이 잠금 해제를 허용하는 `CustomizedSensor.cpp`의 `captureImage`에서의 논리 오류 (Pixel 8, Android 13).
|
||
* **CVE-2024-53835 / CVE-2024-53840** – “비정상적인 근본 원인으로 인한 가능한 생체 인식 우회”가 **2024년 12월 Pixel 게시판**에서 패치되었습니다.
|
||
|
||
이러한 취약점은 잠금 화면을 목표로 하지만, 루팅된 테스터는 앱 수준의 결함과 연결하여 인앱 생체 인식을 우회할 수 있습니다.
|
||
|
||
---
|
||
|
||
### 개발자를 위한 강화 체크리스트 (빠른 펜테스터 노트)
|
||
|
||
* **Keystore** 키를 생성할 때 `setUserAuthenticationRequired(true)` 및 `setInvalidatedByBiometricEnrollment(true)`를 강제 적용하세요. 유효한 생체 인식이 필요합니다.
|
||
* **null 또는 예상치 못한 암호 / 서명**이 있는 `CryptoObject`를 거부하세요; 이를 치명적인 인증 오류로 간주합니다.
|
||
* `BiometricPrompt`를 사용할 때, `BIOMETRIC_STRONG`을 선호하고 **고위험 작업에 대해 `BIOMETRIC_WEAK` 또는 `DEVICE_CREDENTIAL`로 절대 대체하지 마세요.**
|
||
* 최신 `androidx.biometric` 버전(≥1.2.0-beta02)을 고정하세요 – 최근 릴리스는 자동 null-암호 검사를 추가하고 허용된 인증자 조합을 강화합니다.
|
||
|
||
## 참고 문헌
|
||
|
||
- [Universal Android Biometric Bypass – Frida CodeShare](https://codeshare.frida.re/@ax/universal-android-biometric-bypass/)
|
||
- [Android Pixel Security Bulletin 2024-12-01](https://source.android.com/security/bulletin/pixel/2024-12-01)
|
||
|
||
|
||
{{#include ../../banners/hacktricks-training.md}}
|