TCPサーバの接続情報と、サーバのプログラム script.py
が与えられた。
script.py
は、以下の処理をするものだった。
flag.txt
の内容を読み込み、それをもとに整数m
を生成するp, q
とするm
の257乗をp*q
で割った余りを計算し、ct
とする(p-1)*(q-1)
における逆元d
を求めるn, 257, ct
を出力するs
の入力を受け付けるd
をs
で割った余りを出力する
s
として1 << 139 = 696898287454081973172991196020261297061888
を与えると、
この値は2の140乗未満になり、出力される余りはd
の下位139ビットになる。
すると、d
の下位ビットがp*q
のビット数の1/4程度得られるので、
SageMathを使ってCoppersmith's Attackをやってみる - ももいろテクノロジー
を参考にd
の値が復元できそうに思えた。
しかし、このページのプログラムをそのまま動かしてもd
の値は得られなかった。
そこで、得られているd
の値の上位に何ビットかを全探索で補うようにした。
Information to connect to a TCP server and a server program script.py
were given.
What script.py
does is:
flag.txt
and generate an integer m
based on that.p, q
.m
to the 257th power modulo p*q
and name it ct
.(p-1)*(q-1)
and name it d
.n, 257, ct
.s
which is not less than 1 and less than 2 to the 140th power.d
modulo s
.
Entering 1 << 139 = 696898287454081973172991196020261297061888
as s
,
this value should be less than 2 to the 140th power and the remainder will be the least 139 bits of d
.
This means that we can obtain the lower part of p
and its length is about 1/4 of the bit length of p*q
.
Referring to SageMathを使ってCoppersmith's Attackをやってみる - ももいろテクノロジー,
it seemed the value of d
can be recovered.
However, the value of d
wasn't found by simply running the program on the page.
Seeing this, I had it to add several bits to the top of the obtained part of d
by brute-forcing.
Using the Shell in
I got this result after about 45 minutes:
得られたd
の値を用い、以下のように復号を行った。
I decrypted the message with the obtained value of d
in this way:
この復号結果に
I obtained the flag by applying "From Hex" on