The s in rsa stands for secure.
By alex (@kyrili : not the isss officer - someone y’all don’t know)
Contact jocelyn (@jocelyn3270 on discord)
nc betta.utctf.live 4374
Connect to the service. The service provides us with an N value and an e value that last for the entire instance. We are provided an oracle that will infinitely sign messages for us. Once we enter 0 into the program, the oracle will ask us to produce our own valid message and signature pair (such that the message has not been requested previously).
Note that RSA signatures are calculated as follows:
And the receiver of the RSA signature can raise to the power to confirm that the message is actually from the owner of the RSA private key:
The goal of this challenge is known as a forgery attack, in which an attacker attempts to forge a valid message and signature pair, pretending to tbe owner of the RSA private key. In this case, the simplest forgery attack can be used. Here’s why:
- Let’s first query the oracle for the signatures of two distinct messages:
- Now, consider what would happen if we multiplied these two equations/congruence relations:
Note that we have now produced a valid message and signature pair! The product of is the message that corresponds to the signature
Therefore, in order to forge the signature, we can first query the oracle for the signatures for two messages (I used 2 and 3) and then, after sending 0 to terminate the oracle, send the result of as the message and the result of as the signature to get the flag!
Here’s the implementation:
from pwn import *
p = remote("betta.utctf.live", 4374)
p.recvline()p.recvline()p.recvline()
m1 = 2m2 = 3n = int(p.recvline().decode('ascii')[:-1].split(' ')[-1])p.recvuntil(b': ')p.sendline(str(m1).encode())s1 = int(p.recvline().decode('ascii')[:-1].split(' ')[-1])p.recvuntil(b': ')p.sendline(str(m2).encode())s2 = int(p.recvline().decode('ascii')[:-1].split(' ')[-1])
m_forge = (m1*m2)%ns_forge = (s1*s2)%n
p.recvuntil(b': ')p.sendline(b'0')p.recvline()p.sendlineafter(b': ', str(m_forge).encode())p.sendlineafter(b': ', str(s_forge).encode())p.interactive()Run the script to get the flag!
utflag{a1m05t_t3xtb00k_3x3rc153}