어느날 갑자기 문자가 왔습니다. 나를 낚기 위해서... 앱이 어떤식으로 동작하는지 궁금해져서 확인해본 내용을 정리해봤습니다.
동작은 메세지가 오고 링크를 누르면 공공기관 홈페이지와 비슷한 사이트를 만들어서 apk를 다운로드 하도록 유도합니다.
APK를 받아서 apk decomile을 시도해보았습니다.
요즘에는 온라인툴들이 좋아져서 3종의 온라인 apk decompiler를 이용하여 비교하였습니다.
1) http://www.javadecompilers.com/apk
2) https://www.decompiler.com/
3) https://appscms.com/apk-decompiler
1,2 번은 비슷한 수준이며
그중 가장 결과물이 좋은것은 아래 컴파일러였습니다.
https://appscms.com/apk-decompiler
비교
1,3비교
소스 분석
시작은 AndroidManifest.xml 에서 부터 시작합니다.
이런 프로그램들은 재부팅 시점에도 동작하게 만들어야 하기때문에 BOOT_COMPLETED 인텐트를 받아서 동작하는 코드가 있어야합니다.
열어보면 아래와 같은 부분이 보입니다.
<receiver android:name="gl2z9b6.dw">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
부팅 되었을때 여기를 호출한다는 코드이고 gl2z9b6.dw 여기를 따라가보면 jw.e를 실행 시키도록 되는데
package gl2z9b6; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; public class dw extends BroadcastReceiver { public void onReceive(Context context, Intent intent) { jw.e(context); } }
jw 코드는 서비스 관련 코드로 계속 메모리에 실행되도록 하는 코드인데 조금만 따라가보면 native(C언어)코드로 연결되어 있습니다.
package gl2z9b6; import android.app.Service; import android.content.Context; import android.content.Intent; import android.os.IBinder; import android.os.SystemClock; import dmvtga.pj.ggkgoq.ry.R; import j.oi; public class jw extends Service { static boolean a; private void a(Intent intent) { if (!a) { a = true; try { Object[] objArr = {((DzApplication) getApplication()).a, this, intent, new int[]{R.drawable.ic_launcher, R.layout.main, R.id.textView}, "", 0}; oi.py(objArr[0], objArr[1], objArr[2], objArr[3], null); d(c(), getSystemService("alarm")); } catch (Exception unused) { } } } private void b(long j2, Object obj, Intent intent, int i) { oi.ih2(obj, this, intent, j2); } private static long c() { return SystemClock.elapsedRealtime() + 22000; } private void d(long j2, Object obj) { b(j2, obj, new Intent(getClass().getName()), 1); } public static void e(Context context) { try { oi.s2t(context, jw.class); } catch (Exception unused) { } } public IBinder onBind(Intent intent) { return null; } public void onCreate() { a(null); } }
package j, native 연결되는 코드
package j; public class oi { public static native void bbf(Object[] objArr); public static native String dvg(int i); public static native String dvg2(Object obj, int i); public static native Object ez(Object obj, String str); public static native Object gp(Object obj, int i); public static native void ih2(Object obj, Object obj2, Object obj3, long j2); public static native Object kv1(String str, byte[] bArr, int i); public static native Object lv(String str, String str2); public static native Object oqs(String str, Object obj); public static native void py(Object obj, Object obj2, Object obj3, Object obj4, Object obj5); public static native void s2t(Object obj, Object obj2); public static native Object vqz(String str, String str2); public static native Object yk(Class cls); }
그래서 실제적인 코드는 위 내용만 보고는 알 수 없습니다. 즉 위 함수들이 C 언어로 되어 있는데...
resources\lib\armeabi-v7a\libkc.so 여기 파일에 내용이 있습니다만, so파일은 disassemble 해도 보기가 어렵습니다.
so 파일은 ELF 로 되어있어서 https://onlinedisassembler.com/ 여기에 파일을 올리면 내용을 조금 볼 수 는 있지만 구체적으로 어떤 내용인지는 시간을 가지고 분석해봐야 합니다.
java 소스 코드도 전체적으로 확인해 보았지만 특별히 어떤 동작을 하는지 정확히 알 수는 없었습니다. native코드쪽을 더 파야하는데 확인하기가 쉽지 않아서 아쉽지만 여기에서 마쳐야 할것 같습니다.