LOVENSE 상세 분석 보고서

LOVENSE.apk (LumiSphere) 심층 분석 보고서

분석일: 2026-02-13

분석자: 주식회사 아크링크 ([비공개] .ai, deep-scan.ai)

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

Phase: 22

CVSS 3.1: 7.6 (High)

취약점: 18개 | 기법: 22개 | 코딩 버그: 12개

1. 앱 기본 정보

항목 · 내용

**파일명** · LOVENSES.apk

**표시 이름** · LOVENSE

**외부 패키지** · com.vortexus.swklewklewcx

**내부 패키지** · com.astreon.lumisphere

**앱 패밀리** · Wavegrid Gen1.5 (LumiSphere 변종)

**Compile SDK** · 32 (Android 12)

**프레임워크** · Kotlin + EasyHttp + FastJSON + Luban

**DEX 수** · 2개 (smali: 6,953 / smali_classes2: 1,407)

**총 smali** · 8,360개

**파일 크기** · -

**난독화** · 없음 (원본 클래스명 유지)

1.1 앱 컴포넌트

컴포넌트 · 클래스명 · 용도

**Application** · com.astreon.lumisphere.Myapplication · EasyHttp/MMKV 초기화

**Launcher** · com.astreon.lumisphere.view.MainActivity · 초대코드 입력 + 로그인

**Secondary** · com.astreon.lumisphere.view.SecondActivity · 데이터 수집 + 전송

**BlankJ Utils** · com.blankj.utilcode.util.UtilsTransActivity · 유틸리티 (에뮬레이터 탐지)

특징: 서비스(Service) 없음. 1-shot 수집 패턴 - 권한 획득 후 즉시 수집/전송 후 종료.

1.2 라이브러리 스택

라이브러리 · 버전 · 용도 · QF 대응

EasyHttp (com.zhouyou.http) · - · HTTP 클라이언트 · ✅ 동일

FastJSON (com.alibaba.fastjson) · - · JSON 파서 · ✅ 동일

Luban (top.zibin.luban) · - · 이미지 압축 · ✅ 동일

MMKV (com.tencent.mmkv) · - · 키-값 저장소 · ❌ QF=DataStore

BlankJ (com.blankj.utilcode) · - · 유틸리티/에뮬레이터 탐지 · ✅ 동일

PermissionX (com.permissionx.guolindev) · - · 런타임 권한 요청 · ✅ 동일

OkHttp3 (okhttp3) · - · HTTP 기반 · ✅ 동일

GsonUtils · - · JSON 직렬화 · ✅ 동일

1.3 교차 바인딩 발견 (Cross-Binding Anomaly)

> 핵심 발견: lovenses(LumiSphere)의 코드에서 EchoVerse의 ViewBinding 클래스를 사용

```

lovenses 패키지: com.astreon.lumisphere

사용되는 Binding: com.solsticecore.echoverse.databinding.ActivityHomeBinding

com.solsticecore.echoverse.databinding.ActivityContainBinding

```

의미: LumiSphere와 EchoVerse는 동일한 Android 프로젝트 템플릿에서 파생됨.

레이아웃 XML은 EchoVerse 원본을 그대로 사용하고, Kotlin 코드만 패키지명을 변경.

이는 두 변종이 같은 빌드 시스템에서 패키지명만 바꿔 대량 생산되는 증거.

1.4 Gen1.5 변종 비교

항목 · lovenses (LumiSphere) · QF (EchoVerse)

내부 패키지 · com.astreon.lumisphere · com.solsticecore.echoverse

ViewBinding · echoverse.databinding.* · echoverse.databinding.*

저장소 · MMKV · DataStore

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

SSL 방식 · HttpsUtils TrustAll + setCertificates([]) · HttpsUtils TrustAll

초대코드 로직 · 반전 (if-eq, 200=실패) · 정상 (if-ne, 200=성공)

SMS 구현 · getMsgs() 구현, 미호출 · getMsgs() 구현, 미호출

Luban · ✅ 사용 · ✅ 사용

서비스 · 없음 · 없음

smali 수 · 8,360 · 9,115

cleartext · 허용 · -

2. 권한 분석 (10개)

2.1 AndroidManifest 선언 권한

# · 권한 · 위험도 · 실제 사용

1 · `READ_CONTACTS` · **Critical** · ✅ 연락처 전수 탈취

2 · `READ_PHONE_STATE` · **High** · ✅ 기기 정보 수집

3 · `READ_PHONE_NUMBERS` · **High** · ✅ 전화번호 탈취

4 · `READ_EXTERNAL_STORAGE` · **High** (maxSdk=32) · ✅ 이미지 접근

5 · `READ_MEDIA_IMAGES` · **High** · ✅ 갤러리 이미지 탈취

6 · `READ_MEDIA_VIDEO` · **High** · ⚠️ 선언만 (코드 미사용)

7 · `WRITE_EXTERNAL_STORAGE` · **Medium** · ⚠️ 캐시 저장용

8 · `MOUNT_UNMOUNT_FILESYSTEMS` · **Medium** · ⚠️ 선언만

9 · `INTERNET` · Normal · ✅ C2 통신

10 · `ACCESS_NETWORK_STATE` · Normal · ✅ 네트워크 상태 확인

2.2 숨겨진 런타임 권한 확인

```smali

SecondActivity.smali:344 - READ_SMS checkSelfPermission

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

invoke-static {v1, v2}, Landroidx/core/app/ActivityCompat;->checkSelfPermission(...)I

```

READ_SMS는 AndroidManifest에 미선언이지만, SecondActivity.shareCOntain()에서 checkSelfPermission으로 확인.

그러나 requestPermissions()로 요청하지 않음 → 런타임에 권한을 얻을 수 없음.

결론: QF와 동일한 패턴. SMS 관련 코드는 구현되어 있으나 활성화되지 않은 휴면 코드.

2.3 권한 요청 흐름

```

SecondActivity.onCreate()

→ init() - MMKV에서 INVITECODE/ISUPLOAD 로드

→ setList() - btnSync 클릭 리스너 설정

→ getPerInfo(3) - PermissionX로 권한 요청

→ READ_EXTERNAL_STORAGE

→ READ_CONTACTS (permissionSize=3일 때만)

→ READ_PHONE_NUMBERS

→ READ_PHONE_STATE

→ 성공 시 shareCOntain() 호출

```

3. 코드 구조 분석

3.1 패키지 구조

```

com.astreon.lumisphere/

├── Myapplication.smali # Application 초기화

├── bean/

│ ├── CollectBeanDTO.smali # 연락처 데이터 구조 (name, number)

│ ├── InfoBeanDTO.smali # 범용 데이터 구조 (path, content, displayName, date, type)

│ └── ResultSuccessCallBack.smali # HTTP 콜백 인터페이스

├── util/

│ ├── GlobuleValue.smali # 전역 상수

│ ├── HttpUtil.smali # C2 URL + OkHttp 파일 업로드

│ ├── MMKVStorage.smali # MMKV 키-값 저장소 래퍼

│ ├── PermissDialog.smali # 권한 요청 다이얼로그

│ └── StatusUtils.smali # 데이터 수집 유틸리티 (Java로 작성!)

└── view/

├── BaseActivity.smali # 베이스 액티비티

├── MainActivity.smali # 초대코드 입력

└── SecondActivity.smali # 데이터 수집/전송

```

3.2 아키텍처 패턴

```

Kotlin (view/*) + Java (util/StatusUtils) 혼합

├── ViewBinding (com.solsticecore.echoverse.databinding.*)

├── EasyHttp (선언적 HTTP)

├── MMKV (고성능 키-값 저장)

├── PermissionX (런타임 권한)

└── Luban (이미지 압축)

```

특이점: StatusUtils.java는 Java로 작성 (.source "StatusUtils.java"). 나머지는 모두 Kotlin.

이는 Gen3(Java 전체)의 StatusUtils(=ReadContactUtils)를 그대로 가져온 것으로, Gen1.5가 Gen3 코드를 차용한 증거.

3.3 SSL/TLS 우회 구현

2중 SSL 우회:

1. EasyHttp 레벨 (Myapplication.smali:64):

```smali

const/4 v1, 0x0

new-array v1, v1, [Ljava/io/InputStream;

invoke-virtual {v0, v1}, Lcom/zhouyou/http/EasyHttp;->setCertificates([Ljava/io/InputStream;)

```

→ 빈 배열 = 모든 인증서 신뢰

2. OkHttp 레벨 (HttpUtil.smali:103):

```smali

const/4 v0, 0x0 # null

invoke-static {v0, v0, v0}, Lcom/zhouyou/http/https/HttpsUtils;->getSslSocketFactory(...)

```

→ 모든 파라미터 null = TrustAll

3. Network Security Config (res/xml/network_security_config.xml):

```xml

<base-config cleartextTrafficPermitted="true" />

```

→ 평문 HTTP도 허용 (실제로는 HTTPS 사용)

결론: 3중 SSL 우회. MITM 공격에 완전 노출.

4. 네트워크/C2 분석

4.1 C2 서버 정보

항목 · 내용

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

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

**프로토콜** · HTTPS (TrustAll, cleartext 허용)

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

4.2 API 엔드포인트

# · 메소드 · 엔드포인트 · 용도 · 호출 위치

1 · POST · `[비공개] · 초대코드 로그인 · MainActivity.goToNext()

2 · POST · `[비공개] · 연락처+기기정보 업로드 · SecondActivity.startNextInfo()

3 · POST · `[비공개] · 이미지 업로드 (Luban 압축) · HttpUtil.postFile()

4.3 API 버전 분석

lovenses는 API v1 사용:

· webapp/login (AppUser 계층 없음)

· webapp/saveAddressBook (AppUser 계층 없음)

· webapp/image/{userName} (AppUser 계층 없음)

API 버전 · 앱 · 패턴

**v1** · Y, QF, **lovenses**, LOVEM · `webapp/login`, `webapp/saveAddressBook`

**v2** · ze, zine, Flirting_95, Flirting_138 · `webapp/AppUser/checkInviteCode`, `webapp/AppUser/upPhoneBook`

4.4 saveAddressBook 전송 데이터

SecondActivity.startNextInfo() (687-818줄) 분석:

```json

{

"[homeCode_key]": "[INVITECODE from MMKV]",

"[model_key]": "[android.os.Build.*]",

"[phone_key]": "[getLine1Number]",

"[operator_key]": "[getSimOperatorName]",

"[contacts_key]": "[전체 연락처 JSON]"

}

```

특이점: 필드명이 리소스 문자열 ID (getString(R.string.xxx))로 참조됨.

실제 키 이름은 resources.arsc에서 확인 필요하나, QF와 동일 패턴으로 추정:

· inviteCode, deviceModel, phoneNumber, operatorName, data

4.5 이미지 업로드 흐름

```

SecondActivity.startImgShowInfo()

→ StatusUtils.getAlbum(context) # MediaStore 이미지 목록

→ Luban.with(context) # 이미지 압축

→ .load(path)

→ .setCompressListener(listener)

→ .launch()

→ 압축 완료 콜백

→ HttpUtil.postFile(activity, url, file, callback)

→ OkHttp MultipartBody (image/*)

→ POST to webapp/image/{userName}

```

Luban 압축: 100KB 이하로 JPEG 품질을 10%씩 감소 (StatusUtils.compressImage 참조).

5. 방어기제 분석

5.1 방어기제 목록

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

1 · 초대코드 검증 · MainActivity$goToNext$2 · **반전 우회** · if-eq→if-ne 패치

2 · 에뮬레이터 탐지 · BaseActivity (BlankJ) · **우회 완료** · BlankJ 반환값 패치

3 · SSL Certificate Pinning · - · **없음** · TrustAll이므로 불필요

4 · 재업로드 방지 · MMKV ISUPLOAD 플래그 · **우회 가능** · MMKV 값 리셋

5.2 초대코드 검증 (반전 로직)

```smali

MainActivity$goToNext$2.smali:160-172

const/16 v1, 0xc8 # 200

invoke-virtual {v0}, Ljava/lang/Integer;->intValue()I

move-result v0

if-eq v0, v1, :cond_2 # 200이면 → 에러 메시지 표시 (Toast)

200이 아니면 → 성공 (MMKVStorage에 저장 + startUp)

```

반전 패턴: HTTP 200 = 실패 (에러 Toast), HTTP ≠200 = 성공 (MMKV 저장 후 진행)

· ze: 정상 (if-ne, 200=성공)

· zine, Y, Flirting_95, Flirting_138: 반전 (if-eq, 200=실패)

· QF: 정상 (if-ne, 200=성공)

· lovenses: 반전 (if-eq, 200=실패)

5.3 MMKV 키-값 저장

키 · 용도 · 설정 위치

IFFIRST · 첫 실행 여부 (Boolean) · MainActivity.startUp()

UUIDVALUE · 기기 UUID · MainActivity$goToNext$2.onSuccess()

INVITECODE · 초대코드 · MainActivity$goToNext$2.onSuccess()

ISUPLOAD · 업로드 완료 여부 (Boolean) · SecondActivity (추정)

5.4 재업로드 방지

```smali

SecondActivity.init():246-256

invoke-virtual {v0, v1, v2}, Lcom/astreon/lumisphere/util/MMKVStorage;->getBoolean("ISUPLOAD", false)Z

move-result v0

iput-boolean v0, p0, Lcom/astreon/lumisphere/view/SecondActivity;->containIt:Z

:270-276 - XOR로 버튼 비활성화

xor-int/lit8 p0, p0, 0x1 # containIt을 반전

invoke-virtual {v0, p0}, Landroid/widget/TextView;->setEnabled(Z)V

```

→ ISUPLOAD=true이면 containIt=true → XOR → btnSync 비활성화 = 재업로드 불가

6. 데이터 수집 흐름

6.1 전체 수집 흐름

```

[사용자가 btnSync 클릭]

→ setList$lambda$0

→ getPerInfo(3) # 권한 요청 (4개)

→ shareCOntain() # 전화번호 수집

→ TelephonyManager.getLine1Number()

→ READ_SMS checkSelfPermission (확인만)

→ READ_PHONE_NUMBERS checkSelfPermission

→ READ_PHONE_STATE checkSelfPermission

→ startNextInfo() # 연락처 + 기기정보 전송

→ StatusUtils.getContact()

→ StatusUtils.getOperatorName()

→ POST webapp/saveAddressBook

→ startImgShowInfo() # 이미지 전송

→ StatusUtils.getAlbum()

→ Luban 압축

→ HttpUtil.postFile() per image

```

6.2 수집 데이터 종류

# · 데이터 · 수집 메서드 · 전송 API · 상태

1 · 연락처 (이름+전화번호) · StatusUtils.getContact() · saveAddressBook · ✅ 활성

2 · 연락처 (상세 - 복수번호) · StatusUtils.getContacts() · saveAddressBook · ✅ 활성

3 · 연락처 (직접 URI) · StatusUtils.getContactss() · saveAddressBook · ✅ 활성

4 · 이미지 경로 · StatusUtils.getAlbum()/getImg() · image/{userName} · ✅ 활성

5 · 전화번호 · TelephonyManager.getLine1Number() · saveAddressBook · ✅ 활성

6 · 통신사명 · StatusUtils.getOperatorName() · saveAddressBook · ✅ 활성

7 · SMS 메시지 · StatusUtils.getMsgs() · - · ⚠️ **휴면**

6.3 휴면 SMS 수집 코드

StatusUtils.getMsgs() (703-874줄):

```smali

const-string v1, "content://sms/"

invoke-static {v1}, Landroid/net/Uri;->parse(...) # SMS 접근

Calendar 1일 필터

invoke-static {}, Ljava/util/Calendar;->getInstance()

const/4 v2, 0x5 # Calendar.DATE

const/4 v4, -0x1 # -1일

invoke-virtual {v1, v2, v4}, Ljava/util/Calendar;->add(II)V

```

구현 상태: SMS 수집 코드가 완전히 구현되어 있으나 4중 안전장치로 비활성:

1. READ_SMS가 AndroidManifest에 미선언

2. SecondActivity.shareCOntain()에서 checkSelfPermission만 하고 request하지 않음

3. getMsgs()를 호출하는 코드가 SecondActivity에 없음

4. saveSms API 엔드포인트 없음

v3.0 추가 발견 - SMS WHERE null (StatusUtils.smali:770):

```smali

Calendar 1일 필터 계산 (라인 730-739) → 타임스탬프 변환 (746-750)

그러나 ContentResolver.query()에서:

const/4 v5, 0x0 # ← selection = null (WHERE절 미적용!)

const/4 v6, 0x0 # ← selectionArgs = null

const/4 v7, 0x0 # ← sortOrder = null

invoke-virtual/range {v2 .. v7}, Landroid/content/ContentResolver;->query(...)

```

→ Calendar 코드 존재하나 WHERE절에 null 전달 → 전체 SMS 수집 (QF, Y, Flirting_95와 동일 패턴)

→ Gen1.5/Gen3 코드가 동일한 버그 있는 소스에서 파생되었음을 확인.

6.3.1 StatusUtils 메서드 활성 분석 (9개 중 3개만 활성)

# · 메서드 · 라인 · SecondActivity 호출 · 상태

1 · `compressImage` · 16 · ❌ · Dead

2 · `getAlbum` · 77 · ✅ 라인 634 · **활성**

3 · `getContact` · 189 · ✅ 라인 695 · **활성**

4 · `getContacts` · 294 · ❌ · Dead

5 · `getContactss` · 483 · ❌ · Dead (오타명)

6 · `getImg` · 621 · ❌ · Dead

7 · `getMsgs` · 703 · ❌ · Dead (SMS)

8 · `getOperatorName` · 877 · ✅ 라인 762 · **활성**

9 · `saveFile` · 897 · ❌ · Dead

> 6개 Dead Method (67%): QF(70%)와 거의 동일.

> StatusUtils가 공용 라이브러리로 복사되어 필요한 것만 호출하는 "마켓 카트" 패턴 확인.

6.4 이미지 수집 상세

2가지 이미지 수집 경로:

1. getAlbum(): MediaStore.Images.Media.EXTERNAL_CONTENT_URI → _data, _display_name, _id

2. getImg(): MediaStore.Images.Media.EXTERNAL_CONTENT_URI → _data (date_modified DESC 정렬)

이미지 압축 파이프라인:

```

원본 이미지 → Luban 압축 → JPEG 100KB 이하

→ StatusUtils.compressImage() 백업 압축

→ saveFile() → /ExternalCacheDir/Ask/ 폴더에 저장

→ HttpUtil.postFile() → C2 서버 업로드

```

JPEG 품질 80(0x50)으로 저장 (StatusUtils.saveFile():974).

7. 연락처 수집 상세

7.1 3중 연락처 수집

메서드 · 접근 방식 · 수집 필드

getContact() · ContactsContract.CommonDataKinds.Phone.CONTENT_URI · display_name, data1, contact_id

getContacts() · ContactsContract.Contacts.CONTENT_URI + 서브쿼리 · name, data1 (trim+공백/대시 제거)

getContactss() · content://com.android.contacts/data/phones (직접 URI) · display_name, data1

getContacts()의 전화번호 정규화:

```smali

invoke-virtual {v5}, Ljava/lang/String;->trim() # 양끝 공백 제거

invoke-virtual {v5, " ", ""}, replace() # 공백 제거

invoke-virtual {v5, "-", ""}, replace() # 대시 제거

```

7.2 디버그 로그 노출

getContactss() (571-610줄):

```smali

const-string v4, "getContact==="

invoke-static {v3, v1}, Landroid/util/Log;->d("TAG", ...) # 이름 로그

invoke-static {v3, v1}, Landroid/util/Log;->d("TAG", ...) # 번호 로그

```

getMsgs() (834-863줄):

```smali

const-string v6, "address:${address},date:${date},type:${type},body:${body}"

invoke-static {v2, v1}, Landroid/util/Log;->e("TAG", ...) # SMS 로그

```

→ 수집된 데이터가 Logcat에 평문으로 출력됨. 포렌식 증거로 활용 가능.

8. 초대코드 및 인증 흐름

8.1 초대코드 입력 → 로그인

```

MainActivity.onCreate()

→ init()

→ MMKV.getBoolean("IFFIRST")

→ true: 이미 인증됨 → startUp() → SecondActivity

→ false: 새 사용자 → UUID 생성

→ setList()

→ startBtn 클릭

→ codeNumber EditText에서 초대코드 읽기

→ 빈 문자열 검사

→ mainUid 빈 문자열이면 UUID.randomUUID() 생성

→ goToNext(uuid, inviteCode) 호출

```

8.2 goToNext() API 호출

```json

POST [비공개]

{

"name": "[초대코드]",

"cId": "[UUID]"

}

```

응답 처리 (반전):

· code ≠ 200: MMKV에 UUIDVALUE/INVITECODE 저장 → startUp() → SecondActivity

· code = 200: msg 필드를 Toast로 표시 (에러)

9. 교차 분석 (Cross-Reference Analysis)

9.1 Gen1.5 패밀리 교차 바인딩 트리

```

[EchoVerse 프로젝트 템플릿]

├── databinding/

│ ├── ActivityHomeBinding (초대코드 화면)

│ └── ActivityContainBinding (데이터 수집 화면)

├── QF (com.solsticecore.echoverse)

│ ├── 패키지명: solsticecore.echoverse ← 원본

│ ├── 저장소: DataStore

│ └── 초대코드: 정상 (200=성공)

├── lovenses (com.astreon.lumisphere)

│ ├── 패키지명: astreon.lumisphere ← 교체

│ ├── ViewBinding: echoverse.databinding.* ← 원본 유지!

│ ├── 저장소: MMKV

│ └── 초대코드: 반전 (200=실패)

└── LOVEM (com.direlia.quantumfluly) [미분석]

└── 패키지명: direlia.quantumfluly

```

교차 바인딩의 의미:

ViewBinding 클래스는 레이아웃 XML에서 자동 생성됨.

lovenses가 echoverse.databinding.*을 사용한다는 것은

레이아웃 XML의 패키지가 여전히 echoverse임을 의미.

→ 빌드 프로세스: EchoVerse 프로젝트 복제 → Kotlin 코드의 패키지만 변경 → XML은 미수정 → 빌드

9.2 C2 클러스터 분류

클러스터 · C2 도메인 · 앱 · API 버전

**pinonaoshsfpaohjgadsf** · *.xyz · Y, Flirting_95 · v1/v2

**xxayjgagagxxg** · *.xyz/*.monster · ze, zine, Flirting_138 · v2

**bhyjznbalkf** · *.monster · **lovenses** · v1

**yuoaophgioashoig** · [비공개] · QF, nyang · v1

**daujsd** · *.work · Chinso, LOVEM · -

lovenses는 독립 C2 도메인 ([비공개]). 다른 앱과 공유하지 않음.

9.3 Gen1.5 진화 다이어그램

```

[Wavegrid Gen1] (com.cryonix.wavegrid)

│ Java, 연락처만, 서비스 기반

├─→ [Gen1.5 EchoVerse 템플릿]

│ │ Kotlin, EasyHttp, Luban, 비서비스

│ │

│ ├─→ QF (solsticecore.echoverse)

│ │ DataStore, 정상 초대코드, nyang C2

│ │

│ ├─→ lovenses (astreon.lumisphere)

│ │ MMKV, 반전 초대코드, 독립 C2

│ │

│ └─→ LOVEM (direlia.quantumfluly) [미분석]

│ Chinso C2 공유

└─→ [Gen3 SMS] (com.xyx.sms)

Java, SMS+연락처+이미지, 서비스 기반

```

9.4 StatusUtils 혈통 분석

메서드 · lovenses · QF · Gen3 (Flirting_95)

getContact() · ✅ · ✅ · ✅ (ReadContactUtils)

getContacts() · ✅ · ✅ · ✅

getContactss() · ✅ · ✅ · ✅

getAlbum() · ✅ · ✅ · ✅

getImg() · ✅ · ✅ · ✅

getMsgs() · ✅ (휴면) · ✅ (휴면) · ✅ (**활성**)

getOperatorName() · ✅ · ✅ · ✅

compressImage() · ✅ · ✅ · ✅

saveFile() · ✅ · ✅ · ✅

→ StatusUtils는 Gen3의 ReadContactUtils를 완전 복사 (Java .source 유지).

Gen1.5는 Kotlin이지만 유틸리티 클래스만 Java 원본 그대로 사용.

10. 취약점 분석

# · 취약점 · 심각도 · 설명

1 · **3중 SSL 우회** · **Critical** · EasyHttp+OkHttp+NSC 모두 인증서 검증 비활성화

2 · **비난독화** · **High** · 모든 클래스/메서드명 원본 노출

3 · **디버그 로그** · **Medium** · 탈취 데이터가 Logcat에 평문 출력

4 · **교차 바인딩 노출** · **Medium** · EchoVerse ViewBinding이 빌드 시스템 노출

5 · **휴면 SMS 코드** · **Medium** · getMsgs() 구현 존재 (향후 활성화 위험)

6 · **MMKV 평문 저장** · **Low** · 초대코드/UUID가 MMKV에 평문 저장

11. MALBIO 게놈

항목 · 내용

**패밀리** · Wavegrid Gen1.5 (LumiSphere 변종)

**내부 패키지** · com.astreon.lumisphere

**세대** · 1.5 (Gen1 구조 + Kotlin 현대화)

**빌드 템플릿** · EchoVerse (솔스티스코어)

**저장소** · MMKV (Tencent)

**고유 특성** · 독립 C2 ([비공개]), 반전 초대코드

**교차 바인딩** · echoverse.databinding.ActivityHomeBinding/ActivityContainBinding

**연관 앱** · QF (동일 템플릿), LOVEM (동일 세대)

**혈통** · Gen3 StatusUtils.java 완전 복사 (getMsgs 포함)

**SMS 상태** · 휴면 (구현 완료, 미활성화)

12. 피해 영향 평가

12.1 위협 수준

항목 · 평가

**종합 위협** · **High**

**데이터 유출** · 연락처 전수 + 갤러리 이미지 전량 + 전화번호 + 통신사명

**프라이버시** · Critical (연락처+이미지 복합 탈취)

**지속성** · 낮음 (서비스 없음, 1-shot 수집)

**은닉성** · 낮음 (디버그 로그 노출, 비난독화)

**확장 가능성** · **높음** (휴면 SMS 코드 존재)

12.2 피해 시나리오

1. 즉시 피해: 연락처 전수 + 갤러리 이미지 탈취 → 몸캠피싱 협박 소재

2. 확산 피해: 탈취된 연락처로 추가 피싱 SMS 발송

3. 잠재 피해: 휴면 SMS 코드가 활성화되면 인증번호/금융 SMS 탈취 가능

13. IOC (Indicators of Compromise)

13.1 도메인/URL

유형 · 값

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

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

**Login API** · [비공개]

**Contact API** · [비공개]

**Image API** · [비공개]

13.2 패키지/파일

유형 · 값

**외부 패키지** · com.vortexus.swklewklewcx

**내부 패키지** · com.astreon.lumisphere

**빌드 바인딩** · com.solsticecore.echoverse.databinding.*

**Application** · com.astreon.lumisphere.Myapplication

**캐시 폴더** · /ExternalCacheDir/Ask/

13.3 행위 패턴

패턴 · 설명

MMKV IFFIRST 플래그 · 첫 실행 시 false → true

UUID 생성 · java.util.UUID.randomUUID()

Logcat "TAG" · getCo

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