web-dev-qa-db-ja.com

opensslコマンドラインツールを使用してSSLトラフィックを復号化する-パート5に続く

以前の投稿から パート1パート2パート および パート4 私は計算/復号化したと思いますすべてが正しく、クライアントの暗号化されたハンドシェイクメッセージの復号化を試みる準備ができています。すべてのキーを取得したら、次のステップに進みます。私はこれを数日間読んで研究してきましたが、ただ行き詰まっています。

以前の投稿のガイドラインに従って、私は思いついた

_20 bytes for a client MAC key: 64666eafe1cbd51f2e2b50799b40f6007c3dc56f
20 bytes for a server MAC key: e0aac1312d35b5e8b6bf9af6ecf07e1dff27c784
32 bytes client encryption key:
4bf20108190203c4210ff9df6c4eb6e907ddd1f49646ab4b243c80a6ae9b4808
32 bytes for a server encryption key:
 ca94445e3d771d3e06b71ee0deb4c1879986c4c6a4b78bf1c3c1083a6ddce9ff
_

暗号化されたクライアントハンドシェイクメッセージ:

_Hex.       FILE SIZE: 40
 ADDRESS   000 001 002 003 004 005 006 007       ASCII
===============================================================================
00000000   09A 01B 0F3 06B 078 06C 03B 059      ~Z  ^[  -s   k   x   l   ;   Y
00000008   085 061 07C 076 0AF 0D9 085 0D6      ~E   a   |   v  -/  -Y  ~E  -V
00000010   08F 0FD 0AF 06D 09F 01A 025 0EF      ~O  -}  -/   m  ~_  ^Z   %  -o
00000018   040 015 097 002 0B5 0AD 0EF 040       @  ^U  ~W  ^B  -5  --  -o   @
00000020   02B 0DB 051 096 0CE 076 0A9 03F       +  -[   Q  ~V  -N   v  -)   ?
00000028   0D7 030 049 03A 0CC 0F9 029 044      -W   0   I   :  -L  -y   )   D
00000030   07F 0A9 0C6 0F1 017 02D 06B 040      ^?  -)  -F  -q  ^W   -   k   @
00000038   035 0F5 057 08E 0BF 0E9 05C 06D       5  -u   W  ~N  -?  -i   \   m
00000040
_

私はopensslend -d -Kのバリエーションを使用する必要があると思いますが、RFCとgoogleの間でつまずいて、それを明確に説明する解決策/例を見つけます。 opensslのコマンドラインでこれを行う方法/方法を知っている人はいますか?ありがとう

更新。 RFC 7.4.9PRF(master_secret, finished_label, Hash(handshake_messages))で見落とした理由/方法がわかりません。すべてのハンドシェイクメッセージをログに記録しました。opensslコマンドラインだけでこれをシミュレートする方法を誰かが説明できますか?これまでにキャプチャ/復号化したデータを使用します。ハンドシェイクメッセージのハッシュは、これより前に実行する必要があるようです RFCセクション5 生成したmaster_secretを使用することを想定していますこれのシードがわかりません以前使用していた方法でopensslを使用する必要があります。このハッシュに連結されたラベルがあるのがわかりません。この時点までのすべてのハンドシェイクメッセージを連結して使用するだけですか?私がいる場所で迷子になっている多くのステップがあります。ありがとう

_openssl dgst -sha256 -mac hmac -macopt hexkey:$key <seed -binary >a1
_
1
David B

投稿するたびに新しいファイルダンプ形式を使用しているように見えることに興味があります:-)

以前と同じように(RSA-with-)AES256CBC HMAC)SHA1:はい、ARIAを除いてopenssl encでTLSCBC暗号を復号化できます。 (RC4も、TLSを含むあらゆる目的でRC4を使用することは避けてください。OTOHencはAEAD暗号を実行できません。GCMまたはCCMではなく、ChaCha/Polyでもありません。)TLS1.2のレコード形式。 (および1.1)CBC暗号については、---(RFC5246セクション6.2.3.2 で説明されています。 AESの場合、最初の16オクテットはIVで、残りは暗号文であり、プレーンテキストレコード本文(この場合はFinishedメッセージ)とHMACとパディングに復号化する必要がありますが、TLSパディングはPKCS5 /と同じではありません。 7パディングはenc(および内部的にはEVP_{??crypt,Cipher}* AP​​I)でサポートされているため、その部分を自分で行う必要があります。

システムのmanページ またはWeb で説明されているように、いくつかのスタックでかなりの数の質問があります(ただし、ほとんどの場合、コマンドラインをJavaおよびpythonなどは仕様に準拠していません)、openssl encのデフォルトはpassword-based暗号化(PBE)これはここで必要なことではありません。「キーベース」の復号化を行うには、-d-K(小文字ではなく大文字)を16進数のキーで指定し、-ivをで指定する必要があります。暗号で使用される場合の16進のIV(AES-CBCでは使用):

$ echo $key; echo $iv
4bf20108190203c4210ff9df6c4eb6e907ddd1f49646ab4b243c80a6ae9b4808
9A1BF36B786C3B5985617C76AFD985D6
$ sed 1,2d <1346633.dat
8FFDAF6D9F1A25EF
40159702B5ADEF40
2BDB5196CE76A93F
D730493ACCF92944
7FA9C6F1172D6B40
35F5578EBFE95C6D
$ sed 1,2d <1346633.dat |xxd -p -r |openssl aes-256-cbc -d -K $key -iv $iv -nopad |xxd
0000000: f730 34cc b90f b0b0 6313 9a0f 239c 6e87  .04.....c...#.n.
0000010: 187f ff00 52d1 3e9c 2aef d5cd c07e 15be  ....R.>.*....~..
0000020: dee0 aa95 6994 5ce6 768d 1952 ac00 17ba  ....i.\.v..R....

残念ながら、ご覧のとおり、この復号化は無効です。TLSスタイルのパディングで終了せず、Finishedメッセージで開始されません。これは、クライアントによる最初のCCS後の送信である必要があります。派生キーが間違っているか、このレコードのダンプが間違っています。

役立つ可能性のある1つの提案:(edit)openssl s_client -debugを使用して接続を確立し、その出力をファイルに記録します。これにより、さまざまな入力(Finishedを含む暗号化されたレコードを含む)のデータとして使用したり検証したりできる16進数(およびASCII)のすべてのレコードがダンプされ、最後の「SSL-Session」ブロックには正しい値が含まれます。クロスチェックとして使用できるマスターシークレット。 -msgを追加して、暗号化されたメッセージをダンプすることもできます。これはかさばりますが、もう少し便利で、以下で行いました。もう1つの可能性は、セットアップにもう少し手間がかかりますが、sysprop javax.net.debug=sslとlogで実行されるJava SSL/TLS(JSSE)クライアントプログラムから接続することです。これはlotsマスターシークレットを含む情報and作業キー。


このshouldがどのように機能するかの例として、ログに記録されたサンプルセッション(数週間前に最初のQで実際に作成した)の手順を実行しました。マスターと作業中の派生物を渡し、クライアントの終了メッセージを復号化して検証します。

$ cat tempc
2f e9 97 3e e4 11 89 81 c5 bc 18   11 7b c9 e9 3d
64 cb 88 6e a4 ac f2 01 95 05 d7
fe 3d 09 f4 13 4a d7 39 77 bf 50 dc f4 7b 9b b8
3c 0b 2f bf 98 5a 9c 4c 2d 28 6c 6a b6 93 a9 29
c5 5f f1 a3 cd
$ # this is the hexdump of from s_client -debug, cleaned up 
$
$ echo $key; echo $iv
7d18617e178fc6320019442c6cd071ca4b4f7d2bb83f6194c23681aefd84f120
2fe9973ee4118981c5bc18117bc9e93d
$ # you can see the IV is the first line (16 bytes) of tempc
$ sed 1d tempc |xxd -p -r |openssl aes-256-cbc -d -K $key -iv $iv -nopad |tee tempc! |xxd
0000000: 1400 000c 5bbc 39d8 6c5d dbb1 076b b91b  ....[.9.l]...k..
0000010: 9f4e 5c55 fd9e a185 6901 4bc0 6f02 2c0d  .N\U....i.K.o.,.
0000020: 5bb0 d8c9 0b0b 0b0b 0b0b 0b0b 0b0b 0b0b  [...............
$ # those last 12 bytes are SSL/TLS-style padding 
$ # the first 4 bytes are a handshake message header for x14=Finished,
$ # followed by the 12 byte verify_data value, total 16 bytes 
$
$ echo $mkey
28a3244d49c644f889b44f2bae54466b6913fb1e
$ { printf '\0\0\0\0\0\0\0\0\x16\x03\x03\0\x10'; head -c16 tempc! ; } \
> |openssl sha1 -mac hmac -macopt hexkey:$mkey -binary |xxd -p 
9f4e5c55fd9ea18569014bc06f022c0d5bb0d8c9
$ # the 20 bytes after the 16-byte message and before the padding 
$ # correctly match HMAC-SHA1 of the pseudoheader plus the message

'verify_data'in終了メッセージに関しては、はい、以前のすべてのハンドシェイクメッセージのハッシュを取得する必要があります7.4.9(TLS1.3ではこれは「トランスクリプト」ハッシュと呼ばれます)で説明されているように、次にPRF(以前の投稿で説明されている)で、キーはマスターシークレットで、シードは固定ラベル「クライアントが終了しました」または「サーバーが終了しました」(該当する場合)とそのトランスクリプトハッシュ。それはかなり多くの作業であり、私は例のためにそれをしませんでしたが、おそらく必要であれば可能です。

2