【问题标题】:Find SSL Version after Handshake in OpenSSL在 OpenSSL 中握手后查找 SSL 版本
【发布时间】:2017-02-25 03:21:03
【问题描述】:

我想找出目标支持的协议,但问题是它们有很多不支持特定版本的网站,但是当我执行握手时它是成功的,因为目标超过了我提供和执行的版本在支持的版本上握手 [仅在 1 个网站上发生过]

示例:我传递了一个版本:TLSVersion.TLS_1_2,但握手是使用 TLSv1_0 执行的,因为它不支持 TLSVersion.TLS_1_2

由于上述问题,我想检查握手版本,我不想使用 scapy.ssl_tls

version = [SSL.SSLv23_METHOD,
            SSL.TLSv1_METHOD,
            SSL.TLSv1_1_METHOD,
            SSL.TLSv1_2_METHOD]
context = OpenSSL.SSL.Context(version)
soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
soc.settimeout(CONNECTION_TIMEOUT)
connection = OpenSSL.SSL.Connection(context,soc)
connection.connect((host,port))
connection.do_handshake() 
#wants to check version here

【问题讨论】:

    标签: ssl encryption openssl pyopenssl


    【解决方案1】:

    在 OpenSSL 中握手后查找 SSL 版本...

    如果我正确解析了您想要的内容...您想要openssl s_client 打印的协议版本:

    $ openssl version
    OpenSSL 1.1.0b  26 Sep 2016
    
    $ openssl s_client -connect www.google.com:443 -servername www.google.com
    CONNECTED(00000005)
    depth=2 C = US, O = GeoTrust Inc., CN = GeoTrust Global CA
    verify error:num=20:unable to get local issuer certificate
    Server did acknowledge servername extension.
    ---
    ...
    ---
    New, TLSv1.2, Cipher is ECDHE-RSA-CHACHA20-POLY1305
    Server public key is 2048 bit
    Secure Renegotiation IS supported
    No ALPN negotiated
    SSL-Session:
        Protocol  : TLSv1.2
    ...
    

    “New, TLSv1.2” 的第一条消息告诉您有关密码的信息。也就是说,ECDHE-RSA-CHACHA20-POLY1305 是什么时候第一次到达 TLS 的。在ECDHE-RSA-CHACHA20-POLY1305 的情况下,密码套件首次出现在 TLS 1.2 中。

    s_client 的源代码位于<openssl src>/apps/s_client.c。 OpenSSL 1.0.2 中负责的代码在第 2210 行左右:

    /* line 2210 */
    c = SSL_get_current_cipher(s);
    BIO_printf(bio, "%s, Cipher is %s\n",
               SSL_CIPHER_get_version(c), SSL_CIPHER_get_name(c));
    ...
    

    “Protocol: TLSv1.2”的第二条消息告诉你在密钥交换和后续密码选择和批量传输过程中使用的协议版本。

    OpenSSL 1.0.2 中负责的代码是第 105 行附近的 <openssl src>/ssl/ssl_txt.c

    /* line 105 */
    int SSL_SESSION_print(BIO *bp, const SSL_SESSION *x)
    {
        unsigned int i;
        const char *s;
    
        if (x == NULL)
            goto err;
        if (BIO_puts(bp, "SSL-Session:\n") <= 0)
            goto err;
        if (x->ssl_version == SSL2_VERSION)
            s = "SSLv2";
        else if (x->ssl_version == SSL3_VERSION)
            s = "SSLv3";
        else if (x->ssl_version == TLS1_2_VERSION)
            s = "TLSv1.2";
        else if (x->ssl_version == TLS1_1_VERSION)
            s = "TLSv1.1";
        else if (x->ssl_version == TLS1_VERSION)
            s = "TLSv1";
        else if (x->ssl_version == DTLS1_VERSION)
            s = "DTLSv1";
        else if (x->ssl_version == DTLS1_2_VERSION)
            s = "DTLSv1.2";
        else if (x->ssl_version == DTLS1_BAD_VER)
            s = "DTLSv1-bad";
        else
            s = "unknown";
        if (BIO_printf(bp, "    Protocol  : %s\n", s) <= 0)
            goto err;
    
        ...
    }
    

    我想找出目标支持的协议,但问题是它们有很多不支持特定版本的网站,但是当我执行握手时...

    这是一个不同的问题。您应该在 SSLScan - Fast SSL Scanner 上查看sslscan 的源代码,了解它是如何工作的。 Sourceforge 似乎被遗弃了。它缺少 SNI 和其他新功能,例如安全协商和 ALPN。

    你可以试试这个来自 GitHub 的 sslscanrbsec/sslscan。 GitHub 得到了积极维护,并且似乎更新了。


    示例:我传递了一个版本:TLSVersion.TLS_1_2,但握手是使用 TLSv1_0 执行的,因为它不支持 TLSVersion.TLS_1_2

    这不会发生。 TLS 仅指定一个协议版本。这个想法是你尝试 TLS 1.2。如果失败,那么您将退回到 TLS 1.1。如果失败,那么您将回退到 TLS 1.0。 广告无限

    try-and-fallback 方法是RFC 7504, TLS Fallback Signaling Cipher Suite Value (SCSV) for Preventing Protocol Downgrade Attacks 的原因。这是浏览器人群的一个糟糕的创可贴。例如,请参阅Last Call: <draft-ietf-tls-downgrade-scsv-03.txt> (TLS Fallback Signaling Cipher Suite Value (SCSV) for Preventing Protocol Downgrade Attacks) to Proposed Standard

    TLS 确实接受许多人认为的一系列协议版本。我们试图让它改变几次。例如,请参阅A new TLS version negotiation mechanism

    【讨论】:

    • 感谢您的见解!这值得更多的支持:-)
    【解决方案2】:

    我想在握手时检查版本

    在pyOpenSSL中检查客户端和服务器用于剩余会话的版本的相关函数是get_protocol_version_nameget_protocol_version

    connection.do_handshake()
    #wants to check version here
    print(connection.get_protocol_version_name())
    

    请注意,这些函数仅在 pyOpenSSL 0.16.0 之后可用

    请不要在创建上下文时指定 TLS 方法列表,但 only a single method 本质上指定了客户端支持的最小 TLS 版本。因此

    context = OpenSSL.SSL.Context(SSL.TLSv1_METHOD)
    

    允许客户端使用 TLS 1.0 及更高版本。如果您改为使用SSL.TLSv1_2_METHOD,客户端将被限制为 TLS 1.2 或更好,因此无法与仅支持 TLS 1.0 的服务器建立 SSL 连接。

    【讨论】:

    • 我的版本没有这个功能。 --python-openssl 已经是最新版本(0.15.1-2build1)
    • @hassan_anwer: 引用我自己的话:“这些功能仅在 pyOpenSSL 0.16.0 之后可用”。由于current version is 0.16.2 您的版本 0.15.1 显然不是最新的。虽然它可能是您的系统附带的最新版本,但这是另一回事。
    • @hassan_anwer:如果您的系统没有提供所需的 pyOpenSSL 版本并且您不知道如何安装它,您可以安装包含 pyOpenSSL 0.16 的 anaconda python。这可以与您现有的 python 分开安装。
    • 知道了,谢谢我使用这个 apt-get install libssl-dev 升级
    • sudo pip install --upgrade pyopenssl
    猜你喜欢
    • 2017-05-25
    • 2017-03-10
    • 2021-05-10
    • 1970-01-01
    • 1970-01-01
    • 2020-09-02
    • 1970-01-01
    • 2020-06-28
    • 1970-01-01
    相关资源
    最近更新 更多