은행 앱을 사칭한 안드로이드 악성코드 분석

dusty
12 min readFeb 28, 2022

이 글에서는 2021년 가을 은행 앱을 사칭해, 사용자의 정보를 탈취하는 악성 행위를 하는 악성코드 샘플을 입수하여, 정적 분석을 진행하며 샘플이 어떤 특징을 가지고 있는지, 어떤 악성 행위를 하는지 등을 정리하였습니다. 해당 악성코드는 사용자가 입력한 개인정보 및 연락처, 통화 기록 등 다양한 개인 정보를 수집한 다음, 이를 C&C(Command & Control) 서버에 전송하는 등의 기능을 가지고 있습니다.

악성코드 입수 경로 및 외관

해당 악성코드는 2021년 9월 18일, 한국 시간으로 23시 06분에 수집하였습니다. 악성코드가 배포되던 주소는 http://61.227.52[.]208/wooribank.apk 입니다.

악성코드는 “우리은행”이라는 이름으로 설치되며, 앱 아이콘 또한 우리은행의 인터넷 뱅킹 앱 아이콘을 도용하고 있습니다. 해당 APK 파일의 SHA256 해시는 6bf3853d2814acef8aa805efda34b156de18e96814a226c66eb4339b567eca55 이며, 패키지 이름은 com.cdnb.w003 입니다.

AndroidManifest.xml 분석

악성 앱의 AndroidManifest.xml 파일을 분석해보면, 다음과 같은 권한을 사용하는 것을 확인할 수 있습니다.

3. AndroidManifest.xml 중 권한에 관련된 부분

악성 행위를 수행하는 앱 답게 통화 및 SMS 수신, 발신부터 거의 모든 권한을 요구하는 것을 확인할 수 있습니다.

해당 악성코드에는 2개의 entrypoint 역할을 하는 클래스가 존재합니다. 첫 번째는 com.ppnt.ccmd.aavv.Nforg 클래스로, 사용자가 악성코드를 실행하면 가장 먼저 실행되게 됩니다.

4. AndroidManifest.xml 파일 중 어플리케이션 서브클래스의 정의 부분

두 번째는 com.cdnb.w003.MainActivity 클래스로, launcher 액티비티로 등록되어 있습니다.

5. launcher 액티비티를 등록하는 부분

또한 해당 앱이 접근성 서비스(Accessibility Service)를 이용하는 것을 확인할 수 있습니다.

6. 접근성 서비스를 사용하기 위한 인텐트 필터를 정의하는 부분

APK 구조 분석

해당 APK 파일의 내부 구조는 다음과 같습니다.

secret-classes.dexsecret-classes2.dex 라는 파일이 존재하며, Resources/assets 경로 내에는 app.html 등의 파일이 존재함을 확인할 수 있습니다.

lib 경로에는 armv7-a 아키텍쳐 용의 네이티브 라이브러리 파일이 10개 존재하는 것을 확인할 수 있습니다. 이들 중 rtmp, h264 등은 정상적인 뱅킹 앱이라면 거의 사용하지 않는 영상 처리에 관련된 라이브러리로, 일반 뱅킹 앱과는 다른 동작을 할 것이라고 추측해볼 수 있습니다. (다만 아래에서 언급되는 libfirebase.so 파일과 같은 경우처럼 네이티브 라이브러리 파일 이름과 실제 동작이 관련이 없는 경우도 있습니다.)

APK 파일 내부의 파일 중 secret-classes.dexsecret-classes2.dex 파일을 확인해보면, 정상적인 dex 파일 헤더를 가지고 있지 않은 것을 확인할 수 있습니다.

10. secret-classes.dex 및 secret-classes2.dex 파일의 내용을 헥스 에디터를 통해 확인한 화면

정상적인 dex 파일의 경우, 다음과 같이 dex라는 ASCII 캐릭터로 시작하는 헤더를 가지고 있습니다.

11. classes.dex 파일의 구조 (정상적인 dex 헤더를 가진 dex 파일)

소스 코드 분석

dex 파일 복호화

APK 분석 도구를 활용해 entrypoint가 되는 두 클래스를 분석해보면, 해당 악성코드는 암호화된 secret-classes.dex 파일과 secret-classes2.dex 파일을 실행 중에 복호화해서, Android Reflection이라는 테크닉을 이용해 이를 동적으로 로드해 사용하는 것을 확인할 수 있습니다.

12. com.ppnt.ccmd.aavv.Nforg 클래스의 void a(File, File, m) 메소드

12번 그림의 코드에서 확인할 수 있듯이, 해당 메소드는 dex 확장자를 가지면서, classes.dex 파일이 아닌 파일을 a(zipFile, zipEntry, file3, mVar) 메소드로 넘겨주게 됩니다. 해당 메소드를 분석해보면, InDe.decrypt() 메소드를 호출하는 것을 확인할 수 있습니다.

13. com.ppnt.ccmd.aavv.Nforg 클래스 내의 복호화 함수를 호출하는 메소드

com.ppnt.ccmd.aavv.InDe.decrypt 메소드는 네이티브 라이브러리로 구현되어 있습니다.

14. Inde.decrypt 메소드의 선언 및 네이티브 라이브러리를 로드하는 코드

libdn_ssl.so 파일을 분석하면, dex 파일을 복호화하는 루틴 및 이에 사용된 암호화 방식, 키 등을 파악할 수 있습니다.

15. libdn_ssl 내의 InDe_decrypt 함수를 디컴파일한 코드

네이티브 라이브러리 내의 복호화 함수를 분석한 결과, AES-128-ECB 모드를 사용하며 dbcdcfghijklmaop 를 키로 하여 dex 파일을 복호화하는 것을 알 수 있었습니다.

암호화 방식과 키를 모두 알고 있으므로, 악성 앱의 실행 없이도 dex 파일을 복호화하는 스크립트를 작성할 수 있습니다. 필자가 복호화에 사용한 파이썬 스크립트는 다음과 같습니다.

16. 복호화한 dex 파일을 헥스 에디터로 확인한 결과

16번 그림에서 볼 수 있듯, 복호화된 파일은 정상적인 dex 헤더를 가지고 있으며, jadx-gui 등의 자바 디컴파일러를 이용해 분석 또한 가능합니다.

악성 행위 분석

해당 악성코드는 안드로이드 앱의 접근성 서비스 권한을 이용하여, 사용자가 이를 허용하도록 유도한 다음, 다른 권한을 자체적으로 획득하는 기능을 가지고 있습니다.

17. 사용자에게 접근성 서비스의 허용을 요구하는 코드

사용자가 접근성 서비스의 권한을 허용한 경우, 다음과 같은 코드를 사용하여 다른 권한들을 자체적으로 획득하게 됩니다.

18. 접근성 서비스 권한 허용 이후, 자체적으로 다른 권한들을 획득하는 코드

접근성 서비스를 통해 다른 권한을 사용자 입력 없이 획득하는 것 외에도, 악성 앱이 임의로 다른 앱을 실행하여 2FA를 우회하는 등의 추가적인 악성 행위가 가능합니다. 다른 안드로이드 악성 코드에서 이러한 사례가 보고된 바 있습니다. (How is Android Accessibility Service affected by a banking Trojan?)

이러한 과정을 통해 권한을 획득한 다음, 악성 앱은 다음과 같은 정보를 C&C 서버로 전송하게 됩니다.

  • 연락처 정보
  • SMS
  • 통화 기록
  • 음성 녹음 및 영상
  • GPS 정보
  • 설치된 앱 정보
  • 화면에 표시되는 콘텐츠

이외에도 다음과 같은 악성 행위를 수행합니다.

  • 전화 앱을 대체하여 수신 및 발신 통화를 조작하거나 녹음
  • SMS 수신 및 발신
  • 사용자의 동의 없는 통화 및 SMS 발신

수집한 정보를 C&C 서버로 전송할 때, 다음과 같은 암호화 과정을 거치게 됩니다.

19. C&C 서버와 통신에 사용하는 암호화 / 복호화 메소드

AES-128-CBC 모드를 사용하며, 암호화 / 복호화 키는 rb!nBwXv4C%Gr^84 , IV는 1234567812345678 을 사용하고 있는 것을 확인할 수 있습니다.

C&C 서버 정보 분석

악성코드가 수집한 정보를 송신하는 C&C 서버의 주소를 파악하기 위해 분석을 마저 진행하였습니다.

해당 악성코드는 네이티브 라이브러리에 암호화되어 보관된 IP 주소와, Github Gist를 이용해 배포하는 C&C 주소를 사용하는 방식을 취하고 있습니다. 네이티브 라이브러리의 경우, com.google.oms.firebase 라는 이름의 클래스 내에서 libfirebase.so 파일을 로드하여 사용하고 있습니다.

20. libfirebase.so 라이브러리를 로드하는 코드

해당 네이티브 라이브러리를 분석하면, AES-128-ECB 모드를 통해 라이브러리 내의 암호화된 문자열을 복호화하여 사용함을 확인할 수 있습니다.

MTIzNDU2Nzg5MGFiY2RlZg 를 base64 디코드하면 1234567890abcdef 가 복호화에 사용되는 키임을 확인할 수 있습니다. 이를 통해 암호화된 문자열 중, CNn+B8i6sDpvF+8HUizn8ynbXbnXD0WBfOjqvrSeqUk= 를 base64 디코드한 다음 복호화하면 http://45.115.127[.]106/ 이라는 문자열을 얻을 수 있습니다.

두 번째 C&C 주소는 secret-classes2.dex 파일을 복호화 한 다음, 다음과 같은 코드를 통해 확인할 수 있습니다.

23. Github Gist를 이용해 C&C 주소를 습득하는 코드

maxw201653 이라는 유저의 깃허브 계정을 통해, 암호화된 C&C 주소를 습득하는 코드입니다. (해당 계정은 22년 2월 현재 존재하지 않는 상태입니다.) 해당 Gist의 데이터 또한 그림 19의 암호화 / 복호화 메소드를 사용합니다.

여기까지 직접 샘플을 분석한 다음, 동일한 악성코드 혹은 유사한 악성코드의 분석 결과가 있는지 검색해보았습니다.

ThreatMiner — Android Trojan Targeting Korean Demographic using GitHub for C2

ThreatMiner에서 분석한 카카오뱅크 및 국민은행 앱으로 위장한 악성 앱이, 이번 글에서 분석한 악성코드와 유사한 구조(ok.htmlhuokuan.html, 파일 내의 동일한 중국어 주석 등), C&C 서버와의 통신에 사용하는 AES-128-CBC 암호화에 동일한 키, IV를 사용하는 것을 확인할 수 있었습니다. 또한, 위 분석 보고서에서 분석한 샘플도 Github Gist를 통해 C&C 서버 정보를 전달하고 있으며, minida1004 라는 다른 Github 계정이 사용된 것을 확인할 수 있었습니다.

Cyble — Sophisticated Spyware Posing As A Banking Application To Target Korean Users

Cyble에서 우리은행 앱으로 위장한, 패키지명이 다른 유사한 샘플을 분석한 보고서를 찾을 수 있었습니다. 해당 보고서에 따르면, 이 악성코드는 안드로이드 에뮬레이터 또는 유사한 분석 환경을 검출하는 anti-sandbox 테크닉이 적용되어 있으며, 이후 확인한 결과 제가 분석한 샘플에서도 동일한 코드를 확인할 수 있었습니다.

ESTsecurity — 해외결제를 위장한 스미싱 지속적 유포중!

이외에도 해당 샘플과 동일하게 99754106633f94d350db34d548d6091a.zip 라는 스트링을 가지고 있는, 유사한 악성행위를 하는 샘플에 대한 분석 보고서를 이스트시큐리티 홈페이지에서 찾을 수 있었습니다.

이번 샘플 분석을 통해, Android Refelction 및 Java Reflection에 대해 알게 되었고, 접근성 서비스 권한을 이용해 다른 권한을 획득하는 안드로이드 악성코드의 테크닉에 대해 알 수 있었습니다. Cyble의 보고서를 통해 안드로이드 앱에서 사용하는 anti-sandbox 테크닉에 대해 공부할 수 있는 기회 또한 얻을 수 있었습니다.

안드로이드 악성코드가 Accessibility Feature를 이용해 어떤 악성 행위를 할 수 있는지 공부할 수 있는 계기가 되었습니다. How is Android Accessibility Service affected by a banking Trojan? 문서를 참고했습니다.

Android Reflection 및 Java Reflection에 대한 정보는 다음 블로그 포스팅을 참고했습니다. Charleszz — 안드로이드와 Java의 Reflection

--

--