RCTF 2017 / RSA sign2
May 22, 2017
Task : https://ctftime.org/task/4171
First get (N / e / key_len)
Using ruby to get N and E
To get N
$ruby -r openssl -e 'p OpenSSL::PKey::RSA.new(File.open("public.pem")).n.to_i'
#output 99103278939331174405096046174826505890630650433457474512679503637107184969587849584143967014347754889469667043136895601008192434248630928076345525071962146097925698057299368797800220354529704116063015906135093873544219941584758892847007593809714204471472620455658479996846811490190888414921319427626842981521
To get E
$ruby -r openssl -e 'p OpenSSL::PKey::RSA.new(File.open("public.pem")).e.to_i'
#output : 3
As E is == 3 (CVE-2016-1494)
And key length
$ruby -r openssl -e 'p OpenSSL::PKey::RSA.new(File.open("public.pem")).n.num_bits'
#output : 1024
Exploit Bleichenbacher’s RSA signature forgery
import os
import binascii
import hashlib
import rsa
from pwn import *
from gmpy2 import mpz, iroot, powmod, mul, t_mod
def to_bytes(n, endianess='big'):
h = '%x' % n
s = ('0'*(len(h) % 2) + h).decode('hex')
return s
def from_bytes(b):
return int(b.encode('hex'), 16)
def get_bit(n, b):
return ((1 << b) & n) >> b
def set_bit(n, b, x):
if x == 0: return ~(1 << b) & n
if x == 1: return (1 << b) | n
def cube_root(n):
return int(iroot(mpz(n), 3)[0])
message = "0YMrY4ZuMYU2YhoTZTSZROgC0HTQNI6M".encode("ASCII")
message_hash = hashlib.md5(message).digest()
ASN1_blob = rsa.pkcs1.HASH_ASN1['MD5']
suffix = b'\x00' + ASN1_blob + message_hash
sig_suffix = 1
for b in range(len(suffix)*8):
if get_bit(sig_suffix ** 3, b) != get_bit(from_bytes(suffix), b):
sig_suffix = set_bit(sig_suffix, b, 1)
while True:
prefix = b'\x00\x01' + os.urandom(1024/8 - 2)
sig_prefix = to_bytes(cube_root(from_bytes(prefix)))[:-len(suffix)] + b'\x00' * len(suffix)
sig = sig_prefix[:-len(suffix)] + to_bytes(sig_suffix)
if b'\x00' not in to_bytes(from_bytes(sig) ** 3)[:-len(suffix)]: break
exploit = binascii.b2a_hex(sig)
print "message : 0YMrY4ZuMYU2YhoTZTSZROgC0HTQNI6M"
print "exploit : " ,exploit
r = remote('rsasign1.2017.teamrois.cn', 3001)
print r.recvuntil('Show me your magic words:\n')
r.send(message)
print r.recvuntil('Show me again:\n')
r.send(exploit)
print r.recv(1024)
#RCTF{perfect_si9_i_can_nerver_Do_b3tter}