识别ssl / tls python套接字服务器的数据包交换类型

时间:2018-05-26 20:30:17

标签: python sockets ssl tls1.2

目前,我正在尝试对密钥交换和加密如何为程序进行逆向工程。我主要用线鲨来弄清楚数据包是如何被加密的。我发现他们使用的是ECDHE-RSA-AES128-GCM-SHA256和TLS1.2

这是我现在所拥有的。

import socket, ssl

tcpSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcpSocket.bind(('', 443))
tcpSocket.listen(1)

while True:
    newsocket, fromaddr = tcpSocket.accept()
    newsocket = ssl.wrap_socket(newsocket,
                            server_side=True,
                            do_handshake_on_connect=True,
                            certfile="cert.pem",
                            ssl_version=ssl.PROTOCOL_TLSv1_2,
                            ciphers="ECDHE-RSA-AES128-GCM-SHA256")
    try:
        #Later add stuff
        pass
    finally:
        newsocket.shutdown(socket.SHUT_RDWR)
        newsocket.close()

我试图使用简单的图片here来想象它是如何工作的。 我使用了我看到的here

的wireshark数据包

目前使用此代码,服务器永远不会回复客户端密钥交换,而只是崩溃导致https://hastebin.com/wiqojapule.sql

所以我试图问的主要问题是为什么python程序永远不会确认客户端然后发送服务器问候。目前它只是发回客户端Hello。

此外,这是我的python套接字的线鲨和程序:here

1 个答案:

答案 0 :(得分:1)

比较两个pcap文件(使用真实服务器和测试服务器),有两点突出:

  • 在工作案例(真实服务器)中,客户端正在发送带有目标主机名的server_name扩展名(SNI),服务器将返回由公共CA签名的证书。
  • 在失败的情况下(测试服务器),客户端没有发送server_name扩展名,服务器只返回自签名证书。然后客户端关闭连接,即握手未完成。

针对测试服务器丢失的SNI扩展可能是由于将目标作为IP地址而不是主机名。这可能也不是问题所在。

很可能是客户端根本不喜欢服务器发送的自签名证书,因此关闭了连接。一个更好的行为客户端可能会在关闭之前首先发送一个TLS警报unknown CA,但是TLS堆栈不发送这些警报而只是关闭连接并不罕见。

  

...我正在尝试对密钥交换和加密如何为程序进行反向工程

这里的逆向工程似乎没什么特别之处。客户端似乎使用标准中指定的TLS,可能是通过使用许多可用的TLS堆栈中的一些而不是通过实现它自己的。与OP的假设相反,只使用特定密码,客户端实际上提供了几个密码(ClientHello中提供了19个密码),服务器可以选择其中任何一个。

实际上预计会出现关于自签名证书的行为:正确的客户端不应接受与不受信任证书的服务器的连接。