27.3 如何用Wireshark解密HTTPS报文 https://scz.617.cn/network/201512241045.txt Q: 工作中经常会用到Wireshark来抓包,但是一些SSL加密的数据无法直接查看。之前的 方式是你要有目标服务器的私钥并且在Wireshark里设置一下,但你很可能没有私钥, 而且现在的SSL协议大都开始使用前向密钥交换算法,用私钥解密不再可行。 A: gzp@nsfocus 2015-12-24 10:45 Firefox、Chrome可以通过设置SSLKEYLOGFILE环境变量导出所有的会话密钥,估计是 为了方便调试。Wireshark可以通过这种格式的密钥来解密。 set SSLKEYLOGFILE=\sslkey.log Wireshark Edit Preferences Protocols TLS(过去是SSL) (Pre)-Master-Secret log filename \sslkey.log start Firefox start Chrome 访问任意HTTPS站点,用Wireshark抓包,已经可以同步解密,除了"Reassembled TCP" 还能看到"Decrypted SSL data"。除了"Follow TCP Stream",还能用"Follow SSL Stream"。 为了方便调试,可以在系统变量中增加SSLKEYLOGFILE。支持UNC路径。 还可以这样用 chrome.exe --ssl-key-log-file=\sslkey.log launcher.exe --ssl-key-log-file=\sslkey.log D: scz 2022-10-25 16:04 参看 -------------------------------------------------------------------------- NSS Key Log Format https://firefox-source-docs.mozilla.org/security/nss/legacy/key_log_format/index.html Keep SSL/TLS key logging working with all Firefox builds from Mozilla https://bugzilla.mozilla.org/show_bug.cgi?id=1188657 libnss3: re-enable SSLKEYLOGFILE support https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=842292 -------------------------------------------------------------------------- NSS 3.24 (仅由Firefox 48/49使用)优化编译时缺省不支持SSLKEYLOGFILE,可在 make时指定"NSS_ALLOW_SSLKEYLOGFILE=1"以支持SSLKEYLOGFILE。听说某些开发版 Firefox的"about:config"中可以新建布尔值"NSS_ALLOW_SSLKEYLOG=1",将之设为 true,未确认。 不太清楚如何快速识别NSS库是否启用了优化编译,有个歪招,用strings检查NSS库 有无SSLKEYLOGFILE字符串。 cd /d "%ProgramFiles%\Mozilla Firefox" $ strings -f *.dll | grep SSLKEYLOGFILE nss3.dll: SSLKEYLOGFILE Windows中Firefox 102.4.0esr支持SSLKEYLOGFILE。 $ strings -f /snap/firefox/current/usr/lib/firefox/* | grep SSLKEYLOGFILE /snap/firefox/current/usr/lib/firefox/libssl3.so: SSLKEYLOGFILE Ubuntu 22中snap版Firefox 106支持SSLKEYLOGFILE,相关代码在libssl3.so 中,不在libnss3.so中。 $ strings -f /snap/opera/current/usr/lib/x86_64-linux-gnu/opera/* | grep SSLKEYLOGFILE /snap/opera/current/usr/lib/x86_64-linux-gnu/opera/opera: SSLKEYLOGFILE Ubuntu 22中snap版Opera 92支持SSLKEYLOGFILE,相关代码直接位于主程序中。 Windows中SSLKEYLOGFILE可以位于任意目录;Linux中SSLKEYLOGFILE必须位于$HOME 或其下各级子目录中,且无法用"../"及符号链接绕过。之前不知Linux这个天坑,误 以为Ubuntu 22中snap版Firefox、Opera均不支持SSLKEYLOGFILE,无意中发现正解。 下列命令达不到预期效果,不会生成sslkey.log SSLKEYLOGFILE=/tmp/sslkey.log firefox SSLKEYLOGFILE=/tmp/sslkey.log opera opera --ssl-key-log-file=/tmp/sslkey.log 下列命令会生成sslkey.log SSLKEYLOGFILE=$HOME/src/sslkey.log firefox SSLKEYLOGFILE=$HOME/src/sslkey.log opera opera --ssl-key-log-file=$HOME/src/sslkey.log "SSLKEYLOGFILE="生成文件权限0665(-rw-rw-r--),"--ssl-key-log-file="生成文 件权限0600(-rw-------),居然有这种区别,有意思。 D: scz 参看 -------------------------------------------------------------------------- NSS Key Log Format https://firefox-source-docs.mozilla.org/security/nss/legacy/key_log_format/index.html Your Browser Knows All Your Secrets https://isc.sans.edu/forums/diary/Psst+Your+Browser+Knows+All+Your+Secrets/16415/ SSL/TLS: What's Under the Hood http://www.sans.org/reading-room/whitepapers/authentication/ssl-tls-whats-hood-34297 The First Few Milliseconds of an HTTPS Connection http://www.moserware.com/2009/06/first-few-milliseconds-of-https.html -------------------------------------------------------------------------- sslkey.log形如: # Comment lines begin with a sharp character RSA <16 bytes of hex encoded encrypted pre master secret> <96 bytes of hex encoded pre master secret> CLIENT_RANDOM <64 bytes of hex encoded client_random> <96 bytes of hex encoded master secret> The RSA form allows ciphersuites using RSA key-agreement to be logged and is supported in shipping versions of Wireshark. The CLIENT_RANDOM format allows other key-agreement algorithms to be logged but is only supported starting with Wireshark 1.8.0 The CLIENT_RANDOM entry is for Diffie-Hellman negotiated sessions and the RSA entry is for sessions using RSA or DSA key exchange. 示例: # SSL/TLS secrets log file, generated by NSS CLIENT_RANDOM 754027ec6cb6899bc3fc7d98979c2589735c1146181d9418706881a3a022fbf2 24d12b81bf9ea2b1dd0c411ab875097ed5b8bd1716a7a8ebe93907129f473aa97797dae1743c3e1f2625a82e65a6f1cb 发散一下。 Firefox、Chrome之外的其他进程,假设有SSL/TLS通信,有时同样有用Wireshark抓 包查看明文的需求,毕竟那个界面比较熟悉。 sslkey.log的格式是明确的: RSA <16 bytes of hex encoded encrypted pre master secret> <96 bytes of hex encoded pre master secret> CLIENT_RANDOM <64 bytes of hex encoded client_random> <96 bytes of hex encoded master secret> 利用调试器或其他进程注入、Hook技术获取"pre master secret"、"client_random"、 "master secret",填写sslkey.log,就能用Wireshark解密报文。这里的原始需求是 方便地旁路观察SSL/TLS明文数据,因此不考虑调试本身就可以获取明文数据这个事 实。 Firefox的Live HTTP Headers插件可以查看HTTPS明文。 D: scz 2018-10-22 关于"前向保密",参看: https://en.wikipedia.org/wiki/Forward_secrecy One of the problems with the way Wireshark works is that it can't easily analyze encrypted traffic, like TLS. It used to be if you had the private key(s) you could feed them into Wireshark and it would decrypt the traffic on the fly, but it only worked when using RSA for the key exchange mechanism. As people have started to embrace forward secrecy this broke, as having the private key is no longer enough derive the actual session key used to decrypt the data. DH是密钥磋商算法,密钥不是由一方发送给另一方,而是双方共同产生一个密钥。参 看: Diffie Hellman key exchange https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange DH算法简要描述如下: -------------------------------------------------------------------------- p 一个大素数,公开 (p-1)/2应该也是素数 g 模p的原根,公开 由于p是素数,所以g是模p的生成元 x A产生的大随机数,保密 x < p-1 X=g^x mod p A向B发送X 由于p是素数,若x等于p-1,则X等于1,将来Z必等于1,不妥 y B产生的大随机数,保密 y < p-1 Y=g^y mod p B向A发送Y Z=Y^x mod p=X^y mod p A计算密钥 Z=Y^x mod p B计算密钥 Z=X^y mod p -------------------------------------------------------------------------- DH算法无法验证对方身份,所以单靠DH算法自身不能抵御MITM攻击,需要其他手段辅 助。 sslkey.log中的CLIENT_RANDOM就是前述x。x不会在网络上传输,传输的是X。启用前 向保密之后,RSA公私钥对只用于签名、校验签名,并不用于加密、解密。 sslstrip、mitmproxy等工具是SSL/TLS层的中间人,相当于拥有x、y。若只是TCP Relay,对于SSL/TLS层来说实质上还是旁路抓包,而DH算法确保纯旁路时无法拿到x、 y,即使嗅探者拥有RSA公私钥对也没有用于加密、解密的对称会话密钥Z。