在OpenSSL握手后查找SSL版本

时间:2016-10-15 21:28:11

标签: ssl encryption openssl pyopenssl

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

示例:我通过了一个版本: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

2 个答案:

答案 0 :(得分: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));
...

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

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尝试此sslscan rbsec/sslscan 。 GitHub是一个积极维护,似乎更新。

  

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

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

try-and-fallback方法是RFC 7504, TLS Fallback Signaling Cipher Suite Value (SCSV) for Preventing Protocol Downgrade Attacks的原因。这是一个来自浏览器人群的可怕的乐队助手。例如,请参阅Last Call: (TLS Fallback Signaling Cipher Suite Value (SCSV) for Preventing Protocol Downgrade Attacks) to Proposed Standard

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

答案 1 :(得分:1)

  

我想检查握手时的版本

检查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连接。