前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >深入Android组件安全攻防(揭秘手Q强制下线提示原理)

深入Android组件安全攻防(揭秘手Q强制下线提示原理)

作者头像
开发者技术前线
发布2020-11-23 15:05:47
8870
发布2020-11-23 15:05:47
举报
文章被收录于专栏:开发者技术前线

本文继续Android安全话题,继续说道第四篇,继续对具体安全漏洞做具体的防止实践。本篇介绍组件劫持攻防。本文让你明白手机QQ强制登录提示功能的原理。

ps: 安全漏洞详细 可点这里

Activity

Activity是android最基本的组件,也是最常用的组件,基本运行原理请见:https://developer.android.com/reference/android/app/ActivityManager.html, activity的启动模式(四大启动模式自行找文看)决定了安全存在风险。于是存在了劫持风险。Activity劫持主要的表现是自己的Activity被恶意攻击,或者仿冒的恶意Activity界面进行攻击和非法用途。此漏洞的存在允许执行网络钓鱼攻击,以及用户在相关活动中处理的信息泄露。此外,此漏洞允许攻击者修改数据,从而危及其完整性。

轻度劫持

原理:

恶意被第三方程序启动,绕过本身的业务逻辑,造成数据泄露。主要体现在自己的首页被非法启动,绕过登录界面,导致可直接进行数据浏览和查看,或者携带对本app有害的指令,造成其他问题。

可以参考以前本号发布的安全要点与规范 中权限的描述。由于android所有组件通讯都会是基于intent来实现的,对于Intent的处理都有相关的action 中的 permission 进行过滤,所以如果开发者不严谨就会造成acivity被恶意开启。

解决方案: 第二篇安全要点中已经说明组件权限,具体属性请自行阅读,这里不过多解释!

代码语言:javascript
复制
<activity android:name=".MainActivity"   
    android:label="@string/title_activity_single" 
    android:exported="false"
    android:permission="自定义权限"      
    android:protectionLevel="normal" />

如果还需要做加固,Android 提供各种 API 来在运行时检查、执行、授予和撤销权限。这些 API是 ContextWraper的一部分,这个类提供有关应用程序环境的全局信息。

代码语言:javascript
复制
    if (context.checkCallingOrSelfPermission("自定义权限") 
          != PackageManager.PERMISSION_GRANTED) { 
    // The Application requires permission to access the // Internet"); 
    } else { 
      // handler 
    }

深度劫持

原理: 启动一个Activity时,给它加入一个标志位FLAG_ACTIVITY_NEW_TASK,就能使它置于栈顶并立马呈现给用户。如果不加以区别就能获取用户的相关信息,如果伪造出一个登录界面,搜集后发往云端,那么就会造成账户秘密泄露。被恶意程序截获 ,产生恶意程序的界面或者假冒伪造的界面覆盖在最上层,导致非法采集用户信息,盗取账号和密码。俗称钓鱼。 常用攻击要体现在登录和支付。

解决方案: 没有直接的解决方案, 只能引导用户!通过遍历系统当前最上层Activity,来判断是否是自己应用的界面,来做友好提示,防止用户被钓鱼程序劫持。下面就请来姿势砸我吧!

代码语言:javascript
复制
public static boolean checkMyself(Context context) { 
   PackageManager pm = context.getPackageManager();    
   List<ApplicationInfo> listAppcations =   
       pm.getInstalledApplications(PackageManager.GET_UNINSTALLED_PACKAGES);

   Collections.sort(listAppcations, new        
         ApplicationInfo.DisplayNameComparator(pm));    
      // 排序 
     List<ApplicationInfo> appInfos = new ArrayList<ApplicationInfo>(); 
     // 保存过滤查到的AppInfo 
    for (ApplicationInfo app : listAppcations) {        
     //这个排序必须有. 
     if ((app.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 
        //appInfos.add(getAppInfo(app));     
        safePackages.add(app.packageName); 
       } 
     }    //得到所有的系统程序包名放进白名单里面.
    ActivityManager activityManager = 
          (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); String runningActivityPackageName; 
     int sdkVersion;     try { 
           sdkVersion =   
                   Integer.valueOf(android.os.Build.VERSION.SDK); 
         } catch (NumberFormatException e) {
            sdkVersion = 0;
         } 
       if (sdkVersion >= 21) {       
        //获取系统api版本号,如果是5x系统就用这个方法获取当前运行的包名 
       runningActivityPackageName = getCurrentPkgName(context); 
        } else { 
             runningActivityPackageName = 
                 activityManager.getRunningTasks(1).get(0).topActivity.getPackageName(); 
        } 

       //如果是4x及以下,用这个方法. 
       if (runningActivityPackageName != null) {        
        //有些情况下在5x的手机中可能获取不到当前运行的包名,
         所以要非 空判断。
         if(runningActivityPackageName.equals(context.getPackageName())  ) { 
         safe = true; 
        } 
       // 白名单比对 
        for (String safePack : safePackages) { 
           if (safePack.equals(runningActivityPackageName)) {
            
               safe = true;
             }
          } 
       } 
      return safe;
}

因此在需要的检测的Activity中调用代码检查!

代码语言:javascript
复制
@Override protected void onStop() { 
     super.onStop();     if (checkMyself(this)){ 
        //todo 
    } else { 
       //todo
   } 
}

目前,QQ强制登录下线就利用这种原理,无论你停留在任何应用,当QQ账号在其他设备登陆时,当前总会提示对话框告知用户, 虽然很烦人,但用户无法阻止,手机QQ的service在收到推送时 立即在actiivity启动一个用来展示重新登录的透明activity, 用来伪造对话框覆盖在其他activity栈顶。为什么不直接提示Dialog?Android因为限制了dialog的show, dialog的初始化必须依赖acitvity的context, 因此这种组件攻击就成了手机QQ强制提示登录下线的实现原理。需要代码的朋友可以关注留言来索要。

Service

本地服务(Local)

该服务依附在主进程上,不是独立的进程。本地服务在一定程度上节约了资源,由于是在同一进程因此不需要IPC,也不需要AIDL。相应bindService会方便很多。主进程被Kill后,服务便会终止。

远程服务(Remote)

该服务是独立的进程,对应进程名格式为所在包名加上你指定的android:process字符串。由于是独立的进程,因此在Activity所在进程被Kill的时候,该服务依然在运行,不受其他进程影响,有利于为多个进程提供服务具有较高的灵活性。但由于独立的进程,会占用一定资源,并且使用AIDL进行IPC稍微麻烦一点。一些提供系统服务的Service通常是常驻的。

拒载服务

由于Service于外界也是通过Intent机制来协助应用间的交互与通讯,因此Intent的信息和描述就可能对Service发起攻击,造成自己的服务被停止服务漏洞.

1) 漏洞位置: 处理getIntent()的intent附带的数据 2) 漏洞触发前提条件: getIntent()的intent附带空数据、异常或畸形数据; 处理getXXXExtra()获取的数据时没有进行异常捕获. 3) 漏洞原理: Android系统中提供了Intent机制来协助应用间的交互与通讯,其负责对应用中一次操作的动作、动作涉及数据、附加数据进行描述,系统则根据此Intent的描述,负责找到对应的组件,将Intent传递给调用的组件,并完成组件的调用。调用的组件在处理Intent附加数据的时候,没有进行异常捕获,因此当处理空数据、异常或者畸形数据时,导致应用崩溃。

  • 空指针异常;
  • 类型转换异常;
  • 数组越界访问异常;
  • 类未定义异常;
  • 其他异常;

外界劫持

service也需要在manifest注册,因此权限属性和activity一样,出于安全考虑,应将不必要的组件设置私有,防止引起拒绝服务,尤其是杀毒、安全防护、锁屏防盗等安全应用; 在AndroidMenifest.xml文件中,将相应组件的“android:exported”属性设置为“false”,如下示例:

代码语言:javascript
复制
<service android:name="MyService"
         android:exported="false"> 
     <intent-filter> 
          <action android:name="android.intent.action_tamic"/>
     </intent-filter>
 </service>

Content Provider和Receiver

Content Provider和Receiver同上,具体我们也需要加入权限和声明为内部使用。干货文章有啥理由不关注呢?

猜你喜欢

Andrroid安全要点与规范

Android安全漏洞大全

技术 - 资讯 - 感悟

END

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2017-06-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 开发者技术前线 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • ps: 安全漏洞详细 可点这里
  • Activity
  • 目前,QQ强制登录下线就利用这种原理,无论你停留在任何应用,当QQ账号在其他设备登陆时,当前总会提示对话框告知用户, 虽然很烦人,但用户无法阻止,手机QQ的service在收到推送时 立即在actiivity启动一个用来展示重新登录的透明activity, 用来伪造对话框覆盖在其他activity栈顶。为什么不直接提示Dialog?Android因为限制了dialog的show, dialog的初始化必须依赖acitvity的context, 因此这种组件攻击就成了手机QQ强制提示登录下线的实现原理。需要代码的朋友可以关注留言来索要。
  • Service
    • 本地服务(Local)
      • 远程服务(Remote)
        • 拒载服务
          • 外界劫持
          • Content Provider和Receiver
          相关产品与服务
          腾讯云代码分析
          腾讯云代码分析(内部代号CodeDog)是集众多代码分析工具的云原生、分布式、高性能的代码综合分析跟踪管理平台,其主要功能是持续跟踪分析代码,观测项目代码质量,助力维护团队卓越代码文化。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档