2020년 3~4월에 팀 프로젝트로 연구하던 내용이 잠시 버려져있다가, 2021년 5월에 새롭게 연구를 시작해서 8월 31일날 모든 작업을 마쳤다. 12월 중순 경 Minor revision을 받고, 1월 10일에 최종 Accept되었다. 디지털 포렌식 분야에서는 SCI급 저널 중에 거의 최고라고 인정받는 Forensic Science International: Digital Investigation
저널에 등재될 수 있어서 무척이나 영광이다. 논문 링크
스스로 평가해보자면, "가장 난이도가 높은" 메신저 3개(Signal, Wickr, Threema)를 묶어서 unrooted 디바이스로부터의 데이터 추출부터, 데이터 복호화 알고리즘 파악, 데이터 복호화 스크립트 작성까지를 수행하였다. 메신저로부터 암호화되지 않은 "원본 데이터를 획득"하기에 필요한 모든 과정을 논문에 담았다는 점에서 가치가 있으며, 흔히 메신저 포렌식에서 수행하는 내용인 '사용자 행위에 따른 아티팩트의 변화'와는 거리가 다소 있는 연구이다. 오히려 데이터 추출, 수집 및 애플리케이션 내부 구조 분석에 가까운 연구이다.
내가 연구했던 메신저들이 난이도가 높은 이유는, 해당 메신저들이 Database 뿐만 아니라, 사진과 같은 Multimedia 파일까지 암호화했기 때문이다. 또 Signal 메신저는 AndroidKeyStore로부터 암호화 키를 가져오기 때문에 일반적인 포렌식 방법으로는 키 추출이 되지 않아, 일종의 해킹 기법을 사용하여 이를 우회하였다. 연구 대상으로 삼았던 3개 메신저 모두에서 메신저에 접근할 때에 사용자의 암호를 필요로하는 Messenger Lock을 적용하였는데, 이것 역시 최대한 우회하기 위해 노력하였다.
한계도 분명하다. 대개의 포렌식 분석이 그러하듯, 메신저 애플리케이션이 시간이 지남에 따라 변화할 수 있다는 점이다. 나 역시도 2021년 발표된 Wickr의 이전 연구에서 일부 파라미터가 변경되었음을 분석 중에 발견하였다. 내 논문 역시 머지 않은 시기에 outdated 될 것이고, 이것은 너무나 뚜렷한 한계이다.
한편 논문 쓰는 법에 대해서도 많이 배울 수 있었는데, 논문 쓰는 방법에 대해서는 자세히 써놨으니 여기에서 확인!
생략
옛날 메신저 분석 사례에서는 암호화된 아티팩트가 없는 경우가 많았다. 최근에 들어서야 메신저 데이터에 대해 복호화를 시도하여 성공한 논문들이 조금씩 나오기 시작하였다.
Signal은 2020년 Oxygen Forensic for Android 도구를 통해 살펴봤을 때 아무 데이터도 나오지 않았다. 2019년에는 Signal의 데이터베이스 보호 메커니즘에 대한 연구가 존재하지만, 복호화랑은 거리가 멀었다.
Wickr는 2016년 2017년에 꾸준히 연구되었으나, 복호화를 직접적으로 시도하지는 않았고, 일부 .wic
파일이 암호화에 사용되었을 것임을 발견하였다. 2021년에 (국민대 연구실) Wickr의 데이터베이스와 멀티미디어 파일에 대해 복호화를 성공하였다!! 그러나 분석 결과 일부 파라미터가 outdated 되었음을 발견하였다.
Threema는 전혀 연구된 사례가 없다.
종단간 암호화를 디폴트로 적용하고, 데이터베이스 뿐만 아니라 멀티미디어 파일까지 암호화하여야 한다.
Messenger lock 기능을 지원하여아 하는데, 메신저 앱을 열 때에 패스워드나 지문 등 사용자 인증을 요구하는 기능이다.
안드로이드 데이터는 크게 내부 저장소와 외부 저장소로 나뉜다.
내부 저장소는 /data/data/<PACKAGE>
의 경로를 갖고, 외부 저장소는 일반적으로 /storage/emulated/0/
의 경로를 갖지만 바뀌는 경우도 존재한다.
ADB(Android Debug Bridge)를 통해 데이터 추출을 시도하였다.
디바이스 루팅이 된 경우에는 모든 데이터를 추출할 수 있었으나, 그렇지 않은 경우에는 외부 저장소의 데이터만을 추출할 수 있었다.
여기서부터 unrooted device에서 내부 저장소의 데이터를 추출하기 위한 여정이 시작되는데,,
백업류
- ADB Backup 으로 데이터 백업하여 추출
- Smart Switch를 통한 추출
- Google Drive mobile Backup을 통한 추출
루팅류
- One-click rooting solution (KingoRoot, Dr.Fone)을 통한 루팅 시도
- TWRP를 통한 custom ROM 설치
그래서 마지막으로 성공한 방법은, Magisk
를 이용한 루팅이다. 구체적인 루팅 방법은 여기!
Magisk라는 도구를 이용해서 안드로이드 보호 기법을 우회해서 TWRP와 같은 custom ROM을 넣는 방법이 유일하였다.
그러나!! Magisk는 루팅할 때에 공장 초기화 (Full Data Wipe)를 반드시 요구하기 때문에, 포렌식적으로 데이터 추출을 위해 루팅을 이용할 수는 없다는 결론을 내리게 되었다.
방법을 고민하다가 발견한 방법이 Messenger Backup Migration 이라는 방법이다.
메신저들에서는 새로운 디바이스를 이용하려는 사람들을 위해 메신저 내부의 데이터를 새로운 디바이스로 백업해주는 기능을 가지고 있는데, 이를 이용해서 데이터를 rooted device로 넘겨오는 방법이다. 데이터 추출 대상으로 하는 디바이스 이외에 rooted 디바이스 1개를 추가로 준비하여 백업 파일을 옮겨오고, 이를 PC로 추출하여 분석하면 된다. 그리 어렵지 않은 내용이니 아래 그림을 참고.
Unrooted device로부터 데이터를 추출하기 위해서, 위와 같은 방법을 사용하였다. 그것은 바로 "Messenger Backup Migration"이라는 방법인데, 쉽게 말하면 메신저에서 자체적으로 지원하는 백업을 이용하는 것이다. rooted device 1개를 추가로 구비한 후에, unrooted에서 rooted로 백업 파일을 옮겨 설치하는 것이다. 이후에는 ADB를 통해서 rooted 에서 파일을 추출하면 된다.
추후에 있을 데이터 분석을 효과적으로 수행하기 위해서 데이터를 나열해보는 과정이다.
내부 저장소, 외부 저장소에서 발견할 수 있는 의심스러운(?) 파일들을 표로 정리하였다. 예를 들자면 이런 식,
정적 분석과 동적 분석을 이용하여 메신저의 복호화 과정을 분석하였다
정적 분석을 위해서, JEB
와 IDA
를 이용하였다. jadx-gui
도 비슷한 분석을 수행해주지만, 성능 면에서는 조금 떨어졌다. 메신저가 오픈 소스로 제공되는 경우에는 Android Studio
를 이용했다. Android Studio의 다양한 검색 기능은 연구에 많은 도움이 되었다.
안드로이드는 다양한 Entry point를 갖기 때문에, 이전 단계로부터 분석의 Keyword를 잡는 것이 시간 단축에 많은 도움이 되었다. 이를테면 암호화에 사용된 것으로 추정되는 적당한 크기의 바이너리 파일인 key.dat
파일이 내부 저장소에 존재한다면, 분석의 시작점을 해당 스트링 검색으로부터 출발하는 것이다. 그마저도 어려울 때에는 데이터베이스 관련 모듈인 SQLCipher
에서 데이터베이스 패스워드를 설정하는 함수인 openOrCreateDatabase()
를 시작점으로 하였다. 여튼 이전 단계에서 힌트를 많이 얻는 것이 중요하다!!
동적 분석을 위해서, Frida
를 이용하였다. Frida를 이용하면 Hooking 기법을 통해 함수 시작점과 반환점에서 오가는 데이터를 엿볼 수 있다. 정적 분석을 통해 많은 내용을 확인할 수 있지만, 정적 분석만으로는 (찐 개발자가 아닌 이상은) 한계가 분명히 온다,, Frida를 통해 데이터를 직접 로그로 찍어보고 내가 잘 분석하고 있는지 확인할 수 있다.
Wickr에서 일부 로직은 정적 분석으로 분석이 불가능하였다. Native 라이브러리 (.so
) 내부에서 동작하는 로직이었는데, 아마도 IDA의 기술적 문제점으로 전혀 알 수 없는 로직으로 데이터가 반환되는 경우가 존재하였다. 이 경우에 Frida Hooking을 통해 10000개의 테스트 케이스를 만들어 직접 실험, 관찰해봄으로써 그 규칙을 파악할 수 있었다. 하여튼 좋다!!
스크립트 작성으로 복호화 알고리즘을 제대로 분석했는지 검증하여야 한다.
(복호화를 수행하는 것이다 보니 데이터, 로직, 파라미터가 모두 정확해야 Python 스크립트로부터 결과값이 딱! 하고 나오는데, 그 쾌감이란,,,)
또 3개의 메신저는 모두 SQLCipher
를 이용하고 있었기 때문에, 최종적으로 데이터베이스를 열기 위해서 PRAGMA
값들을 발견해주어야 한다. String Search를 잘 이용하면 발견이 크게 어렵지는 않은데, 그래도 하나 더 신경써야 하는 느낌이다
Data Lising
Decryption Algorithm
Database Decryption
Multimedia Decryption
Log Decryption
Extraction Prevention
기능을 적용. 절대 유출 불가!!!! 루팅되어 있어도 마찬가지 절대 안 됨!!
따라서 해킹 앱 (rogue app)을 개발하여, 해당 앱으로부터 키를 가져와서 복호화를 수행해야 한다.
추가(제보) 여기 링크를 이용하면 Frida를 통해 Keystore를 후킹해볼 수 있다고 한다 (테스트 해보지는 않았음.)
해킹 앱은 Signal의 정상적인 Keystore 값을 가져와서 내부에서 복호화를 수행하는 역할을 한다. 이 경우에도 우리는 키를 알지는 못하고 단지 사용할 수 있을 뿐이다.
따라서 Table 2에서 Step 1 과정은 Python 코드가 아니라 별도의 Application 내부에서 수행되었다.
Data Listing
Decryption Algorithm
Database Decryption
Multimedia Decryption
Wickr's Preference file
Wickr는 오픈 소스가 아니어서 JEB로 분석을 수행했고, 대부분의 암호화 관련 처리를 Native Library (.so
파일)에서 수행하기 때문에 IDA를 주로 이용하여 분석했다. 난이도가 (당연히) 높았으며, 어려웠다!
한편 이전 연구에서는 복호화에 사용자 패스워드를 반드시 필요로 했었는데, 나는 사용자 패스워드 없이 내부 파일로만 복호화를 수행할 수 있는 것을 발견하여 가치가 있었다.
(Wickr 자동 로그인 관련 취약점이라고 생각했는데, 이유는 패스워드가 걸려 있는 경우에도 자동 로그인에서 사용하던 내부 파일이 삭제되지 않아 내부 파일을 그대로 복호화할 수 있었기 때문이다. 그러나 Wickr Bugbounty에서는 내 의견을 무시했다!)
Threema는 Messenger Lock 기능을 우회하지 못했다. 따라서 사용자의 패스워드가 없이는 복호화가 불가능하다. 한편,, 이건 진짜 비밀인데 Threema는 Messenger Backup
을 ZIP 파일로 하기 때문에 사실 앞의 모든 과정을 거칠 필요 없이 ZIP 파일을 풀어내기만 해도 모든 데이터를 획득할 수 있다. 그래도 뭐 이 기능이 언제까지 이렇게 있지는 않을테니까,,
이제부터 논문 얘기 아닙니다!
연구를 수행하면서 한계점을 너무 절실하게 느꼈다.
내가 열심히 수행한 연구가, 빛을 발하기도 전에 1~2년 내로 분명히 쓸모 없어질 것이다.
내가 SCI급 논문을 얻은 것 이외에 정말 사회에 도움이 될만한 연구를 했는가?라는 측면에서 조금 안타까웠다.
그래서, 안드로이드 애플리케이션 분석 자동화에 관심을 가지게 되었다.
FlowDroid라는 도구가 그 중에서 가장 유명한데, Android Application에 대해 Taint Anlaysis를 자동화해준다. 사용자의 개인 정보를 taint라고 가정하고, 개인 정보가 외부로 유출될 수 있는 곳에 도달하는지 밝혀내는 것을 그 목표로 한다.
이를테면 다음과 같다.
// 사용자의 위치 정보를 가져오는 함수
location.getLatitude();
// 로부터 아래 함수까지 데이터가 실제로 전달되는지 여부를 파악하는 것이다.
// 외부 인터넷에 연결하는 함수
HttpURLConnection conn = (HttpURLConnection) Url.openConnection();
실제로 지금 연구를 진행하고 있으며, 연구 내용은 안드로이드 애플리케이션 포렌식 분석 자동화이다.
APK 파일을 넣었을 때, 모든 암호화 구조와 파라미터, 저장 위치를 자동으로 파악할 수 있게 하는 것을 목표로 하고 있다.