En este post resolveremos el reto 6 de la CyberCamp 2018, es un reto de criptografía de nivel medio.

Enunciado

Nuestros expertos han capturado un pendrive que contenía estos dos ficheros, pero parece que uno de ellos ha sufrido daños… (Respuesta: flag{X})

Ficheros: key.pem y secret.txt
Aquí teneis un enlace para poder descargaros los retos y probarlo vosotros mismos: RetosCyberCamp2018.zip

Solución

key.pem

-----BEGIN RSA PRIVATE KEY-----
MIIBOwIBAAJBAMSwf+/I42wFwNpDQiGuv0fb9w5Ria2JJAjzrYEYKp4HAKB8nXxm                                       
yGx6OWAhI+4PYFYT3pf95J/mg5buCvP19fMCAwEAAQJAKuxRnyR57PL8eSVAY1Vd                                       
TPNF4QwOPZ62DHYRISEC++UtRemqE1eBPkRgswiJ91+r9y8EnVw/SvL4GYQmeovS                                       
sQIhAOq8Heinxe4udriNOd35SgJV9e87YglCCIfCoAirR0qtAiEA1oIMcKaiRiUj                                       
2S/Q4YFTNySdT+fH16huoSQrEapD9x8*********************************                                       
****************************************************************                                       
********************************************
-----END RSA PRIVATE KEY-----

El objetivo será obtener la rsa completa que nos permita desencriptar el fichero secret.txt que contiene el flag.
Para identificar las partes de la clave privada y poder conseguir una completa nos ayudaremos de: OpenSSL 512 bit RSA Private Key Breakdown

Tal y como leemos en la fuente anterior lo primero que haremos será pasar a hexadecimal la clave privada:

#!/usr/bin/python3
import base64
import re

f = open('key.pem','r')
text = f.read()
b64re = re.search('-----BEGIN RSA PRIVATE KEY-----(.*?)\*',text,re.DOTALL)

b64text=''
for i in b64re.groups():
	b64text+=i
b64text += '=='
hextext= base64.b64decode(b64text).hex()
print(hextext)

Ejecutando este codigo obtenemos el hexadecimal:

3082013b020100024100c4b07fefc8e36c05c0da434221aebf47dbf
70e5189ad892408f3ad81182a9e0700a07c9d7c66c86c7a39602123
ee0f605613de97fde49fe68396ee0af3f5f5f3020301000102402ae
c519f2479ecf2fc79254063555d4cf345e10c0e3d9eb60c76112121
02fbe52d45e9aa1357813e4460b30889f75fabf72f049d5c3f4af2f
81984267a8bd2b1022100eabc1de8a7c5ee2e76b88d39ddf94a0255
f5ef3b6209420887c2a008ab474aad022100d6820c70a6a2462523d
92fd0e1815337249d4fe7c7d7a86ea1242b11aa43f71f

Con ayuda de la fuente mencionada (OpenSSL 512 bit RSA Private Key Breakdown) obtenemos el valor del modulus y del privateExponent que serán suficiente para obtener una rsa.

Estas lineas de python nos harán más sencillo el trabajo de buscarlos:

RSAparts = re.search('.*0241(.*?)02030100010240(.*?)0221.*',hextext)
print ('Modulus: ' + RSAparts.group(1))
print ('PrivateExponent: ' + RSAparts.group(2))

Vamos a pasar a decimal el valor de estos:

print('Modulus: ' + str(int('00c4b07fefc8e36c05c0da434221aebf47dbf70e5189ad892408f3ad81182a9e0700a07c9d7c66c86c7a39602123ee0f605613de97fde49fe68396ee0af3f5f5f3',16)))
print('PrivateExponent: ' + str(int('2aec519f2479ecf2fc79254063555d4cf345e10c0e3d9eb60c7611212102fbe52d45e9aa1357813e4460b30889f75fabf72f049d5c3f4af2f81984267a8bd2b1',16)))
Modulus: 10301462485885628960044483731568219162112763799280370427320989812791133660478338863686400103379584534619195146948984319238450317509883535167584488637462003
PrivateExponent: 2248066229353437987496470792512453582808745408811936125418386503845748105835761421582818218461308527222315728160111745761960814756422210129349807952351921 

He unido todos estos pasos en un solo script: GitHub – 06_getRSA.py

Con la herramienta rsatool obtendremos la rsa para desencryptar el secret.txt:

python rsatool.py -f PEM -o k.pem -n 10301462485885628960044483731568219162112763799280370427320989812791133660478338863686400103379584534619195146948984319238450317509883535167584488637462003 -d 2248066229353437987496470792512453582808745408811936125418386503845748105835761421582818218461308527222315728160111745761960814756422210129349807952351921

openssl rsautl -decrypt -in secret.txt -out /tmp/result.txt -inkey k.pem

¿Me ayudas a compatirlo?