38. Android APK 리버스 엔지니어링
APK 분석의 첫 질문은 “비밀을 꺼낼 수 있는가”가 아니라 “이 패키지가 어떤 신뢰 경계를 가정하는가”다. 승인된 앱, CTF 샘플, 자기 소유 APK만 복사하고 분석한다. APK는 ZIP 컨테이너지만, 매니페스트·DEX·네이티브 라이브러리·리소스가 서로 다른 단서를 제공하므로 압축을 푸는 것만으로 끝나지 않는다.
구조를 보존하며 시작하기
해시와 패키지 정보를 먼저 기록한 뒤 정적 산출물을 별도 디렉터리에 만든다.
sha256sum target.apk
apkanalyzer manifest permissions target.apk
jadx -d jadx-out target.apk
apktool d -o apktool-out target.apk
jadx의 Java 유사 코드는 탐색용이고, 정확한 동작은 DEX와 smali를 대조한다. AndroidManifest.xml의 exported component, intent-filter, deep link, permission과 networkSecurityConfig를 먼저 읽는다. assets/, res/xml/, BuildConfig, 문자열 리소스에서는 URL과 feature flag가 나오지만, 문자열 하나를 곧바로 비밀이나 취약점으로 단정하지 않는다.
동적 관찰과 판단
에뮬레이터 또는 테스트 기기에서 로그, 파일, IPC, 네트워크를 관찰한다. TLS 프록시를 쓰려면 테스트 인증서와 디버그 빌드 설정을 명시적으로 준비하고, 제3자 앱의 인증서 고정을 우회하는 방식은 사용하지 않는다. 자기 소유 앱이라면 디버그용 네트워크 보안 설정이나 테스트 훅을 추가하는 편이 Frida 후킹보다 재현성과 책임성이 높다.
분석 결과는 “토큰이 평문이다”가 아니라 저장 위치, 수명, 접근 제어, 로그 노출 여부로 기술한다. SharedPreferences에 값이 있다는 사실만으로 취약점은 아니며, 백업·루팅·다른 프로세스 접근과 결합될 때 위험이 커진다. 재패키징을 시험할 때도 서명키가 바뀌어 업데이트·무결성 검증이 실패할 수 있음을 기록하고, 원본과 실험본을 혼동하지 않는다.
방어 관점의 결론
클라이언트에 포함된 값은 결국 사용자에게 전달된 값이다. API 권한, 라이선스, 서버 측 비밀을 APK 난독화에 맡기지 말고 서버에서 검증한다. 최소 권한 매니페스트, 비내보내기 컴포넌트, 안전한 저장소, 디버그 로그 제거가 도구보다 오래가는 개선이다.