ksnctf: HTTPS is secure, Writeup (TLS 通信解読)
ksnctf(https://ksnctf.sweetduet.info/ ) の No.33 である HTTPS is secure の Writeup をメモします。 こちらは、2つの類似した証明書を利用して、TLS 通信を破ることでフラグを取り出します。パケットファイルは、http://ksnctf.sweetduet.info/q/33/q33.pcap から落としてきます。以下、Wireshark に取り込んでパケットキャプチャを行います。
TLS 通信の復習と共に、回答の手順が含まれますので、ネタバレしたくない場合は、読まないようお願いします。
TLS 通信のハンドシェイクについて
TLSのコネクションを確立するためには、以下のハンドシェイクを通して行われます。最初の ClientHello でクライアントが利用可能な暗号スイートを提示し、それに対してサーバーは自身が利用可能な暗号スイートと比較し、使用する暗号スイートを返します。それと同時 Certificate メッセージでサーバの証明書も返します。
クライアント サーバー
ClientHello -------->
ServerHello
Certificate*
ServerKeyExchange*
CertificateRequest*
<-------- ServerHelloDone
Certificate*
ClientKeyExchange
CertificateVerify*
[ChangeCipherSpec]
Finished -------->
[ChangeCipherSpec]
<-------- Finished
Application Data <-------> Application Data
公開鍵の取得
q33.pcapファイル中では、SSL通信のハンドシェイクが No.4 ~ No.12のパケットで192.168.66.129のクライアントから192.168.0.39のサーバへ, No.73 ~ No.81のパケットで192.168.66.129のクライアントから192.168.0.40のサーバへと2回行われていることが確認されます。 与えられたヒントが、2つの類似した証明書を利用するとのことなので、このそれぞれ2つのSSL通信中の証明書を利用してときます。
- 192.168.66.129のクライアントから192.168.0.39のサーバへのハンドシェイク
4 2013-11-04 04:02:38.599927 192.168.66.129 192.168.0.39 TLSv1 131 Client Hello
5 2013-11-04 04:02:38.600656 192.168.0.39 192.168.66.129 TCP 60 443 → 1529 [ACK] Seq=1 Ack=78 Win=64240 Len=0
6 2013-11-04 04:02:38.600714 192.168.0.39 192.168.66.129 TLSv1 1514 Server Hello
7 2013-11-04 04:02:38.600720 192.168.0.39 192.168.66.129 TLSv1 199 Certificate, Server Hello Done
8 2013-11-04 04:02:38.600727 192.168.66.129 192.168.0.39 TCP 54 1529 → 443 [ACK] Seq=78 Ack=1606 Win=64240 Len=0
9 2013-11-04 04:02:38.600798 192.168.66.129 192.168.0.39 TLSv1 364 Client Key Exchange, Change Cipher Spec, Finished
10 2013-11-04 04:02:38.601768 192.168.0.39 192.168.66.129 TCP 60 443 → 1529 [ACK] Seq=1606 Ack=388 Win=64240 Len=0
11 2013-11-04 04:02:38.605380 192.168.0.39 192.168.66.129 TLSv1 97 Change Cipher Spec, Finished
12 2013-11-04 04:02:38.606914 192.168.66.129 192.168.0.39 TLSv1 376 Application Data
- 192.168.66.129のクライアントから192.168.0.40のサーバへのハンドシェイク
73 2013-11-04 04:02:39.695588 192.168.66.129 192.168.0.40 TLSv1 131 Client Hello
74 2013-11-04 04:02:39.695782 192.168.0.40 192.168.66.129 TCP 60 443 → 1531 [ACK] Seq=1 Ack=78 Win=64240 Len=0
75 2013-11-04 04:02:39.696909 192.168.0.40 192.168.66.129 TLSv1 1514 Server Hello
76 2013-11-04 04:02:39.696942 192.168.0.40 192.168.66.129 TLSv1 191 Certificate, Server Hello Done
77 2013-11-04 04:02:39.696952 192.168.66.129 192.168.0.40 TCP 54 1531 → 443 [ACK] Seq=78 Ack=1598 Win=64240 Len=0
78 2013-11-04 04:02:39.697976 192.168.66.129 192.168.0.40 TLSv1 364 Client Key Exchange, Change Cipher Spec, Finished
79 2013-11-04 04:02:39.698182 192.168.0.40 192.168.66.129 TCP 60 443 → 1531 [ACK] Seq=1598 Ack=388 Win=64240 Len=0
80 2013-11-04 04:02:39.702073 192.168.0.40 192.168.66.129 TLSv1 97 Change Cipher Spec, Finished
81 2013-11-04 04:02:39.702174 192.168.66.129 192.168.0.40 TLSv1 372 Application Data
証明書1の公開鍵
No.4のパケットで最初に ClientHello が投げられています。
4 2013-11-04 04:02:38.599927 192.168.66.129 192.168.0.39 TLSv1 131 Client Hello
具体的にパケットの中身を見てみると、TLS の層で11種類の暗号スイートをサーバへ提示しています。RSAとDHEの暗号化方式を提示していることがわかります。
Frame 4: 131 bytes on wire (1048 bits), 131 bytes captured (1048 bits)
Ethernet II, Src: Vmware_37:6a:33 (00:0c:29:37:6a:33), Dst: Vmware_f4:85:b0 (00:50:56:f4:85:b0)
Internet Protocol Version 4, Src: 192.168.66.129, Dst: 192.168.0.39
Transmission Control Protocol, Src Port: 1529, Dst Port: 443, Seq: 1, Ack: 1, Len: 77
Secure Sockets Layer
TLSv1 Record Layer: Handshake Protocol: Client Hello
Content Type: Handshake (22)
Version: TLS 1.0 (0x0301)
Length: 72
Handshake Protocol: Client Hello
Handshake Type: Client Hello (1)
Length: 68
Version: TLS 1.0 (0x0301)
Random
Session ID Length: 0
Cipher Suites Length: 22
Cipher Suites (11 suites)
Cipher Suite: TLS_RSA_WITH_RC4_128_MD5 (0x0004)
Cipher Suite: TLS_RSA_WITH_RC4_128_SHA (0x0005)
Cipher Suite: TLS_RSA_WITH_3DES_EDE_CBC_SHA (0x000a)
Cipher Suite: TLS_RSA_WITH_DES_CBC_SHA (0x0009)
Cipher Suite: TLS_RSA_EXPORT1024_WITH_RC4_56_SHA (0x0064)
Cipher Suite: TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA (0x0062)
Cipher Suite: TLS_RSA_EXPORT_WITH_RC4_40_MD5 (0x0003)
Cipher Suite: TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 (0x0006)
Cipher Suite: TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA (0x0013)
Cipher Suite: TLS_DHE_DSS_WITH_DES_CBC_SHA (0x0012)
Cipher Suite: TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA (0x0063)
Compression Methods Length: 1
Compression Methods (1 method)
Extensions Length: 5
Extension: renegotiation_info
ClientHelloを受け取ったサーバは次にServerHelloを返しています。
6 2013-11-04 04:02:38.600714 192.168.0.39 192.168.66.129 TLSv1 1514 Server Hello
具体的なパケットの中身を見てみるとクライアントから提示された暗号スイートに対して、TLS_RSA_WITH_RC4_128_MD5 の暗号スイートを選択したことが分かります。つまり、RSA の公開鍵暗号でRC4の共有鍵暗号方式でMD5のハッシュ関数を使用していることがわかります。
Frame 6: 1514 bytes on wire (12112 bits), 1514 bytes captured (12112 bits)
Ethernet II, Src: Vmware_f4:85:b0 (00:50:56:f4:85:b0), Dst: Vmware_37:6a:33 (00:0c:29:37:6a:33)
Internet Protocol Version 4, Src: 192.168.0.39, Dst: 192.168.66.129
Transmission Control Protocol, Src Port: 443, Dst Port: 1529, Seq: 1, Ack: 78, Len: 1460
Secure Sockets Layer
TLSv1 Record Layer: Handshake Protocol: Server Hello
Content Type: Handshake (22)
Version: TLS 1.0 (0x0301)
Length: 81
Handshake Protocol: Server Hello
Handshake Type: Server Hello (2)
Length: 77
Version: TLS 1.0 (0x0301)
Random
Session ID Length: 32
Session ID: 69bebcfca11a7c53259807575f85846ab23daf9e3b15d86f...
Cipher Suite: TLS_RSA_WITH_RC4_128_MD5 (0x0004)
Compression Method: null (0)
Extensions Length: 5
Extension: renegotiation_info
その後、サーバは証明書をクライアントに返しています。
7 2013-11-04 04:02:38.600720 192.168.0.39 192.168.66.129 TLSv1 199 Certificate, Server Hello Done
具体的にパケットの中身を見ていくと、subjectPublicKey の modulus というところに公開鍵の情報が含まれています。こちらの modulus が最初に必要な情報となります。
Frame 7: 199 bytes on wire (1592 bits), 199 bytes captured (1592 bits)
Ethernet II, Src: Vmware_f4:85:b0 (00:50:56:f4:85:b0), Dst: Vmware_37:6a:33 (00:0c:29:37:6a:33)
Internet Protocol Version 4, Src: 192.168.0.39, Dst: 192.168.66.129
Transmission Control Protocol, Src Port: 443, Dst Port: 1529, Seq: 1461, Ack: 78, Len: 145
[2 Reassembled TCP Segments (1510 bytes): #6(1374), #7(136)]
Secure Sockets Layer
TLSv1 Record Layer: Handshake Protocol: Certificate
Content Type: Handshake (22)
Version: TLS 1.0 (0x0301)
Length: 1505
Handshake Protocol: Certificate
Handshake Type: Certificate (11)
Length: 1501
Certificates Length: 1498
Certificates (1498 bytes)
Certificate Length: 754
Certificate: 308202ee308201d6020900b5ca76b816420d2f300d06092a... (id-at-commonName=chihiro,id-at-organizationName=Chihiro,id-at-localityName=Otowa,id-at-countryName=JP)
Certificate Length: 738
Certificate: 308202de308201c602090094f8fffe850d57e3300d06092a... (id-at-commonName=ksnctf.sweetduet.info,id-at-organizationName=ksnctf)
signedCertificate
serialNumber: -7712132893252954141
signature (sha1WithRSAEncryption)
issuer: rdnSequence (0)
validity
subject: rdnSequence (0)
subjectPublicKeyInfo
algorithm (rsaEncryption)
subjectPublicKey: 3082010a0282010100ba7d3b1ed67d7ecfad8d536bee3531...
modulus: 0x00ba7d3b1ed67d7ecfad8d536bee3531747be94ea9e4ac14...
publicExponent: 65537
algorithmIdentifier (sha1WithRSAEncryption)
Padding: 0
encrypted: 8a6269e64c5d98953adc0a6f1b21f3c363c4f29c5f3181c0...
Secure Sockets Layer
こちらの値を右クリックで 「コピー > 値」と選択すると、値が取り出されます。
00ba7d3b1ed67d7ecfad8d536bee3531747be94ea9e4ac1403a3300fbefdfc4ee241362519fb8e28baa27279408d303f38c3ae1972b2cd5b152edaa2e9a29223f1c91199a0374c5a06d18c0b55d767b78445be755c65787a8bc5e0a9288728457c91441e03216506c87e696eb54f4b149082b1bd83d2772d7ac87cb6f06c61ca0dafec275c9a30a75c9fc8d39a6567210162cdeb5f686670b5850729c12f3d69d516ab28818c43460d3d0531e6b25e0230a184fb1bb8a00ee0b737e248d7e6a70bc6abe2f3d915c3d7583113c8d72855c0e3cb50531480eaece5dbab5ea1641788b3079d3db02a0fe121fd1b411c108a86c4b02f4c8f9b2a8386cf908b4b531983
上記は16進数の数字ですが、10進数に直すと以下のようになります。変換は、どのような手段でもいいのですが、「2進数、8進数、10進数、16進数相互変換ツール( https://hogehoge.tk/tool/number.html )」こちらのサイトのツールを利用しました。こちらの値をu1とします。
23542078401445977491582187555358406277626961530410681341351413646839204193911833858881038261034069118969161638703136657118916899182578490915497753149887260831567926516391758114231928168566639210404236451288838928257916305340669368491719913927522510658180812971112923019250500479662167443924407765948316698727000721627241198221156194402344915063743640702715180639778981629051287418843949981843258352590283355963590064164706331873913433484206976862304714043765574194257912501410672053921789284948212520207569618096303687722482311329735803729406182287210885757517187688163718098757454136048850395842585001590124979624323
証明書2の公開鍵
No.73 ~ No.81のパケットで192.168.66.129のサーバと TLS 通信のハンドシェイクが行われています。 証明書1と同様の手順でNo.76のCertificateのメッセージを送っているパケットからsubjectPublicKeyのmodulusの値を取り出してきます。
00a4daad49eae0b5c59da0452978ae987e1b96f149dedb62274c97f99ac4544aa90db4aaf9a0967f118b7009097bcb0baeb4a19636777a7747e06ad84496c9c61d18a7b5ca776585a817526ed6d9f0f2abd8c434c62cbf025eb7ce5a83e4a7f9938f3862de24e6292f43270ffda757c17aaa797ff9fe18fd1cb23921dc585d4550384ff5c4f24e6dfc6d4f44b569345808239247c20d266cd0f5e373889ed4e459590b7d742d2837c1c48dcf9418e22191ab4a0bca0ed79b1d45c0ca5d36ea6960c9360c11412329fd5d90ff3467f2d82e23021adf3b6d8be24903b76effc938154ec219f344118f1c41fec31171b62945a07e35762a961a05795389086052dec7
10進数に直すと以下のようになります。こちらの値をu2とします。
20810915617344661448636429656557804394262814688853534649734586652859523797380885650024809244693377123486154907319690068259378744245911427062593140588104970879344505836367952513105241451799550533959908906245319537215140226739848280012005678383612764589285444929414256249733809498630880134204967826503346173071037885178145189051140796573786694250069189599080301164473268293037575740360272856085402928759232391893060067823996007021668671352199570084430112300612196486186252109596457909476374557998336186613887204545677563178904634941310201398366965571422359228917354256271527331840144577394174480450746748283277750230727
メッセージの復号
先程の公開鍵を取得する中で、ハンドシェイク中で TLS_RSA_WITH_RC4_128_MD5 の暗号スイートが使用されることを決めていました。つまり、公開鍵暗号方式として、RSA が使用することになりました。
こちらの RSA ですが、暗号化されたメッセージを解くことが困難な根拠は、巨大な素数同士の積は素因数分解をすることが困難なことが大変難しいことを根拠としています。
証明書1の先程の取り出した値をu1で積を構成するそれぞれの素数をp1,q1とします。証明書2についても同様にu2で、積を構成するそれぞれの素数をp2,q2とします。
すると、以下のような式となります。
u1 = p1 * q1
u2 = p2 * q2
1024ビットの素因数分解を総当りで行うとなると億レベルのお金をかけて何年というほどの計算を要するものになるため、普通にしては解けません。 しかし、u1 と u2 がもし仮に、共通の因数を持つと仮定してみると、それを最大公約数を求める要領で同じ手順で求められることになります。 つまり、q1 と q2 が同じ値として、q = q1 = q2 とすると、以下の式になります。
u1 = p1 * q
u2 = p2 * q
ここで、最大公約数を求めるために u1 と u2 に対して、ユークリッドの互除法を適用します。すると、q の値が求められます。実際に Python で実行すると、以下のようなコードとなります。
def gcd(x, y):
r = modlog(x, y)
while r != 0:
x = y
y = r
r = modlog(x, y)
return y
def modlog(x, y):
r = x % y
return r
def main():
u1 = 20912068408571562329765690555061159289641629285082404210189101064954330953315593257557260077525915152641073106397431556875680393639301995231540409600633056790407217644109479375811025952060540276714119842291972532268686811648476477127818267411283106601195166099848608860814911133056759210847640244371352294577674757844032344743192797680553522630615249481210459669536735468283778508143359159893770374788694416907786510825727199111604249000530550012491935109887922826382346971222271516625157446929215544796309806757863550058676780306722906895167581167203804721314732494889662194466565293268848629536070864750745494338531
u2 = 20810915617344661448636429656557804394262814688853534649734586652859523797380885650024809244693377123486154907319690068259378744245911427062593140588104970879344505836367952513105241451799550533959908906245319537215140226739848280012005678383612764589285444929414256249733809498630880134204967826503346173071037885178145189051140796573786694250069189599080301164473268293037575740360272856085402928759232391893060067823996007021668671352199570084430112300612196486186252109596457909476374557998336186613887204545677563178904634941310201398366965571422359228917354256271527331840144577394174480450746748283277750230727
q = gcd(u1, u2)
print(q)
if __name__=="__main__":
main()
すると、以下の値が得られます。こちらがqの値となります。
149964660518396798660782215517197000054264985822608779681144262791391323000835825727277636178043097046988857828384650158626906824855399961360412435818827649355003329726451846544435103030378220357694459358803967598155925736581896165952170564324730092516286266118841005062382011803493961966912439338500328959743
すると、u1,u2,qの値が分かっていることから、p1,p2の値はそれぞれ以下のようにして求められます。
p1 = u1 / q
p2 = u2 / q
実際に計算すると、p1は以下のようになります。
139446642537534304777628614240154046272434122794892522124374234093313897652592278876204620931659231555942782873768406065030569534203407105601097455479995730772421725109267044663491213232687718387909353507690622331780468229128999879032054673690005684809410661625656125511253714586807242182927209779610158700317
p2は以下のようになります。
138772131683595539379264396620735603425702925342291987755841498194704959931781364169698055070785331880014332847610595576230231417278730047109315439655930883451174914691703480278864120207968103099432047374677543229331540706277526947368767969434429565383119554767303697722958157645742281397722992120606265055289
以上で RSA の復号が困難な根拠とされた素因数分解ができました。 2つの証明書の類似性とは、2つの数字に共通の因数を持つことのようだったようです。 あとは、これを元に秘密鍵を構築します。
秘密鍵の構築
pem 形式の秘密鍵について
pem 形式の秘密鍵は、ASN.1のバイナリデータをBase64でエンコードされたテキストファイルとなります。こちらのファイルの中身は、-----BEGIN RSA PRIVATE KEY-----で始まり、-----END RSA PRIVATE KEY-----で終わるファイルとなります。この間に挟まれたデータは、ASN.1をDERという形式でエンコードされたバイナリファイルとなります。
RSAにおけるASN.1の定義は、以下のように定められています。versionは0か1の値で、otherPrimeInfosはversionが0のときは存在しません。
RSAPrivateKey ::= SEQUENCE {
version Version,
modulus INTEGER, -- n
publicExponent INTEGER, -- e
privateExponent INTEGER, -- d
prime1 INTEGER, -- p
prime2 INTEGER, -- q
exponent1 INTEGER, -- d mod (p-1)
exponent2 INTEGER, -- d mod (q-1)
coefficient INTEGER, -- (inverse of q) mod p
otherPrimeInfos OtherPrimeInfos OPTIONAL
}
(引用: RSA 秘密鍵/公開鍵ファイルのフォーマット http://bearmini.hatenablog.com/entry/2014/02/05/143510 )
publicExponentであるeの値は、公開指数として655337がよく用いられるそうです。以下のような理由があるようです。
公開指数eの値として65537もよく使われますが,その理由としては, これが素数であり,しかも65537=2^16+1 が成り立つためです。これを2進表現したものは1を 2つしか含まないので,この値でべき乗するには17回の乗算で済みます。 これは3を指数eとした場合の2回と比べると多いですが, 512ビットを無作為に選択した場合に必要とする平均乗算回数768回と比べると圧倒的に少ないといえます。 また,65537をeとして使う場合,eに3を使う場合に生じる問題をほとんど避けることが可能です。
(引用: RSA暗号体験入門 http://post1.s105.xrea.com/)
証明書1の秘密鍵の取得
秘密鍵を求めるに当って、prime1 である p , prime2 である q , publicExponent である e の3つをパラメータとして pem形式のファイルを作成することができます。
最初に証明書1から pem形式のファイルを求めるために、p1,q,e(=65537)の値から以下のようにして、pem形式のデータを出力します。こちらのデータをファイルに保存します。
ただし、こちらは Python の Crypto モジュールを使用しますので、pip install pycrypto
のようにモジュールをインストールする必要があります。
from Crypto.PublicKey import RSA
from Crypto.Util.number import inverse
p = 139446642537534304777628614240154046272434122794892522124374234093313897652592278876204620931659231555942782873768406065030569534203407105601097455479995730772421725109267044663491213232687718387909353507690622331780468229128999879032054673690005684809410661625656125511253714586807242182927209779610158700317
q = 149964660518396798660782215517197000054264985822608779681144262791391323000835825727277636178043097046988857828384650158626906824855399961360412435818827649355003329726451846544435103030378220357694459358803967598155925736581896165952170564324730092516286266118841005062382011803493961966912439338500328959743
e = 65537
n = p*q
d = inverse(e, (p-1)*(q-1))
key = RSA.construct(map(int, (n,e,d)))
print(key.exportKey().decode('utf-8'))
上記を genpem1.py という名前で保存したとします。すると、以下のようにして秘密鍵を出力します。
python genpem1.py > private1.pem
こちらの秘密鍵はパスがかかった状態で、このままでは利用できないので、以下のコマンドを実行してパスを解除します。
openssl rsa -in private1.pem -out private.pem.unencrypted
上を実行しないと、Wireshark に読み込ませると、下記のエラーが出力されます。 ssl_load_key: can't import pem data: Base64 unexpected header error.
(参考: https://serverfault.com/questions/224589/error-while-decrypting-https-traffic-in-wireshark )
証明書2の秘密鍵の取得
こちらも証明書1の秘密鍵の取得の手順と同様にして、以下の gempem2.py というファイル名で Python のコードを準備します。
from Crypto.PublicKey import RSA
from Crypto.Util.number import inverse
p = 138772131683595539379264396620735603425702925342291987755841498194704959931781364169698055070785331880014332847610595576230231417278730047109315439655930883451174914691703480278864120207968103099432047374677543229331540706277526947368767969434429565383119554767303697722958157645742281397722992120606265055289
q = 149964660518396798660782215517197000054264985822608779681144262791391323000835825727277636178043097046988857828384650158626906824855399961360412435818827649355003329726451846544435103030378220357694459358803967598155925736581896165952170564324730092516286266118841005062382011803493961966912439338500328959743
e = 20912068408571562329765690555061159289641629285082404210189101064954330953315593257557260077525915152641073106397431556875680393639301995231540409600633056790407217644109479375811025952060540276714119842291972532268686811648476477127818267411283106601195166099848608860814911133056759210847640244371352294577674757844032344743192797680553522630615249481210459669536735468283778508143359159893770374788694416907786510825727199111604249000530550012491935109887922826382346971222271516625157446929215544796309806757863550058676780306722906895167581167203804721314732494889662194466565293268848629536070864750745494338531
e = 65537
n = p*q
d = inverse(e, (p-1)*(q-1))
key = RSA.construct(map(int, (n,e,d)))
print(key.exportKey().decode('utf-8'))
以下のコマンドを実行して秘密鍵を生成します。
python genpem2.py > private.pem
openssl rsa -in private2.pem -out private2.pem.unencrypted
TLS 通信の復号
最後に暗号化された TLS 通信を作成した秘密鍵で復号します。
Wireshark で実際に Certificate メッセージを送っていたフロー上(パケット No.7)で、右クリックします。「プロトコル設定 > RSA keys list...」を選択します。
SSL Decryptというウィンドウで、「IP addres, Port, Protocol, Key File, Password」の列名の表が現れますので、以下のように入力します。Protocolとしてhttp,Portとして443を指定します。httpsと指定するわけではないことに注意して下さい。
192.168.0.39 443 http /Users/......../private1.pem.unencrypted
192.168.66.129 443 http /Users/......../private2.pem.unencrypted
すると、先程まで、SSL通信として中身が見えていなかった通信(No.12 と No.81)が以下のようにHTTPプロトコルとして通信が見えるようになりました。
12 2013-11-04 04:02:38.606914 192.168.66.129 192.168.0.39 HTTP 376 GET /flag.jpg HTTP/1.1
81 2013-11-04 04:02:39.702174 192.168.66.129 192.168.0.40 HTTP 372 GET /flag.jpg HTTP/1.1
なお、こちらのデバッグとして、「プロトコル設定 > SSL debug file...」という項目でデバッグログの出力設定ができるので、こちらに出力されるログを見ながらデバッグすることが可能です。
最後の上記通信中でやりとりされていたjpgの画像ファイルを取り出します。 「ファイル(F) > オブジェクトをエクスポート > HTTP...(H)」を選択します。 最後にパケット49と125のファイルを選択してSaveします。
すると、2枚の画像ファイルが取り出されます。これらを組み合わせると、"FLAG_"で始まる文字列が取り出されます。画像のイメージはページ最後に載せておきます(答えは伏せています)。
補足
クライアントとして、ブラウザが提示する暗号スイートについて
SSL Labsの以下のサイトの実行結果により、ブラウザが提示する暗号スイートについて、確認してみました。
参照: SSL/TLS Capabilities of Your Browser
Chrome(バージョン: 63.0.3207.0(Official Build)canary (64 ビット))を使用したところ、クライアントから提示される暗号スイートは以下のようになっていました。
TLS_GREASE_AA (0xaaaa) -
TLS_AES_128_GCM_SHA256 (0x1301) Forward Secrecy 128
TLS_AES_256_GCM_SHA384 (0x1302) Forward Secrecy 256
TLS_CHACHA20_POLY1305_SHA256 (0x1303) Forward Secrecy 256
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02b) Forward Secrecy 128
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f) Forward Secrecy 128
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 (0xc02c) Forward Secrecy 256
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030) Forward Secrecy 256
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca9) Forward Secrecy 256
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca8) Forward Secrecy 256
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (0xc013) Forward Secrecy 128
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014) Forward Secrecy 256
TLS_RSA_WITH_AES_128_GCM_SHA256 (0x9c) 128
TLS_RSA_WITH_AES_256_GCM_SHA384 (0x9d) 256
TLS_RSA_WITH_AES_128_CBC_SHA (0x2f) 128
TLS_RSA_WITH_AES_256_CBC_SHA (0x35) 256
TLS_RSA_WITH_3DES_EDE_CBC_SHA (0xa) WEAK 112
(1) When a browser supports SSL 2, its SSL 2-only suites are shown only on the very first connection to this site. To see the suites, close all browser windows, then open this exact page directly. Don't refresh.
Firefox(55.0.3 (64-bit))を使用したところ、クライアントから提示される暗号スイートは以下のようになっていました。
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02b) Forward Secrecy 128
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f) Forward Secrecy 128
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca9) Forward Secrecy 256
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca8) Forward Secrecy 256
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 (0xc02c) Forward Secrecy 256
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030) Forward Secrecy 256
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (0xc00a) Forward Secrecy 256
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (0xc009) Forward Secrecy 128
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (0xc013) Forward Secrecy 128
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014) Forward Secrecy 256
TLS_DHE_RSA_WITH_AES_128_CBC_SHA (0x33) Forward Secrecy 128
TLS_DHE_RSA_WITH_AES_256_CBC_SHA (0x39) Forward Secrecy 256
TLS_RSA_WITH_AES_128_CBC_SHA (0x2f) 128
TLS_RSA_WITH_AES_256_CBC_SHA (0x35) 256
TLS_RSA_WITH_3DES_EDE_CBC_SHA (0xa) WEAK 112
プロフェッショナル SSL/TLSには、以下のような記述がありますが、上記の通り、必ずしも現時点では、ブラウザ等の実装でそうではなさそうです。
現在、TLSでは3つの鍵アルゴリズムに対応しておますが、そのうちで完全に実用的といえるのは1つ、RSAのみです。DSAはかなり以前から見捨てられており、ECDSAはこれから数年かけて利用が広がるアルゴリズムです。
(引用: プロフェッショナル SSL/TLS https://www.lambdanote.com/products/tls )
作成したpem形式の秘密鍵のフォーマットの形式確認方法
作成したpem形式の秘密鍵のフォーマットが正しいかを確認する方法があります。
private1.pem.unencryptedについては、以下のコマンドを実行します。
$ openssl asn1parse -inform pem < private1.pem.unencrypted
以下の結果が出力されます。
0:d=0 hl=4 l=1187 cons: SEQUENCE
4:d=1 hl=2 l= 1 prim: INTEGER :00
7:d=1 hl=4 l= 257 prim: INTEGER :A5A7CE44462E8AC6E4DA5E8A8D58E003B8267568B358106CF06412884CEEB7CC4251C2CCE2DB74689D1AFA109BDE9762402E81D96CB6C8C6C5AEBC8D45A96BF214A618B499A8C6134035C5039BF9A39BC47190E4CC4560CB75AB8D63635CDEE8E50F5815B29180CC51A4C8CF76A8BBE6E61C68ACA385FDF99E712B10A6BE7ED794CF27540B7AA00F59DA5579040A9B3B7C23E9E22A15C29EB0C060B96D1F48D1C458E2C412512962CE5AF885237B6138DF6C9E85D101C266C3B80B02FF97D6FDE46598E19E3FA1DF2C56BD34ADDFE716569A2ED42C6442BF2DB5E9A51CC2D7DD4497717DDD9A8A66AE281E1A2ABF7DF7A59779B499CC0F8167A19E3CA5C9BBE3
268:d=1 hl=2 l= 3 prim: INTEGER :010001
273:d=1 hl=4 l= 257 prim: INTEGER :96B06F11EC45AA380336218A27CA10FD5126AAE6F33DC8B35079B7E20519A2584C7BD3984D45143F95AA548F873A94BAEB6762F745CD801650FD02C7FFF67E1B586D3F4C09FB5D3365D583C224C091F3C05F0E4F1302896A8B3FE2FDE6053540E61D6F234DACCE5D0E67B7C4014CBCA0EDF229C5E17AA1EDD01361F963B525EBBEAA2BAB232940ACFFB08F2683A291BF28F803B37360CE3A8B4875D1DAEB34A6D0A90D9E4B8EA29AEC615B71329221B3C2F46DCA19B80B96540BCE135716DC46E5B3B320257B0593BFF2C74D0388E20A4597EF0AACA32340F569B0BB53ED9DA811E5959A89800624EEA057224254D20C9C257FD08A570F6F6E946F7D20734F01
534:d=1 hl=3 l= 129 prim: INTEGER :C6941FD1FD3DEDF69080356F0C76E2497F2569519BCEFFF5DC72B63FAE2F352ED1F4EFB254FCDDB45979216C9164FF946234A3EFDD0143747F55380E003BECCED49D04A8E2A1F35586C3A15C3B81EE1FB18D8528C02C2A0FA29209E4621C316DFA4FF4FA400D3EC4AA900F631AF61E6BB6F0D1EDA6F2FBF8E10E15B51B7D171D
666:d=1 hl=3 l= 129 prim: INTEGER :D58E882C1BE40C480E11A517C3DEEECDBBE5FD02EBE7A9F1F5F4E47CF8CD1B6443888238CB4A3424913487744D5DE2EC32D7DAFCB4A53B23DFED9A1261B3E9C7FE5AF4534908D0F700ED15402598C2E0C36880D8C999BA8A560D963728AE21E02D39FCDB6D118E88175BD89033B08D2958A7E8D0EFA7A26A2A7E3E1D1D42AEFF
798:d=1 hl=3 l= 128 prim: INTEGER :4CDC0C2CE4CDD18AFB8704278535868457F80CF98F4AE17B31E61C702D650C3AA0FD22C16D6FAA0822116644754A183A40808B6B4DA92D88ABB83A48010330B72547D903DD243DE0BE967DA00B5050F0677295359E9BF973AFC2C29D68F3EC95DAAA93F14055601412C84B8C5A652485207BB965389717BBCEAFFAEAEC46D069
929:d=1 hl=3 l= 128 prim: INTEGER :71C005D058DAD39FDDBE904D644B6EAFAF1205FE74616528387644EE3C28241AF7CDD26F25F95464D5E340F335F278588F8C625C906C22602D7A85C29CC0141A2EE58B9681246D09E438644552C157AC18E9A517D3EA4A6E3CFFE7AF61BFBED385C38967E7649EA2E6AE496025E83888796C969A13CD1AB9AA00AC5D1DA4D349
1060:d=1 hl=3 l= 128 prim: INTEGER :79F4EEF19181750A4313AF2495331ED2AB837D54CB2D9447FC40A5B92383ACB44F28186405DD8C400650B1E87DB84981CC250C6CE00120319CD6AD00CEE30E48D59F6E1983AEBA91D57A47DBF072A0A13CAEE426DED9E5635895780746DADAACD568E70B7462FBA117CE8F869D447CBBF2753CCE8FC6BD4934EE4D112EEB9AA2
同様にprivate2.pem.unencryptedについては、以下のコマンドを実行します。
$ openssl asn1parse -inform pem < private2.pem.unencrypted
以下の結果が出力されます。
0:d=0 hl=4 l=1186 cons: SEQUENCE
4:d=1 hl=2 l= 1 prim: INTEGER :00
7:d=1 hl=4 l= 257 prim: INTEGER :A4DAAD49EAE0B5C59DA0452978AE987E1B96F149DEDB62274C97F99AC4544AA90DB4AAF9A0967F118B7009097BCB0BAEB4A19636777A7747E06AD84496C9C61D18A7B5CA776585A817526ED6D9F0F2ABD8C434C62CBF025EB7CE5A83E4A7F9938F3862DE24E6292F43eifjccfuvccgdgniddrfugibhlthkkucegrjvfifikhc
270FFDA757C17AAA797FF9FE18FD1CB23921DC585D4550384FF5C4F24E6DFC6D4F44B569345808239247C20D266CD0F5E373889ED4E459590B7D742D2837C1C48DCF9418E22191AB4A0BCA0ED79B1D45C0CA5D36EA6960C9360C11412329FD5D90FF3467F2D82E23021ADF3B6D8BE24903B76EFFC938154EC219F344118F1C41FEC31171B62945A07E35762A961A05795389086052DEC7
268:d=1 hl=2 l= 3 prim: INTEGER :010001
273:d=1 hl=4 l= 256 prim: INTEGER :30DFFC5C5BDC7F47B571DCCF6CCE26BBCCA635A7370147DA6AE4EBC5ACCB68CF32170C51B200AC6FA12D78206DA9472F66B2397CB0738885B0CD3C8D293F6D13174A31A5733C9021C3B856D0301135812965125866CFC27E1E7479757D0728014D86E419044B908E48947E332FB7DECEE557DC4F5BBC40DE8F204D1FACBB0A5F424B3B658651BD0F2F704D81F7E51DA39A6C37D6BDB7E0A256859735FB4AA0B3100CC352EAB05F35D499B3AB73BECC22433013D6F72AAD5F57B4D5B242EA8176102D2E4393BEF21772538A27D6A4D7137777B0A41B3120E9EF0FE3099A78F454775FEA44FF8978996401D1E474AE8704E25B5F329099E364CA6F677A2E275B61
533:d=1 hl=3 l= 129 prim: INTEGER :C59E3A2D1E4F9084A4D06997B987D39FC007C0BBD781C4658860D8BA81D7AB0D94A19548BDF92EEEB4EC3CDB6BFDABF674C09FC0A34C96488ABD8936671BB888AB9D0E825CF0FA93E33A6CA9CE9BFDA28F1F39E63EF426274771F3A9F9109D6554B34801C29FDF3BC03DCEFDA3469F2609E8AC02B32A48B82360B78B15EE1839
665:d=1 hl=3 l= 129 prim: INTEGER :D58E882C1BE40C480E11A517C3DEEECDBBE5FD02EBE7A9F1F5F4E47CF8CD1B6443888238CB4A3424913487744D5DE2EC32D7DAFCB4A53B23DFED9A1261B3E9C7FE5AF4534908D0F700ED15402598C2E0C36880D8C999BA8A560D963728AE21E02D39FCDB6D118E88175BD89033B08D2958A7E8D0EFA7A26A2A7E3E1D1D42AEFF
797:d=1 hl=3 l= 128 prim: INTEGER :07BB3D036EE026034A7F6CE226BC0DA77E57CF4E8A0BE5A72342C6B7E5448EC8A53BFD1F2F6F844A8A81839002159698B9D09F6F65F4251D097088E1BBFEF5A543318DD3C3D719B697793DAF170A3B4E14D35FEC8621FF2C223B6F1103518716E3CD6FCFC1D187664B0B200204554AFCADFE905C3AAE38D21B70393E13C990E1
928:d=1 hl=3 l= 128 prim: INTEGER :71C005D058DAD39FDDBE904D644B6EAFAF1205FE74616528387644EE3C28241AF7CDD26F25F95464D5E340F335F278588F8C625C906C22602D7A85C29CC0141A2EE58B9681246D09E438644552C157AC18E9A517D3EA4A6E3CFFE7AF61BFBED385C38967E7649EA2E6AE496025E83888796C969A13CD1AB9AA00AC5D1DA4D349
1059:d=1 hl=3 l= 128 prim: INTEGER :35D4716BF825CA1701850D080F507CA4C757B692BCBF641FD1E47EFE264832CE90308FC1B3530570634E988907DF27404D9E4E1191810EBB5A841337C09ADE3613315E26F55CC18951AA1D21A24847AFCA30ED5B2FFAC88E63453D1DF6476B6C90A6A56930FBC79B5EBBB556C5BE8BE495DA5D02DAA10C3006712A6145F92791
上記について、先程のRSAのASN.1での定義を表現したものに対応しています。
RSAPrivateKey ::= SEQUENCE {
version Version,
modulus INTEGER, -- n
publicExponent INTEGER, -- e
privateExponent INTEGER, -- d
prime1 INTEGER, -- p
prime2 INTEGER, -- q
exponent1 INTEGER, -- d mod (p-1)
exponent2 INTEGER, -- d mod (q-1)
coefficient INTEGER, -- (inverse of q) mod p
otherPrimeInfos OtherPrimeInfos OPTIONAL
}
private1.pem.unencryptedの場合、以下のように対応することが分かります。
version = 00
modulus(n) = A5A7CE44462E8AC6E4DA5E8A8D58E003B8267568B358106CF06412884CEEB7CC4251C2CCE2DB74689D1AFA109BDE9762402E81D96CB6C8C6C5AEBC8D45A96BF214A618B499A8C6134035C5039BF9A39BC47190E4CC4560CB75AB8D63635CDEE8E50F5815B29180CC51A4C8CF76A8BBE6E61C68ACA385FDF99E712B10A6BE7ED794CF27540B7AA00F59DA5579040A9B3B7C23E9E22A15C29EB0C060B96D1F48D1C458E2C412512962CE5AF885237B6138DF6C9E85D101C266C3B80B02FF97D6FDE46598E19E3FA1DF2C56BD34ADDFE716569A2ED42C6442BF2DB5E9A51CC2D7DD4497717DDD9A8A66AE281E1A2ABF7DF7A59779B499CC0F8167A19E3CA5C9BBE3
publicExponent(e) = 010001
privateExponent(d) = 96B06F11EC45AA380336218A27CA10FD5126AAE6F33DC8B35079B7E20519A2584C7BD3984D45143F95AA548F873A94BAEB6762F745CD801650FD02C7FFF67E1B586D3F4C09FB5D3365D583C224C091F3C05F0E4F1302896A8B3FE2FDE6053540E61D6F234DACCE5D0E67B7C4014CBCA0EDF229C5E17AA1EDD01361F963B525EBBEAA2BAB232940ACFFB08F2683A291BF28F803B37360CE3A8B4875D1DAEB34A6D0A90D9E4B8EA29AEC615B71329221B3C2F46DCA19B80B96540BCE135716DC46E5B3B320257B0593BFF2C74D0388E20A4597EF0AACA32340F569B0BB53ED9DA811E5959A89800624EEA057224254D20C9C257FD08A570F6F6E946F7D20734F01
prime1(p) = C6941FD1FD3DEDF69080356F0C76E2497F2569519BCEFFF5DC72B63FAE2F352ED1F4EFB254FCDDB45979216C9164FF946234A3EFDD0143747F55380E003BECCED49D04A8E2A1F35586C3A15C3B81EE1FB18D8528C02C2A0FA29209E4621C316DFA4FF4FA400D3EC4AA900F631AF61E6BB6F0D1EDA6F2FBF8E10E15B51B7D171D
prime(q) = D58E882C1BE40C480E11A517C3DEEECDBBE5FD02EBE7A9F1F5F4E47CF8CD1B6443888238CB4A3424913487744D5DE2EC32D7DAFCB4A53B23DFED9A1261B3E9C7FE5AF4534908D0F700ED15402598C2E0C36880D8C999BA8A560D963728AE21E02D39FCDB6D118E88175BD89033B08D2958A7E8D0EFA7A26A2A7E3E1D1D42AEFF
exponent1(d mod (p-1)) = 4CDC0C2CE4CDD18AFB8704278535868457F80CF98F4AE17B31E61C702D650C3AA0FD22C16D6FAA0822116644754A183A40808B6B4DA92D88ABB83A48010330B72547D903DD243DE0BE967DA00B5050F0677295359E9BF973AFC2C29D68F3EC95DAAA93F14055601412C84B8C5A652485207BB965389717BBCEAFFAEAEC46D069
exponent2(d mod (q-1)) = 71C005D058DAD39FDDBE904D644B6EAFAF1205FE74616528387644EE3C28241AF7CDD26F25F95464D5E340F335F278588F8C625C906C22602D7A85C29CC0141A2EE58B9681246D09E438644552C157AC18E9A517D3EA4A6E3CFFE7AF61BFBED385C38967E7649EA2E6AE496025E83888796C969A13CD1AB9AA00AC5D1DA4D349
coefficient((inverse of q) mod p) = 79F4EEF19181750A4313AF2495331ED2AB837D54CB2D9447FC40A5B92383ACB44F28186405DD8C400650B1E87DB84981CC250C6CE00120319CD6AD00CEE30E48D59F6E1983AEBA91D57A47DBF072A0A13CAEE426DED9E5635895780746DADAACD568E70B7462FBA117CE8F869D447CBBF2753CCE8FC6BD4934EE4D112EEB9AA2
q の値で素数であることの確認
以下のPythonのファイルを用意します。
def is_prime(q):
q = abs(q)
if q == 2: return True
if q < 2 or q&1 == 0: return False
return pow(2, q-1, q) == 1
def main():
x = 149964660518396798660782215517197000054264985822608779681144262791391323000835825727277636178043097046988857828384650158626906824855399961360412435818827649355003329726451846544435103030378220357694459358803967598155925736581896165952170564324730092516286266118841005062382011803493961966912439338500328959743
z = is_prime(x)
print z
if __name__=="__main__":
main()
上記ファイルを実行すると、以下の結果が出力されます。
True
取得した画像
正常に完了した場合、以下のような画像を取り出すことができます。