꿈을꾸는 파랑새

오늘은 무료 SecureVPN 위장해서 개인정보를 유출하는 VPN인 thesecurevpn에 대해 글을 적어보겠습니다.
일단 해당 악성코드는 Bahamut APT(바하무트 APT)에서 수행을 했으며 해당 피싱+악성코드는 안드로이드 사용자를 대상으로 공격을 진행했으며 2022년1월부터 시작해서 꾸준히 가짜 SecureVPN 웹사이트를 만들어서 악성코드를 배포하고 있습니다.
기본적으로 정상적인 SecureVPN 하고는 전혀 관계가 없습니다.
VPN이라는 것은 자신의 국가에서 다른 서비스를 이용하고 싶거나 아니면 넷플릭스 같은 곳에서 다른 국가에서 서비스되고 있는 넷플릭스 서비스 등을 이용하고 싶으면 이런 VPN 서비스를 이용합니다.

그런데 이런 VPN 서비스도 인지도가 있는 서비스를 이용해야지 문제가 되지 않지만, 무료 VPN 들은 개인정보를 가져가는 데 이용이 됩니다. 오늘은 이런 VPN 서비스를 제공하는 척하면서 개인정보를 가져가는 악성코드에 대해 글을 적어 보겠습니다. 기본적으로 유포 방식은 다음과 같습니다.

https://thesecurevpn(.)com->https://thesecurevpn(.)com/apk/SecureVPN_107.apk

VPN 으로 위장한 악성코드 유포 사이트 검색 결과
VPN 으로 위장한 악성코드 유포 사이트 검색 결과

먼저 구글 검색으로는 해당 악성코드 유포하는 사이트는 구글 검색에서 검색은 되고 있지만, 접속은 차단돼 있으며 대부분 보안 업체들이 차단하고 있으며 2022-11-25 05:10:41 UTC 바이러스토탈에서는 검색을 해보면 다음과 같이 차단을 하는 업체들을 볼 수가 있습니다.
Antiy-AVL:Malicious
Avira:Malware
BitDefender:Malware
CRDF:Malicious
Dr.Web:Malicious
ESET:Malware
ESTsecurity:Malicious
Forcepoint ThreatSeeker:Malicious
Fortinet:Malware
G-Data:Malware
Heimdal Security:Malicious
Kaspersky:Malware
Sangfor:Malware
Seclookup:Malicious
Sophos:Malware
Viettel Threat Intelligence:Malicious
VIPRE:Malicious
어차피 국내 업체들도 대응하고 있으니 크게 문제가 될 것이 없으며 해당 사이트는 이미 폭발했습니다.
마지막으로 악성코드 유포는 secureVPN_1010b(.)apk 이라는 이름으로 유포가 되었습니다. 정상적인 SecureVPN 사이트는 다음과 같습니다.

https://securevpn(.)com/

악성코드 유포 사이트 웹 소스VPN 악성코드 최종 다운로드 APK
악성코드 유포 사이트 웹 소스

입니다. 웹사이트는 Free Bootstrap 5 HTML5를 가지고 만들어졌으며 해당 악성코드 특징은 다음과 같습니다.
부트스트랩 5(베타 2)
CSS3 및 HTML5
Gulp 기반 워크플로
단일 페이지 템플릿
반응형 페이지
브라우저 호환성
Hero header
그라데이션 스타일
호버 효과
Font Awesome(폰트 어썸)
등을 사용했습니다.

V3 VPN 악성코드 사이트 차단
V3 VPN 악성코드 사이트 차단

그리고 해당 악성코드는 보안 업체들에 탐지될 때마다 다음과 같이 변경이 되었습니다.

SecureVPN_107(.)apk
SecureVPN_108(.)apk
SecureVPN_109(.)apk
SecureVPN_1010(.)apk
secureVPN_1010b(.)apk

그리고 제가 확보한 악성코드 해쉬값은 다음과 같습니다.

파일명: SecureVPN_107.apk
사이즈:29.0 MB
CRC32:0716fab7
MD5:7ac30a4488748e4be24c04325f147c9f
SHA-1:b54fff5a7f0a279040a4499d5aabce41ea1840fb
SHA-256:a71290070f826292c0ce907f21280e46cb4b800163ca3b81301c75710387ff1b
SHA-512:2bde3d4bb8a5df81f1e0230cf6e1464853bb52c104ce3da594a0218fee62b83610d673b999c186b158b469c50213be4057c8a23aea2b693fd9083293db44cc9c
입니다.
일단 합법적인 SoftVPN 사용은 SecureVPN_107(.)apk 사용이 되었으며 SecureVPN_108(.)apk~secureVPN_1010b(.)apk 까지는 OpenVPN에 삽입이 되었습니다. 일단 먼저 해당 악성코드 권한은 다음과 같습니다.

SecureVPN_107.apk 악성코드 권한
SecureVPN_107.apk 악성코드 권한

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="com.android.vending.BILLING"/>
uses-permission android:name="android.permission.GET_ACCOUNTS" android:maxSdkVersion="22"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_SMS"/>
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.READ_CALL_LOG"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.CALL_PHONE"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>

일단 권한을 보면 인터넷 연결, 안드로이드 스마트폰 기기의 계정 목록 불러오기, 카메라 권한, 외장 메모리 읽고 쓰고, 문자 읽고 쓰고, 스마트폰 사용자의 위치 정확도를 올리기 위한 권한, 전화 걸기, 스마트폰 배터리 최적화 끄기, 와이파이 권한, 스마트폰 부팅 시 앱 실행, 스마트폰 기기를 켜진 상태로 유지 등이 보이는 것을 확인할 수가 있습니다.
DEX 파일은 6개가 존재하고 있으며 각각 해쉬값들은 다음과 같습니다.

악성코드 DEX 파일 정보
악성코드 DEX 파일 정보

[DEX Base Info]
Dex File Name:classes.dex
File Size:10405912 bytes
MD5:bba2ffb2b16a084df0924015705245d5
Dex File Name:classes2.dex
File Size:1299732 bytes
MD5:ab83cc88bed0437668d23f0ced059010
Dex File Name:classes3.dex
File Size:3997444 bytes
MD5:2f709e2789280ae8b6f80a16742c2f4d
Dex File Name:classes4.dex
File Size:388148 bytes
MD5:445762024f72a6584cfa80ddada63d8f
Dex File Name:classes5.dex
File Size:36660 bytes
MD5:0c1666d65d3d1dc9075689a4b7e54f2d

이며 악성코드는 VPN인 것처럼 동작하면 악성 코드는 활성화 키를 요청한 다음 공격자의 C&C 서버에 대해 제공된 키를 확인하는 스파이웨어처럼 동작을 진행합니다.

다만, 정상적으로 키가 맞으면 C&C 서버 간의 성공적인 통신에 필요한 토큰을 반환 키가 올바르지 않으면 VPN이 동작하지 않습니다.

스마트폰을 통제 하기 위한 가짜 SecureVPN 권한 요청SecureVPN 활성화키 요구
스마트폰을 통제 하기 위한 가짜 SecureVPN 권한 요청

com.example.monitoring(.)BuildConfig 에서는 다음과 같이 SoftVPN의 고유한 패키지 이름 com.secure(.)vpn를 사용을 합니다.
패키지 이름은 의 PARENT_APPLICATION_ID 값에서 확인할 수 있습니다.

package com.example.monitoring;

/* loaded from: classes4.dex */
public final class BuildConfig {
    public static final String BASE_URL_MONITORING = "https://ft8hua063okwfdcu21pw(.)de";
    public static final String BASE_URL_MONITORING_LOCAL = "http://193.203.238(.)196:3000";
    public static final String BUILD_TYPE = "debug";
    public static final boolean DEBUG = Boolean.parseBoolean("true");
    public static final String LIBRARY_PACKAGE_NAME = "com.example.monitoring";
    public static final String PARENT_APPLICATION_ID = "com.secure.vpn";
    public static final String VERSION_NAME = "1.0.7";
이며 com.remotelogger(.)RemoteLogger IMEI 관련 코드는 다음과 같습니다.
 public final String getIMEI(Context context) {
        String deviceId;
        Uri uri = Settings.System.DEFAULT_NOTIFICATION_URI;
        if (Build.VERSION.SDK_INT >= 29) {
            String deviceId2 = Settings.Secure.getString(context.getContentResolver(), "android_id");
            Intrinsics.checkNotNullExpressionValue(deviceId2, "{\n            Settings.S…ure.ANDROID_ID)\n        }");
            return deviceId2;
        }
        Object systemService = context.getSystemService("phone");
        if (systemService == null) {
            throw new NullPointerException("null cannot be cast to non-null type android.telephony.TelephonyManager");
        }
        TelephonyManager mTelephony = (TelephonyManager) systemService;
        if (Build.VERSION.SDK_INT >= 23 && context.checkSelfPermission("android.permission.READ_PHONE_STATE") != 0) {
            String lowerCase = (Build.ID + ((Object) Build.BOARD) + ((Object) Build.HARDWARE) + Build.TIME + ((Object) Build.HOST)).toLowerCase(Locale.ROOT);
            Intrinsics.checkNotNullExpressionValue(lowerCase, "this as java.lang.String).toLowerCase(Locale.ROOT)");
            return lowerCase;
        }
        if (mTelephony.getDeviceId() != null) {
            if (Build.VERSION.SDK_INT >= 26) {
                deviceId = mTelephony.getImei();
            } else {
                deviceId = mTelephony.getDeviceId();
            }
        } else {
            deviceId = Settings.Secure.getString(context.getContentResolver(), "android_id");
        }
        Intrinsics.checkNotNullExpressionValue(deviceId, "{\n            val mTelep…)\n            }\n        }");
        return deviceId;
    }
}

com.example.monitoring.BuildConfig
com.example.monitoring.BuildConfig

유심 수집 관련은 다음과 같습니다.(com.example.monitoring(.)utils.Helpers)

유심 관련 코드
유심 관련 코드

public final String getSimSerialNumber(@NotNull Context context) {
            SubscriptionManager sm;
            List sis;
            Intrinsics.checkNotNullParameter(context, "context");
            Object systemService = context.getSystemService("phone");
            if (systemService == null) {
                throw new NullPointerException("null cannot be cast to non-null type android.telephony.TelephonyManager");
            }
            TelephonyManager telephonyManager = (TelephonyManager) systemService;
            if (ActivityCompat.checkSelfPermission(context, "android.permission.READ_PHONE_STATE") == 0 && (sm = SubscriptionManager.from(context)) != null && (sis = sm.getActiveSubscriptionInfoList()) != null) {
                SubscriptionInfo si = sis.get(0);
                String serialNumber = si.getIccId();
                si.getNumber();
                if (serialNumber != null) {
                    return serialNumber;
                }
            }
            return "";
        }

기타 다른 코드 들은 위치들은 다음과 같습니다.

Delete SMS, Contacts: 
com.anchorfree.ucr.tracker.EventsStorage$InsertHistoryTask.run
com.anchorfree.ucr.tracker.EventsStorage.delete
com.tonyodev.fetch2core.StorageResolverHelper.deleteFile
com.anchorfree.sdk.KeyValueStorageImpl.remove
Getting Location:androidx.appcompat.app.TwilightManager.getLastKnownLocationForProvider
Collect IMEI, phone number, system version, etc: 
com.anchorfree.partner.api.utils.DeviceIDProvider$TelephonySource.provide
org.acra.collector.DeviceIdCollector.collect
com.remotelogger.RemoteLogger.getIMEI
Geting SIM Serial Number: com.anchorfree.partner.api.utils.DeviceIDProvider$TelephonySimSource.provide

스마트폰 위치 관련 코드
스마트폰 위치 관련 코드

androidx.appcompat.app.TwilightManager 에서는 스마트폰의 위치정보 관련 코드가 있는 것을 확인할 수가 있습니다.

private Location getLastKnownLocation() {
        Location coarseLoc = null;
        Location fineLoc = null;
        int permission = PermissionChecker.checkSelfPermission(this.mContext, "android.permission.ACCESS_COARSE_LOCATION");
        if (permission == 0) {
            coarseLoc = getLastKnownLocationForProvider("network");
        }
        int permission2 = PermissionChecker.checkSelfPermission(this.mContext, "android.permission.ACCESS_FINE_LOCATION");
        if (permission2 == 0) {
            fineLoc = getLastKnownLocationForProvider("gps");
        }
        return (fineLoc == null || coarseLoc == null) ? fineLoc != null ? fineLoc : coarseLoc : fineLoc.getTime() > coarseLoc.getTime() ? fineLoc : coarseLoc;
    }

    private Location getLastKnownLocationForProvider(String provider) {
        try {
            if (this.mLocationManager.isProviderEnabled(provider)) {
                return this.mLocationManager.getLastKnownLocation(provider);
            }
            return null;
        } catch (Exception e) {
            Log.d(TAG, "Failed to get last known location", e);
            return null;
        }
    }

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

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

유효한 APK 서명 v1을(를) 찾았습니다.
서명자 GOOGLE.RSA (META-INF/GOOGLE.SF)
유형: X.509
버전: 3
시리얼 번호: 0xb3998086d056cffa
소유자: EMAILADDRESS=android@android(.)com, CN=Android, OU=Android, O=Android, L=Mountain View, ST=California, C=US
유효 시작 시각: Wed Apr 16 07:40:50 GMT+09:00 2008
유효 종료 시각: Sun Sep 02 07:40:50 GMT+09:00 2035
공개키 타입: RSA
지수: 3
모듈러스 크기 (비트): 2048
모듈러스: 19752360514994145315516200922626500113201095930210877139293882360491442085478786151541720152971477143983881863321664523422547611110099273765224120568364777034650912678907821093580890163251737414924719328467952497043183923122387299431695133597891714742890183331347183051675551539479800577268863336014071199303706368639398312068986268364026599287186671128600025042565642878806622080419423130708573166425292783829265431121684947027209494790403079505375733937016316815543438173887549948849561798979965946715421653838315942924851269843940189181281036840618385212605258797972686986149267500613535276192842406091462405965863
서명 유형: MD5withRSA
서명 OID: 1.2.840.113549.1.1.4
MD5 지문: 8D DB 34 2F 2D A5 40 84 02 D7 56 8A F2 1E 29 F9 
SHA-1 지문: 27 19 6E 38 6B 87 5E 76 AD F7 00 E7 EA 84 E4 C6 EE E3 3D FA 
SHA-256 지문: C8 A2 E9 BC CF 59 7C 2F B6 DC 66 BE E2 93 FC 13 F2 FC 47 EC 77 BC 6B 2B 0D 52 C1 1F 51 19 2A B8

인증서 정보를 보면 지난 2022.5.17 에 적은 SecureVPN_108.apk 인증서 하고 똑같은 것을 사용하는 것을 확인할 수가 있었습니다.

[소프트웨어 팁/보안 및 분석] - VPN 앱으로 위장 하고 있는 악성코드-SecureVPN_108.apk

 

VPN 앱으로 위장 하고 있는 악성코드-SecureVPN_108.apk

오늘은 VPN 앱 으로 위장하는 악성코드인 SecureVPN_108.apk에 대해 글을 적어 보겠습니다. VPN이라는 것은 자신의 국가에서 다른 서비스를 이용하고 싶거나 아니면 넷플릭스 같은 곳에서 다른 국가에

wezard4u.tistory.com

2022-11-25 07:20:33 UTC 기준 바이러스토탈(Virus Total)에서 탐지하는 백신 프로그램들은 다음과 같습니다.
Alibaba:TrojanSpy:Android/Agent.6011ae1c
Antiy-AVL:Trojan/Generic.ASMalwAD.455
Avast:Android:Bahamut-D [Trj]
Avast-Mobile:Android:Evo-gen [Trj]
AVG:Android:Bahamut-D [Trj]
Avira (no cloud):ANDROID/SpyAgent.FKWX.Gen
BitDefenderFalx:Android.Trojan.SpyAgent.EW
Cynet:Malicious (score: 99)
Cyren:AndroidOS/Trojan.EKZA-6
DrWeb:Android.Spy.988.origin
ESET-NOD32:A Variant Of Android/Spy.Bahamut.M
F-Secure:Malware.ANDROID/SpyAgent.FKWX.Gen
Fortinet:Android/Agent.BTS!tr.spy
Google:Detected
Ikarus:Trojan.AndroidOS.Agent
K7GW:Spyware (0058c7361)
Kaspersky:HEUR:Trojan-Spy.AndroidOS.Agent.abe
Lionic:Trojan.AndroidOS.Agent.C!c
MAX:Malware (ai Score=99)
McAfee:Artemis!445762024F72
McAfee-GW-Edition:Artemis!Trojan
Microsoft:TrojanSpy:AndroidOS/Bahamut.G
Sophos:Andr/Spy-BHC
Symantec:Trojan.Gen.MBT
Symantec Mobile Insight:AppRisk:Generisk
Tencent:Dos.Trojan-Spy.Agent.Jflw
Trustlook:Android.Malware.Spyware
ZoneAlarm by Check Point:HEUR:Trojan-Spy.AndroidOS.Agent.abe
입니다. 일단 기본적으로 백신앱은 기본적으로 설치하고 특히 구글 플레이 스토어 또는 원스토어, 갤럭시 스토어등 기본적으로 공식 스토어가 아닌 곳에서는 앱을 다운로드 및 설치하는 것은 위험한 행동이며 구글 플레이 스토어 에서도 악성코드는 올라오고 있으니 항상 인지도가 있는 백신 앱을 사용을 하는 것이 좋으면 그리고 인터넷 사이트 즉 외부에서 따로 다운로드 하는 APK 파일을 설치하는 것은 악성코드에 감염될 확률을 높이는 것이기 때문에 가능한 외부 앱은 설치를 하지 않는 것이 좋습니다.

그리드형

공유하기

facebook twitter kakaoTalk kakaostory naver band