解密https流量

解密https流量

要想解密https流量方法无非就两种

  1. 使用密钥解
  2. 使用中间人MITM去解

但由于我并没有去考虑如何用MITM去解密https流量,所以我只介绍我使用密钥解的总结,当然,我并不是通过了解了https的整个过程去自行代码实现的,只是通过别人实现好的模型去进行解密,以下分别使用wireshark和scapy去解密

获取密钥使用wireshark解密

客户端

如果你是客户端角度出发,那么需要获取到ssl/tls通信过程中的随机会话密钥,可以配置sslkeylogfile文件的环境变量,配置后会自动写入环境变量指定的文件中,详细网上自行搜,很多文章都有介绍如何写,也很简单

在配置好环境变量后,还需配置wireshark去进行使用,也自行到网上搜寻

以下方式访问https网站都会写入密钥

  1. openssl(待验证)

    • 可以使用openssl在linux命令行下生成

    • 使用python带的ssl库来进行生成,方法是使用ssl.create_default_context函数即可
      Python SSL操作手册

  2. 使用chrome和firefox

    实际上新版的firefox和chrome并不支持写入SSLKEY了,具体哪个版本支持需自行在网上搜索文章查看

  3. 使用curl执行也会写入

使用wireshark可以直接解密所有版本的ssl/tls流量,非常强大

服务端

在服务端要是想获取密钥需要进行一些配置,本方法只尝试过apache2和nginx

nginx
  1. 首先保证服务端具有写SSLKEY密钥功能
    先查看配置

    libssl-dev/focal-updates,now 1.1.1f-1ubuntu2.16 amd64 [installed]
    libssl1.1/focal-updates,now 1.1.1f-1ubuntu2.16 amd64 [installed]
    openssl/focal-updates,now 1.1.1f-1ubuntu2.16 amd64 [installed]
    

    确保有libssl的包以及openssl的包,如果直接安装不行,需要考虑吧换软件源或者在官方网站下载相应的包

    http://security.ubuntu.com/ubuntu/pool/main/o/openssl/

  2. 复制该链接源码sslkeylog.c,粘贴为C文件,编译:cc sslkeylog.c -shared -o libsslkeylog.so -fPIC -ldl,并将生成的so文件放于/usr/local/lib

  3. 配置nginx.service

    vim /lib/systemd/system/nginx.service
    

    或者使用命令systemctl edit nginx写入

    写入内容如下

    [Service]
    Environment=SSLKEYLOGFILE=/tmp/sslkey.log
    Environment=LD_PRELOAD=/usr/local/lib/libsslkeylog.so
    

    最好赋予sslkey.log其用户写入权限

  4. ./nginx/nginx.conf中添加以下:

    env LD_PRELOAD=/usr/local/lib/libsslkeylog.so;
    env SSLKEYLOGFILE=/tmp/sslkey.log;
    
  5. 重启nginx

    # systemctl daemon-reload
    # systemctl restart nginx
    

    最后使用外部curl https://xxx.xxx.xxx来进行访问,然后查看/tmp/sslkey.log是否有写入密钥
    如若不行,则使用以下命令查看是否有引入libsslkey.so文件,-p参数为nginx的进程号PID

    lsof -n -p 10313 |grep ssl
    

详细请看这篇

Extracting openssl pre-master secret from nginx

apache2

如果你使用的是apache,那么也需要配置,需要的话请看这篇文章

Extracting openssl pre-master secret from apache2

然后就可以使用wireshark去解了

获取密钥使用scapy解密

这个方式说实话有很大的弊端,虽然可以在代码层面解,但是对于https协议只支持tls1.2以下版本解,tls1.3并不支持,并且最离谱的是只能一次解一个包,真的大无语(而且这方法找了好久,真的无语)

  1. 先配置nginx只支持TLS1.2

    {
        server_name  xxx.xxx.com; 
        listen 443; 
        ssl on;
        access_log          /logs/nginx/xxx.xxx.com_access.log main;
        error_log           /logs/nginx/xxx.xxx.com_error.log;
        ssl_certificate     /opt/nginx/ssl/xxx.xxx.com.pem;   # 公钥证书
        ssl_certificate_key /opt/nginx/ssl/xxx.xxx.com.key;   # 私钥证书
        ssl_session_timeout 5m;                               # 客户端能够重用会话缓存中ssl参数的过期时间
        # 指定支持的协议,这里表示支持1、1.1和1.2, 如果只写1.2表示仅支持1.2.  注:OpenSSL版本要求 >= 1.0.1
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;                        
        # 加密套件,多个之间用冒号分隔,前有感叹号的表示必须废弃
        ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
        # 设置协商加密算法,优先使用服务端定义的加密套件
        ssl_prefer_server_ciphers on;                         
    }
    

    或者apache2

    vim /etc/apache2/sites-available/ssl.conf
    ## 添加
    SSLProtocol ALL -SSLv2 -SSLv3
    
  2. 在python安装scapy库,需要到github原作者处下载(不要使用pip install scapy

    git clone https://github.com/secdev/scapy.git
    

    进入scapy目录里面执行python3 setup.py install

    监听到的pcap包使用scapy去解

    参照作者的笔记去写python代码吧

    The lack of PFS: a danger to privacy

    以下是自己写的垃圾测试代码:

    from scapy.all import *
    import os
    import sys
    import binascii
    
    from scapy.layers.tls.record import TLSApplicationData
    
    onesslkeyfile = './sslkey.log'
    
    def method_filter_HTTP(pkt):
        if pkt.haslayer(Raw):
            pkt.payload.payload.show()
            pktdump.write(pkt)
    def method_filter_TLS(pkt):
        if pkt.haslayer(TLS):
            if pkt.haslayer(TLSApplicationData):
                pkt[TLSApplicationData].show()
                # print(pkt.src)
            pktdump.write(pkt)
            ## pktdump_payload.write(pkt)
        ## else:
            ## pkt.payload.payload.show()
    def method_save(pkt):
        pktdump.write(pkt)
    
    ## resolve the tls traffic
    ## load_layer("http")
    
    port = 80
    try:
        port = int(sys.argv[1])
    except:
        pass
    if not os.path.exists('sss.pcap'):
        pktdump = PcapWriter("sss.pcap", append=True, sync=True)
        ## pktdump_payload = PcapWriter("sss_payload.pcap", append=True, sync=True)
        if port == 443:
            print(port)
            load_layer("tls")
            pkts = sniff(filter=f'tcp and tcp port {port}', prn=method_filter_TLS, iface='eth0')
        else:
            print(port)
            pkts = sniff(filter=f'tcp and tcp port {port}', prn=method_filter_HTTP, store=0, iface='eth0')
        ## src iZwz9gwr0avfole4msfavlZ
        with open(os.getenv('SSLKEYLOGFILE'), 'r') as f:
        	sslkey = f.readlines()[-1]
        data = sslkey.strip().split(" ")
        ## print('\n', data[1], '---', binascii.unhexlify(data[1]))
    
    
        f = open(onesslkeyfile, 'w')
        f.writelines(sslkey)
        f.close()
    
    else:
        load_layer("tls")
        # config of decrypting a pcap files automationly
        # key = PrivKey('raw_data/pki/srv_key.pem')
        conf.tls_session_enable = True
        conf.tls_nss_filename = onesslkeyfile
    
        ## packets = rdpcap("./sss_payload_TLSv1.2.pcap")
        pktdump = PcapWriter("sss1.pcap", append=True, sync=True)
        packets = sniff(offline='sss.pcap', prn=method_save)
    
        print("==============================================================================================================")
        for i in range(len(packets)):
        ## packets[i].show()
        if packets[i].haslayer(TLSApplicationData):
        packets[i][TLSApplicationData].show()
        ## tls = packets[i][TLS].type
        ## print(tls)
        ## packets[i][TLS].show()
        print("==============================================================================================================")
    

记录找的过程失败的经历

尝试过的方法

目前找过的方法有:

  1. wireshark:这个说实话很强大,连tls1.3都可以解,但我需要的是可以使用python\命令行去解的

  2. tshark :此命令在linux下使用,可以解析pcap包并且可以抓包,-o参数有点可疑,这是在使用pyshark发现的

  3. pyshark:python的库,本质是调用tshark去解析https报文,其中有个FileCapture()函数似乎可以解ssl traffic(override_prefs参数),但也失败了,或许可以继续尝试

    How to decrypt TLS Packets using PyShark?

    Decrypt SSL packets using PyShark

  4. tcpdump:最常见的抓包工具

  5. ssldump:这个专门用于抓https包,其中的-l,-k和-w,-S,-r参数曾专门研究过,但仍不可解密tls,但确实有文章能解出来,我没有成功,原因未知,其中还有个孪生工具sslsniffer

    Decrypting SSL traffic using the SSL::sessionsecret iRules command
    Analyzing HTTP/S traffic under Linux

  6. httpry:也是一个抓包工具,但也不无法解析tls包

  7. scapy:python库,和pyshark有点类似,一开始截包也失败了,直到看到原作者secdev写的文章,发现了,使用pip install scapy后发现无效,后来全局访问发现问题,从github下载scapy源文件,使用python setup.py install后,成功解密tls,但只尝试了tls2,tls3是肯定不行的。scapy还有其他的孪生库如scapy-ssl_tls或许今后可以用到

    scapy文档

    secdev/scapy/notebook

  8. MITM Solution:国外一位小哥和我一样的困扰,在stack overflow求助

    Decrypt SSL/TLS with specific Private Key via SCAPY

    在了解情况后,貌似MITM也可以解决,原话为

    At this time I was solved my problem with NGINX custom logging format and watchdog to detect fast new TLS events for my TCP services Because nginx has MITM ability and if i want to use this solution then its enough...
    
  9. 反向代理,使用nginx作为服务端的反向代理,同时提供http服务,再抓取client到nginx的traffic
    nginx配置:

    server {
        listen *:80;
        listen [::]:80;
        server_name local.reverse.proxy.com;
    
        location / {
            proxy_pass https://www.google.com/;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Real-Port $remote_port;
            proxy_set_header Connection "";
            proxy_http_version 1.1;
        }
    }
    

有用的库

python的sslkeylog库

https://sslkeylog.readthedocs.io/en/latest/

https://github.com/segevfiner/sslkeylog

nginx配置sslkeylog

https://github.com/tiandrey/nginx-sslkeylog

github找到的说不定有用

tls-decryption

JS-or-Python-to-decrypt-TLS-v1.2-https

xmpp-mitm

telepath

dssl

TLS1.2过程

This is the standard, modern TLS 1.2 handshake:

JS-or-Python-to-decrypt-TLS-v1.2-https

xmpp-mitm

telepath

dssl

TLS1.2过程

This is the standard, modern TLS 1.2 handshake:

解密https流量_第1张图片

你可能感兴趣的:(https,python,wireshark,nginx,apache)