移动APP安全漏洞检测与利用

1. 本地文件存储

eg: 数据库
在程序中如果使用了SharedPreference或者SQLiteDatabase,要查看SharedPreference或SQLiteDatabase是否设置了安全权限

1.1. 禁止全局读写

如下代码是不安全的:

try{
            SQLiteDatabase rdb = penOrCreateDatabase("all_r_db",Context.MODE_WORLD_READABLE,null);
            SQLiteDatabase wdb = penOrCreateDatabase("all_w_db",Context.MODE_WORLD_WRITEABLE,null,null);
}catch(SQLiteException e){
            e.printStackTrace();
}

应改为MODE_PRIVATE模式创建

try{
            SQLiteDatabase rdb = penOrCreateDatabase("all_r_db",Context.MODE_PRIVATE,null);
            SQLiteDatabase wdb = penOrCreateDatabase("all_w_db",Context.MODE_PRIVATE,null,null);
}catch(SQLiteException e){
            e.printStackTrace();
}

1.2. 数据加密保存

敏感数据需要加密后保存,比如身份证号、手机号码、信用卡号、银行卡号等

2. 安全通信

eg:网络通信

2.1. 信任任意整证书

如下代码中程序中有重写TrustManager的证书验证方法,而且checkServerTrusted方法没有真正实现服务器端的证书校验而且代码中这样写:httpsURLConnection.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);,会导致默认信任所有主机。verify方法没有实现校验服务器证书域名是否相符的功能

public static String getUnSafeFromServer (){
    String response="";
    final String https_url ="https://XXXX/";
    new AsyncTask<String ,Void,Boolean>(){
        @Override
        protected Boolean doInBackground (String ... Param){
            try{
                TrustManager [] trustAllCerts = new TrustManager[] {
                    new X509TrustManager (){
                        @Override
                        public void checkClientTrusted (X509Certificate[] X509Certificates,String s) throws CertificateException {
                            
                        }
                        @Override
                        public void checkServerTrusted (X509Certificate[] X509Certificates,String s) throws CertificateException{
                        }
                        @Override
                        public X509Certificate[] getAcceptedIssuers(){
                            return new X509Certificate[0];
                        }
                    }
                };
                SSLContext sslContext = SSLContext.getInstance("TLS");
                sslContext.init(null,trustAllCerts,null);
                
                URL url = new URL(https_url);
                HttpsURLConnection httpsURLConnection = (HttpsURLConnection) url.openConnection();
                httpsURLConnection.setSSLSocketFactory(sslContext.getSocketFactory());
                httpsURLConnection.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
                final HostnameVerifier hostnameVerifier = new HostnameVerifier(){
                    @Override
                    public boolean verify(String s ,SSLSession sslsession){
                        return true;
                    }
                };
.......   
}

2.2. 解决方法

  @Override
              public void checkServerTrusted(X509Certificate[] chain,
                      String authType)
                      throws CertificateException {
                  for (X509Certificate cert : chain) {

                      // Make sure that it hasn't expired.
                      cert.checkValidity();

                      // Verify the certificate's public key chain.
                      try {
                          cert.verify(((X509Certificate) ca).getPublicKey());
                      } catch (NoSuchAlgorithmException e) {
                          e.printStackTrace();
                      } catch (InvalidKeyException e) {
                          e.printStackTrace();
                      } catch (NoSuchProviderException e) {
                          e.printStackTrace();
                      } catch (SignatureException e) {
                          e.printStackTrace();
                      }
                  }
              }

3. 加密

3.1. 敏感逻辑实现

设计要求,需查看工程中是否有使用Native实现的关键敏感逻辑程序

3.2. 硬编码

加密密钥写在了代码里,如果应用被反编译了,很容易导致加密被破解,造成敏感信息泄露

4. 组件安全

安卓平台四大组件Activity,Service,Provider,Receiver均有exported属性设置。

4.1. Activity导出

对于Activity组件,如果有intent filter设置的话,exported默认为true,必须关闭。如果没有则可以不关注是否设置了该Activity组件exported为false,因为默认是false。如果Activity组件有Intent-filter配置,例如XML中

<activity android:name=".AutoTestActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>

则该Activity组件的相关配置是不安全的,如下配置才是安全的:

<activity android:name=".AutoTestActivity"android:exported ="false">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>

举个栗子:2014年的时候华为网盘android客户端本地密码绕过:
启动设置本地的密码的activity:com.huawei.dbank.v7.ui.setting.LocalPassWordInitActivity,即可重置本地密码

4.2. Activity劫持

用户打开安卓手机上的某一应用,进入到登陆页面,这时恶意软件侦测到用户的这一动作,立即弹出一个与该应用界面相同的Activity,覆盖掉了合法的Activity
在建立的正常Activity的登陆界面(也就是MainActivity)中重写onKeyDown方法和onPause方法,这样一来,当其被覆盖时,就能够弹出警示信息

@Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        //判断程序进入后台是否是用户自身造成的(触摸返回键或HOME键),是则无需弹出警示。
        if((keyCode==KeyEvent.KEYCODE_BACK || keyCode==KeyEvent.KEYCODE_HOME) && event.getRepeatCount()==0){
            needAlarm = false;
        }
        return super.onKeyDown(keyCode, event);
    }

    @Override
    protected void onPause() {
       //若程序进入后台不是用户自身造成的,则需要弹出警示
        if(needAlarm) {
            //弹出警示信息
            Toast.makeText(getApplicationContext(), "您的登陆界面被覆盖,请确认登陆环境是否安全", Toast.LENGTH_SHORT).show();
            //启动我们的AlarmService,用于给出覆盖了正常Activity的类名
            Intent intent = new Intent(this, AlarmService.class);
            startService(intent);
        }
        super.onPause();
    }

4.3. Service

对于Service组件,与Activity组件类似,要检查如果有intent filter设置的话,exported默认为true,必须关闭。具体代码示例与验证规则与Activity一致。

4.4. Provider

对于Provider组件,根据使用的Android SDK版本而定,如果版本为16(安卓4.1)或以下版本,则必须有exported的属性设置为false,如果是17(安卓4.2)以上版本则不必须

4.5. Receiver

对于Receiver组件,与Activity组件一致,主要查看是否有Intent filter,如果有则必须检查是否设置该属性为false

5. WebView组件

5.1. Webview File域同源策略绕过

可造成cookie等敏感信息泄露,黑客可利用该漏洞获取FireFox的所有文件。低版本的系统Webview组件也存在同样的漏洞,应用程序使用Webview并支持File域,就会受到该漏洞的攻击
如果程序中有使用WebView,在设置WebView建议关闭file协议:

mWebView.setAllowFileAccess(false)
setAllowFileAccessFromFileURLs(false)
setAllowUniversalAccessFromFileURLs(false)

如果必须使用,则应该禁止调用javascript

webView.getSettings. setJavaScriptEnabled(false);

eg:WebView允许js访问本地文件,并且允许js运行,则可以上传一个含有js代码的文件(代码内容为延迟读取自身)并将目标WebView启动让其读取上传的文件,然后将文件删掉并创建一个软链接到目标APP私有文件,则在延迟时间过后,WebView就会显示读取到的私有文,达成了攻击目的

5.2. WebView隐藏接口问题

如果使用Android4.4之前版本程序使用WebView,需要移除searchBoxJavaBridge_、accessibility、accessibilityTraversal危险接口。这三个接口存在远程代码执行的威胁

5.3. 远程命令执行攻击

13年下半年,Webview曝出了比较严重的远程命令执行漏洞。在webView 下有一个非常特殊的接口函数addJavascriptInterface。能实现本地java和js的交互。利用addJavascriptInterface这个接口函数可实现反射穿透webkit控制android 本机,比如向本机写入文件。技术细节可参考如下文章:《WebView中接口隐患与手机挂马利用》
处理方法
1、不要将不必要组件导出。
2、如需导出,禁止使用File域。
3、如需使用File协议,禁止js执行:setJavaScriptEnabled(False)

5.4. WebView绕过证书校验漏洞

禁止使用proceed()函数忽略证书错误,应该抛给系统进行安全警告。当SSL错误处理时,使用了proceed方法。造成假如SSL证书错误仍然可以访问


示例

6. 小结

  • 本地文件存储:
    对于敏感数据本地存储的要求,其实可以总结为:能不存就不存,非要存的话一定要加密。加密密钥不要硬编码到代码中,最好是获取每个终端的特有信息,如IMEI、mac之类
  • 安全通信
    1.真正实现TrustManager
    2.禁止使用AllowAllHostnameVerifier和ALLOWALLHOSTNAMEVERIFIER实例化,应该使用STRICTHOSTNAME_VERIFIER严格校验。
    3.禁止使用SSLCertificateSocketFactory;->getInsecure()函数禁用所有SSL安全校验。
    4.禁止使用proceed()函数忽略证书错误,应该抛给系统进行安全警告。
  • 安卓四大组件:
    如非必要,exported可以都显示的设置为false,在应用进入后台运行时要弹出提示信息(目前看来这个都有做了,基本上所有银行都会有这个功能),不要在本地做密码验证
  • WebView:
    1、禁止使用addJavascriptInterface方法
    2、设置WebView建议关闭file协议,mWebView.setAllowFileAccess(false)setAllowFileAccessFromFileURLs(false),setAllowUniversalAccessFromFileURLs(false)
    3、移除危险方法removeJavascriptInterface("searchBoxJavaBridge_")、removeJavascriptInterface("accessibility")、removeJavascriptInterface("accessibilityTraversal")
    4、使用handler.cancel()
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,616评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,020评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,078评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,040评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,154评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,265评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,298评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,072评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,491评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,795评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,970评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,654评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,272评论 3 318
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,985评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,223评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,815评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,852评论 2 351

推荐阅读更多精彩内容

  • 前言对于一款成熟的App,在某个时间点一定会开始涉及或者说要开始考虑安全问题。本着一贯的风格,把自己最近一段时间以...
    肖丹晨阅读 12,935评论 1 26
  • 随着移动互联网的发展,各大传统保险公司和银行金融公司都开发了自己的App,那么App的信息安全就变得非常重要了。如...
    码农一颗颗阅读 2,935评论 1 6
  • 初衷: 开发 Android 更加高效、高质量地进行 App 开发,呈现给用户体验好、性能优、稳定性佳、安全性高的...
    枫羽望空阅读 3,039评论 0 64
  • 3听说有个海岛,在海的中央! 那里很繁华, 去那里的门票 是时间! 于是每天都有许多人来到这里! 交出了他们的时间...
    遇见丝路阅读 247评论 0 3
  • 时间过得总是很快,当我们以为时间很慢,总是很长。 规划开始的时候,并没有规划结束,最后一天,回忆成...
    南宫圣衣阅读 113评论 0 0