修改openssl源码控制ssl握手过程

上篇文章 结尾说道使用openssl s_client命令无控制握手过程,本篇将使用修改源码方式控制ssl握手过程

说明:本篇文章继续上篇文章的openssl环境进行

握手过程

cd /data/angelotong/openssl/openssl-master/apps
time ./openssl s_client -debug -connect 14.152.86.41:443 -showcerts -prexit -servername appdlssl.dbankcdn.com -state -tls1_2>/dev/null

可以看到ssl具体握手过程:

image.png

源码分析

打开s_client.c,进入s_client_main函数:

image.png

从890~2975行,初始化环境,并根据./openssl s_client传入的参数 设置握手信息。

1903行,SSL_CTX_set_info_callback(ctx, apps_ssl_info_callback);

此处设置握手时每个步骤都会执行的回调函数,参见文档,也就是说每个握手执行后,都会调用这个函数。

image.png
image.png

从2975行开始,是一个for (;;)状态机,执行握手,数据传输时的状态转换。

下面不远处,2915行,真正开始SSL握手,文中指定了握手协议使用TLSv1.2。

image.png

源码修改

上面说到回调函数apps_ssl_info_callback,我们可以在这个回调函数里控制ssl握手过程,如client接收到server hello之后,执行sleep,探测服务端握手超时时间:

vim apps/s_cb.c
image.png

apps_ssl_info_callback功能很简单,调用SSL_state_string_long(s)来得到当前握手的步骤,包括:

SSL_connect:before SSL initialization
SSL_connect:SSLv3/TLS write client hello
SSL_connect:SSLv3/TLS write client hello
SSL_connect:SSLv3/TLS read server hello
...
SSL_connect:SSLv3/TLS read server certificate
SSL_connect:SSLv3/TLS read server key exchange
SSL_connect:SSLv3/TLS read server done
SSL_connect:SSLv3/TLS write client key exchange
SSL_connect:SSLv3/TLS write change cipher spec
SSL_connect:SSLv3/TLS write finished
SSL_connect:SSLv3/TLS write finished
SSL_connect:SSLv3/TLS read server session ticket
SSL_connect:SSLv3/TLS read change cipher spec
SSL_connect:SSLv3/TLS read finished

修改apps_ssl_info_callback函数,加入:

    if(strcmp(SSL_state_string_long(s), "SSLv3/TLS write client key exchange") == 0){
        sleep(59);
    }

这里的sleep(59)可以让握手过程中client接收到server hello之后,等待一段时间再向server发送write client key exchange :

image.png

重新编译

保存上面修改,重新编译:

由于我们之前执行过config,并且不需要安装,所以仅执行make就可以:

cd /data/angelotong/openssl/openssl-master
make -j 48

gdb调试

开始调试

cd apps
gdb ./openssl
run s_client -debug -connect 14.152.86.41:443 -showcerts -prexit -servername appdlssl.dbankcdn.com -state -tls1_2>/dev/null

可以看到客户端收到server hello后,59s后才执行client key exchange

image.png

可以看到,server等待59s后收到client key exchange操作,仍可以继续进行sll握手

修改sleep(59)为sleep(61),再次执行,发现server返回ssl握手失败

image.png

结论:server端握手超时时间为60s。

抓包分析

在我们上面设置sleep(59)前,开始抓包:

tcpdump -i eth0 host 14.152.86.41 -w baidu.pcap

抓包继续,将sleep时间设置为61,重新编译运行。

使用wireshark打开刚刚抓的包,第一次sleep(59)时握手成功:

image.png

第二次sleep(61),握手失败,再次验证了server端握手超时时间为60s的结论。

image.png

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券