TCPサーバの接続情報と、ファイル sha256ctr.py
が与えられた。
sha256ctr.py
は、ブロックごとに、カウンタの値のバイト列表現のSHA-256ハッシュ値をメッセージとxorし、カウンタに1を足す、という方法で暗号化するプログラムであり、以下の機能がある。
まず、SHA-256の仕様を確認する。
Information for connecting to a TCP server, and a file sha256ctr.py
were given.
sha256ctr.py
is a program that encrypts messages by, for each blocks, performing XOR of the message and SHA-256 hash value of the counter value represented as bytes, and then adding 1 to the counter value.
It has these functions:
To begin with, let's check the specification of SHA-256.
RFC 6234 - US Secure Hash Algorithms (SHA and SHA-based HMAC and HKDF)
SHA-256の計算は、メッセージにその長さを用いた指定の形式のパディングを加えた後、ブロックごとに計算を行って状態を更新することで行う。
そして、最終ブロックを処理した後の状態が、そのままハッシュ値として出力される。
このため、ハッシュ値がわかっているメッセージにパディングに相当するデータを加えて新しいメッセージを作成すると、
もとのメッセージそのものはわからなくても、もとのメッセージのハッシュ値を用いて新しいメッセージのハッシュ値を求めることができる。
具体的には、以下の手順でflagの暗号化に用いられるハッシュ値を求めることができる。
まず、カウンタの初期値は高々256ビットなので、それより大きめの値を送ることでメッセージの長さを固定できる。
今回は、
Calculation of SHA-256 is performed by adding padding in specified format using the message length to the message and updating the status via calculation for each blocks.
The status after processing the last block is outputted as the hash value without modification.
Because of this characteristics, when data that matches with the padding is added to a message with known hash value to create a new message,
we can calculate the hash value for the new message from the hash value of the original message without knowing the original message itself.
In this case, we can obtain the hash value used for encrypting the flag in these steps.
Firstly, since the initial value of the counter is at most 256-bit long, we can fix the length of the message by sending a value larger than the size.
I decided to send this value:
を送ることにした。
これを送ると、メッセージは38バイトになり、このときのパディングは 80 ... 00 00 00 00 00 00 01 30
である。
次に、メッセージとして32バイトのゼロ、すなわち
Sending this, the message becomes 38-byte long and the padding for this message will be 80 ... 00 00 00 00 00 00 01 30
.
Then, send a 32-byte sequence of zero as a message for encryption:
を送って暗号化させる。
すると、暗号文としてカウンタの値のSHA-256ハッシュ値が得られる。
そして、メッセージとしてパディングのデータを追加するような値をカウンタに加える。
すなわち、今回は
Doing this, we can obtain the SHA-256 hash value of the counter value as the ciphertext.
Then, add a value to the counter to add a padding data as the message.
Specifically, send this value in this case:
を加える。このとき、1回暗号化したことによりカウンタに1が加算されたのを打ち消すため、1を引いた値を加えるのがポイントである。
この状態でflagを暗号化する。
このとき、ハッシュ値を求めるメッセージは64バイトである。
最初のブロックの暗号化に用いられるハッシュ値は、先ほど求めたハッシュ値の状態から、ブロック 80 00 00 00 ... 00 00 02 00
に対する計算により状態を進めることで得られる。
ハッシュ値を入力とし、このブロックに対する計算をして新しいハッシュ値を求める以下のプログラムを作成した。
Note that we should subtract 1 from the value to add to cancel the addition of 1 caused by doing the encryption once.
Then, encrypt the flag.
Here, the message for which a hash value will be calculated is 64-byte long.
The hash value used for encrypting the first block can be obtained by advancing the status from the hash value obtained before using a block 80 00 00 00 ... 00 00 02 00
.
I created this program to take a hash value and calculate new hash value using this block.
このプログラムで求めた新しいハッシュ値と、flagを暗号化した暗号文をxorすると、flagの前半部分が得られる。
ただし、今回のflagを暗号化した暗号文は、2ブロック分の長さがある。
この手順において、(0x3001 << (8 * 62)) + (0x80 << (8 * 38)) - 1
を加えるかわりに、1ではなく2を引いた値
We can obtaine the former part of the flag by performing XOR of the new hash value calculated using this program and the ciphertext of the flag.
Note that the ciphertext for the flag is 2-block long here.
In these steps, instead of adding (0x3001 << (8 * 62)) + (0x80 << (8 * 38)) - 1
, adding this value with 2 subtracted instead of 1:
を加えると、2を引いたのがハッシュ値を求めるための暗号化およびflagの前半の暗号化と相殺して、flagの後半の暗号化に calc.py
で計算できるハッシュ値が用いられる。
よって、新しいハッシュ値とxorすることで、flagの後半部分が得られる。
これらを組み合わせることで、flagが得られた。
Will make the hash value that can be calculated using calc.py
used for encrypting the latter part of the flag because the 2 subtracted will be canceled with encryptions for obtaining the hash value and for the former part of the flag.
We can obtain the latter part of the flag by performing XOR of the new hash value and the ciphertext.
I obtained the flag by combining these results.