Forensics/DFC

[2021 DFC] 2021 디지털포렌식 챌린지 - 301 - What is the secret information

pental 2021. 10. 29. 02:37

1. Identify all unlock methods that the A is using (PIN / Pattern / Password)

A는 2014년 3월에 안드로이드 기기를 구입하였기 때문에 당시 최신 릴리즈 버전인 KitKat 이하의 버전임을 유추해 볼 수 있다.

[그림-1] KitKat AVD 생성

KitKat 이하의 안드로이드 기기에서 사용되는 화면 잠금 유형과 특징 및 아티팩트를 알아보기 위해 안드로이드 SDK(Software Development Kit)을 사용해 AVD(Android Virtual Device)를 생성한다.

[그림-2] Screen lock Type

KitKat AVD에서 지원하는 화면 잠금 해제 방법은 Slide, Pattern, PIN, Password 총 4가지로 구성되어 있다.

위 표는 KitKat 이하 버전에서 잠금 방식에 따른 아티팩트의 위치이다.

만들어진 KitKat AVD에서 None, Slide, Pattern, PIN/Password를 순서대로 추가하며 “/data/system” 경로의 변경 사항을 비교하면 다음과 같다.

그림-3] Lock Type – None
[그림-4] Lock Type – Slide (gesture.key)
[그림-5] Lock Type – PIN/Password (password.key)

1. None -> Slide

gesture.key, password.key 파일 2개가 생성된다.
password.key 파일 크기는 0 이기 때문에 gesture.key에 Slide 정보가 담긴 것을 유추할 수 있다.

2. Slide -> Pattern

Slide와 같지만 gesture.key 내용은 바뀐다.

3. Slide -> PIN

gesture.key 내용을 유지한 채로 password.key에 데이터가 쓰여진다. 3. PIN -> Password PIN과 같지만 password.key 내용은 바뀐다.

해당 동적 분석 과정을 진행함으로써 잠금 방식을 바꾸더라도 기존에 설정했던 잠금 방식의 아티 팩트 데이터는 남아 있다는 것을 알 수 있다. 다시 None 으로 바꿀 시 password.key만 초기화가 된다.

[그림-6] data.img

문제에서 주어진 “data.img” 바이너리는 안드로이드 리눅스 파일 시스템의 “/data” 경로를 이미징 뜬 데이터다.

[그림-7] /data/system Artifacts

[그림-7]은 Magnet Axiom Process 를 사용해 “data.img”를 분석한 결과이며 “/data/system” 경로의 아티팩트들이다. gesture.key, passwordkey 2개의 바이너리 데이터가 존재하는 것으로 보아 Pattern, PIN 혹은 Password 방식을 사용한 것을 알 수 있다.

Pattern, PIN, Password 잠금 방식 중 어느 잠금 방식들이 사용되었는지 확인하기 위해 분석을 진 행한다. 다음은 gesture.key를 사용하여 올바른 입력 값을 찾는 과정이다.

[그림-8] P-Decode

해당 지문으로 보아 gesture.key 데이터는 Pattern의 데이터임을 알 수 있다. P-Decode 도구로 gesture.key 바이너리를 분석할 수 있다.

[그림-9] Pattern 입력 값 (741258.svg)

“data.img” 바이너리의 “/data/system/gesture.key” 정보는 Pattern 잠금 해제 방법이며 Raw 값으 로는 070401020508 임을 알 수 있다.

다음은 password.key, locksetting.db 바이너리를 사용하여 PIN, Password를 식별하는 과정이다.

[그림-10] lockscreen.password_salt

“/data/system/locksetting.db” 데이터베이스에서 locksettings 테이블의 lockscreen.password_salt 값을 확인한다. 해당 salt 값은 0x8076f4ec72cfc224(-9189888693227240924)이다.

password.key 데이터는 다음과 같다.

2BD22D97D0FFE3B6F6D7EC6FB3996737EAAC4EF36A3C230E790E8E5E51E2580DBC0F9906

해당 데이터 값은 SHA1과 MD5로 구성이 되어 있으며, SHA1과 MD5의 값을 따로 나누게 되면 다음과 같다.

SHA1 2BD22D97D0FFE3B6F6D7EC6FB3996737EAAC4EF3
MD5 6A3C230E790E8E5E51E2580DBC0F9906

구해진 Salt 값과 MD5 해쉬를 사용해 hashcat 을 사용해 원본 문자열을 알아낸다.

[그림-11] hashcat – 평문 도출(ninano1)

무차별 대입으로 나온 결과 값 ninano1를 확인할 수 있으며 PIN은 아스키를 입력할 수 없기 때 문에 password.key는 Password로 인해 생긴 아티팩트임을 알 수 있다.


2. Find all keys (numbers / pattern / string) to unlocking the screen. (If Pattern is used, write it down by referring to the coordinates in the figure below.)

휴대폰을 구입한 시점에서 당시 최신 폰 포함 이하 모델에서는 “보조키”개념이 존재하지 않는다. 즉, 패턴을 설정해두고 여러 번 틀렸을 경우 패스워드 입력으로 넘어가는 형식이 아니라 대기 시 간이 생기게 된다. 때문에 잠금 화면을 해제할 수 있는 방법은 현재 기기에서 설정된 방법 하나 로만 해제할 수 있다.

“/data” 경로의 이미지가 있는 경우 설정되어 있는 잠금 방법을 알아내는 방법은 여러가지가 존재한다.

1. “/data/system/locksettings.db” 확인

[그림-12] locksettings.db (data.img)

locksettings.db 의 locksettings 테이블에는 lockscreen.password_type이 존재한다. 해당 값 은 현재 기기의 잠금 해제에 따라 값이 바뀐다.

2. “/data/system/device_policies.xml” 확인

[그림-13] PASSWORD 타입의 device_policies.xml (KiKat AVD)

다음은 AVD에서 임의로 만든 Password 타입의 device_policies.xml 파일이다. 설정한 Password의 quality 값(327680)과 입력 길이, 알파벳의 lowercase, uppercase, letters, numeric 정보를 볼 수 있 으며 이 정보를 가지고 현재 설정된 잠금 해제 타입을 유추할 수 있다.

[그림-14] device_policies.xml (data.img)

주어진 문제 파일에서 추출한 device_policies.xml 데이터이다. quality 값은 65536으로 Pattern임을 알 수 있으며 알파벳, 숫자 정보가 없는 것을 볼 수 있다.

[그림-15] Pattern 입력 값 (741258.svg)

해당 문제 기기에서 설정된 잠금 해제의 유일한 방법은 Pattern 방식이며 입력 값은 1번 지문에 서 구한 “070401020508” 임을 알 수 있다.


3. What is the A’s secret information?

[그림-16] com.example.secretbox-1.apk

“/data/app/” 경로에서 설치된 apk 중 의심스러워 보이는 “secretbox.apk”을 발견할 수 있다.

[그림-17] scretbox.apk

해당 어플리케이션을 실행해보면 ENCRYPT 버튼과 SHOW ME THE SECRET(이하 “SECRET 버튼”라 한다)버튼을 볼 수 있다. 해당 앱은 ENCRYPT 기능만 활성화가 되어 있는 상태이며 입력한 값을 암호화한 뒤 Base64로 보이는 문자열을 출력해준다.

[그림-18] /data/data/com.example.secretbox/shared_prefs/secret_preference.xml (data.img)

암호화된 유저 입력 값은 “/data/data/com.example.secretbox/shared_prefs/secret_preference.xml 해당 경로에 저장이 된다.

[그림-19] SECRET 버튼 클릭 이벤트

Jadx를 사용하여 디컴파일하여 동작방식을 확인한다. SECRET 버튼 클릭 시 PreferenceManger에서 “secret” 값을 가져온 후 decrypt를 진행한다.

[그림-20] decrypt, getSecurity 함수

Decrypt 시 KeyStore에서 키를 가져온 후 안드로이드 SDK 버전에 따라 암복호화 키를 가져온다.

[그림-21] /data/system/framework_atlas.config

안드로이드 버전은 “/data/system/framework_atlas.config” 파일에서 확인할 수 있으며 4.4.2- 4174703 버전을 사용한다. 문제의 안드로이드 기기는 Android 4.4.2 KitKat API Level 19(SDK)이기 때문에 getSecurityKey 함수에서 generateKeyPairPreM 함수를 호출하며 해당 함수에서는 RSA의 키 쌍을 반환해준다.

[그림-22] getCipher 함수

이후 getCipher 함수로 가져온 RSA 키를 가지고 Cipher 객체를 생성한다. init 함수의 mode 값이 2일 경우 복호화를 진행하며 복호화 시 공개키를 사용한다. 또한 RSA_MODE 변수에는 “RSA/ECB/PKCS1Padding” 문자열이 들어있다.

[그림-23] KeyStore

암호화에 사용되는 KeyStore 파일들은 “/data/misc/keystore/user_0”에 존재한다. 해당 키 파일들 은 휴대폰 잠금 해제 타입에 따른 올바른 해제 값으로 암호화가 되어 있기 때문에 [그림-9]에서 구했던 패턴 값 070401020508 으로 복호화 해줄 수 있다.

[그림-24] keystore-decryptor 모듈을 사용한 복호화 코드

[그림-18]의 secret_preference.xml 값을 복호화 해야 될 문자열로 설정한 뒤 [그림-9]의 패턴 값으 로 keystore 데이터인 “.masterkey”, “10055_USRCERT_KEY_ALIAS”(공개키)를 복호화 후 구해진 RSA 키로 입력했던 secret 문자열을 복호화 할 수 있다.

비밀 정보 : Fri 16 May 2021 13:00:55 PM, WoderLand