Skip to content

Commit 8f3457b

Browse files
committed
更新Sink点和漏洞报告生成规则
1 parent 6cee5ad commit 8f3457b

File tree

2 files changed

+105
-39
lines changed

2 files changed

+105
-39
lines changed

SourcesAndSinks.txt

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
<android.net.Uri: java.util.Map getQueryParameterNames()> -> _SOURCE_
99
<android.net.Uri: java.lang.String getQueryParameter(java.lang.String)> -> _SOURCE_
1010

11-
# IntentIntent重定向
11+
# Intent重定向
1212
<android.app.Activity: void setResult(int,android.content.Intent)> -> _SINK_
1313

1414
# LaunchAnyWhere漏洞
@@ -33,15 +33,15 @@
3333
<android.webkit.WebSettings: void setAllowFileAccessFromFileURLs(boolean)> -> _SINK_
3434
<android.webkit.WebSettings: void setAllowUniversalAccessFromFileURLs(boolean)> -> _SINK_
3535

36-
# Provider文件读写漏洞
36+
# Provider漏洞
3737
<android.net.Uri: java.lang.String getLastPathSegment()> -> _SOURCE_
3838
<android.os.ParcelFileDescriptor: android.os.ParcelFileDescriptor open(java.io.File,int)> -> _SINK_
3939
<android.content.ContentProvider: android.os.ParcelFileDescriptor openFile(android.net.Uri,java.lang.String)> -> _SINK_
4040
<android.content.ContentResolver: android.net.Uri insert(android.net.Uri,android.content.ContentValues)> -> _SINK_
4141
<android.content.ContentResolver: int delete(android.net.Uri,java.lang.String,java.lang.String[])> -> _SINK_
4242
<android.content.ContentResolver: int update(android.net.Uri,android.content.ContentValues,java.lang.String,java.lang.String[])> -> _SINK_
4343

44-
# 文件系统操作
44+
# 文件读写漏洞
4545
<java.io.File: boolean delete()> -> _SINK_
4646
<java.io.File: boolean createNewFile()> -> _SINK_
4747
<java.io.File: boolean mkdir()> -> _SINK_
@@ -64,23 +64,24 @@
6464
<java.io.PrintWriter: void <init>(java.io.File,java.lang.String)> -> _SINK_
6565
<java.io.PrintWriter: void <init>(java.lang.String)> -> _SINK_
6666
<java.io.PrintWriter: void <init>(java.lang.String,java.lang.String)> -> _SINK_
67+
<oversecured.ovaa.utils.FileUtils: java.io.File copyToCache(android.content.Context,android.net.Uri)> -> _SINK_
6768

68-
# 广播相关(比如BroadcastAnyWhere)
69+
# 广播漏洞(比如BroadcastAnyWhere)
6970
<android.content.Context: void sendBroadcast(android.content.Intent)> -> _SINK_
7071
<android.content.Context: void sendBroadcast(android.content.Intent,java.lang.String)> -> _SINK_
7172
<android.content.Context: void sendOrderedBroadcast(android.content.Intent,java.lang.String)> -> _SINK_
7273
<android.app.Activity: void sendBroadcast(android.content.Intent)> -> _SINK_
7374
<android.app.Activity: void sendBroadcast(android.content.Intent,java.lang.String)> -> _SINK_
7475
<android.app.Activity: void sendOrderedBroadcast(android.content.Intent,java.lang.String)> -> _SINK_
7576

76-
# SharedPreferences(可能导致信息泄露、沙箱文件篡改、DOS等)
77+
# 沙箱文件篡改漏洞
7778
<android.content.SharedPreferences$Editor: android.content.SharedPreferences$Editor putString(java.lang.String,java.lang.String)> -> _SINK_
7879
<android.content.SharedPreferences$Editor: android.content.SharedPreferences$Editor putInt(java.lang.String,int)> -> _SINK_
7980
<android.content.SharedPreferences$Editor: android.content.SharedPreferences$Editor putLong(java.lang.String,long)> -> _SINK_
8081
<android.content.SharedPreferences$Editor: android.content.SharedPreferences$Editor putFloat(java.lang.String,float)> -> _SINK_
8182
<android.content.SharedPreferences$Editor: android.content.SharedPreferences$Editor putBoolean(java.lang.String,boolean)> -> _SINK_
8283

83-
# Settings Provider 写入(system/global/secure)
84+
# Settings Provider篡改漏洞
8485
<android.provider.Settings$System: boolean putString(android.content.ContentResolver,java.lang.String,java.lang.String)> -> _SINK_
8586
<android.provider.Settings$System: boolean putInt(android.content.ContentResolver,java.lang.String,int)> -> _SINK_
8687
<android.provider.Settings$System: boolean putLong(android.content.ContentResolver,java.lang.String,long)> -> _SINK_
@@ -94,13 +95,13 @@
9495
<android.provider.Settings$Secure: boolean putLong(android.content.ContentResolver,java.lang.String,long)> -> _SINK_
9596
<android.provider.Settings$Secure: boolean putFloat(android.content.ContentResolver,java.lang.String,float)> -> _SINK_
9697

97-
# 反射相关(可能导致代码执行)
98+
# 反射导致RCE漏洞
9899
<java.lang.Class: java.lang.reflect.Method getMethod(java.lang.String,java.lang.Class[])> -> _SINK_
99100
<java.lang.Class: java.lang.reflect.Method getDeclaredMethod(java.lang.String,java.lang.Class[])> -> _SINK_
100101
<java.lang.reflect.Method: java.lang.Object invoke(java.lang.Object,java.lang.Object[])> -> _SINK_
101102
<java.lang.Class: java.lang.Object newInstance()> -> _SINK_
102103

103-
# 命令执行
104+
# 命令执行漏洞
104105
<java.lang.Runtime: java.lang.Process exec(java.lang.String)> -> _SINK_
105106
<java.lang.Runtime: java.lang.Process exec(java.lang.String[])> -> _SINK_
106107
<java.lang.Runtime: java.lang.Process exec(java.lang.String,java.lang.String[])> -> _SINK_

parse_result.py

Lines changed: 96 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -9,36 +9,76 @@
99
print("Warning: javalang library not found. Source code extraction may be limited.")
1010
javalang = None
1111

12+
# 加载Source-Sink分类配置
13+
def load_sink_categories(file_path):
14+
categories = {}
15+
current_category = "其他漏洞"
16+
17+
if not os.path.exists(file_path):
18+
print(f"Warning: SourcesAndSinks file not found at {file_path}")
19+
return categories
20+
21+
try:
22+
with open(file_path, 'r', encoding='utf-8') as f:
23+
for line in f:
24+
line = line.strip()
25+
if not line:
26+
continue
27+
28+
if line.startswith('#'):
29+
# 提取注释作为分类,去除 # 和可能的说明
30+
comment = line.lstrip('#').strip()
31+
# 去除括号及后面的内容(通常是说明)
32+
if '(' in comment:
33+
comment = comment.split('(')[0]
34+
elif '(' in comment:
35+
comment = comment.split('(')[0]
36+
37+
# 忽略Source的注释头
38+
if "Source" in comment or "数据源点" in comment or "检测规则" in comment:
39+
continue
40+
41+
current_category = comment.strip()
42+
43+
elif '-> _SINK_' in line:
44+
# 提取方法签名
45+
parts = line.split('->')
46+
if len(parts) > 0:
47+
method_sig = parts[0].strip()
48+
categories[method_sig] = current_category
49+
except Exception as e:
50+
print(f"Error loading sink categories: {e}")
51+
52+
return categories
53+
1254
# 漏洞类型分类
13-
def classify_vulnerability(sink_method, sink_def):
14-
if 'TheftOverwriteProvider' in sink_method:
15-
return 'ContentProvider文件读写漏洞', '高'
16-
elif 'startActivity' in sink_def or 'startService' in sink_def or 'bindService' in sink_def:
17-
if 'DeeplinkActivity' in sink_method:
18-
return 'Intent重定向漏洞', '高'
19-
else:
20-
return 'LaunchAnyWhere漏洞', '中'
21-
elif 'WebView' in sink_def or 'WebSettings' in sink_def:
22-
return 'WebView漏洞', '高'
23-
elif 'SharedPreferences' in sink_def:
24-
return '信息泄露漏洞', '中'
25-
elif 'exec' in sink_def or 'Runtime' in sink_def:
26-
return '命令执行漏洞', '高'
27-
elif 'reflect' in sink_def.lower() or 'Method' in sink_def and 'invoke' in sink_def:
28-
return '反射漏洞', '高'
55+
def classify_vulnerability(sink_method, sink_def, sink_categories=None):
56+
vuln_type = '其他漏洞'
57+
severity = '低'
58+
# 1. 优先使用配置文件中的分类 (Source-Sink映射)
59+
if sink_categories and sink_def in sink_categories:
60+
vuln_type = sink_categories[sink_def]
2961
else:
30-
return '其他漏洞', '低'
62+
# 如果找不到映射,不再尝试任何启发式分类,直接标记为其他漏洞
63+
# 这样确保所有分类都来自Source-Sink文件的定义
64+
pass
65+
# 3. 确定风险等级
66+
if any(k in vuln_type for k in ['命令执行', '反射', '文件读写', 'Intent重定向']):
67+
severity = '高'
68+
elif any(k in vuln_type for k in ['广播漏洞', 'LaunchAnyWhere', '沙箱文件', 'WebView', 'Provider']):
69+
severity = '中'
70+
return vuln_type, severity
3171

3272
# 生成修复建议
3373
def generate_fix_advice(vuln_type):
3474
advice_map = {
35-
'ContentProvider文件读写漏洞': [
75+
'Provider漏洞': [
3676
'对Uri的lastPathSegment进行严格验证',
3777
'限制可访问的文件路径范围',
3878
'实施文件权限检查',
3979
'使用应用专用目录而非外部存储'
4080
],
41-
'Intent重定向漏洞': [
81+
'Intent重定向': [
4282
'对deeplink参数进行白名单验证',
4383
'限制可重定向的URL范围',
4484
'实施Intent校验机制',
@@ -56,23 +96,41 @@ def generate_fix_advice(vuln_type):
5696
'设置合理的WebSettings配置',
5797
'使用WebView安全最佳实践'
5898
],
59-
'信息泄露漏洞': [
60-
'避免在SharedPreferences中存储敏感信息',
61-
'对存储的敏感信息进行加密',
62-
'使用系统密钥库存储敏感数据',
63-
'定期清理不需要的存储数据'
99+
'文件读写漏洞': [
100+
'避免使用外部存储存储敏感数据',
101+
'验证文件路径以防止路径遍历',
102+
'使用应用私有目录',
103+
'对写入的文件内容进行加密'
104+
],
105+
'广播漏洞': [
106+
'限制广播接收者的导出属性',
107+
'对接收到的Intent进行校验',
108+
'使用LocalBroadcastManager',
109+
'设置广播权限'
110+
],
111+
'沙箱文件篡改漏洞': [
112+
'避免在SharedPreferences中存储敏感明文',
113+
'使用EncryptedSharedPreferences',
114+
'正确设置文件访问模式(MODE_PRIVATE)',
115+
'定期清理敏感数据'
116+
],
117+
'Settings Provider篡改漏洞': [
118+
'避免修改系统全局设置',
119+
'检查修改设置的权限',
120+
'验证写入设置的值',
121+
'遵循Android安全最佳实践'
64122
],
65123
'命令执行漏洞': [
66124
'避免使用Runtime.exec等危险方法',
67125
'对输入参数进行严格验证',
68126
'使用安全的替代方案',
69127
'实施最小权限原则'
70128
],
71-
'反射漏洞': [
72-
'避免使用反射执行未知代码',
73-
'对反射调用的目标进行验证',
74-
'使用安全的替代方案',
75-
'实施权限检查'
129+
'反射导致RCE漏洞': [
130+
'避免使用反射执行外部可控代码',
131+
'对反射调用的目标类和方法进行白名单验证',
132+
'限制反射调用的权限',
133+
'使用非反射的替代实现'
76134
],
77135
'其他漏洞': [
78136
'对输入进行严格验证',
@@ -385,6 +443,13 @@ def parse_flowdroid_result(input_file, output_file, source_dir=None):
385443
print(f"错误: 文件 {input_file} 不存在")
386444
return 1
387445

446+
# 加载Sink分类
447+
script_dir = os.path.dirname(os.path.abspath(__file__))
448+
sink_file = os.path.join(script_dir, 'SourcesAndSinks.txt')
449+
sink_categories = load_sink_categories(sink_file)
450+
if sink_categories:
451+
print(f"已加载 {len(sink_categories)} 条Sink分类规则")
452+
388453
try:
389454
# 解析XML文件
390455
tree = ET.parse(input_file)
@@ -423,7 +488,7 @@ def parse_flowdroid_result(input_file, output_file, source_dir=None):
423488
if sink is not None:
424489
sink_method = sink.get('Method', '')
425490
sink_def = sink.get('MethodSourceSinkDefinition', '')
426-
vuln_type, severity = classify_vulnerability(sink_method, sink_def)
491+
vuln_type, severity = classify_vulnerability(sink_method, sink_def, sink_categories)
427492
key = (vuln_type, severity)
428493
vuln_stats[key] = vuln_stats.get(key, 0) + 1
429494

@@ -452,7 +517,7 @@ def parse_flowdroid_result(input_file, output_file, source_dir=None):
452517
sink_line = sink.get('LineNumber', None)
453518

454519
# 分类漏洞
455-
vuln_type, severity = classify_vulnerability(sink_method, sink_def)
520+
vuln_type, severity = classify_vulnerability(sink_method, sink_def, sink_categories)
456521

457522
# 生成漏洞标题
458523
severity_icon = '🔴' if severity == '高' else '🟡' if severity == '中' else '🟢'

0 commit comments

Comments
 (0)