Q 상세 분석 보고서

Q 악성앱 심층 분석 보고서

분석일: 2025-09-04 (초기) / 2026-02-13 (심층 재분석)

분석자: 주식회사 아크링크 ([비공개] 대표)

분석 목적: 피싱/스미싱 [피해자 정보 비공개] 위한 악성앱 분석

보고서 버전: v4.0 (ML Gold Standard Extended)

총 분석 Phase: 14

1. 앱 기본 정보

항목 · 내용

**파일명** · Q.apk

**패키지명 (외부)** · net.embercrest.quantumtrail

**메인 패키지 (내부)** · com.solsticecore.echoverse

**앱 이름** · Q

**Application 클래스** · com.solsticecore.echoverse.Myapplication

**Version Code** · 10062

**Version Name** · 1.6.2

**Target SDK** · 34 (Android 14)

**Min SDK (원본)** · 29 (Android 10)

**Min SDK (패치)** · 21 (Android 5.0)

**Compile SDK** · 34

**프레임워크** · Native Android (Kotlin)

**패밀리** · Wavegrid 변종

**아이콘** · @mipmap/logoicon

**위협 등급** · **EXTREME**

코드 규모

항목 · 수량

**smali/ 파일 수** · 7,914

**smali_classes2/ 파일 수** · 1,725

**총 smali 파일** · 9,639

**핵심 패키지 (echoverse) 파일** · 18

**Activity 수** · 2

**Callback 클래스** · 3

이중 패키지 구조

Q는 외부 패키지명 net.embercrest.quantumtrail과 내부 메인 패키지 com.solsticecore.echoverse가 다른 이중 구조를 사용한다. 이는 ML의 com.iuenf.foejs(외부) / com.tushiweih.wavegrid(내부) 패턴과 동일하며, Wavegrid 변종 생성 시 외부 패키지만 변경하고 내부 코드베이스를 재사용하는 전략을 보여준다.

Chinso와의 코드베이스 동일성 증거

항목 · Chinso · Q · 일치

총 smali 파일 수 · 9,639 · 9,639 · **완전 동일**

smali/ 파일 수 · 7,914 · 7,914 · **완전 동일**

smali_classes2/ 파일 수 · 1,725 · 1,725 · **완전 동일**

핵심 클래스 구조 · 동일 · 동일 · **완전 동일**

라이브러리 구성 · BlankJ+FastJSON+Luban · BlankJ+FastJSON+Luban · **완전 동일**

j62 메서드 수 · 9개 (5활성+4dormant) · 9개 (5활성+4dormant) · **완전 동일**

결론: Q와 Chinso는 smali 파일 수가 정확히 일치 (9,639 = 9,639). 패키지명과 C2 URL만 다르고 나머지는 동일한 코드베이스에서 빌드된 것이 수학적으로 확인됨.

Wavegrid 패밀리 소속 근거

· `[비공개] 접두사를 사용하는 RuoYi 기반 C2 서버

· webapp/login, webapp/saveAddressBook, webapp/image/ 엔드포인트 체계

· HTTP 200 = 실패 역로직 초대코드 인증 (T001)

· FastJSON 기반 응답 파싱 (com.alibaba.fastjson)

· BlankJ AndroidUtilCode 라이브러리 (에뮬레이터 탐지)

· SharedPreferences 기반 상태 관리 (IFFIRST, UUIDVALUE, INVITECODE, ISUPLOAD)

패키지 구성 (라이브러리 의존성)

패키지 · 위치 · 용도

`com/solsticecore/echoverse` · smali/ · 핵심 악성 로직 (18 파일)

`com/alibaba/fastjson` · smali/ · JSON 파싱 (C2 응답 처리)

`com/blankj/utilcode` · smali/ · Android 유틸리티 (에뮬레이터 탐지 포함)

`com/google` · smali/ · Google 라이브러리

`com/gyf/immersionbar` · smali/ · 상태바/네비게이션바 커스터마이징

`com/permissionx` · smali/ · 권한 요청 라이브러리

`com/zhouyou/http` · smali/ · HTTP 네트워크 라이브러리

`okhttp3` · smali_classes2/ · OkHttp HTTP 클라이언트

`retrofit2` · smali_classes2/ · REST API 클라이언트 (미사용 추정)

`top/zibin/luban` · smali_classes2/ · Luban 이미지 압축

2. 권한 분석

요청 권한 목록 (총 10개, 위험 7개)

# · 권한 · 위험도 · 피해 시나리오

1 · `READ_CONTACTS` · **위험** · 피해자의 연락처 전체를 탈취하여 지인 대상 2차 피싱에 활용

2 · `READ_PHONE_STATE` · **위험** · IMEI, 기기 모델, SIM 정보를 수집하여 [피해자 정보 비공개] 고유 식별

3 · `READ_PHONE_NUMBERS` · **위험** · [피해자 정보 비공개] 전화번호 직접 탈취. 보이스피싱 콜백 번호로 악용 가능

4 · `READ_MEDIA_IMAGES` · **위험** · 갤러리의 사진을 무단 탈취. 신분증 사진 등 민감 이미지 유출 (API 33+)

5 · `READ_MEDIA_VIDEO` · **위험** · 동영상 파일 무단 탈취. 사적 영상물로 협박 가능 (API 33+)

6 · `READ_EXTERNAL_STORAGE` · **위험** · API 32 이하에서 외부 저장소 전체 파일 접근 (maxSdkVersion=32)

7 · `WRITE_EXTERNAL_STORAGE` · **위험** · 외부 저장소 쓰기 (이미지 압축 캐시 /Ask 디렉토리)

8 · `INTERNET` · 일반 · C2 서버와의 네트워크 통신

9 · `ACCESS_NETWORK_STATE` · 일반 · 네트워크 연결 상태 확인

10 · `MOUNT_UNMOUNT_FILESYSTEMS` · 일반 · 파일시스템 마운트/언마운트

미선언 권한 (Dormant 코드 관련)

미선언 권한 · 관련 Dormant 코드 · 위험

`READ_SMS` · j62.g() SMS 수집 코드 존재 · 코드 활성화 시 SMS 전체 탈취 가능

참고: w0() 메서드에서 android.permission.READ_SMS 권한을 런타임으로 확인하는 코드가 존재하지만, 이는 getLine1Number() 호출을 위한 것이며 실제 SMS 수집과는 별개. 그러나 j62.g()에는 완전한 SMS 수집 코드가 Dormant 상태로 존재한다.

권한 요청 흐름 (SecondActivity.s0)

```

SecondActivity 진입 → v0() → s0(3) 호출

[API 33+ 분기]

├─ READ_MEDIA_IMAGES 요청

├─ READ_MEDIA_VIDEO 요청

└─ 인자=3이면 추가: READ_CONTACTS, READ_PHONE_NUMBERS, READ_PHONE_STATE

[API 32- 분기]

├─ READ_EXTERNAL_STORAGE 요청

└─ 인자=3이면 추가: READ_CONTACTS, READ_PHONE_NUMBERS, READ_PHONE_STATE

[모든 권한 허용 시]

w0() 호출 → 데이터 수집 시작

[권한 거부 시]

x0(100) → 앱 설정 화면 이동 유도

```

3. 코드 구조 분석

전체 핵심 클래스 맵

# · 클래스 · smali 파일 · 줄 수 · 역할

1 · `Myapplication` · `smali/com/solsticecore/echoverse/Myapplication.smali` · ~70 · Application 진입점. C2 URL 설정 + SSL bypass

2 · `MainActivity` · `smali/com/solsticecore/echoverse/view/MainActivity.smali` · ~394 · 초대코드 입력 UI, 로그인 API 호출

3 · `MainActivity$a` · `smali/com/solsticecore/echoverse/view/MainActivity$a.smali` · ~197 · 로그인 콜백. HTTP 역로직 처리 (**검증 1/2**)

4 · `SecondActivity` · `smali/com/solsticecore/echoverse/view/SecondActivity.smali` · ~806 · 권한 요청, 연락처/미디어 수집 총괄

5 · `SecondActivity$a` · `smali/com/solsticecore/echoverse/view/SecondActivity$a.smali` · ~144 · 이미지 Luban 압축 → 업로드 콜백

6 · `SecondActivity$b` · `smali/com/solsticecore/echoverse/view/SecondActivity$b.smali` · ~196 · 연락처 업로드 콜백 (**검증 2/2**)

7 · `di0` · `smali/di0.smali` · ~198 · 네트워크 싱글톤. SSL bypass, 파일 업로드

8 · `j62` · `smali/j62.smali` · ~831 · **DataHelper** - 9개 데이터 수집 메서드

9 · `pv1` · `smali/pv1.smali` · ~939 · SharedPreferences 래퍼 (SPUtils)

10 · `fi0` · `smali/fi0.smali` · - · SSL trust-all 팩토리 생성

11 · `fi0$d` · `smali/fi0$d.smali` · - · trust-all X509TrustManager 구현

12 · `qx` · `smali/qx.smali` · - · OkHttp 래퍼 싱글톤

13 · `qx$e` · `smali/qx$e.smali` · - · HostnameVerifier (항상 true)

14 · `CollectBeanDTO` · `smali/com/solsticecore/echoverse/bean/CollectBeanDTO.smali` · - · 연락처 데이터 모델

15 · `InfoBeanDTO` · `smali/com/solsticecore/echoverse/bean/InfoBeanDTO.smali` · - · 미디어 정보 모델

16 · `ResultSuccessCallBack` · `smali/com/solsticecore/echoverse/bean/ResultSuccessCallBack.smali` · - · 콜백 인터페이스

앱 실행 흐름

```

[사용자 앱 설치]

[Myapplication.onCreate()]

C2 URL 설정: "[비공개]

SSL bypass: fi0$d trust-all + qx$e hostname bypass

OkHttp(qx) 싱글톤 초기화, 재시도 3회 설정

[MainActivity.onCreate()]

T() → SharedPrefs 확인: IFFIRST 플래그

├─ IFFIRST == true → r0() → SecondActivity 이동 (재실행 시)

└─ IFFIRST == false → 초대코드 입력 화면 표시

[초대코드 입력 → q0() → o0(uuid, code)]

POST webapp/login { name: 초대코드, cId: UUID }

[MainActivity$a 콜백 — 검증 1/2]

FastJSON 파싱 → code 필드 추출

├─ code == 200 → 실패 (msg Toast 표시)

└─ code != 200 → 성공 → UUIDVALUE/INVITECODE 저장 → r0()

[SecondActivity.onCreate()]

T() → INVITECODE, ISUPLOAD 로딩

u0() → "접속하기" 버튼 리스너 설정

[접속하기 클릭 → v0() → s0(3)]

권한 요청 (READ_CONTACTS, READ_PHONE_NUMBERS, READ_PHONE_STATE, READ_MEDIA_*)

[권한 허용 → t0() → w0()]

getLine1Number() → 전화번호 수집

├─ C0() → 연락처 수집 + webapp/saveAddressBook POST

└─ B0() → 미디어 스캔 + Luban 압축 + webapp/image/ POST

[SecondActivity$b 콜백 — 검증 2/2]

FastJSON 파싱 → code 필드 추출

├─ code == 200 → 실패 (msg Toast 표시)

└─ code != 200 → 성공 → ISUPLOAD=true, "synSuc" 가짜 에러 표시

```

Q 고유: 이중 초대코드 검증

Q는 Chinso(1곳)와 달리 2곳에서 초대코드를 검증한다:

검증 위치 · 클래스 · 라인 · 용도

**검증 1** · `MainActivity$a.smali` · 148 · 로그인 시 초대코드 유효성

**검증 2** · `SecondActivity$b.smali` · 106 · 데이터 업로드 시 서버 응답

우회 시: 2곳 모두 if-eq → if-ne 패치 필요. 1곳만 패치하면 로그인은 성공하지만 데이터 업로드 응답에서 차단됨.

난독화 수준

레벨 · 상태 · 예시

패키지명 · 이중 구조 (외부 ≠ 내부) · `net.embercrest.quantumtrail` ≠ `com.solsticecore.echoverse`

Activity명 · **미난독화** · `MainActivity`, `SecondActivity`

유틸리티 · **R8 난독화** · `di0`, `fi0`, `j62`, `pv1`, `qx`

Bean · **미난독화** · `CollectBeanDTO`, `InfoBeanDTO`

메서드명 · **R8 축소** · `o0()`, `q0()`, `r0()`, `w0()`, `C0()`, `B0()`

4. 네트워크/C2 분석

C2 서버 정보

항목 · 내용

**도메인** · [비공개]

**Base URL** · `[비공개]

**프로토콜** · HTTPS (SSL 검증 비활성화)

**서버 프레임워크** · RuoYi (Spring Boot 기반)

**TLD** · `.store` (저비용 TLD, 위험도 높음)

**도메인 특성** · 랜덤 문자열 (`fgjjodawde`) — 자동 생성 일회용 도메인

API 엔드포인트 (총 3개)

# · 엔드포인트 · 메소드 · 파라미터 · 용도

1 · `[비공개] · POST · `{name: 초대코드, cId: UUID}` · 초대코드 인증

2 · `[비공개] · POST · HashMap (5 fields) · 연락처+기기정보 업로드

3 · `[비공개] · POST · File (multipart/image/*) · 미디어 파일 업로드

C2 URL 하드코딩 위치

```smali

Myapplication.smali

const-string v0, "[비공개]

di0.smali static fields

.field public static final b:Ljava/lang/String; = "[비공개]"

.field public static final c:Ljava/lang/String; = "[비공개]

.field public static final d:Ljava/lang/String; = "webapp/login"

.field public static final e:Ljava/lang/String; = "webapp/saveAddressBook"

.field public static final f:Ljava/lang/String; = "webapp/image/"

```

데이터 전송 구조 (webapp/saveAddressBook)

필드명 · 값 소스 · 설명

`userName` · SharedPrefs INVITECODE (F필드) · 초대코드 ([피해자 정보 비공개])

`model` · 하드코딩 `"android"` · 기기 플랫폼

`bjPhone` · `TelephonyManager.getLine1Number()` (E필드) · [피해자 정보 비공개]

`operatorName` · `j62.h()` → `getSimOperatorName()` · 통신사명

`phoneContent` · `j62.c()` → FastJSON 직렬화 · 연락처 JSON 배열

Wavegrid C2 인프라 비교

앱 · C2 도메인 · TLD · 상태

ML (YLOVE) · [비공개] · .online · 독립 C2

Chinso · [비공개] · .work · LOVEM과 공유

**Q** · **[비공개]** · **.store** · **독립 C2**

j0z · [비공개] · .online · 독립 C2

모든 Wavegrid 변종이 동일한 서버 프레임워크(RuoYi)와 API 구조(`[비공개])를 공유하지만, 각각 다른 일회용 도메인을 사용한다. 이는 하나의 C2가 차단되어도 다른 변종은 영향받지 않도록 하는 분산 인프라 전략이다.

5. 방어기제 분석

5.1 에뮬레이터 탐지

위치: com/blankj/utilcode/util/d.smali (DeviceUtils)

BlankJ 기반 에뮬레이터 탐지 (Chinso/ML과 동일):

y() 메소드 - 종합 탐지 (8가지 시그니처):

```

1. Build.FINGERPRINT: "generic" 시작 여부

2. Build.FINGERPRINT: "vbox", "test-keys" 포함 여부

3. Build.MODEL: "google_sdk", "Emulator", "Android SDK built for x86" 포함

4. Build.MANUFACTURER: "Genymotion" 포함

5. Build.BRAND/DEVICE: "generic" 시작

6. Build.PRODUCT: "google_sdk" 일치

7. TelephonyManager.getNetworkOperatorName(): "android" 일치

8. 전화 다이얼 Intent 처리 가능 여부

```

z() 메소드 - CPU 아키텍처 탐지:

```

· /proc/cpuinfo에서 "intel" 또는 "amd" 문자열 존재 여부

```

5.2 초대코드 인증 (T001 역로직) — 이중 검증

검증 1 (로그인 시): MainActivity$a.smali:148

```smali

const/16 v2, 0xc8 # 200

if-eq v0, v2, :cond_2 # 200이면 → 실패(cond_2) 이동

200이 아니면 → 성공 처리 (UUID/INVITECODE 저장)

```

검증 2 (업로드 시): SecondActivity$b.smali:106

```smali

const/16 v2, 0xc8 # 200

if-eq v0, v2, :cond_3 # 200이면 → 실패(cond_3) 이동

200이 아니면 → 성공 처리 (ISUPLOAD=true, synSuc 표시)

```

Chinso와의 차이: Chinso는 MainActivity$a에만 검증이 있지만, Q는 SecondActivity$b에도 동일한 역로직 검증이 존재. 우회 시 2곳 모두 패치 필요.

5.3 API 레벨 제한 (D003)

원본 minSdkVersion: 29 (Android 10)

# · 메서드 · API 레벨 · 위치

1 · `Activity.registerActivityLifecycleCallbacks()` · 29+ · androidx/lifecycle/n$a.smali:73, o$c$a.smali:55

2 · `Window.setStatusBarContrastEnforced()` · 29+ · ImmersionBar.smali:2565

3 · `Window.setNavigationBarContrastEnforced()` · 29+ · ImmersionBar.smali:2607

5.4 SSL 인증서 검증 완전 비활성화

이중 우회 메커니즘:

A. fi0$d.smali — trust-all X509TrustManager:

```smali

checkClientTrusted → return-void (검증 없음)

checkServerTrusted → return-void (검증 없음)

getAcceptedIssuers → 빈 배열 반환

```

B. qx$e.smali — HostnameVerifier 우회:

```smali

.method public verify(Ljava/lang/String;Ljavax/net/ssl/SSLSession;)Z

const/4 p0, 0x1 # 항상 true 반환

return p0

.end method

```

효과: 인증서 체인 검증 + 호스트명 검증 모두 우회. MITM 공격에 완전 노출.

6. 데이터 탈취 분석

수집 대상

데이터 유형 · 수집 메서드 · DTO 클래스 · 전송 API · 상태

**연락처** · j62.c() · `InfoBeanDTO` · `webapp/saveAddressBook` · **활성**

**미디어 경로** · j62.b() · `InfoBeanDTO` · `webapp/image/` · **활성**

**전화번호** · `getLine1Number()` · HashMap 직접 · `webapp/saveAddressBook` · **활성**

**통신사명** · j62.h() · HashMap 직접 · `webapp/saveAddressBook` · **활성**

**이미지 압축** · j62.a() + j62.i() · File · `webapp/image/` · **활성**

**연락처 (상세)** · j62.d() · `CollectBeanDTO` · - · **Dormant**

**연락처 (직접)** · j62.e() · `CollectBeanDTO` · - · **Dormant**

**이미지 (정렬)** · j62.f() · `InfoBeanDTO` · - · **Dormant**

**SMS** · j62.g() · `InfoBeanDTO` · - · **Dormant**

전송 흐름

```

1. SecondActivity.w0()

→ getLine1Number() 전화번호 수집

→ C0() 호출

→ j62.c() 연락처 수집 → FastJSON 직렬화

→ HashMap 5필드 구성

→ POST webapp/saveAddressBook

2. SecondActivity.w0()

→ B0() 호출

→ j62.b() 미디어 스캔

→ Luban 압축 (vu0$b)

→ SecondActivity$a.f() 콜백

→ new Thread() { di0.a(file, inviteCode) }

3. SecondActivity$b 콜백

→ code != 200: ISUPLOAD=true + synSuc 가짜 에러

```

7. 우회 결과

Phase 1: 기본 패치 (v1)

패치 항목 · 파일 · 수정 내용 · 결과

minSdkVersion · apktool.yml · 29 → 21 · 적용

초대코드 역전 (1/2) · MainActivity$a.smali:148 · `if-eq` → `if-ne` · 적용

초대코드 역전 (2/2) · SecondActivity$b.smali:106 · `if-eq` → `if-ne` · 적용

결과: 크래시 - registerActivityLifecycleCallbacks (API 29+)

Q 고유 특징: Chinso(1곳)와 달리 2곳 패치 필요

Phase 2: API 29+ 제거 (v2) — 최종 성공

패치 항목 · 파일 · 수정 내용

registerActivityLifecycleCallbacks (1) · n$a.smali:73 · return-void

registerActivityLifecycleCallbacks (2) · o$c$a.smali:55 · return-void

setStatusBarContrastEnforced · ImmersionBar.smali:2565 · 제거

setNavigationBarContrastEnforced · ImmersionBar.smali:2607 · 제거

최종 결과: 정상 실행 (PID: 5402)

최종 산출물

항목 · 상태

Android 9 호환 · 성공 (minSdk 29 → 21)

초대코드 우회 · 성공 (**2곳** if-eq → if-ne)

API 29+ 제거 · 성공 (4개 메서드)

APK 빌드/서명 · 성공 (Q_modified_v2.apk)

LD Player 실행 · 성공 (PID: 5402)

8. MALBIO 유전체

패밀리 분류: Wavegrid 변종

유전자 · 값 · 정규화 · 설명

permission_count · 7 · 0.5833 · 위험 권한 7개

dangerous_perm_ratio · 0.7 · 0.7 · 10개 중 7개 위험

data_exfil_count · 4 · 0.6667 · 연락처+전화번호+통신사+미디어

phase_count · 10 · 0.3636 · 10단계 분석

contacts_access · 1 · 1.0 · 연락처 접근

camera_access · 0 · 0.0 · 카메라 미접근

sms_access · 0.5 · 0.5 · SMS 코드 존재 (Dormant)

storage_access · 1 · 1.0 · 저장소 접근

phone_access · 1 · 1.0 · 전화상태 접근

ssl_bypass · 1 · 1.0 · SSL+Hostname 이중 우회

c2_known · 1 · 1.0 · C2 서버 확인됨

tld_type · 2 · 0.6667 · .store (저비용 TLD)

api_endpoint_count · 3 · 0.25 · 3개 API

has_invitation_code · 1 · 1.0 · 초대코드 사용 (이중 검증)

bypass_level · 3 · 1.0 · 완전 우회

is_wavegrid · 1 · 1.0 · Wavegrid 패밀리

dormant_code · 4 · 0.8 · 4개 Dormant 메서드

유전적 거리

비교 대상 · 거리 · 관계

Chinso · 0.0100 · **사실상 동일** (smali 9,639 = 9,639)

FileM/FileQ · 0.0213 · **거의 동일**

j0z · 0.1959 · **근거리**

QN · 0.2258 · 근거리

ML (YLOVE) · 0.4483 · 원거리

9. 피해 영향

위험 등급: **EXTREME**

v2.0 HIGH → v3.0 EXTREME 상향.

사유: Dormant SMS 코드(j62.g) + SSL 이중 우회(인증서+호스트명) + 이중 초대코드 검증으로 인한 높은 의도성 확인

피해 영향 점수

카테고리 · 점수 · 설명

**개인정보** · 70/100 · 연락처, 전화번호, 기기정보, 통신사 + Dormant SMS

**금융** · 45/100 · 전화번호 기반 금융사기 가능성

**미디어** · 65/100 · 사진/동영상 탈취, Luban 압축 대량 전송

**통신** · 40/100 · 연락처 기반 2차 피싱 확산

**기기** · 25/100 · IMEI 등 기기 식별 정보

**감시** · 20/100 · 1회성이지만 Dormant SMS 위험

실제 피해 시나리오

```

1단계: 스미싱/메신저 통해 Q.apk 설치 유도

2단계: 초대코드 입력 ("로그인" 버튼)

3단계: "접속하기" 클릭 → 권한 요청

(거부 시 앱 설정 화면으로 이동 유도)

4단계: 권한 허용 즉시 데이터 수집 + C2 전송

5단계: "synSuc" 가짜 에러 → 앱 삭제 유도 (증거 인멸)

6단계: 탈취 연락처로 2차 피싱 발송

```

10. IOC (Indicators of Compromise)

네트워크 IOC

```

도메인: [비공개]

Base URL: [비공개]

TLD: .store (저비용, 랜덤 문자열 도메인)

```

API 엔드포인트 IOC

```

POST [비공개]

POST [비공개]

POST [비공개]

```

패키지 IOC

```

패키지명 (외부): net.embercrest.quantumtrail

메인 패키지 (내부): com.solsticecore.echoverse

Application: com.solsticecore.echoverse.Myapplication

MainActivity: com.solsticecore.echoverse.view.MainActivity

SecondActivity: com.solsticecore.echoverse.view.SecondActivity

```

파일 IOC

```

원본: Q.apk

패치: Q_modified.apk, Q_modified_v2.apk (최종)

```

난독화 클래스 매핑 IOC

```

di0 → NetworkUploadSingleton (C2 통신, SSL bypass)

j62 → DataHelper (데이터 수집 9개 메서드)

pv1 → SPUtils (SharedPreferences 래퍼)

fi0 → SSLTrustAllFactory (SSL 검증 비활성화)

fi0$d → TrustAllX509TrustManager

qx → OkHttpSingleton

qx$e → TrustAllHostnameVerifier

```

SharedPreferences 키 IOC

```

IFFIRST: 최초 인증 여부 (boolean)

UUIDVALUE: 기기 UUID (string)

INVITECODE: 사용된 초대코드 (string)

ISUPLOAD: 데이터 업로드 완료 여부 (boolean)

```

문자열 IOC

```

"로그인" - 초대코드 입력 화면 버튼 (Chinso의 "성인입장"과 다름)

"초대코드를 입력해주세요" - 입력 힌트

"초대 코드를 입력하십시오." - 빈 입력 시 Toast

"온라인으로 파일을 저장하고..." - 가짜 클라우드 서비스 설명

"접속하기" - 데이터 탈취 트리거 버튼

"알 수 없는 오류로 인해..." - 탈취 성공 후 가짜 에러 (synSuc)

"서비스 이용 알림" - 권한 요청 다이얼로그 타이틀

"getContact===" - j62.e() 디버그 로그 (개발자 흔적)

```

11. 분석 타임라인

Phase · 날짜 · 작업 · 결과

Phase 1 · 2025-09-04 · APK 디컴파일 + 기본 패치 (v1) · minSdk 패치, 초대코드 2곳 역전, 크래시 (API 29+)

Phase 2 · 2025-09-04 · API 29+ 메서드 4개 제거 (v2) · 정상 실행 성공 (PID: 5402)

Phase 3 · 2026-02-13 · 전수 코드 분석 (9,639 smali) · Chinso와 smali 수 완전 동일 확인

Phase 4 · 2026-02-13 · 핵심 클래스 16개 심층 분석 · 이중 초대코드 검증 구조 확인

Phase 5 · 2026-02-13 · j62 DataHelper 심층 분석 · 9개 메서드 중 4개 Dormant 발견

Phase 6 · 2026-02-13 · SMS Dormant 코드 분석 (T040) · content://sms/ 수집 코드, Calendar 필터 미적용

Phase 7 · 2026-02-13 · di0 + SSL 이중 우회 분석 · fi0$d(TrustManager) + qx$e(Hostname)

Phase 8 · 2026-02-13 · UI/소셜엔지니어링 분석 · 클라우드 서비스 위장, 가짜 에러

Phase 9 · 2026-02-13 · Chinso/Wavegrid 코드베이스 교차 분석 · 동일 코드베이스 수학적 증명

Phase 10 · 2026-02-13 · ML Gold Standard 보고서 확장 · v2.0(465줄) → v3.0(800줄+)

Phase 11 · 2026-02-14 · j62 바이트코드 정밀 분석 · 9개 메서드 smali 코드 완전 해석

Phase 12 · 2026-02-14 · SSL 체인 전체 코드 플로우 · fi0→fi0$d→qx→qx$e→di0 체인 완전 추적

Phase 13 · 2026-02-14 · 네트워크 보안 설정 + 데이터 모델 분석 · network_security_config + DTO 필드 매핑

Phase 14 · 2026-02-14 · Developer Profiling + 위험도 매트릭스 · v3.0 → v4.0 Gold Standard Extended

12. 패치된 APK

최종 파일: Q_modified_v2.apk

위치: C:\Develop\Deep_Coding\apk\Q\

패치 항목 · 대상 파일 · 원본 → 패치

minSdkVersion · apktool.yml · 29 → 21

초대코드 역전 (1/2) · MainActivity$a.smali:148 · `if-eq` → `if-ne`

초대코드 역전 (2/2) · SecondActivity$b.smali:106 · `if-eq` → `if-ne`

Lifecycle 호출 제거 (1) · n$a.smali:73 · return-void

Lifecycle 호출 제거 (2) · o$c$a.smali:55 · return-void

StatusBar 호출 제거 · ImmersionBar.smali:2565 · 제거

NavigationBar 호출 제거 · ImmersionBar.smali:2607 · 제거

13. j62 DataHelper 심층 분석

> 핵심 발견: Chinso와 동일한 9개 메서드, 동일한 4개 Dormant 코드

j62.g() SMS Dormant 코드 — Chinso와 비교

항목 · Chinso j62.g() · Q j62.g()

URI · content://sms/ · content://sms/

수집 필드 · address, date, type, body · address, date, type, body

Calendar 필터 · DAY_OF_MONTH - 1 (1일) · **DAY_OF_MONTH - 1 (1일)**

필터 적용 · **미적용** (null selection) · **미적용** (null selection)

디버그 로그 · 없음 · `Log.e("TAG", "address:...")`

Manifest 권한 · READ_SMS 미선언 · READ_SMS 미선언

Q의 SMS 코드 특이점: Q와 Chinso 모두 Calendar.add(DAY_OF_MONTH, -1) (1일 전)을 설정하지만, 실제 쿼리에서는 selection이 null로 전달되어 날짜 필터가 적용되지 않는다. 이는 개발자가 필터 로직을 구현

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