其乐融融的IT技术小站

基于机器学习的 Android 恶意 App 识别

问题描述

Android 市场的开放性导致了恶意软件(Malware)的盛行。据 360 安全中心报告,每天都能截获数万个 Android 恶意软件,使得 Android Malware Detection 成为研究人员热议的话题。传统的 Android 恶意软件检测方法主要依赖于基于规则或签名的检测机制,其中使用 yara 实现相对简单。但这种基于签名的检测方法是信息密集型的,需要持续收集新的签名,而基于规则的实现则极为复杂,极易导致误报或让狡猾的恶意软件逃过检测。

随着机器学习的流行,越来越多的研究人员开始尝试利用机器学习来实现恶意软件的检测。核心思路是从 Android 的 APK 文件中提取信息,用于训练模型,随后预测其他 APK 文件是否为恶意软件。根据信息提取方法的不同,主要分为两类:一类是通过静态分析,从 APK 中提取 permissions、intents、receivers 等组件,以及通过反编译提取代码调用,利用这些信息进行模型训练;另一类是通过实际安装运行 APK,拦截网络请求和监听系统 API 调用来获取数据,作为模型训练的基础。

在探讨此问题时,由于“Incinerator”项目的动态检测功能尚未完全实现,我们暂时缺乏研究动态分析的条件,因此选择采用静态分析方法进行研究。

当前主流方案

基于静态分析的机器学习训练方案主要包括以下几类:

  1. 权限提取训练:
  • 从 AndroidManifest.xml 中提取 permissions 信息进行模型训练。
  • 综合信息提取训练:

从 AndroidManifest.xml 中提取 permissions、intents、receivers 等信息,并通过反编译从 APK 中基于规则抽取 Android 系统 API 调用等信息进行模型训练。

  • 整体 APK 训练:
  • 将整个 APK 文件作为机器学习训练的输入,包括将 APK 文件的二进制字节流作为输入,或通过反编译抽取 opcode 作为训练输入。

据文献报道,这些方案可实现 90% 以上的准确率。尤其是方案 3,准确率在 92%-93% 之间,而方案 1 和 2 在多数研究中可达到 95% 以上的准确率。

我们试图重现文献中的方案,首先着手基于 permissions 的方案进行验证。

数据源:

  • 恶意软件集合:

a. 来自威胁情报公司 abuse.ch 的 Malware APK 集合 2000 个(简称 MB)

b. VirusShare 2020/2021/2022 的 Malware 集合(简称 VS2020/VS2021/VS2022)

  • 良性软件集合:

a. 从应用宝下载的 APK 10000 个

b. 从 APKPURE 下载的 APK 10000 个

训练方法

通过静态分析从 APK 的 AndroidManifest.xml 中抽取 AOSP (Android Open Source Project) permissions,并通过 One-hot Encoding 的方式输入模型进行训练。模型选择采用传统的机器学习二分类模型如随机森林、SVM 等进行训练。经测试,随机森林的效果最佳,准确率可达 98%。

我们选择应用宝的 APK 作为良性样本,VS2022 作为恶意软件样本,进行训练。训练数据如下:

模型

Precision

Recall

FPR

随机森林

0.983

0.983

0.056

SVM

0.981

0.977

0.063

然后我们对其他数据集进行测试验证:

数据集

Precision

Recall

FPR

APKPure

0.0

NAN

0.59

MB

1.0

0.95

NAN

VS2020

1.0

0.96

NAN

VS2021

1.0

0.94

NAN

在进行 APKPure 数据集的验证时,发现模型的假阳性率异常高,超过了 50%,这表明模型在不同数据集的交叉验证上表现不佳。同时,在 MB、VS2020、VS2021 数据集上得到的高准确率由于高假阳性率而变得无意义。

为了深入理解模型的预测表现,我们选择使用 LinearSVM(线性支持向量机)来解释模型的预测结果,并尝试探讨可能出现的问题:

在训练过程中,共有 265 个权限被用于训练模型。我们重点分析了对于 Malware 预测结果影响最大的 30 个权限:

0 1.9507425950717683 android.permission.READ_SMS
1 1.6805547441380115 android.permission.SEND_SMS
2 1.5291784053142392 android.permission.RECEIVE_SMS
3 1.281383891333467 android.permission.WRITE_SMS
4 1.1385944832617678 android.permission.GET_DETAILED_TASKS
5 1.0870145778775504 android.permission.MANAGE_USERS
6 0.9822953162458009 android.permission.SET_TIME_ZONE
7 0.9815855293627985 android.permission.REQUEST_DELETE_PACKAGES
8 0.8705538278525148 android.permission.ACCOUNT_MANAGER
9 0.7701851337780519 android.permission.ACCESS_CACHE_FILESYSTEM
10 0.7493889020376178 android.permission.PERSISTENT_ACTIVITY
11 0.742267985802697 android.permission.SET_PREFERRED_APPLICATIONS
12 0.6575763216374741 android.permission.USE_SIP
13 0.6423455602781643 android.permission.MODIFY_PHONE_STATE
14 0.5733719308777389 android.permission.READ_CALL_LOG
15 0.5713221448442122 android.permission.WRITE_SECURE_SETTINGS
16 0.5177117115666185 android.permission.CLEAR_APP_CACHE
17 0.5013751180995185 android.permission.WRITE_SYNC_SETTINGS
18 0.47540432455574055 android.permission.INJECT_EVENTS
19 0.450576746748121 android.permission.BIND_ACCESSIBILITY_SERVICE
20 0.4497437629117625 android.permission.READ_SYNC_STATS
21 0.40721040702182304 com.android.alarm.permission.SET_ALARM
22 0.3958974436391258 android.permission.GET_PACKAGE_SIZE
23 0.35828369132005317 android.permission.TRANSMIT_IR
24 0.3538089622374305 android.permission.CHANGE_COMPONENT_ENABLED_STATE
25 0.3303834311984685 android.permission.STATUS_BAR
26 0.3277728921018696 android.permission.WRITE_USER_DICTIONARY
27 0.31322691738916597 android.permission.SET_DEBUG_APP
28 0.28600828593282673 android.permission.INSTALL_PACKAGES
29 0.27804088205285526 android.permission.SHUTDOWN

导致 Benign 结果最重要的 30 个权限:

1 -1.0280830288092226 android.permission.FORCE_STOP_PACKAGES
2 -1.0244749163270055 android.permission.DELETE_CACHE_FILES
3 -0.9235183435775582 android.permission.READ_PRIVILEGED_PHONE_STATE
4 -0.7975588094210508 android.permission.USE_BIOMETRIC
5 -0.7691538868495551 android.permission.READ_CELL_BROADCASTS
6 -0.7288571523071693 android.permission.REQUEST_INSTALL_PACKAGES
7 -0.7278186994140812 android.permission.WRITE_CALL_LOG
8 -0.7029898754031535 android.permission.READ_SEARCH_INDEXABLES
9 -0.6832562629713737 android.permission.ACCESS_NOTIFICATION_POLICY
10 -0.6442707037030093 android.permission.BIND_NOTIFICATION_LISTENER_SERVICE
11 -0.6229441323892875 android.permission.CAPTURE_AUDIO_OUTPUT
12 -0.5951302503005503 android.permission.REORDER_TASKS
13 -0.552113274404841 android.permission.FACTORY_TEST
14 -0.5512329811397917 android.permission.CAMERA
15 -0.5415431826751977 android.permission.PACKAGE_USAGE_STATS
16 -0.5373788445105623 android.permission.READ_SYNC_SETTINGS
17 -0.5300427083556158 android.permission.ACCESS_WIFI_STATE
18 -0.48952375397337794 android.permission.READ_PHONE_NUMBERS
19 -0.4822239255635727 android.permission.STOP_APP_SWITCHES
20 -0.4525220364959383 android.permission.WRITE_MEDIA_STORAGE
21 -0.4133049145725493 com.android.browser.permission.WRITE_HISTORY_BOOKMARKS
22 -0.3902532535519829 android.permission.CAPTURE_VIDEO_OUTPUT
23 -0.34681147328619505 android.permission.READ_FRAME_BUFFER
24 -0.34134222449779317 android.permission.WRITE_GSERVICES
25 -0.3335042039412585 android.permission.BIND_APPWIDGET
26 -0.3263774109427998 android.permission.AUTHENTICATE_ACCOUNTS
27 -0.3136298914538836 android.permission.NFC
28 -0.3000955825422318 android.permission.READ_EXTERNAL_STORAGE
29 -0.2846046321402758 android.permission.CALL_PRIVILEGED
30 -0.28338090002182315 android.permission.READ_CALENDAR

在表格中,第二列显示了通过 SVM 计算得到的权重值。由于在标签设定中,Malware 被标记为 1,而 Benign 被标记为 0,且训练数据的格式是 0,1,1,0,...0,1,1,0,...这样的布尔值,因此,当权重为正时,该权重在计算 Malware 的预测结果时具有较高的重要性;权重值越大,其重要性越高。相反,当权重为负时,该权重在计算 Benign 的预测结果时具有较高的重要性;权重值越小,其重要性越高。

通过分析这些权限及其功能,我们发现 Malware 相关的权限通常比 Benign 相关的权限具有更高的危害性。在一定程度上,这种模型的设计是合理的。例如,模型成功识别了与 SMS 相关的权限主要与 Malware 相关,并赋予了较高的权重,这意味着,基本上,一个 APP 如果包含 SMS 权限,就非常可疑。实际上,普通的 APP 不应该请求此类权限,因为短信管理通常是系统 APP 的职责。

然而,这里存在一个问题:权限的存在是因为 Android 系统认为某些行为可能不妥,需要用户确认。所以,理论上,所有需要请求的权限都有可能对用户造成损害。因此,没有请求权限应该被视为一个加分项。但在二分类机器学习的情境下,模型会做出区分,因为 Benign 类别的存在意味着一定会有一部分权限被视为支持 Benign 的证据。

现在我们来分析为什么会出现如此高的假阳性率: 我们使用 LinearSVC 来解释模型的预测结果,并对一些具有假阳性的权限信息进行分析:

0.1773649887447295 android.permission.WAKE_LOCK
0.01285824377030036 android.permission.INTERNET
-0.1357928094523775 android.permission.ACCESS_NETWORK_STATE
0.43102404170044467 com.android.alarm.permission.SET_ALARM
0.1773649887447295 android.permission.WAKE_LOCK
0.14741402851800423 android.permission.SYSTEM_ALERT_WINDOW
0.02740438240042149 android.permission.FOREGROUND_SERVICE
0.01285824377030036 android.permission.INTERNET
-0.1357928094523775 android.permission.ACCESS_NETWORK_STATE
-0.15043626374678254 android.permission.WRITE_EXTERNAL_STORAGE
-0.1975995718519041 android.permission.CHANGE_WIFI_STATE
-0.20461138790573433 android.permission.VIBRATE
-0.511067438637911 android.permission.ACCESS_WIFI_STATE
0.1773649887447295 android.permission.WAKE_LOCK
0.02740438240042149 android.permission.FOREGROUND_SERVICE
0.01285824377030036 android.permission.INTERNET
-0.1357928094523775 android.permission.ACCESS_NETWORK_STATE
-0.33867385510052594 android.permission.READ_EXTERNAL_STORAGE
-0.511067438637911 android.permission.ACCESS_WIFI_STATE

而真阳的权限信息:

0.32757400447767016 android.permission.INSTALL_PACKAGES
0.2870058866311678 android.permission.READ_PHONE_STATE
0.1773649887447295 android.permission.WAKE_LOCK
0.1545767541451571 android.permission.FLASHLIGHT
0.14613075920332474 android.permission.BLUETOOTH_ADMIN
0.140268653568319 android.permission.GET_ACCOUNTS
0.08641386050999389 android.permission.MOUNT_UNMOUNT_FILESYSTEMS
0.06460516872049353 android.permission.ACCESS_COARSE_LOCATION
0.01285824377030036 android.permission.INTERNET
-0.009804892771664459 android.permission.ACCESS_FINE_LOCATION
-0.12321341834571817 android.permission.READ_LOGS
-0.1357928094523775 android.permission.ACCESS_NETWORK_STATE
-0.15043626374678254 android.permission.WRITE_EXTERNAL_STORAGE
-0.15994619600450963 android.permission.CHANGE_NETWORK_STATE
-0.16005902734200772 android.permission.WRITE_SETTINGS
-0.1975995718519041 android.permission.CHANGE_WIFI_STATE
-0.20461138790573433 android.permission.VIBRATE
-0.23536025455979454 android.permission.CALL_PHONE
-0.24802834827531783 android.permission.ACCESS_LOCATION_EXTRA_COMMANDS
-0.30018060973660377 android.permission.BLUETOOTH
-0.33867385510052594 android.permission.READ_EXTERNAL_STORAGE
-0.511067438637911 android.permission.ACCESS_WIFI_STATE
-0.5625902678304402 android.permission.CAMERA
-0.7242676191415552 android.permission.REQUEST_INSTALL_PACKAGES

通过分析,我们发现了一个模式:拥有较少权限的 APK 往往会被误判,而权限较多的 APK 基本能得到正确的预测。深入探究后,我们理解到这种现象的出现主要是由于 APKPure 样本中大多数 APK 的权限数量较少,而我们的训练模型主要基于权限较多的应用宝 APK 样本。因此,预测误差的产生在一定程度上是由样本差异导致的。

为了解决这个问题,一个直接的方法是将 APKPure 的数据也纳入训练过程,以增强模型的泛化能力和预测准确性。

我们采取了以下措施:从 APKPure 样本中随机抽取一半,即 5000 个 APK,同时从应用宝样本中随机抽取一半,约 5000 个 APK,一同用于模型的训练。然后,我们使用这个新训练得到的模型来预测未参与训练的样本。结果显示,新模型的预测准确率得到了显著提高。

模型

Precision

Recall

FPR

随机森林

0.994

0.967

0.008

SVM

0.994

0.967

0.008

然后我们对其他数据集进行测试验证:

数据集

Precision

Recall

FPR

APKPure 未参与训练的样本

0.0

NAN

0.018

MB

1.0

0.878

NAN

VS2020

1.0

0.92

NAN

VS2021

1.0

0.89

NAN

假阳性率已降至可接受的水平。这个实验揭示了一个重要的现象:在训练集上获得理想的结果相对容易,但在现实世界中准确预测却可能面临挑战。无人能保证所收集的样本完美地反映了现实世界的情况,而我们的目标是识别那些真正与恶意软件(Malware)相关的特征。因此,我们决定尝试探索其他可能的解决方案。

1. 基于 Intents 和 Receivers 的训练

随后,我们扩展了特征集,加入了从 AndroidManifest.xml 中提取的 intents 和 receivers 信息进行训练,然而,这并没有提高模型的准确率。

2. 基于系统 API 调用的训练

我们进一步尝试提取 APK 中的所有系统 API 调用,将其转换为适合卷积神经网络(CNN)的格式,并通过 CNN 来训练模型。在训练集上,模型达到了令人满意的 97% 的准确率,但在数据集交叉验证时,表现仍然不尽如人意。

在这过程中,我们遇到了几个问题:、

  • API 调用频率的不明显差异: 最初,我们通过反编译提取了所有出现过的 API 调用,却发现这些 API 的调用频率并没有明显差异。例如,我们原本认为 accessibilityservice 的调用明显与恶意软件相关,却发现在良性软件中也频繁出现。后来我们了解到,这主要是因为大多数 APK 都依赖于 android 这个库,而该库中包含了大量的系统 API 调用。由于 Malware 和 Benign APK 都依赖于大量的第三方库,这些库中存在大量的系统 API 调用,使得我们难以从系统 API 调用的统计结果中区分 Malware 和 Benign。即便我们使用了 incinerator 的 SCA 分析功能来检测和剔除这些第三方库,结果仍然不尽如人意。
  • 第三方库的干扰: 我们发现,很少有研究考虑到第三方库的干扰,并提出剔除第三方库的具体方案。如果不剔除这些库,基于静态分析的方法几乎毫无意义,因为静态抽取会抽取出大量未被调用的 API,而这在 Malware 和 Benign APK 中没有明显区别。
  • 反编译和脱壳问题: 由于这种方法涉及从 APK 中抽取系统 API 调用,需要进行反编译。然而,许多 Malware 都加壳处理,而脱壳是一个复杂的对抗技术。我们查阅的资料中,很少提到这一点。脱壳对于非专业团队来说可能太过困难,但至少应该从数据集中筛选出没有壳的 APK。如果不进行脱壳,直接抽取的话,只能得到极少数的 dexloader 等系统 API 调用,这大大影响了训练效果。

3. 回归基于 Permissions 的模型

鉴于前述的尝试未能取得预期效果,我们重新回到基于 Permissions 的模型,寻求通过其他方法提升交叉验证的准确率。我们进行了以下尝试:

  • 通过 Select 模型选择 Permissions 采用此法的目的是寻找 Malware 实际所利用的 Permissions。然而,实际测试结果显示,训练准确率下降,验证准确率也下降,且交叉验证的准确率更是降低。
  • 我们的实验过程如下: 使用 SelectFromModel 方法,基于 RandomForestClassifier 模型(该模型包含所有参与训练的数据)进行参数抽取。我们分别抽取了 100、50、30 个 Permissions 进行实验,并得到了如下数据:
  • 选取 100 个 Permissions训练数据:

模型

Precision

Recall

FPR

随机森林

0.989

0.974

0.013

数据集

Precision

Recall

FPR

APKPure

0.0

NAN

0.64

MB

1.0

0.95

NAN

VS2020

1.0

0.96

NAN

VS2021

1.0

0.94

NAN

  • 选取 50 个 Permissions训练数据

模型

Precision

Recall

FPR

随机森林

0.981

0.986

0.063

数据集

Precision

Recall

FPR

APKPure

0.0

NAN

0.59

MB

1.0

0.94

NAN

VS2020

1.0

0.96

NAN

VS2021

1.0

0.94

NAN

  • 训练 30 个 Permissions训练数据

模型

Precision

Recall

FPR

随机森林

0.983

0.983

0.054

数据集

Precision

Recall

FPR

APKPure

0.0

NAN

0.59

MB

1.0

0.96

NAN

VS2020

1.0

0.96

NAN

VS2021

1.0

0.95

NAN

分析及新的尝试

从前述数据中可见,减少 Permissions 的数量并未能改善假阳性率或提高准确率。

  • 利用自编码器(Auto Encoder)进行降维
  • 为了进一步尝试改善模型表现,我们转向了自编码器(Auto Encoder)技术,期望通过对 Permissions 的分组和降维来提高准确率。自编码器是一种能够学习数据编码的神经网络,通常被用于降维或特征学习。我们的想法是通过自编码器将 Permissions 的高维数据转换为低维数据,同时保留与 Malware 识别相关的重要信息。
  • 然而,尽管我们尝试了自编码器的降维方法,交叉验证的结果仍然不尽如人意,假阳性率依然较高。

模型

Precision

Recall

FPR

随机森林

0.977

0.980

0.074

数据集

Precision

Recall

FPR

APKPure

0.0

NAN

0.64

MB

1.0

0.95

NAN

VS2020

1.0

0.95

NAN

VS2021

1.0

0.92

NAN

通过业务逻辑选择 Permissions

随后,我们尝试通过业务规则来挑选适当的 Permissions。我们的方法是这样的:

  • 我们统计了所有 Malware 中每个 Permission 的出现频率 mp 和所有 Benign 中每个 Permission 的出现频率 bp。
  • 然后计算了 bp/mp

然而,这种方法也未能提高训练准确率和验证准确率。例如,android.permission.INTERNET 这样的权限在 Malware 和 Benign 中出现的概率非常接近,大约都在 97% 左右,这样的权限参与训练并没有太大的意义。类似地,android.permission.WAKE_LOCK 在 Malware 和 Benign 中出现的概率也非常接近,大约在 80% 左右。

我们还尝试了其他研究论文中提到的一些方法。经过测试,我们发现无论采取何种方法来筛选 Permissions,筛选后的训练准确率都不如不筛选、直接使用所有 Permissions 进行训练的准确率高。这个发现与许多将 Permissions 筛选作为主要研究目的的论文的结论相左。

结论

经过多次尝试,我们暂时未能训练出一个在单一数据集上训练,而在其他数据集上也具有理想准确率的模型。因此,我们决定将应用宝和 APKPure 的数据合并作为 Benign APK 的训练集,同时将其他几个 Malware 数据集也合并作为 Malware APK 的训练集,以提高样本的平均均衡度。

当然,我们也发现了一些可能的优化方向:

  • 我们注意到 Malware 和 Benign 的 APK 签名存在一定的模式,如果能够验证这些模式,可以将其纳入现有模型中。
  • 在手动分析样本时,我们发现许多 Malware APK 样本在静态分析阶段无法判断为恶意,因为它们的权限没有任何可疑信息。例如,许多 dropper、downloader 等类型的恶意 APK,在权限上与 Benign APK 没有明显区别。因此,人工筛选恶意 APK 可能有助于提高训练准确率。
  • 同时,将动态检测的信息纳入训练模型也是一个值得尝试的方向。我们计划在后续的研究中加入动态信息以提升模型的表现。

原文链接:https://www.liansecurity.com/#/main/news/TfrG0IoBQKl-d7iA6Wuh/detail

赞 ()
分享到:更多 ()

相关推荐

内容页底部广告位3
留言与评论(共有 0 条评论)
   
验证码: