SNI生效条件 - 补充nginx-host绕过实例复现中SNI绕过的先决条件

news/2024/4/27 15:45:12/文章来源:https://blog.csdn.net/qq_55316925/article/details/128988215

文章目录

  • 1.前置环境搭建
  • 2.测试SNI生效条件(时间)
  • 3. 证书对SNI的影响
    • 3.1 双方使用同一个证书:
    • 3.2 双方使用不同的证书与私钥
  • 4. 端口号区分测试
    • 4.1 端口号区分,证书区分:
    • 4.2 端口号区分,证书不区分:
  • 5.总结SNI运行机制
  • 6. SNI机制绕过host头探究
    • 6.1 端口相同的SSL虚拟主机
    • 6.2 端口不同的SSL虚拟主机
    • 6.3 小结

在先前的文章中,我们通过一些列分析,在一个LNMP架构下的站群系统中挖掘出了基于host字段进行注入的SQL注入漏洞。在解决HOST绕过问题时,我们给出了三种解决方案。冒号分割、双写host字段、利用SNI机制。

经过测试,冒号分割是可行的,双写host字段被高版本的nginx返回了400,无法使用。最后一个则是SNI机制。

SNI(Server Name Indication)定义在RFC 4366,是一项用于改善SSL/TLS的技术,在SSLv3/TLSv1中被启用。它允许客户端在发起SSL握手请求时(具体说来,是客户端发出SSL请求中的ClientHello阶段),就提交请求的Host信息,使得服务器能够切换到正确的域并返回相应的证书。

我们知道证书机制是为了加密通信流量,防止第三方窃听而存在的。而同一台主机配置多个网站时,会用到虚拟主机技术,每一个网站对应的证书也是不一样的。那么在用户与服务器第一次建立连接时,将使用哪一个证书进行通信呢?最初就是用的默认证书,而之后为了适应这样的需求,RFC推出了SNI机制,在TLS协议初期,即客户端发送自己的client hello报文时,就将host字段加入进去,以供服务器区分目的网站。选到对应的证书。

随后,证书就为客户端和服务器加密了通信内容,也就是说。后续的通信一旦发现是用某一个证书解密的。不需要再做判断,可以直接将数据报文交给对应的网站即可。也就是在建立了稳定的https通信之后,服务器中间件将不需要对host头进行解析,直接通过证书实现定向解析。

那么,我们会产生一系列思考。

第一:SNI机制会一直触发吗? 单https虚拟主机 —>多https虚拟主机

第二:控制证书为变量,测试证书对于流量解析的影响?—>证明是用证书私钥做流量区分的

第三:控制端口号为变量,测试端口号对于流量解析的影响?

1.前置环境搭建

既然如此我们就需要准备两套完整的nginx解析https虚拟主机进行测试。以及个服务器证书与私钥。

#1.双证书准备
#1.创建证书目录
[root@blackstone nginx]# mkdir certificate
[root@blackstone nginx]# cd certificate/#2.生成私钥 - 要求你输入这个key文件的密码。给nginx使用。每次reload nginx配置时候都要验证这个PAM密码。
openssl genrsa -des3 -out ssl.key 4096
openssl genrsa -des3 -out sslb.key 4096
#3.生成CA证书文件 -- 此处为了区分证书,我们只好开两份CA证书相当于两个机构的认证
openssl req -new -key ssl.key -out aaa.csr
openssl req -new -key sslb.key -out bbb.csr#4.利用CA证书签名生成服务器身份证书 - 证书签发有效期365天
openssl x509 -req -days 365 -in aaa.csr -signkey ssl.key -out aaa.crt
openssl x509 -req -days 365 -in bbb.csr -signkey sslb.key -out bbb.crt
#5.检查生成情况 - 此时包含我们自己的私钥,自己的证书.crt文件,以及csrCA证书
[root@blackstone certificate]# ll
total 32
-rw-r--r-- 1 root root 1895 Feb 10 23:34 aaa.crt
-rw-r--r-- 1 root root 1724 Feb 10 23:32 aaa.csr
-rw-r--r-- 1 root root 1907 Feb 11 00:52 bbb.crt
-rw-r--r-- 1 root root 1728 Feb 11 00:51 bbb.csr
-rw-r--r-- 1 root root 3311 Feb 11 00:50 sslb.key
-rw-r--r-- 1 root root 3311 Jan 11 21:24 ssl.key

网页部署

[root@blackstone www]# mkdir -p /var/www/aaa
[root@blackstone www]# mkdir -p /var/www/bbb
[root@blackstone www]# echo 'this is aaa.com' > /var/www/aaa/index.html
[root@blackstone www]# echo 'this is bbb.com' > /var/www/bbb/index.html

记得修改本机的host文件:C:\Windows\System32\drivers\etc

192.168.2.169 www.bbb.com 
192.168.2.169 www.aaa.com

2.测试SNI生效条件(时间)

1.单个https虚拟主机

 server {listen       443 ssl;server_name  www.aaa.com;ssl_certificate      /usr/local/nginx/certificate/aaa.crt;ssl_certificate_key  /usr/local/nginx/certificate/ssl.key;ssl_session_cache    shared:SSL:1m;ssl_session_timeout  5m;ssl_ciphers  HIGH:!aNULL:!MD5;ssl_prefer_server_ciphers  on;location / {root   /var/www/aaa;index  index.html index.htm;}}

重启nginx,使用浏览器访问,进行抓包分析。

#后面的所有重启都建议直接把nginx关闭,彻底重启
[root@blackstone www]# /usr/local/nginx/sbin/nginx -s quit
Enter PEM pass phrase:
[root@blackstone www]# /usr/local/nginx/sbin/nginx
Enter PEM pass phrase:

可以看到,确实在client hello报文内部,有这个主机名被发送给服务器了。
在这里插入图片描述
故,发送主机名是高版本浏览器的自发行为,不需要任何激发条件。浏览器会主动发送server name 以支持SNI机制。即SNI机制无需配置,只要服务器支持,就可以使用。

3. 证书对SNI的影响

3.1 双方使用同一个证书:

    server {listen       443 ssl;server_name  www.aaa.com;ssl_certificate      /usr/local/nginx/certificate/aaa.crt;ssl_certificate_key  /usr/local/nginx/certificate/ssl.key;ssl_session_cache    shared:SSL:1m;ssl_session_timeout  5m;ssl_ciphers  HIGH:!aNULL:!MD5;ssl_prefer_server_ciphers  on;location / {root   /var/www/aaa;index  index.html index.htm;}}server {listen       443 ssl;server_name  www.bbb.com;ssl_certificate      /usr/local/nginx/certificate/aaa.crt;ssl_certificate_key  /usr/local/nginx/certificate/ssl.key;ssl_session_cache    shared:SSL:1m;ssl_session_timeout  5m;ssl_ciphers  HIGH:!aNULL:!MD5;ssl_prefer_server_ciphers  on;location / {root   /var/www/bbb;index  index.html index.htm;}}

测试访问情况:

在这里插入图片描述
在这里插入图片描述
可以实现分流。

3.2 双方使用不同的证书与私钥

这时,我们尝试进行证书与私钥的区分配置:

server {listen       443 ssl;server_name  www.aaa.com;ssl_certificate      /usr/local/nginx/certificate/aaa.crt;ssl_certificate_key  /usr/local/nginx/certificate/ssl.key;ssl_session_cache    shared:SSL:1m;ssl_session_timeout  5m;ssl_ciphers  HIGH:!aNULL:!MD5;ssl_prefer_server_ciphers  on;location / {root   /var/www/aaa;index  index.html index.htm;}}server {listen       443 ssl;server_name  www.bbb.com;ssl_certificate      /usr/local/nginx/certificate/bbb.crt;ssl_certificate_key  /usr/local/nginx/certificate/sslb.key;ssl_session_cache    shared:SSL:1m;ssl_session_timeout  5m;ssl_ciphers  HIGH:!aNULL:!MD5;ssl_prefer_server_ciphers  on;location / {root   /var/www/bbb;index  index.html index.htm;}}

再次测试访问效果:

[root@blackstone certificate]# /usr/local/nginx/sbin/nginx -s reload
Enter PEM pass phrase:
Enter PEM pass phrase:

在这里插入图片描述
在这里插入图片描述
各自可以收到各自的证书,建立各自的通信。

4. 端口号区分测试

4.1 端口号区分,证书区分:

server {listen       8443 ssl;server_name  www.bbb.com;ssl_certificate      /usr/local/nginx/certificate/bbb.crt;ssl_certificate_key  /usr/local/nginx/certificate/sslb.key;ssl_session_cache    shared:SSL:1m;ssl_session_timeout  5m;ssl_ciphers  HIGH:!aNULL:!MD5;ssl_prefer_server_ciphers  on;location / {root   /var/www/bbb;index  index.html index.htm;}}server {listen       8444 ssl;server_name  www.aaa.com;ssl_certificate      /usr/local/nginx/certificate/aaa.crt;ssl_certificate_key  /usr/local/nginx/certificate/ssl.key;ssl_session_cache    shared:SSL:1m;ssl_session_timeout  5m;ssl_ciphers  HIGH:!aNULL:!MD5;ssl_prefer_server_ciphers  on;location / {root   /var/www/aaa;index  index.html index.htm;}

测试效果:

[root@blackstone certificate]# vim ../conf/nginx.conf
[root@blackstone certificate]# /usr/local/nginx/sbin/nginx -s reload
Enter PEM pass phrase:
Enter PEM pass phrase:

在这里插入图片描述

在这里插入图片描述
可以看到,证书已经分别发送给了两个虚拟主机客户端。实现流量区分

4.2 端口号区分,证书不区分:

server {listen       8443 ssl;server_name  www.bbb.com;ssl_certificate      /usr/local/nginx/certificate/aaa.crt;ssl_certificate_key  /usr/local/nginx/certificate/ssl.key;ssl_session_cache    shared:SSL:1m;ssl_session_timeout  5m;ssl_ciphers  HIGH:!aNULL:!MD5;ssl_prefer_server_ciphers  on;location / {root   /var/www/bbb;index  index.html index.htm;}}server {listen       8444 ssl;server_name  www.aaa.com;ssl_certificate      /usr/local/nginx/certificate/aaa.crt;ssl_certificate_key  /usr/local/nginx/certificate/ssl.key;ssl_session_cache    shared:SSL:1m;ssl_session_timeout  5m;ssl_ciphers  HIGH:!aNULL:!MD5;ssl_prefer_server_ciphers  on;location / {root   /var/www/aaa;index  index.html index.htm;}

中途效果不明显大家可以重启nginx服务,因为服务一直开着可能会有缓存文件。

[root@blackstone nginx]# /usr/local/nginx/sbin/nginx -s quit
Enter PEM pass phrase:
Enter PEM pass phrase:
[root@blackstone nginx]# /usr/local/nginx/sbin/nginx
Enter PEM pass phrase:
Enter PEM pass phrase:

再次测试查看效果:

在这里插入图片描述
在这里插入图片描述
服务端两次传递同一个证书,实现通信。实现完整的虚拟主机分流访问。

5.总结SNI运行机制

通过以上种种测试,我们发现,无论使相同端口号,证书不同。达到证书区分传递的效果。还是证书不同,端口号也不同实现测试环境下的虚拟主机配置。SNI始终都可以准确的找到目标主机,即使是在我们的证书相同的情况下。

其实这一点也不费解,我们回顾一下之前学过的TSL通信过程:

第一次握手:客户端发送协议版本号,随机数,支持套件
第二次握手:服务端发送随机数,版本号,确认支持套件。同时发送服务端证书表明自己的身份(相当于发了个身份证过去)。
第三次握手:客户端收到证书,进行身份验证,验证完毕后利用从证书内部取出的公钥加密传输一串新的随机数pre_master给服务端。此时,客户端,服务端都共享了三个随机数,客户端随机数、服务端随机数、pre_master。于是根据三个随机数双方可以计算出共同的加密对称密钥进行通信。生成完会话密钥后,客户端发一个「Change Cipher Spec」,告诉服务端开始使用加密方式发送消息。再发一个「Encrypted Handshake Message(Finishd)」消息,把之前所有发送的数据做个摘要,再用会话密钥(master secret)加密一下,让服务器做个验证,验证加密通信是否可用和之前握手信息是否有被中途篡改过。
第四次握手:服务器也是同样的操作,发「Change Cipher Spec」和「Encrypted Handshake Message」消息,如果双方都验证加密和解密没问题,那么握手正式完成。
最后就是用会话密钥进行双方的通信

也就是说,客户端服务器通信过程中的密钥是新协商出来的。具有唯一标识性的这样一个密钥。那么通过SNI机制在第一次客户端发送client hello包时就发送的server name 确定到底访问的哪一个虚拟主机。后面的通信,自然可以通过解密密钥寻找到对应的虚拟主机。以此完成完整的SNI机制。

实现了可以为不同的虚拟主机配置这个不同的服务器证书。

6. SNI机制绕过host头探究

这样一个绕过出现的环境就很明显了,必须是配置了SSL的nginx服务器。

之前有同学提出过疑问,认为仅仅配置一个443端口的虚拟SSL主机。难以区分到底是由于我们的请求被转移到了默认的443端口处理虚拟主机上,还是说我们成功绕过了这样一个检测机制呢?接着3.2的环境,我们对其进行进一步的测试:

6.1 端口相同的SSL虚拟主机

#注意那个server在上面,在配置文件里就默认的是默认虚拟主机server {listen       443 ssl;server_name  www.bbb.com;ssl_certificate      /usr/local/nginx/certificate/aaa.crt;ssl_certificate_key  /usr/local/nginx/certificate/ssl.key;ssl_session_cache    shared:SSL:1m;ssl_session_timeout  5m;ssl_ciphers  HIGH:!aNULL:!MD5;ssl_prefer_server_ciphers  on;location / {root   /var/www/bbb;index  index.html index.htm;}}server {listen       443 ssl;server_name  www.aaa.com;ssl_certificate      /usr/local/nginx/certificate/aaa.crt;ssl_certificate_key  /usr/local/nginx/certificate/ssl.key;ssl_session_cache    shared:SSL:1m;ssl_session_timeout  5m;ssl_ciphers  HIGH:!aNULL:!MD5;ssl_prefer_server_ciphers  on;location / {root   /var/www/aaa;index  index.html index.htm;}}

在这里插入图片描述
相同端口号,不同的证书条件下,修改了host文件后跳转到了默认的bbb.com虚拟主机上。绕过失效

6.2 端口不同的SSL虚拟主机

 server {listen       443 ssl;server_name  www.bbb.com;ssl_certificate      /usr/local/nginx/certificate/bbb.crt;ssl_certificate_key  /usr/local/nginx/certificate/sslb.key;ssl_session_cache    shared:SSL:1m;ssl_session_timeout  5m;ssl_ciphers  HIGH:!aNULL:!MD5;ssl_prefer_server_ciphers  on;location / {root   /var/www/bbb;index  index.html index.htm;}}server {listen       8443 ssl;server_name  www.aaa.com;ssl_certificate      /usr/local/nginx/certificate/aaa.crt;ssl_certificate_key  /usr/local/nginx/certificate/ssl.key;ssl_session_cache    shared:SSL:1m;ssl_session_timeout  5m;ssl_ciphers  HIGH:!aNULL:!MD5;ssl_prefer_server_ciphers  on;location / {root   /var/www/aaa;index  index.html index.htm;}}

访问效果:
在这里插入图片描述
在这里插入图片描述
再次进行测试:
在这里插入图片描述
这次没有在跳默认了,说明可行。

6.3 小结

SNI绕过host生效的条件其实就是单一端口下仅仅绑定一台SSL虚拟主机。因为我们在6.1中看到,端口相同时同一服务器绑定多台SSL主机时,所有的请求会交给默认页面。如果漏洞点在默认页面就好说,如果不在。就无法使用SNI进行绕过了。

但同时,如果服务器是单一的配置了一个443端口的ssl虚拟主机,那么将可以进行SNI机制的HOST头绕过。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_256866.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot+Vue实现智能物流管理系统

文末获取源码 开发语言:Java 框架:springboot JDK版本:JDK1.8 服务器:tomcat7 数据库:mysql 5.7/8.0 数据库工具:Navicat11 开发软件:eclipse/myeclipse/idea Maven包:Maven3.3.9 浏…

线程和QObjects

QObject的可重入性: QThread继承了QObject,它发出信号以指示线程开始或完成执行,并提供一些插槽。 QObjects可以在多个线程中使用发出调用其他线程中槽的信号,并将事件发布到在其他线程中“活动”的对象。这是可能的&#xff0…

一个测试人员,在现阶段的环境下如何在测试行业发展和自我价值。

前言周末和几个测试圈子里的大佬饭局上聊了一些职场和测试职业发展相关的话题,我将聊天的内容做了整理和阐述。。朋友圈有测试同学对这篇文章提了比较深刻的建议,下面是他的评价和建议:评价:据说是大佬饭桌总结,有两点…

ThingsBoard-实现定时任务调度器批量RPC

1、概述 ThingsBoard-CE版是不支持调度器的,只有PE版才支持,但是系统中很多时候需要使用调度器来实现功能,例如:定时给设备下发rpc查询数据,我们如何来实现呢?下面我将教你使用巧妙的方法来实现。 2、使用什么实现 我们可以使用规则链提供的一个节点来实现,这个节点可…

【手写 Vuex 源码】第七篇 - Vuex 的模块安装

一,前言 上一篇,主要介绍了 Vuex 模块收集的实现,主要涉及以下几个点: Vuex 模块的概念;Vuex 模块和命名空间的使用;Vuex 模块收集的实现-构建“模块树”; 本篇,继续介绍 Vuex 模…

Elasticsearch7.8.0版本进阶——分布式集群(应对故障)

目录一、Elasticsearch集群的安装1.1、Elasticsearch集群的安装(win10环境)1.2、Elasticsearch集群的安装(linux环境)二、应对故障(win10环境集群演示)2.1、启动集群(三个节点)2.2、…

利用git reflog 命令来查看历史提交记录,并使用提交记录恢复已经被删除掉的分支

一.问题描述 当我们在操作中手误删除了某个分支,那该分支中提交的内容也没有了,我们可以利用git reflog这个命令来查看历史提交的记录从而恢复被删除的分支和提交的内容 二.模拟问题 1.创建git仓库,并提交一个文件 [rootcentos7-temp /da…

TrueNas篇-trueNas Scale安装

安装TrueNAS Scale 在尝试trueNas core时发下可以成功安装,但是一直无法成功启动,而且国内对我遇见的错误几乎没有案例,所以舍弃掉了,而且trueNas core是基于Linux的,对Linux的生态好了很多,还可以可以在t…

最强大的人工智能chatGPT不会还有人没用过吧,再不用就out了

🔗 运行环境:chatGPT 🚩 撰写作者:左手の明天 🥇 精选专栏:《python》 🔥 推荐专栏:《算法研究》 #### 防伪水印——左手の明天 #### 💗 大家好🤗&#x1f9…

Win11下Linux子系统迁移方法及报错解决

Win11 将Linux子系统从C盘迁移到其他盘Win11下Linux子系统迁移方法及报错解决1、下载LxRunOffline2、ERROR:directory is not empty 报错解决参考链接Win11下Linux子系统迁移方法及报错解决 C盘满了,Ubuntu子系统占了100多G怎么办?直接将子系…

一文讲清chatGPT的发展历程、能力来源和复现它的关键之处

1. ChatGPT是什么 chatGPT是什么?这可能是最近被问的最多的一个。 大家第一反应这应该是GPT系列的一个最新模型,普通大众可能更愿意把它看做是一个人工智能。实际上,它其实就是一个基于大规模语言模型的对话系统产品。官网对它定义十分的明…

【三维点云】01-激光雷达原理与应用

文章目录内容概要1 激光雷达原理1.1 什么是激光雷达?1.2 激光雷达原理1.3 激光雷达分类三角法TOF法脉冲间隔测量法幅度调制的相位测量法相干法激光雷达用途2 激光雷达安装、标定与同步2.1 激光雷达安装方式考虑因素2.2 激光雷达点云用途2.3 数据融合多激光雷达数据融…

【蓝桥杯单片机】Keil5中怎么添加STC头文件;从烧录软件中添加显示添加成功后新建工程时依旧找不到

蓝桥杯单片机的芯片型号:IAP15F2K61S2 添加头文件:STC15F2K60S2.H 【1】如何通过烧录软件添加STC头文件: 从ATC-ISP的Keil仿真设置中添加(同时自动下载仿真驱动)仔细阅读添加说明 KEIL5添加STC芯片库_Initdev的博客-…

【寒假day4】leetcode刷题

🌈一、选择题❤1.下列哪一个是析构函数的特征( )。A: 析构函数定义只能在类体内 B: 一个类中只能定义一个析构函数 C: 析构函数名与类名相同 D: 析构函数可以有一个或多个参数答案:B答案解析:析构函数是构造函…

C语言(文件输入输出操作)

目录 一.文件 1.文件概念 2.文本模式和二进制模式 (1)模式结尾映射 (2)存储精度 3.I/O级别 一.文件 1.文件概念 文件:在磁盘或固态硬盘上一段已命名的存储区。对于C来说,文件就是一系列连续的字节,每个字节都能被单独读取(在计算机当…

.Net Core对于`RabbitMQ`封装分布式事件总线

首先我们需要了解到分布式事件总线是什么;分布式事件总线是一种在分布式系统中提供事件通知、订阅和发布机制的技术。它允许多个组件或微服务之间的协作和通信,而无需直接耦合或了解彼此的实现细节。通过事件总线,组件或微服务可以通过发布或…

大家心心念念的RocketMQ5.x入门手册来喽

1、前言 为了更好的拥抱云原生,RocketMQ5.x架构进行了大的重构,提出了存储与计算分离的设计架构,架构设计图如下所示: RocketMQ5.x提供了一套非常建议的消息发送、消费API,并统一放在Apache顶级开源项目rocketmq-clie…

TC3xx FlexRay™ 协议控制器 (E-Ray)-01

1 FlexRay™ 协议控制器 (E-Ray) E-Ray IP 模块根据为汽车应用开发的 FlexRay™ 协议规范 v2.1 执行通信【performs communication according to the FlexRay™ 1) protocol specification v2.1】。使用最大指定时钟,比特率可以编程为高达 10 Mbit/s 的值。连接到物…

就现在!为元宇宙和Web3对互联网的改造做准备!

欢迎来到Hubbleverse 🌍 关注我们 关注宇宙新鲜事 📌 预计阅读时长:8分钟 本文仅代表作者个人观点,不代表平台意见,不构成投资建议。 如今,互联网是各种不同的网站、应用程序和平台的集合。由于彼此分离…

STM32单片机GSM短信自动存取快递柜

实践制作DIY- GC0104-自动存取快递柜 一、功能说明: 基于STM32单片机设计-自动存取快递柜 二、功能介绍: STM32F103C系列最小系统板0.96寸OLED显示器DY-SV17F串口语音播报模块4*4矩阵键盘GSM短信模块4路舵机(模拟4个柜子) ***…