3.10数据安全检测

文章目录
  1. 1. 1 敏感信息检测 # 10001
  2. 2. 2 剪贴板敏感信息泄露风险检测 # 10002
  3. 3. 3 Intent敏感数据泄露风险检测 # 10003
  4. 4. 4 PendingIntent误用风险 # 10004
  5. 5. 5 密钥硬编码风险检测 # 10005
  6. 6. 6 数据或程序加载检查 # 10006
  7. 7. 7 BASE64安全检测 # 10007
  8. 8. 8 文件全局读写漏洞检测 # 10008
  9. 9. 9 日志泄露风险检测 # 10009
  10. 10. 10 外部加载Dex检测 # 10010
  11. 11. 11 外部存储路径检测 # 10011
  12. 12. 12 明文数字证书风险 # 10012

1 敏感信息检测 # 10001

通过正则表达式匹配敏感信息。

我们可以通过如下的几个正则表达式,匹配邮箱地址、手机号、电话号码、身份证号和QQ号等敏感的信息,看是否有在代码中出现,提醒开发者注意这些敏感信息,防止不必要的外泄。

邮箱地址

regexp5 = "[\w.-]+@[\w-]+\.[\w.]+"

手机号

regexp6 = "^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}$"

电话号码

regexp7 = "\d{3}-\d{8}|\d{4}-\d{7}"

身份证号

regexp8 = "^\d{15}|\d{18}$"

QQ号

regexp9 = "[1-9][0-9]{4,}"

2 剪贴板敏感信息泄露风险检测 # 10002

由于Android剪贴板的内容向任何权限的app开放,很容易就被嗅探泄密。同一部手机中安装的其他app,甚至是一些权限不高的app,都可以通过剪贴板功能获取剪贴板中的敏感信息。

风险等级:提醒

问题示例:

1
2
3
4
5
6
7
8
9
10
11
12
clipBtn = (Button) findViewById(R.id.btn_clip);
clipBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {

ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);

ClipData clip1 = ClipData.newPlainText("label","password=123456");

clipboard.setPrimaryClip(clip1);
}
});

漏洞可以利用如下代码利用。
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
public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

ClipboardManager clipBoard = (ClipboardManager)getSystemService(CLIPBOARD_SERVICE);
clipBoard.addPrimaryClipChangedListener( new ClipboardListener() );
}

private void attack() {
ClipboardManager cm = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
ClipData cd2 = cm.getPrimaryClip();
String clipText = cd2.getItemAt(0).getText().toString();
//Log.v("clipboard", "Attacked: " + clipText);
Toast.makeText(getApplicationContext(), "Attacked: " + clipText, Toast.LENGTH_LONG).show();
}

class ClipboardListener implements ClipboardManager.OnPrimaryClipChangedListener {

public void onPrimaryClipChanged() {
attack();
}
}

}

建议:

避免使用剪贴板敏文存储敏感信息或进行加密。

3 Intent敏感数据泄露风险检测 # 10003

APP创建Intent传递数据到其他Activity,如果创建的Activity不是在同一个Task中打开,就很可能被其他的Activity劫持读取到Intent内容,跨Task的Activity通过Intent传递敏感信息是不安全的。

风险等级:提醒

问题示例:

检测是否使用了FLAG_ACTIVITY_NEW_TASK标志。

建议:

尽量避免使用包含FLAG_ACTIVITY_NEW_TASK标志的Intent来传递敏感信息。

4 PendingIntent误用风险 # 10004

使用pendingIntent时候,如果使用了一个空Intent,会导致恶意用户劫持Intent的内容。禁止使用空intent去构造pendingIntent。

风险等级:中危

问题示例:

通过判断代码片段中有没有出现以下函数,即可知道是否使用了空intent构造PendingIntent。

PendingIntent误用风险-函数说明1

PendingIntent误用风险-函数说明2

建议:

禁止使用空intent去构造pendingIntent。

5 密钥硬编码风险检测 # 10005

将密钥硬编码在Java代码、文件中,这样做会引起很大风险。信息安全的基础在于密码学,而常用的密码学算法都是公开的,加密内容的保密依靠的是密钥的保密,密钥如果泄露,对于对称密码算法,根据用到的密钥算法和加密后的密文,很容易得到加密前的明文;对于非对称密码算法或者签名算法,根据密钥和要加密的明文,很容易获得计算出签名值,从而伪造签名。

风险等级:提醒

检测使用以下加密算法的路径,目前该检测项只检测是否在Java层有显式地保存密钥,这应该是最有风险的一种保存方式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
AES/CBC/NoPadding
AES/CBC/PKCS7Padding
AES/CTR/NoPadding
AES/ECB/NoPadding
AES/ECB/PKCS7Padding
AES/GCM/NoPadding
RSA/ECB/NoPadding
RSA/ECB/PKCS1Padding
RSA/ECB/OAEPWithSHA-1AndMGF1Padding
RSA/ECB/OAEPWithSHA-224AndMGF1Padding
RSA/ECB/OAEPWithSHA-256AndMGF1Padding
RSA/ECB/OAEPWithSHA-384AndMGF1Padding
RSA/ECB/OAEPWithSHA-512AndMGF1Padding
RSA/ECB/OAEPPadding

6 数据或程序加载检查 # 10006

风险等级:提醒

需要进行动态分析

  • 是否加载公共区域程序,如sdcard、/data/local/tmp/、应用自创建但其他应用有读写权限的目录上
  • 是否从网络下载,检测方法包括:阅读代码、监听网路请求、见识存储区域文件读写、查看安装包
  • 升级包是否存在公共区域存储

7 BASE64安全检测 # 10007

风险等级:提醒

检测出BASE64字符串,并解密。

8 文件全局读写漏洞检测 # 10008

在使用getDir、getSharedPreferences(SharedPreference)或openFileOutput时,如果设置了全局的可读权限,攻击者恶意读取文件内容,获取敏感信息。在设置文件属性时如果设置全局可写,攻击者可能会篡改、伪造内容,可能会进行诈骗等行为,造成用户财产损失。其中getSharedPreferences如果设置全局写权限,则当攻击app跟被攻击app具有相同的Android:sharedUserId属性时和签名时,攻击app则可以访问到内部存储文件进行写入操作。

风险等级:中危

问题示例:

检测出使用了getDir、getSharedPreferences和openFileOutput函数的参数值是否使用了MODE_WORLD_READABLE和MODE_WORLD_WRITEABLE

建议:

  • 使用MODE_PRIVATE模式创建内部存储文件
  • 加密存储敏感数据
  • 避免在文件中存储明文敏感信息
  • 避免滥用”Android:sharedUserId”属性

如果两个appAndroid:sharedUserId属性相同,切使用的签名也相同,则这两个app可以互相访问内部存储文件数据。

9 日志泄露风险检测 # 10009

在APP的开发过程中,为了方便调试,通常会使用log函数输出一些关键流程的信息,这些信息中通常会包含敏感内容,如执行流程、明文的用户名密码等,这会让攻击者更加容易的了解APP内部结构方便破解和攻击,甚至直接获取到有价值的敏感信息。

风险等级:提醒

问题示例:

检测是否调用了Log.v、Log.d、Log.e、Log.i、Log.w、Log.f、Log.s函数

建议:

在生产环境中移除Log打印。

10 外部加载Dex检测 # 10010

动态加载的DEX文件存储在被其他应用任意读写的目录中(如sdcard),如果没有对外部所加载的DEX文件做完整性校验,应用将会被恶意代码注入,从而执行的是恶意代码。

风险等级:高危

问题示例:

关键:public DexClassLoader (String dexPath, String optimizedDirectory, String libraryPath, ClassLoader parent)

首先获取所有调用了DexClassLoader函数的路径,然后对每个路径下的代码片段进行检查,判断有没有调用Environment.getExternalStorageDirectory().toString()该方法。两个条件同时满足,则判定该路径下的代码片段有风险。

建议:

  • 将所需要动态加载的DEX/APK文件放置在APK内部或应用私有目录中
  • 使用加密网络协议进行下载加载的DEX/APK文件并将其放置在应用私有目录中
  • 对不可信的加载来源进行完整性校验

11 外部存储路径检测 # 10011

文件存放在external storage,例如SD卡,是全局可读写的。由于external storage可以被任何用户操作,且可以被所有的应用修改使用。所以,app的敏感数据建议不要存放在external storage。

风险等级:低危

动态方法监测/data/data/<packagename>/目录下所有生成的目录是否带有明文信息泄露

12 明文数字证书风险 # 10012

Apk中使用的数字证书可被用来校验服务器的合法身份,以及在与服务器进行通信的过程中对传输数据进行加密、解密运算,保证传输数据的保密性、完整性。明文存储的数字证书如果被篡改,客户端可能连接到假冒的服务端上,导致用户名、密码等信息被窃取;如果明文证书被盗取,可能造成传输数据被截获解密,用户信息泄露,或者伪造客户端向服务器发送请求,篡改服务器中的用户数据或造成服务器响应异常。

风险等级:中危

问题示例:

1
2
3
4
5
[
"assets/location_public_key.der",
"assets/verisign.cer",
"res/raw/servicecert.cer"
]