2020年8月,在DEFCON 28大会上(参考3),发布了一个开源的"Android malware analysis engine",名字叫quark-engine
(参考1)。这是台湾“財團法人電信技術中心”(参考2)开发的一个工具。该项目的开发者列表见参考7,目前主要活跃的开发者(负责人)是JunWei Song(参考3,参考5)。
这个APK静态分析引擎,有以下几个特点:
本文在windows上安装quark-engine并进行测试,给出测试结果。因为笔者动手测试时,还未见有类似的中文相关资料,所以记录下来供参考。
安装系统为64位的 windows 10 。
conda create --name env_quark_py38 python=3.8
pip install -U quark-engine
conda install -c anaconda graphviz
至此,quark-engine安装完毕,安装过程非常简单。
用一条命令,就可以给出summary report
quark -a xxx.apk -s
-s,就是summary的缩写,命令运行后,结果如下(考虑篇幅有限,这里只给出部分结果示例):
[!] WARNING: Moderate Risk
[*] Total Score: 153
+---------------------------------------------------------------------------+------------+-------+--------+
| Rule | Confidence | Score | Weight |
+---------------------------------------------------------------------------+------------+-------+--------+
| Initialize bitmap object and compress data (e.g. JPEG) into bitmap object | 60% | 1 | 0.25 |
| Open the camera and take picture | 20% | 1 | 0.0625 |
| Put the compressed bitmap data into JSON object | 60% | 1 | 0.25 |
| Get filename and put it to JSON object | 60% | 1 | 0.25 |
| Get absolute path of file and put it to JSON object | 60% | 1 | 0.25 |
| Scheduling recording task | 40% | 1 | 0.125 |
| Use absolute path of directory for the output media file path | 40% | 1 | 0.125 |
| Check if successfully sending out SMS | 40% | 1 | 0.125 |
| Put data in cursor to JSON object | 60% | 1 | 0.25 |
| Read sensitive data(SMS, CALLLOG) and put it into JSON object | 60% | 1 | 0.25 |
| Query data from URI (SMS, CALLLOGS) | 100% | 1 | 1.0 |
| Read data and put it into a buffer stream | 100% | 1 | 1.0 |
| Read file and put it into a stream | 60% | 1 | 0.25 |
| Read file into a stream and put it into a JSON object | 60% | 1 | 0.25 |
| Put buffer stream (data) to JSON object | 40% | 1 | 0.125 |
| Get location info of the device and put it to JSON object | 100% | 1 | 1.0 |
| Get Location of the device and append this info to a string | 100% | 1 | 1.0 |
| Get JSON object prepared and fill in location info | 60% | 1 | 0.25 |
输入命令到得出结果,大概用了20秒,可以说是静态分析中比较快的了。
这条命令能给出的结果有
用一条命令,就可以给出summary report
quark -a xxx.apk -d
-d,就是detail的缩写,命令运行后,结果如下(考虑篇幅有限,这里只给出部分结果示例):
C:\xxx/.quark-engine/quark-rules\00017.json
Confidence: 100%
[✓]1.Permission Request
[✓]2.Native API Usage
(Landroid/location/Location;, getLatitude)
(Ljava/lang/StringBuilder;, append)
[✓]3.Native API Combination
(Landroid/location/Location;, getLatitude)
(Ljava/lang/StringBuilder;, append)
[✓]4.Native API Sequence
Sequence show up in:
Lorg/wikipedia/util/GeoUtil; sendGeoIntent (Landroid/app/Activity; Landroid/location/Location; Ljava/lang/String;)V
[✓]5.Native API Use Same Parameter
Lorg/wikipedia/util/GeoUtil; sendGeoIntent (Landroid/app/Activity; Landroid/location/Location; Ljava/lang/String;)V
[+] DONE: OK
这条命令,会根据参考4中的quark-rules,去做静态匹配。比如这里匹配到100%的满足规则00017.json
,而这条规则的内容如下:
{
"crime": "Get Location of the device and append this info to a string",
"x1_permission": [],
"x2n3n4_comb": [
{
"class": "Landroid/location/Location;",
"method": "getLatitude",
"descriptor": "()D"
},
{
"class": "Ljava/lang/StringBuilder;",
"method": "append",
"descriptor": "(D)Ljava/lang/StringBuilder;"
}
],
"yscore": 1,
"label": [
"location",
"collection"
]
}
各条json规则中,给出了详细的
这条规则定义的是静态获取location的行为。
这条命令跑完需要1分钟左右。
用一条命令,就可以给出各个静态行为,及其在DEX中的具体代码位置(借助JEB进行进一步分析)。
quark -a xxx.apk -s -c
命令运行后,结果如下(考虑篇幅有限,这里只给出部分结果示例):
+-------------------+--------------------------------------------------------+
| Parent Function | Lnet/hockeyapp/android/PaintActivity;determineFilename |
+-------------------+--------------------------------------------------------+
| Crime Description | * Read sensitive data(SMS, CALLLOG, etc) |
+-------------------+--------------------------------------------------------+
可以得到各个行为对应到DEX代码中的具体位置。这个功能也是各个静态分析工具的必备功能(常用功能)。
用一条命令,就可以画出call graph
quark -a xxx.apk -s -g
-g,就是graph的缩写,命令运行后,会生成一个call_graph_image
文件夹,其中给出了各个CFG的png图片,这里给出一个示例:
[PIC-1]
png图片的文件名,也指定了这个CFG对应的行为,比如 sendGeoIntent_getLatitude_append.png。
能直接在python代码里调用quark-engine进行分析,并获取分解结果,示例步骤如下:
pip install -U quark-engine==21.3.2
下载地址见参考4,下载后保存到本地文件夹。
这里有个小坑,笔者已经提了issue(参考8),但只要按照本文的版本安装进行测试,就不会遇到这个问题了。
from quark.report import Report
APK_PATH = "xxx.apk"
RULE_PATH = "quark-rules-master/"
report = Report()
'''
RULE_PATH can be a directory with multiple rules inside
EX: "rules/"
OR special json rule file, such as "sendLocation_SMS.json"
'''
report.analysis(APK_PATH, RULE_PATH)
json_report = report.get_report("json")
print(json_report)
得到的分析结果如下:
{
'md5': 'xxx',
'apk_filename': 'xxx.apk',
'size_bytes': 22842706,
'threat_level': 'Moderate Risk',
'total_score': 153,
'crimes': [{
'crime': 'Initialize bitmap object and compress data (e.g. JPEG) into bitmap object',
'score': 1,
'weight': 0.25,
'confidence': '60%',
'permissions': [],
'native_api': [{
'class': 'Landroid/graphics/BitmapFactory;',
'method': 'decodeByteArray'
}, {
'class': 'Landroid/graphics/Bitmap;',
'method': 'compress'
}],
'combination': [{
'class': 'Landroid/graphics/BitmapFactory;',
'method': 'decodeByteArray',
'descriptor': '([B I I)Landroid/graphics/Bitmap;'
}, {
'class': 'Landroid/graphics/Bitmap;',
'method': 'compress',
'descriptor': '(Landroid/graphics/Bitmap$CompressFormat; I Ljava/io/OutputStream;)Z'
}],
'sequence': [],
'register': []
}, {
'crime': 'Open the camera and take picture',
'score': 1,
'weight': 0.0625,
'confidence': '20%',
'permissions': [],
'native_api': [],
'combination': [],
'sequence': [],
'register': []
}, {
'crime': 'Put the compressed bitmap data into JSON object',
'score': 1,
'weight': 0.25,
'confidence': '60%',
'permissions': [],
'native_api': [{
'class': 'Landroid/graphics/Bitmap;',
'method': 'compress'
}, {
'class': 'Lorg/json/JSONObject;',
'method': 'put'
}],
'combination': [{
'class': 'Landroid/graphics/Bitmap;',
'method': 'compress',
'descriptor': '(Landroid/graphics/Bitmap$CompressFormat; I Ljava/io/OutputStream;)Z'
}, {
'class': 'Lorg/json/JSONObject;',
'method': 'put',
'descriptor': '(Ljava/lang/String; Z)Lorg/json/JSONObject;'
}],
'sequence': [],
'register': []
}, {
'crime': 'Send binary data over HTTP',
'score': 1,
'weight': 0,
'confidence': '0%',
'permissions': [],
'native_api': [],
'combination': [],
'sequence': [],
'register': []
}]
}
能很清晰的看到它的结果,方便用python做批量测试。关于这个python包更具体的用法,见参考6。