CSR con nulos bytes en ellos

1

Según el artículo de wikipedia.org en certificados X.509 , " hay implementaciones errores con X.509 que permiten, por ejemplo, nombres de sujetos falsificados usando cadenas terminadas en nulo Marlinspike Blackhat 2009 o ataques de inyecciones de código en certificados. "Mi pregunta es ... ¿cómo creo un CSR con bytes nulos dentro de ellos?

Aquí hay una CSR que sí tiene una:

-----BEGIN CERTIFICATE REQUEST-----
MIIBSTCBtQIBADAQMQ4wDAYDVQQKDAVhYgBjZDCBnTALBgkqhkiG9w0BAQEDgY0A
MIGJAoGBALoqjrGPCxX2oWX8APXhB3dzKJAXWHKWSlMWDw1whCP+EpsdFY2pTq+D
RnX8wRIP2yssIii/4FwsDxjcjlYMpSqYBPnEq3Lql/7LeW5ulLn4wk4Gnd4B55WP
BLveMNCORZXtE5rNJISTRMHYZKp7sLOPFlE3Gb5G/o/rkxSqOKOPAgMBAAEwCwYJ
KoZIhvcNAQEFA4GBAB0CX/T2wBTHHE6dcCFwzXsVkqkoewQbLjDLoAjCBy7nFrCI
6+kLPj7zcYi6f+Jg+OcFMl0Oat+2iO7OARSib3S0WyuAFpJQQwZIiG9RISy2HF1A
jQPuWvOan1GsY74Dn0kac6BIaWlY0/9h/iIcl4BiUaFrW+xUinKGWofsdq8l
-----END CERTIFICATE REQUEST-----

Según asn1parse el valor correspondiente a la organizationName tiene una longitud de 5, aunque la cadena mostrada tiene un longitud de cuatro. La cosa es que hay un byte nulo entre el ab y el cd. Esa CSR se generó con una biblioteca llamada phpseclib, pero me gustaría saber cómo generar CSR similares con OpenSSL o alguna otra herramienta más estandarizada.

Intenté esto pero no funcionó:

openssl req -new -key privkey.pem -out test.csr -subj "/O=ab
-----BEGIN CERTIFICATE REQUEST-----
MIICVzCCAT8CAQAwEjEQMA4GA1UEChMHYWIwMDBjZDCCASIwDQYJKoZIhvcNAQEB
BQADggEPADCCAQoCggEBAKe9z81r0pvpqN98WinJVAphD0bRqi1W6OrEh9rx0DPO
RILofZwLP11d8vot19VMHBqB+kQuhtWKc/2Te+F1fgy1NJjcF+tjErE038zMd4O6
sU7QiVuFKRceznaXiL2BKm5nCR5FBMj2gBu2WJ61mUKEkNYEvj7QtcMc/VUTYISq
D2DFoGmSjgltCtUyMqaSGtS6f2fqHFBvxVwLBDm+XSYYLrEREk2PmM1RbFY1b9fO
lKnrvRIN4X+RbqG9iF88Ax5T0L2/D1OjLD24eFY8m/ecrsMwxCAa9FL+oKIvT7M0
OGK+LWOkPpjKwegnppFYGOCEfLBDocSgD8z2AuV24usCAwEAAaAAMA0GCSqGSIb3
DQEBBQUAA4IBAQBmQwFqS8L4YO17hpTZTr/mKq0Mgzzf8PCI6d1OtRgKUM5LbFBX
WqCJSUzSrkCGQdMdFA9l20jw91gxaeLiEDbAS+1I8agel/TD6Hic5457HjyGbPx4
usqm0/c1/JRreG/1dyh2K6/TFPIN8dN++dLohmZlRWZdIMC0D/KNls5M++DiWqw3
J5S24BWIC6FOUsAs5EImd30+s4wXcL+uqlRmyQVZ3C+JI8ZBl5HuIKCLmS2d3rhG
/CBwlZHH4fyeYUpeWec6HUNjfvnJ8amDFyKPlbTgcSSEpXBBPGP4EJ+zrWFjZRe3
YDCxZ0RdBHjKsYzbJZDJEOe9YML5HqoXY1pr
-----END CERTIFICATE REQUEST-----
0cd"

Eso me consiguió esto:

-----BEGIN CERTIFICATE REQUEST-----
MIIBSTCBtQIBADAQMQ4wDAYDVQQKDAVhYgBjZDCBnTALBgkqhkiG9w0BAQEDgY0A
MIGJAoGBALoqjrGPCxX2oWX8APXhB3dzKJAXWHKWSlMWDw1whCP+EpsdFY2pTq+D
RnX8wRIP2yssIii/4FwsDxjcjlYMpSqYBPnEq3Lql/7LeW5ulLn4wk4Gnd4B55WP
BLveMNCORZXtE5rNJISTRMHYZKp7sLOPFlE3Gb5G/o/rkxSqOKOPAgMBAAEwCwYJ
KoZIhvcNAQEFA4GBAB0CX/T2wBTHHE6dcCFwzXsVkqkoewQbLjDLoAjCBy7nFrCI
6+kLPj7zcYi6f+Jg+OcFMl0Oat+2iO7OARSib3S0WyuAFpJQQwZIiG9RISy2HF1A
jQPuWvOan1GsY74Dn0kac6BIaWlY0/9h/iIcl4BiUaFrW+xUinKGWofsdq8l
-----END CERTIFICATE REQUEST-----

es decir. el nombre de la organización es ab000cd, no ab \ 00cd.

    
pregunta neubert 12.06.2014 - 15:51
fuente

1 respuesta

4

Estas cosas normalmente se hacen mediante programación. Las aplicaciones de línea de comandos de OpenSSL están restringidas de muchas maneras y no dan acceso a todo el poder de la biblioteca subyacente. Si observa el código fuente , encontrará la implementación del comando req en apps/req.c . Para el análisis del nombre del sujeto, ese comando se basa en la función parse_name() (definida en apps/apps.c ). Esa función crea internamente los elementos de nombre como tantas cadenas C terminadas en nulo que, por definición, no pueden contener un byte nulo. Por lo tanto, no hay forma posible de lograr lo que busca solo con esa herramienta.

Entonces, una opción es simplemente descargar el código fuente de OpenSSL, parche apps/req.c para incluir un byte nulo donde lo desee, compilarlo y ejecutarlo. Esto requerirá un poco de conocimiento de C. Querrá usar la X509_NAME_add_entry_by_txt () función (o uno de sus acólitos), con un parámetro len explícito (no -1) para usar como "cadena" una secuencia de bytes que incluye su byte nulo. Si observa parse_name() en apps/apps.c , verá que invoca X509_NAME_add_entry_by_NID() con len establecido en -1: ese es el punto exacto que querrá cambiar.

Otra opción es generar una solicitud de certificado "normal", con otra letra donde le gustaría tener su byte nulo (por ejemplo, una 'Z'). Luego, asegúrese de convertir su solicitud al formato binario ("DER"); luego use un editor de archivos binarios para reemplazar la 'Z' con un byte de valor 0; luego vuelva a calcular la firma para que coincida con el contenido de la nueva solicitud. Este último paso se puede realizar con las herramientas básicas de la línea de comandos de Linux ( dd para la cirugía de archivos, sha1sum para obtener un nuevo hash, dc para hacer la aritmética de enteros grandes) pero debe dominar ambos ASN.1 / DER y PKCS # 1 , y si lo hiciera, no habría hecho la pregunta que hizo.

    
respondido por el Tom Leek 12.06.2014 - 16:24
fuente

Lea otras preguntas en las etiquetas