设为首页 加入收藏

TOP

Android应用安全之数据传输安全(一)
2015-07-16 12:57:22 来源: 作者: 【 】 浏览:20
Tags:Android 应用 安全 数据传输

不加密地明文传输敏感数据


  最危险的是直接使用HTTP协议登录账户或交换数据。例如,攻击者在自己设置的钓鱼网络中配置DNS服务器,将软件要连接的服务器域名解析至攻击者的另一台服务器在,这台服务器就可以获得用户登录信息,或者充当客户端与原服务器的中间人,转发双方数据。


早期,国外一些著名社交网站的Android客户端的登录会话没有加密,后来出现了黑客工具FaceNiff,专门嗅探这些会话并进行劫持(它甚至支持在WEP、WPA、WPA2加密的WIFI网络上展开攻击),这是目前我所知的唯一一个公开攻击移动软件漏洞的案例。


这类问题的解决方法很显然-----对敏感数据采用基于SSL/TLS的HTTPS进行传输。


SSL通信不检查证书有效性


  在SSL/TLS通信中,客户端通过数字证书判断服务器是否可信,并采用证书的公钥与服务器进行加密通信。


  然而,开发人员在开发过程中为了解决ssl证书报错的问题(使用了自己生成了证书后,客户端发现证书无法与系统可信根CA形成信任链,出现了CertificateException等异常),会在客户端代码中采用信任客户端中所有证书的方式:?


public static HttpClient getWapHttpClient() {
?
? ? ? ? ? ? ? try {
?
? ? ? ? ? ? ? ? ? ? KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
?
? ? ? ? ? ? ? ? ? ? trustStore.load(null, null);
?
? ? ? ? ? ? ? ? ? ? SSLSocketFactory sf = new MySSLSocketFactory(trustStore);
?
? ? ? ? ? ? ? ? ? ? sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
?
? ? ? ? ? ? ? ?   //此处信任手机中的所有证书,包括用户安装的第三方证书
?
? ? ? ? ? ? ? ? ? ? HttpParams params = new BasicHttpParams();
?
? ? ? ? ? ? ? ? ? ? HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
?
? ? ? ? ? ? ? ? ? ? HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
?
? ? ? ? ? ? ? ? ? ? SchemeRegistry registry = new SchemeRegistry();
?
? ? ? ? ? ? ? ? ? ? registry.register(new Scheme(“http”, PlainSocketFactory.getSocketFactory(), 80));
?
? ? ? ? ? ? ? ? ? ? registry.register(new Scheme(“https”, sf, 443));
?
? ? ? ? ? ? ? ? ? ? ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);
?
? ? ? ? ? ? ? ? ? ? return new DefaultHttpClient(ccm, params);
?
? ? ? ? ? ? ? } catch (Exception e) {
?
? ? ? ? ? ? ? ? ? ? return new DefaultHttpClient();
?
? ? ? ? ? ? ? }
?
? ? ? }


而在客户端中覆盖google默认的证书检查机制(X509TrustManager),并且在代码中无任何校验SSL证书有效性相关代码:


public class MySSLSocketFactory extends SSLSocketFactory {
?
? ? ? SSLContext sslContext = SSLContext.getInstance(“TLS”);
?
? ? ? public MySSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
?
? ? ? ? ? ? ? super(truststore);
?
? ? ? ? ? ? ? TrustManager tm = new X509TrustManager() {
?
? ? ? ? ? ? ? ? ? ? ? public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
?
? ? ? ? ? ? ? ? ? ? }
?
? ? ? ? ? ? ? ? ? ? //客户端并未对SSL证书的有效性进行校验,并且使用了自定义方法的方式覆盖android自带的校验方法
?
? ? ? ? ? ? ? ? ? ? public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
?
? ? ? ? ? ? ? ? ? ? }
?
? ? ? ? ? ? ? ? ? ? public X509Certificate[] getAcceptedIssuers() {
?
? ? ? ? ? ? ? ? ? ? ? ? ? ? return null;
?
? ? ? ? ? ? ? ? ? ? }
?
? ? ? ? ? ? ? };
?
? ? ? ? ? ? ? sslContext.init(null, new TrustManager[] { tm }, null);
?
? ? ? }
}


  如果用户手机中安装了一个恶意证书,那么就可以通过中间人攻击的方式进行窃听用户通信以及修改request或者response中的数据。


  在钓鱼Wifi网络中,同样地,攻击者可以通过设置DNS服务器使客户端与指定的服务器进行通信。攻击者在服务器上部署另一个证书,在会话建立阶段,客户端会收到这张证书,如果客户端忽略这个证书上的异常,或者接受这个证书,就会成功建立会话、开始加密通信。但攻击者拥有私钥,因此可以解密得到客户端发来数据的明文。攻击者还可以模拟客户端,与真正的服务器联系,充当中间人做监听。


手机应用中间人攻击过程:


1 客户端在启动时,传输数据之前需要客户端与服务端之间进行一次握手,在握手过程中将确立双方加密传输数据的密码信息。


2 中间人在此过程中将客户端请求服务器的握手信息拦截后,模拟客户端请求给服务器(将自己支持的一套加密规则发送给服务器),服务器会从中选出一组加密算法与HASH算法,并将自己的身份信息以证书的形式发回给客户端。证书里面包含了网站地址,加密公钥,以及证书的颁发机构等信息。


3 而此时中间人会拦截下服务端返回给客户端的证书信息,并替换成自己的证书信息。


4 客户端得到中间人的response后,会选择以中间人的证书进行加密数据传输。


5 中间人在得到客户端的请求数据后,以自己的证书进行解密。


6 在经过窃听或者是修改请求数据后,再模拟客户端加密请求数据传给服务端。就此完成整个中间人攻击的过程。


防护办法:


  使用CA机构颁发证书的方式可行,但是如果与实际情况相结合来看的话,时间和成本太高,所以目前很少有用此办法来做。由于手机应用服务器其实是固定的,所以证书也是固定的,可以使用“证书或公钥锁定”的办法来防护证书有效性未作

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇深入理解二进制补码 下一篇使用shell进行数学运算

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: