2、使用DB.Browser.for.SQLite打开sqlite文件。
3、查看或检索文件中是否存在用户信息、业务数据、服务系统信息或其他敏感信息。如果存在,记录漏洞,停止测试。
预期结果:客户端数据库文件中不存在敏感数据。
整改建议:如果一定要在客户端存放系统或系统敏感数据,建议加密后再存储。
本地数据库注入/文件遍历检测
安全风险:获取或者篡改app中存储的敏感信息,如手机号、账号、密码等,在业务运行操作时无法保证数据安全。
执行步骤
1、启动drozer连接测试设备。
2、获取开放的provider:run app.provider.info -a appname
3、查找可用的URI:run scanner.provider.finduris -a appname
4、执行SQL注入检测run scanner.provider.injection -a appname
5、执行文件遍历检测 run scanner.provider.traversal -a appname
预期结果:无法获取到相关数据信息。
整改建议:使用参数化查询防御SQL注入,限制Provider组件的权限,取消不必要的Provider组件接口。
4、WebView组件安全测试
WebView是Android系统提供能显示Web页面的系统控件,例如混合类型的App中H5界面就是使用了WebView组件。
WebView远程代码执行漏洞
安全风险:Webview中接口addJavascriptInterface可通过webview对象向页面javascript导出java本地接口,可能导致任意命令执行。
执行步骤
1、使用反编译工具打开应用,反编译出应用源码。
2、在源码中搜索类似写法:
settings.setJavaScriptEnabled(true); //设置开启javascript settings.setJavaScriptCanOpenWindowsAutomatically(true); //设置允许js弹出alert对话框 mWebView.addJavascriptInterface(new JSInvokeClass(), "js2java"); //注入javascript映射
3、如果源码存在上面代码,那么该处就可能存在Web组件远程代码执行的风险。
4、如果存在该风险,将会在该页面中显示出存在问题的接口。
预期结果:系统使用安全接口调用webview。
整改建议
- 建议禁用危险接口addJavascriptInterface导出Java类及方法,并加强访问的url的域控制;
- 严格控制导出方法的权限,避免越权操作;
WebView密码明文保存漏洞
安全风险
- 在使用WebView的过程中开启了setSavePassword保存密码,当用户在WebView中输入的用户名和密码,则会被明文保存到应用。
- 用户数据保存到目录的databases/webview.db中。
- 如果手机被root就可以获取明文保存的密码,造成用户的个人敏感数据泄露。
执行步骤
1、使用反编译工具打开应用,反编译出应用源码。
2、在源码中搜索类似写法:
mWebView.getSettings().setSavePassword(true); //设置开启保存密码 mWebView.loadUrl("http://www.example.com");
3、有则说明风险存在,记录漏洞,停止测试。
预期结果:在调用setSavePassword时设定setSavePassword(false)。
整改建议:使用WebView.getSettings().setSavePassword(false)来禁止保存密码。
WebView组件忽略SSL证书验证错误漏洞
安全风险
Android WebView组件加载网页发生证书认证错误时,会调用WebViewClient类的onReceivedSslError方法,如果该方法实现调用了handler.proceed()来忽略该证书错误,则会受到中间人攻击的威胁,可能导致隐私泄露。
执行步骤
1、使用反编译工具打开应用,反编译出应用源码。
2、在源码中搜索类似写法:
mWebView.getSettings().setJavaScriptEnabled(true); mWebView.addJavascriptInterface(new JsBridge(mContext), JS_OBJECT); mWebView.loadUrl("http://www.example.org/tests/addjsif/"); mWebView.setWebViewClient(new WebViewClient() { @Override public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) { handler.proceed(); //忽略证书错误 } });
3、如上所示代码在onReceivedSslError处理时没有进行cancel,还是使用了proceed(),忽略掉了发生的SSL异常。则说明风险存在。记录漏洞,停止测试。
预期结果:正确的处理SSL错误,避免证书错误的风险。
整改建议:当发生证书认证错误时,采用默认的处理方法handler.cancel(),停止加载问题页面。
5、Broadcast组件安全测试
空广播造成Broadcast组件拒绝服务
安全风险:攻击者可以发送恶意的消息,控制Receiver执行恶意动作或者造成信息泄露。
执行步骤
1、使用工具Drozer扫描暴露的broadcast组件run app.broadcast.info -a xxxx -i和相关action信息;
2、尝试向应用程序的receiver组件发送空值,run app.broadcast.send --action xxx,查看是否能够造成应用程序崩溃,形成拒绝服务。
预期结果:系统为Broadcast组件分配了适当权限。
整改建议:AndroidManifest.xml文件的各receiver标签中,设置android:exported="false";BroadcastReceiver代码中增加消息异常处理机制。
未指定接收组件造成信息泄露
安全风险
应用程序在广播包含敏感信息的消息时,由于未指定具体的接收组件,攻击者可能仿冒receiver来接受来自应用程序的消息,从而窃取敏感信息。
执行步骤
1、反编译apk获取源代码,在源代码中搜索定位发送广播消息的位置,例如搜索sendBroadcast()。
2、查看在新建Intent时,是否显式指定了接收该广播的组件名称,以及要发送的广播中是否包含敏感信息。示例代码如下:
public class ServerService extends Service { // ... private void d() { // ... Intent v1 = new Intent();//未显式指定接收组建名称 v1.setAction("com.sample.action.server_running"); v1.putExtra("local_ip", v0.h); v1.putExtra("port", v0.i); v1.putExtra("code", v0.g); v1.putExtra("connected", v0.s); v1.putExtra("pwd_predefined", v0.r); if (!TextUtils.isEmpty(v0.t)) { v1.putExtra("connected_usr", v0.t); } } this.sendBroadcast(v1); }
3、 如果应用程序未指定接收组件并且广播中包含类似password等信息,则存在信息泄露的风险。