
윤리적 해킹을 위한 Android deeplink, Intent 및 WebView 브리지 평가 도우미
Android 딥링크, Intent 및 WebView 브리지 평가 헬퍼
apk-interceptor는 승인된 애플리케이션 보안 평가를 위한 휴대용 Android 테스트 APK입니다. 보안 엔지니어가 Android 앱이 커스텀 URI 스킴, 딥링크, exported Activity 및 WebView JavaScript 브리지와 같은 외부 진입점을 어떻게 처리하는지 검증하는 데 도움을 줍니다.
이 도구는 의도적으로 제약되어 있습니다:
android.permission.INTERNET을 선언하지 않습니다content:// 페이로드 파일 하나만 제공합니다Android 애플리케이션 보안 평가 중 정적 분석에서 나온 많은 발견 사항은 확정되기 전에 여전히 작은 온디바이스 개념 증명(PoC)이 필요합니다: 커스텀 URI 스킴 등록, 명시적 Intent 전송, 로컬 content:// 페이로드 제공, 또는 JavaScript가 WebView 브리지에 도달할 수 있는지 확인하는 것 등이 있습니다.
각 케이스마다 새로운 일회용 테스트 앱을 만드는 것은 반복적이고 오류가 발생하기 쉽습니다. 매니페스트 항목, authorities, URI 권한 부여, 패키지 이름 또는 Intent 구성의 작은 차이가 검증 속도를 늦추고 결과 재현을 어렵게 만들 수 있습니다.
apk-interceptor는 이러한 확정 단계를 반복 가능하게 만들기 위해 만들어졌습니다. 평가마다 새 PoC APK를 작성하는 대신, 승인된 스킴이나 애플리케이션 ID로 이 도구를 빌드하고, 온디바이스에서 테스트를 실행하며, 설계상 제약된 워크플로우를 유지합니다: INTERNET 권한 없음, 외부 데이터 전송 없음, 셸 실행 없음, root 의존성 없음.
apk-interceptor는 다음 평가 작업에 유용합니다:
자세한 취약점 워크스루:
content://를 통한 WebView JavaScript 브리지 노출이 앱은 전송된 Intent, 수신된 딥링크, 브리지 콜백, JavaScript 결과 및 오류에 대한 인메모리 평가 로그를 유지합니다. 앱 프로세스가 종료되면 로그는 사라집니다. 로그는 영구 저장되지 않으므로 작업하면서 스크린샷이나 화면 녹화로 증거를 캡처하세요.
apk-interceptor는 확정(confirmation) 도구이지 발견 또는 익스플로잇 프레임워크가 아닙니다. 정적 분석에서 무엇을 테스트할지(스킴, Activity 클래스, 브리지 이름) 이미 알고 있다고 가정하고, 도달 가능성을 검증하고 증거를 캡처할 수 있는 안전한 온디바이스 방법을 제공합니다. 평가 장치에 설치하고 고객과 공유할 수도 있도록 설계되었으므로 INTERNET 권한, 셸 실행, 데이터 유출 기능, root 요구 사항이 없습니다.
일반적인 Android 도구와 비교한 위치:
apk-interceptor가 대안보다 가장 확실한 우위를 가진 두 영역:
adb/정적 분석으로는 보여줄 수 없는 부분입니다.content:// → WebView 브리지 검증: 임시 Intent 읽기 권한을 통해서만 페이로드가 전달되는 비-exported 단일 파일 provider와, 먼저 페이로드 구문을 검증할 수 있는 로컬 자체 테스트 WebView를 제공합니다.apk-interceptor는 *전송(sending)*과 *인터셉트(intercepting)*를 다르게 취급하며, 이것이 사용 전에 이해해야 할 가장 중요한 부분입니다:
| 동작 | 모듈 | 빌드 시점에 커스텀 스킴이 필요한가? |
|---|---|---|
| 다른 앱에 Intent 또는 딥링크 전송 | Sender | 아니요, 런타임에 아무 URI, 패키지 또는 Activity를 입력하면 됩니다 |
| 커스텀 스킴의 딥링크 인터셉트(수신) | Interceptor | 예, 스킴은 빌드 시점에 APK에 고정됩니다 |
평가 대상 앱에 조작된 딥링크를 전송하려면 다시 빌드할 필요가 없습니다. Sender 탭의 Implicit Deeplink 모드를 사용하고 아무 URI나 입력하세요.
딥링크를 인터셉트하려면, 즉 Android가 커스텀 스킴을 apk-interceptor로 라우팅하게 하여 가능한 스킴 하이재킹을 관찰하려면 --scheme으로 해당 스킴을 사용해 APK를 빌드해야 합니다. 스킴은 의도적으로 빌드 시점에 고정됩니다(설계상 가드레일). apk-interceptor는 런타임에 임의의 스킴을 절대 등록하지 않습니다. 평가 중인 스킴을 변경하려면 다시 빌드하고 재설치하세요.
adb평가 권한이 있는 커스텀 URI 스킴으로 APK를 빌드하세요:
./build-interceptor.sh --scheme <authorized_custom_scheme>
adb install ./out/apk-interceptor-<authorized_custom_scheme>-debug.apk
선택적 빌드 플래그:
./build-interceptor.sh \
--scheme <authorized_custom_scheme> \
--app-id <custom.application.id> \
--output ./out
--app-id는 빌드 시점에 설치된 애플리케이션 ID(기기의 패키지 ID 및 content://<applicationId>.payload authority)를 설정합니다. 기본값은 com.sterrasec.apkinterceptor입니다. 서로 다른 평가를 위해 여러 개의 별도 설치 가능한 빌드가 필요할 때 --app-id로 재정의하세요. Windows에서는 build-interceptor.bat이 해당합니다.
기본 스킴 intercept-poc-example은 무해한 자리 표시자입니다. 빌드 스크립트는 해당 기본 스킴으로 평가용 APK 생성을 거부합니다.
각 앱 버전의 첫 실행에서 apk-interceptor는 승인된 사용 대화상자를 표시합니다. I understand를 탭하면 동일한 버전에서는 다시 대화상자가 표시되지 않습니다. Sender 탭은 다른 앱에 Intent를 보낼 수 있으므로 지속적인 경고를 계속 표시합니다.
| Sender | Payload | Interceptor |
|---|---|---|
![]() | ![]() | ![]() |
이 탭을 사용하여 커스텀 URI 스킴 인터셉트를 검증하세요.
표시되는 내용:
기본 워크플로우:
Send Test Deeplink 정보: 항상 고정된 test 호스트로 <scheme>://test?<your params>를 전송하므로, apk-interceptor가 스킴을 수신하고 기록하는지 확인하기 위한 용도이며 평가 대상 앱의 특정 딥링크 경로를 구동하기 위한 것이 아닙니다. 평가 대상 앱이 요구하는 호스트나 경로와 일치하는 조작된 딥링크를 보내려면 Sender 탭의 Implicit Deeplink 모드를 대신 사용하세요.
adb 예시:
adb shell am start -W \
-a android.intent.action.VIEW \
-d 'my-authorized-scheme://test?source=adb\&message=hello%20world'
adb shell을 통해 여러 쿼리 파라미터를 보낼 때는 \&를 사용하세요. 그렇지 않으면 기기 셸이 &를 명령 구분자로 취급할 수 있습니다.
예상 결과:
RECEIVED 로그 항목이 나타납니다이 탭을 사용하여 승인된 테스트 중에 통제된 Intent를 전송하세요.
모드:
Intent(ACTION_VIEW, Uri.parse(uri))를 전송합니다필드 및 컨트롤:
Implicit deeplink 워크플로우:
Explicit Activity 워크플로우:
참고 사항:
content:// 첨부는 대상 Activity가 신뢰할 수 없는 Intent 데이터를 WebView에 전달하는지 테스트할 때 유용합니다.data로 전달되며, 이는 Implicit Deeplink 모드에서 입력한 URI를 덮어쓰므로 해당 모드에서는 옵션이 숨겨집니다.PayloadProvider는 exported가 아닙니다. 평가 대상 앱이 첨부된 content:// 페이로드를 읽을 수 있는 유일한 이유는 Intent가 FLAG_GRANT_READ_URI_PERMISSION을 통해 임시 읽기 권한을 부여하기 때문입니다. 해당 플래그를 활성화된 상태로 유지하고 Intent를 통해 URI를 전달하세요. 다른 방식으로 열린 content:// URI는 다른 앱이 읽을 수 없습니다.이 탭을 사용하여 로컬 HTML 페이로드를 만들고 apk-interceptor 자체 테스트 WebView에서 JavaScript 브리지 구문을 검증하세요.
포함 내용:
content:// URI생성된 페이로드 URI 형식:
content://<applicationId>.payload/current.html
provider는 이 고정 파일 하나만 제공합니다:
filesDir/payloads/current.html
페이로드 자체 테스트 워크플로우:
localBridge)을 입력합니다.BRIDGE_RESULT, console.log 및 evaluateJavascript result 항목을 검토합니다.자체 테스트 JavaScript 예시:
console.log("payload loaded");
window.localBridge.logResult(window.localBridge.getInfo());
자체 테스트 브리지는 다음을 노출합니다:
window.<bridgeName>.logResult("message");
window.<bridgeName>.getInfo();
중요한 제한 사항:
자체 테스트 WebView는 로컬 페이로드와 브리지 호출 구문이 apk-interceptor 내부에서 동작한다는 것만 확인합니다. 다른 앱의 WebView가 페이로드를 실행했는지 또는 자체 브리지를 호출했는지는 관찰할 수 없습니다. 평가 대상 앱의 경우 해당 앱의 UI, 로그, 테스트 훅 또는 앱이 디버깅 가능한 경우 Chrome DevTools를 통해 검증하세요.
위험:
Android 앱이 검증된 App Link 대신 커스텀 URI 스킴을 등록합니다. 다른 앱도 동일한 스킴을 등록할 수 있으므로 Android가 앱 선택기를 표시하거나 링크를 다른 앱으로 라우팅할 수 있습니다.
apk-interceptor로 확인할 사항:
단계:
캡처할 증거:
위험:
평가 대상 앱이 충분한 검증 없이 탐색, URL 로딩, 기능 플래그, 계정 선택 또는 렌더링에 딥링크 파라미터를 신뢰합니다.
apk-interceptor로 확인할 사항:
단계:
예시 자리 표시자:
my-authorized-scheme://open?next=https%3A%2F%2Fauthorized-test.example%2Flanding
명시적으로 범위에 포함되지 않는 한 실제 타사 도메인이나 계정을 사용하지 마세요.
위험:
exported Activity가 호출자, 사용자 상태 또는 필요한 권한을 검증하지 않고 민감한 작업을 수행하거나 민감한 데이터를 표시합니다.
apk-interceptor로 확인할 사항:
단계:
content:// 페이로드 URI를 첨부합니다.캡처할 증거:
content://를 통한 WebView JavaScript 브리지 노출위험:
평가 대상 앱이 addJavascriptInterface를 통해 JavaScript 브리지를 노출하는 WebView에 신뢰할 수 없는 content:// Intent 데이터를 로드합니다.
apk-interceptor로 확인할 사항:
content://로 전달할 수 있는지 여부단계:
중요한 제한 사항:
apk-interceptor는 다른 앱이 결과를 명시적으로 반환하거나 표시하지 않는 한 다른 앱의 결과를 수신할 수 없습니다. 이 도구는 로컬 페이로드를 전달하고 구문을 검증하도록 설계되었으며 데이터를 유출하도록 설계되지 않았습니다.
APK가 네트워크 접근을 요청하지 않는지 확인:
aapt dump permissions ./out/apk-interceptor-<scheme>-debug.apk
예상 결과: android.permission.INTERNET 없음.
apk-interceptor로 명시적으로 딥링크 트리거:
adb shell am start -W \
-n com.sterrasec.apkinterceptor/.InterceptActivity \
-a android.intent.action.VIEW \
-d 'my-authorized-scheme://test?source=adb'
Android의 리졸버를 통해 딥링크 트리거:
adb shell am start -W \
-a android.intent.action.VIEW \
-d 'my-authorized-scheme://test?source=adb'
명시적 명령은 InterceptActivity 동작을 확인합니다. 암시적 명령은 매니페스트 intent-filter와 리졸버 동작을 확인합니다.
단위 테스트는 Robolectric으로 JVM에서 실행되므로 기기나 에뮬레이터가 필요하지 않습니다. PayloadProvider를 다루며, provider가 단일 current.html 페이로드 외에 다른 것을 제공하지 못하게 하는 경로 화이트리스트 및 트래버설 검사를 포함합니다.
./gradlew testDebugUnitTest
테스트 결과는 app/build/reports/tests/testDebugUnitTest/index.html에 기록됩니다. 동일한 태스크가 main에 대한 모든 푸시와 풀 리퀘스트에서 CI로 실행됩니다.
android.permission.INTERNET 없음PayloadProvider는 /current.html만 제공MIT
| 시나리오 | 모듈 | 검증에 도움이 되는 내용 |
|---|
| 커스텀 URI 스킴 하이재킹 | Interceptor | 다른 앱이 동일한 커스텀 스킴을 등록하고 링크를 수신할 수 있는지 여부 |
| 딥링크 파라미터 처리 | Sender | 평가 대상 앱이 안전하지 않은 쿼리/경로 파라미터를 수용하는지 여부 |
| Exported Activity 노출 | Sender | exported Activity가 다른 앱에 의해 직접 실행될 수 있는지 여부 |
content://를 통한 WebView 브리지 노출 | Payload + Sender | 로컬 HTML 페이로드가 WebView JavaScript 브리지에 도달할 수 있는지 여부 |
| 로컬 페이로드 구문 확인 | Payload | HTML/JS 페이로드가 자체 테스트 WebView에서 실행되는지 여부 |
| 도구 | 역할 | apk-interceptor와의 차이점 |
|---|
| jadx / MobSF / QARK / Semgrep | 취약한 진입점 찾기(정적) | apk-interceptor는 스캔하거나 디컴파일하지 않습니다. 이미 확보한 발견 사항을 확정할 뿐입니다 |
deep-C / NSDeepLink / adb am start | 딥링크 열거 및 전송 | apk-interceptor도 전송할 수 있지만, 차별점은 하이재킹된 스킴을 수신하고 정확한 URI와 파라미터를 표시하는 것입니다 |
| drozer | 일반 온디바이스 공격 프레임워크(에이전트 + 종종 root) | apk-interceptor는 의도적인 안전 가드레일을 갖춘 단일 경량 APK로, 범위가 더 좁고 클라이언트 안전 배포가 더 쉽습니다 |
| Metasploit / Frida | 무기화 또는 후킹(예: addJavascriptInterface RCE) | apk-interceptor는 무해한 페이로드로 브리지 도달 가능성만 확인합니다. 데이터를 유출하거나 셸 명령을 실행하지 않습니다 |