안드로이드 메모리 덤프 내 중요정보 노출 대응방안 의 개요를 간단히 하면 이렇다.
0. 웹뷰 버전 확인 및 업데이트, 웹뷰 설정 점검 ( 웹뷰 사용 시 ) 1. 메모리(변수)에 중요 정보를 저장 할 때에는 반드시 암호화 해서 저장 2. androidmanifest.xml 파일에 있는 android:debugable 속성을 false로 지정 3. 중요 정보가 사용된 직후 배열을 초기화해서 비워줘야 한다. |
웹뷰 버전 확인 및 업데이트, 웹뷰 설정 점검
알려진 보안 취약점을 해결하려면 WebView 구성 요소를 정기적으로 업데이트하는 것이 중요하기에 WebView 업데이트를 확인하고 앱을 최신 버전으로 유지해야한다.
많은 담당자들이 놓치고 있는 부분이다.
메모리(변수)에 중요 정보를 저장 할 때에는 반드시 암호화 해서 저장
예시 코드와 함께 보겠다.
public class SecurePassword {
private static final char[] PASSWORD_CHARACTERS = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
public static void main(String[] args) throws NoSuchAlgorithmException {
// 비밀번호 입력
Scanner scanner = new Scanner(System.in);
System.out.print("비밀번호를 입력하세요: ");
String password = scanner.nextLine();
// 비밀번호를 암호화
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] hash = md.digest(password.getBytes());
// 암호화된 비밀번호를 char 배열로 변환
char[] encryptedPassword = new char[hash.length];
for (int i = 0; i < hash.length; i++) {
encryptedPassword[i] = (char) hash[i];
}
// 암호화된 비밀번호를 출력
System.out.println("암호화된 비밀번호: " + new String(encryptedPassword));
}
}
출처:https://hyotwo.tistory.com/189
위의 코드를 보았을 때 비밀번호가 암호화되어 메모리에 적재되기 때문에 복호화된 평문 비밀번호는 적재되지 않아 평문노출의 위험이 없다.
androidmanifest.xml 파일에 있는 android:debugable 속성을 false로 지정
androidmanifest.xml 파일은 안드로이드 운영체제와 안드로이드 애플리케이션 패키지 관리자(APK)에 앱에 대한 필수 정보를 제공하는 XML(Extensible Markup Language) 파일이며 AndroidManifest.xml 파일의 android:debuggable 속성은 Android 애플리케이션이 기기나 에뮬레이터에서 실행되는 동안 디버깅할 수 있는지 여부를 지정하는 데 사용된다.
그러므로 아래코드처럼 무단 액세스 및 데이터 노출을 방지하려면 AndroidManifest.xml 파일의 android:debuggable 속성을 false로 설정해야한다.
<application
android:debuggable="false"
...>
...
</application>
중요 정보가 사용된 직후 배열을 초기화해서 비워줘야 한다.
char[] password = {'p', 'a', 's', 's', '1', '2', '3'}; // 중요정보를 포함한 char 배열
// 중요 정보를 더 이상 사용하지 않는 경우
Arrays.fill(password, '\0'); // char 배열을 null 문자('\0')로 초기화
중요 정보를 String 객체에 저장하여 사용 후 다른 문자열로 덮어씌우는 방식으로 구현된 경우도 취약하다.
해당 객체가 참조하는 메모리 영역에 특정한 값으로 덮어씌우는 방식은 이전에 해당 변수에 할당된 참조 값이
여전히 유효한 상태로 남아있을 수 있다. 즉, 메모리에서 중요정보가 그대로 존재하며 그 뒤에 덮어씌운 데이터가 추가된다.
Char Array는 가변성(mutable)을 가지므로, 필요하지 않은 경우 해당 배열을 다른 값으로 초기화하거나 크기를 조정하여 메모리를 해제할 수 있다. 그러나 Char Array에 저장된 비밀번호를 덮어쓰거나 초기화하는 로직이 없다면 해당 정보가 메모리에 존재하게 된다.
메모리 덤프 후 char 자료형에 맞게 바이트 단위로 검색(p a s s w o r d, p,a,s,s,w,o,r,d 등) 할 경우 메모리 내 중요정보를 찾을 수 있으므로 Char Array를 사용하고나서 값을 초기화하는 로직을 구현해야 한다.
Char Array에서 삭제되더라도 String 객체에는 여전히 비밀번호가 저장되어 있으므로 Char Array를 사용하여 중요정보를 저장하고자 할 때는 Char Array에서 직접 처리하도록 구현해야 한다.
그래서 위의 코드처럼 중요정보를 처리할 때 char 배열에 저장하고 사용 후에 초기화해야한다.
위 코드에서는 Arrays.fill(charArray, '\0'); 가 핵심 부분이다.
비밀번호를 받고 char 배열로 변환했을 때 아직 메모리에 남아있지만 Arrays.fill(charArray, '\0'); 코드가 실행됨으로 써
배열이 null 값으로 채워진다. 즉 사용후 바로 비워버려서 메모리에 남지않게 되는 것이다.
'모바일 > Android' 카테고리의 다른 글
[Android] apk 파일 구조에 대하여 (0) | 2023.11.14 |
---|---|
[Android] 안드로이드 구조와 부팅 과정 (1) | 2023.11.13 |
[Android] adb ? 알아볼게요 ( with. code ) (0) | 2023.08.28 |
[Android] 메모리 덤프 ? 4가지 알아볼게요 (0) | 2023.08.28 |
[Android] 소스코드 난독화 (0) | 2023.08.02 |