🎯 Objective

앱이 3rd-party 자격증명(ID/PW)을 어디에, 어떻게 저장하는지 찾아서 값을 확보하라.


🏗️ 시나리오 & 풀이 Step-by-Step

 

단계 작업 핵심 포인트
① 입력 & 저장 앱 화면에서 admin / admin 입력 → SAVE CREDENTIALS 클릭 saveCredentials() 호출, SharedPreferences 에 저장
② 저장 위치 파악 - run-as 명령으로 전용 스토리지 진입 bash adb shell run-as jakhar.aseem.diva ls shared_prefs
- 나의 경우엔 Android Studio Device Explorer 사용
일반 모드의 앱이라도 run-as 로 접근 가능(디버그 빌드)
③ 파일 덤프 bash cat shared_prefs/jakhar.aseem.diva_preferences.xml XML 형태, Base64·암호화 없음
④ 결과 확인 xml <string name="user">admin</string> <string name="password">admin</string> 자격증명이 그대로 노출 → 풀리기 완료


Tip : 디버그 빌드가 아닌 경우에도 루팅, ADB 백업, 앱 데이터 추출(Helium/adb backup) 등으로 동일 취약 노출 가능.


🔍 Root Cause 분석

  1. 평문 저장 : 민감 데이터를 바로 putString() -> 누구나 읽기 가능
  2. 암호화 부재 : Android Keystore / AES 사용 안 함
  3. Debuggable : 개발 편의상 android:debuggable="true" 빌드 → run-as·adb backup 허용
  4. 권한 경계 착각 : MODE_PRIVATE = 다른 앱만 접근 불가일 뿐, 로컬·루트 에선 보호되지 않음

🚧 Mitigation & Hardening 가이드

영역 권장 조치 참고
데이터 암호화 Jetpack EncryptedSharedPreferences or 직접 AES/GCM implementation "androidx.security:security-crypto:1.1.0-alpha06"
키 관리 대칭키는 Android Keystore 내부에 저장 → 외부 유출 방지 KeyGenParameterSpec
Build 설정 출시 APK → android:debuggable="false"<br/>minifyEnabled true, shrinkResources true ProGuard /R8 난독화 병행
백업 차단 android:allowBackup="false" manifest 설정 ADB backup로 데이터 유출 차단
루팅 탐지 SafetyNet / Play Integrity API 로 변조·루트 환경 탐지 → 민감 기능 차단 보안 민감 앱(핀테크) 필수
위험 계층 분리 자격증명은 Secure Server 보관, 토큰만 로컬 캐시(만료·재발급 가능) OAuth 2.0 / JWT 권장