精华内容
下载资源
问答
  • SSH基础:中间人攻击防范

    千次阅读 2019-12-08 11:22:53
    中间人攻击有很多方式,比如常见的ARP或者DNS欺骗,在SSH连接时也有可能碰到类似的情况,所以ssh在know_hosts的管理中加入了对于已知服务器的信任列表的管理,多多少少可以确认一些可能的风险。

    在这里插入图片描述
    中间人攻击有很多方式,比如常见的ARP或者DNS欺骗,在SSH连接时也有可能碰到类似的情况,所以ssh在know_hosts的管理中加入了对于已知服务器的信任列表的管理,多多少少可以确认一些可能的风险。

    Man-In-The-Middle-Attack:中间人攻击MITM

    中间人攻击原理很简单,中间人介于客户端和服务器之前充当代理的角色,客户端和服务器之间的所有信息对于中间人来说都是可见的,中间人可以在信息的传递过程中查看内容或对内容进行修改,比如可以如下图所示,在证书的请求和传递的过程中丢弃客户所请求的证书,而使用自己提供的证书。
    在这里插入图片描述

    SSH的警告信息

    在SSH中也用到了证书,可以使用ECDSA或者RSA方式结合摘要技术生成表示服务器身份的密钥指纹。而一旦当此指纹发生变化时,ssh则会提示有可能有实际的风险,可能会提示如下信息:

    [root@host121 .ssh]# ssh 192.168.163.121
    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
    @    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
    IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
    Someone could be eavesdropping on you right now (man-in-the-middle attack)!
    It is also possible that a host key has just been changed.
    The fingerprint for the ECDSA key sent by the remote host is
    SHA256:y9ir2Jbc7kNZPhP9h/O9juUZbTmGDo6NZi2IZnLwg0s.
    Please contact your system administrator.
    Add correct host key in /root/.ssh/known_hosts to get rid of this message.
    Offending ECDSA key in /root/.ssh/known_hosts:2
    ECDSA host key for 192.168.163.121 has changed and you have requested strict checking.
    Host key verification failed.
    [root@host121 .ssh]#
    

    注意提示信息的主要内容:

    • REMOTE HOST IDENTIFICATION HAS CHANGED: 远程连接的身份发生了变化,因为中间人攻击的方式最重要的一个特点就是服务器侧和客户端没有意识到这个中间人角色的存在,所以进行提示是很重要的,这里提示你之前连接的这台主机已经发生变化了。
    • IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!: 大写一般可表示警告,告诉使用者可能有人在做很讨厌的事情,比如MITM。
    • Someone could be eavesdropping on you right now (man-in-the-middle attack)!:提示可能有人在监控你

    产生SSH的MITM警告信息的条件和方法

    只要事前存在的know_hosts中保存的连接对象机器的密钥指纹一旦发生变化,ssh的时候就会提示上述信息,但是在实际情况中,很多时候此密钥指纹都会发生变化,比如:

    • 重新安装了操作系统
    • 重新安装了openssh或者手动更新了/etc/ssh下的密钥对

    相较于这些更为常见的场景,ssh的警告会宁可误报,不可漏报,只要跟之前留在know_hosts中的密钥指纹不同,就会报错,比如可以使用如下步骤再现:

    • 事前确认两台机器的密钥指纹
    [root@host121 .ssh]# ssh-keyscan -t ECDSA 192.168.163.121
    # 192.168.163.121:22 SSH-2.0-OpenSSH_7.4
    192.168.163.121 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEy3w5004yyzNA8dXo1vo67E63tZybV88SiDupDfnHzHCeZ4tHjNqdabc9Fa+Jwwe5uIjcUFb+Ag4HaBjK4982U=
    [root@host121 .ssh]# ssh-keyscan -t ECDSA 192.168.163.122
    # 192.168.163.122:22 SSH-2.0-OpenSSH_7.4
    192.168.163.122 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBGylOHayVgNd3bV3NViPZ4CrAP/j9baVWGGloJUfrxwvt4+JdmkJVuUW5/aVP8U6Vg2HLFNsCVqszxOTkFpB4bo=
    [root@host121 .ssh]# 
    
    • 修改know_hosts
      之前设定的是连接192.168.163.121这台机器,设定信息如下所示
    192.168.163.121 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEy3w5004yyzNA8dXo1vo67E63tZybV88SiDupDfnHzHCeZ4tHjNqdabc9Fa+Jwwe5uIjcUFb+Ag4HaBjK4982U=
    

    这里偷偷将后面的密钥指纹改成192.168.163.122,know_hosts的信息如下所示:

    [root@host121 .ssh]# cat known_hosts 
    #192.168.163.121 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEy3w5004yyzNA8dXo1vo67E63tZybV88SiDupDfnHzHCeZ4tHjNqdabc9Fa+Jwwe5uIjcUFb+Ag4HaBjK4982U=
    192.168.163.121 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBGylOHayVgNd3bV3NViPZ4CrAP/j9baVWGGloJUfrxwvt4+JdmkJVuUW5/aVP8U6Vg2HLFNsCVqszxOTkFpB4bo=
    [root@host121 .ssh]# 
    

    这样ssh 192.168.163.121时就会提示上述警告信息了。

    避免方法

    方法1: 更新操作系统或其他操作之前事前备份指纹信息

    事前备份密钥指纹信息,重新安装之后恢复,避免出现这种意外操作因为的问题。

    方法2: 及时更新客户端连接的设定信息

    一旦发生变化,及时更新客户端连接设定文件know_hosts

    方法3: 连接时设定StrictHostKeyChecking

    通过-o参数设定StrictHostKeyChecking参数为no,从而忽略此问题,但会提示警告信息。连接示例信息如下所示:

    [root@host121 .ssh]# ssh -o StrictHostKeyChecking=no 192.168.163.121
    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
    @    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
    IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
    Someone could be eavesdropping on you right now (man-in-the-middle attack)!
    It is also possible that a host key has just been changed.
    The fingerprint for the ECDSA key sent by the remote host is
    SHA256:y9ir2Jbc7kNZPhP9h/O9juUZbTmGDo6NZi2IZnLwg0s.
    Please contact your system administrator.
    Add correct host key in /root/.ssh/known_hosts to get rid of this message.
    Offending ECDSA key in /root/.ssh/known_hosts:2
    Password authentication is disabled to avoid man-in-the-middle attacks.
    Keyboard-interactive authentication is disabled to avoid man-in-the-middle attacks.
    Last login: Sat Dec  7 19:54:27 2019 from host121
    [root@host121 ~]#
    

    总结

    实际上这个提示的功能防范即为有限,很多还是在流程上的规范来确保系统的安全,比如最初的know_hosts加入了中间人的指纹信息,ssh是无法辨别的,还是通过用户的确认结合起来才能够完成。

    展开全文
  • SSL中间人攻击安全 问题说明 漏洞影响 能实现ssl中间人攻击有三个可能性,第一个就是自定义的X509TrustManager不校验证书;或实现的自定义HostnameVerifier不校验域名接受任意域名;或使用setHostnameVerifier ...

    前言

    目前,我们在开发App的时候对Https的校验方面都比较忽略,当我们使用一些抓包工具测试的时候,即使手机不安装抓包工具的证书,也可以抓取我们Https进行劫持看见我们的明文内容会泄露用户的隐私数据,下面我就写下我的防护措施。

    概念

    中间人攻击原理

    针对SSL的中间人攻击方式主要有两类,分别是SSL劫持攻击和SSL剥离攻击

    SSL劫持攻击

    SSL劫持攻击即SSL证书欺骗攻击,攻击者为了获得HTTPS传输的明文数据,需要先将自己接入到客户端和目标网站之间;在传输过程中伪造服务器的证书,将服务器的公钥替换成自己的公钥,这样,中间人就可以得到明文传输带Key1、Key2和Pre-Master-Key,从而窃取客户端和服务端的通信数据;

    但是对于客户端来说,如果中间人伪造了证书,在校验证书过程中会提示证书错误,由用户选择继续操作还是返回,由于大多数用户的安全意识不强,会选择继续操作,此时,中间人就可以获取浏览器和服务器之间的通信数据

    SSL剥离攻击

    这种攻击方式也需要将攻击者设置为中间人,之后见HTTPS范文替换为HTTP返回给浏览器,而中间人和服务器之间仍然保持HTTPS服务器。由于HTTP是明文传输的,所以中间人可以获取客户端和服务器传输数据。

    上面的内容来自《Https协议简析及中间人攻击原理》如果还需要对Https的知识理解和补充可以自行Google,这里就不多做解释了。

    抓取不校验的App信息

    通常我们看似做了Https,但是我们没有做一些安全措施的话,我们的数据就会暴露,下面我们来做一些测试。

    安装抓包工具Charles

    Charles是一个很好用的抓包工具,有很多强大的功能,不过是付费的,有30天的试用期。
    这里有一个很简单的教程看了配置下就可以了《十分钟学会Charles抓包(iOS的http/https请求)
    ,虽然是文章是关于IOS但是Android的配置方式是一样的。

    抓取信息

    在这里插入图片描述
    我屏蔽了一些敏感信息,可以看见我们成功的抓取了Https链接里面的明文信息,并且我没有安装抓包工具的证书,下面我们来进行分析。

    为什么用了Https还能抓取明文信息?

    我来展示下我在App中编写的代码:

    OkHttpClient okHttpClient = new OkHttpClient();
            try {
                final TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
                    @Override
                    public void checkClientTrusted(
                            java.security.cert.X509Certificate[] chain,
                            String authType) throws CertificateException {
                    }
    
                    @Override
                    public void checkServerTrusted(
                            java.security.cert.X509Certificate[] chain,
                            String authType) throws CertificateException {
                    }
    
                    @Override
                    public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                        return null;
                    }
                }};
                final SSLContext sslContext = SSLContext.getInstance("TLS");
                sslContext.init(null, trustAllCerts,
                        new java.security.SecureRandom());
                // Create an ssl socket factory with our all-trusting manager
                final SSLSocketFactory sslSocketFactory = sslContext
                        .getSocketFactory();
    
                okHttpClient.setSslSocketFactory(sslSocketFactory);
                okHttpClient.setHostnameVerifier(new HostnameVerifier() {
    
                    @Override
                    public boolean verify(String hostname, SSLSession session) {
                        return true;
    
                    }
                });
    
            } catch (Exception e) {
            }
    

    在代码中造成ssl中间人攻击有三个可能性:

    • 自定义的X509TrustManager不校验证书;
    • 自定义HostnameVerifier不校验域名接受任意域名;
    • 使用setHostnameVerifier (ALLOW_ALL_HOSTNAME_VERIFIER)允许所有域名。
      以上三点这样应用容易遭受中间人攻击,存在用户敏感数据被盗取的风险,其实网上有很多这样的代码,教你简单的配置一个Https链接,是非常不可取的,我们来看看通过 HTTPS 和 SSL 确保安全怎么说:
      在这里插入图片描述
      这里官网已经说明,当我们编写一个没用的TrustManager的时候就不会对链接进行验证了。那么如何编写一个安全的呢。

    PS:这里如果理解有问题的话,需要看一些HTTPS的相关知识,这里我补一张图。方便阅读便于记忆
    SSL/TLS层负责客户端和服务器之间的加解密算法协商、密钥交换、通信连接的建立,安全连接的建立过程如下所示:

    两种签名证书

    目前的Https认证中,分为两种证书:

    • CA机构颁发的证书
      HTTPS网站所用的证书可向可信CA机构申请,不过这一类基本上都是商业机构,申请证书需要缴费,一般是按年缴费,费用因为CA机构的不同而不同。

    • 自签署服务证书
      如果只是APP与后台服务器进行HTTPS通信,可以使用openssl工具生成自签发的数字证书,可以节约费用,不过得妥善保护好证书私钥,不能泄露或者丢失。HTTPS通信所用的数字证书格式为X.509。

    自签名证书认证

    我们先来看一段代码:

            OkHttpClient.Builder builder = new OkHttpClient().newBuilder();
            try {
                client = builder.hostnameVerifier(RELEASE)
                                .sslSocketFactory(getSslSocketFactory1())
                                .build();
    
            } catch (Exception e) {
            }
    

    ps:代码这里我使用了OKhttp,在这里就默认大家会使用了。网上教程很多,可以自行google。

    验证证书有两个重要的步骤:

    • 验证证书是否来自值得信任的来源
    • 主机名验证

    第一步,是通过我们的数字证书生成一个新的SSLSocketFactory替换掉默认的,也就是我们的自定义TrustManager,使系统信任我们的证书,和前面的抓包工具安装证书类似。
    第二步, 是对我们证书的校验,当第一步成功以后,就会将我们Https的域名变为合法的,当我们访问自己的服务器的时候就不会出现SSLHandshakeException

    验证证书是否来自值得信任的来源

    如果申请CA认证的话,需要我们对CA机构缴费,许多公司不愿意缴费,在这种情况下,由于您具有系统不信任的 CA,将发生 SSLHandshakeException。原因可能是您有一个来自 Android 还未信任的新 CA 的证书,或您的应用在没有 CA 的较旧版本上运行。

    在这里,您可以指示 HttpsURLConnection 信任特定的 CA 集。此过程可能有点复杂,下面的示例展示了这个过程,从 InputStream 获取一个特定的 CA,用该 CA 创建 KeyStore,然后用后者创建和初始化 TrustManager。TrustManager 是系统用于从服务器验证证书的工具,可以使用一个或多个 CA 从 KeyStore 创建,而创建的 TrustManager 将仅信任这些 CA。

    如果是新的 TrustManager,此示例将初始化一个新的 SSLContext,后者可以提供一个 SSLSocketFactory,您可以通过 HttpsURLConnection 用它来替换默认的 SSLSocketFactory。这样一来,连接将使用您的 CA 验证证书。

    • 方法1
    public static SSLSocketFactory getSslSocketFactory1() throws NoSuchAlgorithmException, KeyManagementException, CertificateException, KeyStoreException, IOException {
            //以X.509格式获取证书
            CertificateFactory cf = CertificateFactory.getInstance(X_509);
            InputStream caInput = null;
            try {
                 caInput = new BufferedInputStream(new FileInputStream("load-der.crt"));//一般是存放在Assert下
            } catch (IOException e) {
                e.printStackTrace();
            }
            Certificate ca;
            try {
                ca = cf.generateCertificate(caInput);
                System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN());
            } finally {
                caInput.close();
            }
    
            // 创建包含受信任CA的KeyStore
            String keyStoreType = KeyStore.getDefaultType();
            KeyStore keyStore = KeyStore.getInstance(keyStoreType);
            keyStore.load(null, null);
            keyStore.setCertificateEntry(CA, ca);
    
            // 创建一个信任我们的KeyStore中的CA的TrustManager
            String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
            TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
            tmf.init(keyStore);
    
            // 创建一个使用我们的TrustManager的SSLContext
            SSLContext context = SSLContext.getInstance(TSL);
            context.init(null, tmf.getTrustManagers(), null);
    
            return context.getSocketFactory();
        }
    

    上面的代码就是将自签署的服务证书放在Assert包下,然后通过带代码生成一个SSLSocketFactory替换默认的。上面的代码中我们还可以使用另外一种形式来进行验证。

    • 方法2
        public static SSLSocketFactory getSslSocketFactory2() throws NoSuchAlgorithmException, KeyManagementException {
            final TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
    
            private X509Certificate serverCert;
            private final String CRT_NAME = "martin.crt";
    
            @Override
            public void checkClientTrusted(X509Certificate[] chain, String authType) {
    
            }
    
            @Override
            public void checkServerTrusted(X509Certificate[] x509Certificates, String authType) throws CertificateException{
                if (x509Certificates == null) {
                    throw new IllegalArgumentException("check Server X509Certificates is null");
                }
    
                if (x509Certificates.length < 0) {
                    throw new IllegalArgumentException("check Server X509Certificates is empty");
                }
                InputStream caInput = null;
                try {
                    caInput = new BufferedInputStream(Utils.getApp()
                                                           .getAssets()
                                                           .open(CRT_NAME));
                } catch (IOException e) {
                    e.printStackTrace();
                }
                CertificateFactory cf = CertificateFactory.getInstance("X.509");
                serverCert = (X509Certificate) cf.generateCertificate(caInput);
    
    
                for (X509Certificate cert : x509Certificates) {
                    try {
                        cert.checkValidity();
                        cert.verify(serverCert.getPublicKey());//和App预埋证书做对比
                    } catch (InvalidKeyException e) {
                        e.printStackTrace();
                    } catch (NoSuchAlgorithmException e) {
                        e.printStackTrace();
                    } catch (NoSuchProviderException e) {
                        e.printStackTrace();
                    } catch (SignatureException e) {
                        e.printStackTrace();
                    }
                }
            }
    
            @Override
            public X509Certificate[] getAcceptedIssuers() {
                return new X509Certificate[0];
            }
        };};
            final SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
            return sslContext.getSocketFactory();
        }
    

    上面的两种方法,选一种实现就行。

    主机名验证

    正如本文开头所述,验证 SSL 连接有两个关键环节。首先是验证证书是否来自值得信任的来源,这是前面部分重点讲述的内容。而此部分侧重于第二个环节:确保您正在通信的服务器提供正确的证书。

    public static HostnameVerifier RELEASE = new HostnameVerifier() {
    
            @Override
            public boolean verify(String hostname, SSLSession session) {
                return HttpsURLConnection.getDefaultHostnameVerifier().verify(hostname, session);
            }
    };
    

    当我们加入了自签署证书以后,验证就会为true。

    CA机构颁发证书验证

    因为在Android手机刚出厂的时候,系统都会默认装一些CA机构的根证书以作为认证。所以不需要公钥进行自定义TrustManager,那怎么得知我们的链接是进行过CA机构认证的呢?
    在这里插入图片描述
    当我们再google输入百度的网址时候,会出现一个锁的图片,点击后出现下面的证书细节。
    在这里插入图片描述
    上面已经看见百度的证书是CA机构认证的,如果你们公司的也是的话,我们只需要进行主机域名认证就没问题了。

    public static HostnameVerifier RELEASE = new HostnameVerifier() {
    
            @Override
            public boolean verify(String hostname, SSLSession session) {
                return HttpsURLConnection.getDefaultHostnameVerifier().verify(hostname, session);
            }
    };
    

    小结

    今天讲解的内容还是比较简单,总结一下:

    1. 中间人攻击攻击分为
      – SSL剥离攻击
      – SSL劫持攻击

    2. 安装抓包工具Charles,对不进行证书校验的App进行明文抓包。

    3. 两种签名证书
      – 自签名服务证书校验的两个步骤: 自定义SSLContextFactory 2.进行主机名验证。
      – CA认证证书的校验方法。

    参考文章

    展开全文
  • GoSSIP_SJTU · 2015/11/16 10:47Author:张天陆0x00 简述基于PKI体系的SSL/TLS协议近年来暴出很多安全问题,比如著名的HeartBleed、POODLE攻击和Freak攻击等,2014年关于SSL/TLS协议证书验证问题的CVE有成千个。...

    GoSSIP_SJTU · 2015/11/16 10:47

    Author:张天陆

    0x00 简述


    基于PKI体系的SSL/TLS协议近年来暴出很多安全问题,比如著名的HeartBleed、POODLE攻击和Freak攻击等,2014年关于SSL/TLS协议证书验证问题的CVE有成千个。针对SSL协议在实现中暴露出的各种问题,这里我们讨论一下现有的加固和防范方案,主要包括四个方面:

    a) Key pinning策略
    b) HSTS策略
    c) 多路径证书检查策略
    d) DNS-based authentication

    下面我们基于这四个策略做详细介绍。

    0x01 Key Pinning策略


    1、 Key Pinning介绍

    Pinning是把服务器的主机名和证书、公钥等密码学要素联系起来的一种安全技术。例如,当知道某网站的正确证书,再次链接此网站时,可以通过对比已知的正确证书和从网站接收到的证书,判断是否被中间人攻击。当然,没有必要在本地保存某网站的完整证书信息,可以对证书做hash(比如SHA-256),本地保存对应的hash值,这样比完整证书更便捷,并且节省空间。

    相对证书pinning,更为实际的是public key pinning,因为很多时候证书在重新签发时,并没有更换其公钥信息,这也是为什么很多证书拥有相同公钥的原因。这样如果在本地pin的是公钥信息,那么收到不同的证书也没关系,只要公钥内容相同,就可以信任这些证书。

    对于SSH此类不依赖于证书的协议,可以直接pin公钥,但是对于SSL/TLS协议,最好的方式是pin X.509证书的SPKI(SubjectPublicKeyInfo)部分对应的hash值,SPKI部分包含了公钥以及其他额外的用于安全验证的信息(包括所使用的公钥加密算法、公钥位数)。

    2、 pin的位置

    服务器基于安全考虑,会经常更换公私钥对;并且如果私钥泄露,也需要从CA重新签发证书;并且同一个网站有可能部署了多个公私钥对。而如果pin的是服务器的公钥,那么在维护和使用上会相当复杂。

    基于上述因素的考虑,可以将pin的位置放在证书链上。一般来说证书链开始于终端证书,有一个中间CA证书,最后是根CA证书。如果pin的是后两个证书信息(中间CA或者根CA的证书信息),那么服务器终端更换证书时,只要是同一个CA签发的,那么证书链没变,pin的信息也不用更换。

    但是这里会出现另一个问题,CA可能会有很多的上级中间CA,或者不同的根CA,服务器在更换证书时,即使选择的是相同CA,那么上级中间CA有可能不同。

    基于这些考虑,最佳的pin位置可以选择在证书链的第二个证书上,就是给服务器签发证书的CA的证书,因为即使服务器更换证书,也会选择该CA进行证书签发,pin的信息不会变。

    3、何时用pin

    最有效的pinning方式,是在native application中。因为这时作为开发者可以控制通信双方,对于桌面应用和移动应用都可以,比如一些银行软件,支付软件等。

    对于这种情况,如果开发者可以控制通信双方(客户端与服务器),从而既可以使用自己的证书作为pinning信息,也可以使用第三方CA签发的证书。

    4、使用key pinning的不足:

    • 服务器私钥如果泄露,就需要更换密钥对,另外服务器会经常更改密钥对,为了使相同密钥加密的信息不要太多。这时就需要经常的更换pin的信息,操作复杂。
    • 另外同一站点有可能有多个证书,pinning的内容如果不全面,有可能产生错误信息。
    • 对于一些应用在更换pin信息时,需要通过软件升级的方式,不太方便。

    0x02 HSTS策略


    1、 HSTS简介

    HSTS(HTTP Strict Transport Security)HTTP严格传输安全,最早于2009年提出,标准化于2012年11月的RFC 6797,是一套由互联网工程任务组发布的互联网安全策略机制。网站可以选择使用HSTS策略,强制浏览器使用TLS协议,并且中断所有证书出现错误的连接,从而减轻浏览器在执行TLS协议时所面临的一些危险。

    HSTS策略的使用,主要解决了以下几个问题:

    • 面对一个主机名(没有指明协议),浏览器不知道该网站是否使用TLS协议;
    • 当遇到证书错误不是阻断连接,而是给用户告警(用户多会选择忽略);
    • HTTPS页面从一个HTTP origin加载资源,被称为mixed content,攻击者可以通过控制从不安全页面加载到https页面的mix content实现攻击效果;
    • cookie遵守的同源策略和web content的同源策略不同,只根据host隔离,因此https和http会共用cookie。

    HSTS通过两种方式,解决以上问题:

    • 在本地将所有的http转换为https,保证使用了HSTS的网站,只能通过https访问;
    • 当遇到证书错误时,中断链接。

    2、HSTS安全意义

    一些支持https的网站一般情况下也会监听http的请求,之后再讲这些请求重定向为https。例如:当收到http://www.facebook.com时,会将用户访问重定向为https://www.facebook.com。这种重定向是不安全的,因为第一个请求使用的是http,攻击者可以从中获取一些敏感信息(比如之前安全会话中的coocie等),另外,攻击者还可能将用户重定向到一些钓鱼网站。并且根据用户的输入习惯,不会在主机名前加上https,更容易带来威胁。

    HSTS策略防止了这种威胁的存在,它要求浏览器在本地将http协议强制转换为https,之后再与服务器通过https协议进行通信。

    3、HSTS执行

    服务器开启HSTS的方法是,当客户端通过HTTPS发出请求时,在服务器返回的超文本传输协议响应头中包含Strict-Transport-Security字段(非加密传输时设置的HSTS字段无效,Strict-Transport-Security 头信息当通过HTTP请求传递,会被浏览器忽略,因为攻击者可能拦截或者篡改HTTP连接头,直到第一次通过https进行安全连接,并且收到Strict-Transport-Security头信息,才会针对该网站配置HSTS策略,这里可以通过浏览器对HSTS preload方式解决)。

    Strict-Transport-Security字段包括:

    Strict-Transport-Security: max-age=expireTime [; includeSubdomains]
    复制代码

    其中:max-age参数指明了过期时间,单位秒,浏览器需要记住这个网站只能通过HTTPS访问的时间;includeSubdomains是可选参数,指明该网站的子域名也需要通过https访问。

    浏览器对Strict-Transport-Security字段处理:

    当浏览器使用https第一次访问网站,收到服务器响应的包含该字段的头,会记录下这些信息,之后在有效期内,把对该网站的请求都转换为https。每次浏览器收到Strict-Transport-Security头,都会更新max-age指定的有效期时间,这样可以防止HSTS策略过期。

    我们用图形简单介绍HSTS功能:

    图1

    图1标示了正常情况下,服务器收到http请求时,重定向为https的过程,该过程是不安全的;

    图2

    图2标示了第一次安全连接时,收到HSTS的Strict-Transport-Security头信息,之后的访问都会执行HSTS策略。

    图3

    图3标示HSTS策略执行时的过程。

    4、HSTS部署

    HSTS的部署要考虑到全面性。默认情况下,HSTS只针对返回Strict-Transport-Security响应头的主机名部署,但是很多站点可以部署多个域名,因此要注意HSTS策略部署到所有的域名。

    对于一些只有一个主机名的网站也需要考虑部署是否全面的问题。例如用户想要访问某网站时,没有加WWW前缀(输入XXX.com访问www.XXX.com),由于没法控制用户的输入,因此在配置HSTS时要注意覆盖到所有的主机名。

    另外需要注意的是,HSTS部署的全面性要考虑到能够到达网站的所有的路径名,比如用户可能首先通过输入访问根域名,之后再访问其它子域名,此时根域名如果没有部署HSTS策略,有可能会招到SSL剥离攻击。

    5、HSTS Preloading

    当用户第一次正确使用https连接某网站,并且收到Strict-Transport-Security头时,才会根据头信息对该网站设置HSTS策略。为了提高HSTS的安全效率,解决“first visit”问题,Google安全团队在Chrome浏览器中设置了“HSTS preload list”,列表中的域名都会自动的使用HSTS策略。Firefox,Safari以及最新版本的IE浏览器,都会合并使用Chrome的HSTS preload list。

    使用HSTS preload可以满足以下要求:

    • 确保了根域名和子域名都被强制使用https;
    • 对所有的子域名都标注了一个策略有效时间和preload标记,标示域名拥有者同意加入preload list中。

    对于一些金融机构、政府网站或者社交网络等,HSTS策略可以缓解大量SSL/TLS协议遭受到的威胁。但是HSTS策略并不能低于证书伪造攻击,需要key-pinning策略协同使用。

    0x03 多路径证书检测


    多路径证书检查策略,核心思想就是不仅仅依赖PKI体系,抛开CA的权威性,通过多个途径和方法检验客户端收到的证书的合法性。

    多路径证书检查的方法基本有两种:

    • 公证人辅助证书检查;
    • Tor-Network洋葱网络检查;
    • Social network借助社交网络检查。

    这里我们主要介绍前两种方法。

    1、公证人辅助证书检查

    1.1 Notary简介

    公证人协助验证证书,是指通过第三方(Notaries)机构,协助验证证书是否合法有效。最早的出现是Perspectives,Firefox的一个插件,可以将收到的服务器证书与大量的notaries进行对比,这些notaries来自于不同的网络节点,这样即使其中某些节点出现问题,攻击者仍然没办法将所有的notaries攻破。通过对比证书是否相同,判断是否遭受中间人攻击。

    图4

    图4展示了利用notaries进行证书比对的流程,当客户端收到服务器返回的证书后,向设定好的多个notaries发出请求,根据服务器主机名查找多个notaries中对应的证书,通过返回的证书进行比对,如果有不相同,则认为该证书无效。这些notaries部署在不同的网络环境中。

    1.2 Notaries证书获取

    最初的Perspectives所对应的Notaries,会定期的主动的扫描全网的主机,从中获取证书所对应的公钥,存储在本地数据库中,当浏览器的Perspectives插件需要进行证书比对时,从该数据库中获取对应主机的证书公钥,返回给客户端进行比对。2011年,Convergence notary提供了类似的功能,不同的是Convergence notary不会主动的进行全网扫描,仅仅当客户端索求一个本地数据库中没有的证书时,才会向对应的主机进行证书索取。目前Perspectives和Convergence是两个权威的notary维护机构,各自维护这多个可以被共用的notaries。

    1.3 Notaries的评估

    使用Notaries作为第三方,协助进行公钥检查,浏览器可以通过插件完全的依赖所设定的可信Notaries,弱化了以X.509证书为基础的PKI体系。同时,如果某个Notaries被攻破,用户完全可以自行更改设置,选择不同的Notaries。

    使用Notaries进行证书验证也有一些缺点:

    • 降低了用户体验,多了一层证书验证流程,会降低网络访问速度;
    • 对于一些Notaries,会获取到用户想要访问哪些网站的隐私;
    • 一些网站可能会有多个证书,导致Notaries误报的情况出现。

    2、Tor-Network 网络辅助证书检查

    洋葱网络的特点是当用户访问某一个固定的目的端,每次经过的路径是随机的。具体来说,TOR客户端维护一个浏览器一样的代理,其他软件可以使用该代理提供的借口,进入Tor网络,TOR节点在不同次的连接时会选择不同的路径,不会轻易被中间人攻击。利用洋葱网络的这一特点,可以进行多路径证书检查。

    洋葱网络辅助证书检查是建立在正常https协议出现证书警告的情况下,通过洋葱网络再次获取证书,比对两次得到的证书是否相同来判断是否遭受中间人攻击。

    图5

    图5展示了使用Tor-Network进行多路径证书检查的流程:

    • Alice收到https证书警告;
    • 通过洋葱网络代理,接入洋葱网络;
    • 获取目标服务器的证书;
    • 比对两次获取的证书是否相同。

    多路径证书检查的思想都是通过多一次的证书获取,与收到的证书进行对比,从而判断是否遭受中间人攻击,提高通信的安全性,但是这种方式势必会增加TLS连接消耗的时间,降低用户体验。

    0x04 DNS-based authentication策略


    4.1 DANE简介

    DANE(DNS-Based Authentication of Named Entities)是一种将域名和密码学要素联合起来的安全标准,2012年8月在RFC 6698中标准化定义。域名拥有者可以控制DNS的配置,能够利用DNS作为单独的一条渠道来加强TLS的安全执行。DANE方便部署,但是仅靠DNS并不能提供任何安全性质,还需要依靠DNSSEC协议。

    DNSSEC简言之,就是利用数字签名身份认证技术,在进行域名请求时,验证整个请求链中的每个DNS的身份,确保最终收到的域名信息是正确的没有被篡改过。

    目前的认证机制分为两个阶段:一是有一群我们信任的第三方机构为域名真正拥有者签发证书,成为CA;二是客户端(比如浏览器)能够检测某主机名对应的证书是正确的。基于这种分离式的架构是因为通信双方一般是远距离没法碰面的,验证身份容易找到欺骗。而基于DNSSEC协议,DNS请求就可以确保安全性,就可以利用DNS提供身份验证,这样就有一个新的途径同域名拥有者进行通信,从而抛弃掉对CA的依赖性。

    简言之,DANE就是在客户端pin主机名对应的的证书,之后通过DNS请求时,获取主机名的证书,通过对比判断证书的可信性。

    4.2 DANE作用

    • 安全的部署自签名证书

      现在,自签名证书被认为是不安全的,因为没有一种办法区分自签名证书和中间人攻击伪造的证书,也就是说自签名证书都是一样的。但是,我们可以用安全的DNS去pin一个自签名的证书,这样浏览器就可以知道正在使用的自签名证书是安全的,也可以很容易的区分出中间人攻击伪造的证书。

    • 安全的部署私有根证书 如果可以安全的pin一个服务器证书,那么也可以pin这个服务器证书所在的证书链中的任一证书,也就是说可以构造一个你所拥有的网站的根证书,并让客户端信任这个证书,这种方式对拥有很多网站的开发者来说,更为方便。

    • 支持CA颁发的证书和Public key-pinning DANE无须改变现有的认证架构,同样的可以在客户端pin CA颁发的证书和根证书。

    4.3 DANE执行

    DANE扩展了一种新的DNS记录类型,叫做TLSA Resource Record(TLSA RR或者叫做TLSA),TLSA包含四个区域:(1) Certificate Usage;(2)Selector;(3)Matching Type;(4)Certificate Association Data。

    其中Certificate Usage字段有四种不同的值:

    0-CA规范:pin一个CA,在证书链中必须有对应的CA签发的证书;
    1-指定TLS证书:TLSA 记录指定应当用于某一域名的准确TLS证书;
    2-信任点声明:在客户端pin一个某站点自己的CA,该CA可以不是公共信任的CA;
    3-域名颁发证书:在客户端pin一个具体的TLS证书,该证书可以是某主机自己签发的证书

    通过后两种值可以看出,DANE可以完美的支持自签名证书,同时也确保使用自签名证书的安全性。

    自此,我们讲述了四种目前常见的SSL/TLS协议的加固策略,这四种策略固然各有优劣。其中key pinning可以和HSTS结合使用,确保强制使用https的同时也保证了证书安全性。另外,安全性和用户体验总是会存在一些冲突,在取和舍之间不同的人又有着不同的观点。

    展开全文
  • HTTPS 中间人攻击及其防范

    千次阅读 2018-10-09 12:01:58
    转自:https://rolandreed.cn/post/Man-In-Middle-Attack
    展开全文
  • 可信网络连接协议作为可信计算框架中的核心技术,存在中间人攻击的安全威胁。为了解决中间人攻击问题,优化了Diffie-Hellman密钥交换协议,提出了基于数字签名及签名验证的端到端协议。与现有协议相比,提出的方案...
  • 中间人攻击与防御方法

    千次阅读 2020-09-21 13:39:17
    实验二:窃取数据 通过双向欺骗,完成中间人攻击,并成功窃取telnet和FTP密码 八、ARP命令 查看ARP缓存的命令 arp -a 删除ARP缓存表的命令 arp -d 九、如何防御ARP攻击 9.1 ARP静态绑定 PC端命令 arp -s 网关的IP ...
  • ARP中间人攻击与防护

    2020-03-19 19:01:57
    攻击者通过伪造一个ARP的reply包,发送给ARP请求者。由于ARP表的更新规则是,新的信息会覆盖旧的信息,所以攻击者利用这个原理,伪造数据包,将数据包的源MAC写为自己的MAC,源...这样就可以实现ARP中间人攻击。 攻...
  • 密码学中的中间人攻击

    千次阅读 2019-05-28 19:31:17
    之前我们讲了Diffie和Hellman在1976年提出的密钥交换协议,即公玥密码体制的开端,对于该协议来说,通过一般的攻击方式比如窃听是很难得到通信双方协商的公钥的,但中间人攻击是最容易攻破该协议的。下面我们就讲述...
  • HTTPS 防范中间人攻击原理

    千次阅读 2020-10-16 18:45:25
    HTTPS因为增加了CA证书,可以在会话前通过证书验证证明通信的彼此就是所声称的人,因此可以防范中间人攻击。这种防范中间人攻击的前提是在HTTPs协议的双向认证上。如果仅仅实现了HTTPs的单向认证,如不验证客户端,...
  • 中间人攻击&防御方式全解

    千次阅读 2017-09-04 14:40:00
    正如中间人攻击(MiTM)。这种攻击的目的很简单,就是在有线或者无线连接的中间放置一个攻击者。但是,随着云计算、物联网(IoT)、BYOT等网络技术的发展,攻击者也开始寻找新的方式以使那些古老的攻击方式可以重新...
  • 1.什么是中间人攻击? 在手机或者电脑和服务器建立连接的时候,攻击者通过工具或者技术手段将自己位于两端之间,获取数据,进行监听活动的就是中间人攻击。 2.有哪几种攻击: 1.嗅探,监听获取连接数据包。 2....
  • 不知道大家是否还记得,去年一个名为TH4CK的组织撸翻了很多大论坛,时候大家纷纷对其技术...额,步骤什么的网上都有,我就用我不太好的描述能力说说原理和防范吧,水平有限,还请大家多多指教 测试环境: 网关:
  • 清晰图解https如何防范中间人攻击

    千次阅读 2020-06-09 21:37:37
    ... 第一阶段 认证站点 ...客户端通过数字证书验证所访问的站点是真实的目标站点。 第二阶段 协商密钥 ...客户端与站点服务器协商此次...中间人攻击的几种形式 直接抓取报文获得明文信息 非法中间加密代理,窃取明文信息
  • SSL中间人攻击原理与防范,感兴趣的自己看
  • 什么是中间人攻击

    2021-09-07 15:49:04
    中间人攻击(通常缩写为MitM或MiM)是一种会话劫持网络攻击。黑客拦截数字共享的信息,通常是作为窃听者或冒充他人。这种类型的攻击非常危险,因为它可能会导致一些风险,如信息...如何防范中间人攻击? 什么是中间
  • 中间人攻击”的具体过程如下: 过程原理: 本地请求被劫持(如DNS劫持等),所有请求均发送到中间人的服务器 中间人服务器返回中间人自己的证书 客户端创建随机数,通过中间人证书的公钥对随机数加密后传送给中间...
  • 关于RSA中间人攻击

    千次阅读 2018-09-22 09:17:43
    中间人攻击的方法不能破译RSA,但却是一种针对机密性的有效攻击。 所谓中间人攻击,就是主动攻击者混入发送者和接收者中间,对发送者伪装成接收者,对接收者伪装成发送者的攻击方式。 二 攻击过程 场景:发送者...
  • 清晰图解https如何防范中间人攻击 https://blog.csdn.net/oZhuZhiYuan/article/details/106650944 中间人可以获取站点的证书,但不能获取站点的私钥,所以无法与客户端进行密钥协商。但中间人也不是没有办法,既然...
  • 中间人劫持攻击

    2020-11-02 22:40:19
    常见的HTTPS中间人攻击,首先需要结合ARP、DNS欺骗等技术,来对会话进行拦截, 1、SSL证书欺骗攻击 此类攻击较为简单常见。首先通过ARP欺骗、DNS劫持甚至网关劫持等等,将客户端的访问重定向到攻击者的机器,让...
  • 针对SSL的中间人攻击演示和防范

    千次阅读 2016-12-06 22:10:59
    1 中间人攻击概述 中间人攻击(man-in-the-Middle Attack, MITM)是一种由来已久的网络入侵手段,并且在今天仍然有着广泛的发展空间,如SMB会话劫持、DNS欺骗等攻击都是典型的MITM攻击。简而言之,所谓的MITM...
  • HTTPS怎么避免中间人攻击

    千次阅读 2020-09-30 12:30:05
    1.3 防止中间人攻击 这个时候可能就有人想到了,既然内容是明文那我使用对称加密的方式将报文加密这样中间人不就看不到明文了吗,于是如下改造: 双方约定加密方式 使用 AES 加密报文 这样看似中间人获取不到明文...
  • 1. 什么中间人攻击 中间人攻击(Man-in-the-MiddleAttack,简称“MITM攻击”):是指攻击者与通讯的两端分别创建独立的联系,并交换其所收到的数据,使通讯的两端认为他们正在通过一个私密的连接与对方直接对话,但...
  • 中间人攻击以及预防

    2021-03-22 10:22:14
    1. 中间人攻击 中间人攻击(Man-in-the-Middle Attack, MITM)是一种由来已久的网络入侵手段,并且在今天仍然有着广泛的发展空间,如SMB会话劫持、DNS欺骗等攻击都是典型的MITM攻击。当未授权的实体将自己置于两个...
  • 如何防范XSS攻击?什么是CSP? XSS简单来说,就是攻击者想尽一切办法可以执行的代码注入到网页中。 XSS可以分为多种类型,但是总体上分为两类:持久型和非持久型。 持久型也就是攻击的代码被服务端写入数据库中,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 7,682
精华内容 3,072
关键字:

中间人攻击如何防范