DiceCTF 2024 - winter
This is the solution of the challenge “winter” from Dice CTF. Winternitz signature allowing to forge a signature from a previous valid signature.
Details
Author: defund
Points: 116
Description
A simple implementation of the Winternitz signature scheme.
|
|
Downloads server.py
Solution
The scheme is a Winternitz signature. It should used only to sign a single message but here we are allowed to sign two of them. The message is hashed with SHA256. Then each byte is taken individually and interpreted as integer $n_0, n_1, …, n_{256}$
Each private key $q_0, q_1, …, q_{256}$ is iteratively hashed to obtain the signature $s_0, s_1, …, s_{256}$:
$$s_i = H^{256-n_i}(q_i)$$
The first signature is returned to us. Thus if we are able to find two messages $m_1$ and $m_2$ such that each bytes of the hash $h_1$ of $m_1$ are less than each bytes of the hash $h_2$ of $m_2$ we can forge a new signature by computing:
$$\tilde{s_i} = H^{\tilde{n_i}-n_i}(s_i)$$
To find such message I decided to used Bitcoin blocks which have a lot of null bytes, it would allow to reduce the search space. Then I iterated over bitcoin blocks until I found one with a maximum byte value not too high:
|
|
It turns out that block 000000000000000000035796cb87b186324e5b0620312c413b9472895f302667 was a good candidate. I found the corresponding message with a tool I wrote previously:
|
|
Then we need to find another message with the each hash byte bigger the the previous hash:
|
|
Now from the signature returned by the server we can forge a new signature for our message:
|
|
Finally the server accepts the signature and prints the flag:
|
|