대한민국 법무부를 사칭하는 악성 앱이 발견되었는데, 악성 앱 내부에 또 다른 악성 앱이 숨겨져 있는 구조가 확인되었습니다. 이에 관련된 내용들을 정리해봤습니다.

악성 앱 안의 악성 앱


com.helloworld.mytest 안에 com.emersonclimate.aebulletin

com.helloworld.mytest 앱을 열어서 Assets 경로를 들여다보면 com.emersonclimate.aebulletin라는 앱이 숨겨져 있는 것을 확인할 수 있다. PE 악성코드에서도 실행파일의 리소스 영역에 악의적인 코드를 추가로 숨겨두는 경우가 종종 있는 것처럼 이 경우도 비슷한 경우라고 판단된다. 하지만 PE 악성코드처럼 리소스 영역으로 쉽게 분기하는 형태가 아니라 Assets 경로 안에 숨겨진 앱을 인스톨하는 형태기 때문에 관련된 코드들을 봤을 때 com.helloworld.mytest는 "악성 앱 인스톨러"라고 불러야겠다. 

com.helloworld.mytest 의 AndroidManifest.xml 중 일부
인스톨과 관련된 코드 중 일부

 

인스톨러 (com.helloworld.mytest)


인스톨러는 스팸전화와 관련된 앱들이 설치되었는지 확인하고 설치되어 있을 경우 사용자에게 악성 앱으로 소개하며 삭제를 유도한다.

this.setContentView(0x7F09001F);  // layout:activity_web
this.mPkgArray = new String[]{"com.ktcs.whowho", "gogolook.callgogolook2", "com.andr.evine.who", "com.whosthat.callerid", "kr.co.thecall", "com.whox2.lguplus", "com.lguplus.blocksmishing", "tpkorea.com.moim"};
this.mWebView = (WebView)this.findViewById(0x7F0700D4);  // id:webview
WebSettings v11_1 = this.mWebView.getSettings();
v11_1.setJavaScriptEnabled(true);
v11_1.setDomStorageEnabled(true);
this.mWebView.setWebViewClient(new e(this, null));
this.mWebView.loadUrl("file:///android_asset/web/" + this.mType + ".html");
this.mWebView.setBackgroundColor(0);
int v11_2 = this.mType;
if(v11_2 == 2) {
    this.mHandler.postDelayed(this.mRunnable, 666L);
}
else if(v11_2 == 3) {
    this.addedReceiver();
    c.b(this.mContext, "K_INIT_SCAN_DONE", "ok");
}
else if(v11_2 == 4) {
    try {
        c.a(this.mContext);
        this.startActivity(new Intent("android.intent.action.VIEW", Uri.parse("openqjaanqnauth://hello")));
    }
    catch(Exception unused_ex) {
    }
}

정상 앱들을 보고 악성 앱이라고 하지만 법무부를 사칭하기 때문에 사용자들은 충분히 속을 수 있다.

법무부를 사칭하는 악성 앱이 정상 앱을 삭제하라네 ... ?

만약 스팸전화와 관련된 앱들이 하나도 없다면 탐지된 스파이앱이 없다고 친절하게 알려준다.

스파이앱이 스파이앱이 없다고하면 ...

 

악성 앱 (com.emersonclimate.aebulletin)


  • 설치되는 악성 앱이 요구하는 권한
<uses-permission android:name="android.permission.READ_CALL_LOG" />
<uses-permission android:name="android.permission.WRITE_CALL_LOG" />
<uses-permission android:name="android.permission.BOOT_COMPLETED" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.BROADCAST_STICKY" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.RECEIVE_USER_PRESENT" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_UPDATES" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.SYSTEM_OVERLAY_WINDOW" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.WRITE_SMS" />
<uses-permission android:name="android.permission.RECEIVE_MMS" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
<uses-permission android:name="android.permission.REQUEST_DELETE_PACKAGES" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

 

  • 악성 앱 파일의 내부

인스톨러를 통해 설치되는 악성 앱의 내부

악성 앱 파일 내부를 보면 secret-classesN.dex 파일들이 존재하는데 이 파일에 실제 악의적인 행위를 하는 코드들이 들어 있다. 하지만 중국 개발자가 만든 프로텍터로 암호화 되어있기 때문에 복호화하지 않으면 정적 분석은 불가능하다. 물론 키값을 알고 있으면 복호화해서 정적 분석을 할 수 있는데, 이번 경우에는 개발자의 실수(?)로 인해 암호화된 dex 파일을 복호화하는 루틴과 관련된 키 값이 존재하지 않아 암호화된 dex 파일을 복호화할 수 없었다.

 

결론


2020년 9월 2일에 수집된 이 앱은 안타깝게도 정상적으로 동작하지 않는다. 개발자의 실수인지 의도인지 모르겠지만 인스톨러가 내부에 가지고 있는 악성 앱을 인스톨 조차 하지 못하는 문제가 있고, 숨겨진 악성 앱도 강제로 추출해서 확인해본 결과 앱 구성상에 문제가 있어 인스톨러가 악성 앱을 정상 설치 했더라도 동작하지 못했을 것이다. 공격자의 실수로 좋은 힌트를 얻었으니 이제 앞으로 벌어질 공격에 대비만 하면 되겠다.

 

IoC (Indicator of compromise)


  • 피싱 사이트
    • http://nimabi7.gnway[.]cc/seoul/kics/login.html
  • 앱 설치 후 등록되는 아이콘

이런 앱이 실제로 있나?

,