TCPサーバの接続情報が与えられた。
Informattion to connect to a TCP server was given.
Connecting to the server using
これは、Key exchangeと同様の処理を、Aを出力せずに行っていると予想した。
そうだとすれば、shared_secretの値を求めることができれば暗号化の鍵を求めることができるはずである。
Key exchange においては、shared_secretは入力されたBの値をa乗してpで割った余りをとることで作られる。
ということは、もし1以外に mod p における1の3乗根が存在すれば、
その数をBとして入力すると、shared_secretはB、Bの2乗、1のどれかになるはずである。
先ほどのサーバの出力の例について、以下のようにして1の3乗根を求めた。
pの値によっては1以外の3乗根が求まらないことがあったが、何回か接続し直すと1以外の3乗根が求まるpの値になった。
I guessed that this is doing a process like one done in Key exchange without printing the value of A.
Assuming that, we can get the encryption key by obtaining the value of shared_secret.
In "Key exchange", shared_secret is B to the a-th power modulo p.
Therefore, if the 3rd root of 1 modulo p other than 1 exists,
using the value as B will make shared_secret one of B, the square of B, or 1.
Regarding the example of the output from the server, I used 1.
There were no 3rd roots other than 1 for some value of p, but a value of p with which we can calculate 3rd roots other than 1 appeared after several reconnections.
求まった3乗根の1つ
This is one of the 3rd roots:
をサーバに送信すると、以下の出力が得られた。
Sending this value to the server, it printed this:
PythonのインタラクティブモードでB、およびBの2乗をpで割った余りの16進表現を求め、
以下のように
I obtained hexadecimal representations of B and square of B modulo p using the interactive mode of Python,
and obtained corresponding encryption keys using
Fork, From Hex, SHA1, Drop bytes - CyberChef
さらに、以下のようにしてそれぞれの暗号鍵で得られた暗号文の復号を行った。
Then, I decrypted the ciphertext sent from the server using each encryption keys in these steps:
その結果、flagが得られた。
I obtained the flag from the result.