[TOC]
## 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,都可以通過剪貼板功能獲取剪貼板中的敏感信息。
風險等級:`提醒`
問題示例:
```
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);
}
});
```
漏洞可以利用如下代碼利用。
```
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。


建議:
禁止使用空intent去構造pendingIntent。
## 5 密鑰硬編碼風險檢測 # 10005
將密鑰硬編碼在Java代碼、文件中,這樣做會引起很大風險。**信息安全的基礎在于密碼學,而常用的密碼學算法都是公開的,加密內容的保密依靠的是密鑰的保密**,密鑰如果泄露,對于對稱密碼算法,根據用到的密鑰算法和加密后的密文,很容易得到加密前的明文;對于非對稱密碼算法或者簽名算法,根據密鑰和要加密的明文,很容易獲得計算出簽名值,從而偽造簽名。
風險等級:`提醒`
檢測使用以下加密算法的路徑,目前該檢測項只檢測是否在Java層有**顯式地**保存密鑰,這應該是最有風險的一種保存方式。
```
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”屬性
如果兩個app`Android: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中使用的數字證書可被用來校驗服務器的合法身份,以及在與服務器進行通信的過程中對傳輸數據進行加密、解密運算,保證傳輸數據的保密性、完整性。明文存儲的數字證書如果被篡改,客戶端可能連接到假冒的服務端上,導致用戶名、密碼等信息被竊取;如果明文證書被盜取,可能造成傳輸數據被截獲解密,用戶信息泄露,或者偽造客戶端向服務器發送請求,篡改服務器中的用戶數據或造成服務器響應異常。
風險等級:`中危`
問題示例:
```
[
"assets/location_public_key.der",
"assets/verisign.cer",
"res/raw/servicecert.cer"
]
```