miércoles, julio 06, 2011

ASP.Net autenticando con LDAP en Active Directory

El gran Andres Riancho, creador de w3af, ha escrito un post tocando uno de mis temas favoritos: LDAP Injection. Hace ya tiempo que dejé un poco de lado estos temas, ya que le dediqué el 2007 y 2008 al tema de las inyecciones LDAP, tiempo suficiente para que me apeteciera hacer otras cosas, pero como me han llegado varios mensajes pidiendo aclaración sobre si funciona el ejemplo o no en ASP.NET y AD que propone el ejemplo, voy a este tema por un post.

En el artículo publicado, creo que se cometen algunas imprecisiones que son dignas de resaltar, ya que el ejemplo que aparece no funciona tal y como está descrito, y puede llevar a error a muchos personas, así que vamos a hacer un resumen.

Resumen de las diferentes implementaciones LDAP

El primer paper que habla de LDAP Injection, el de Sacha Faust, hacía un ejemplo de inyección en el que a partir de un filtro LDAP simple, es decir, algo como (atributo=valor) inyectaba un filtro compuesto, haciendo algo como (atributo=injección), donde en injección ponía un nuevo filtro LDAP del tipo foo)(|(atributo2=valor).

Esa acción genera 2 filtos LDAP y no funciona ni en OpenLDAP ni en Microsoft ADAM [Active Directory Application Mode] o el nuevo MS LDS [Ldap Directory Services]. OpenLDAP porque solo ejecuta el primer filtro y desecha el segundo al no ser una lista de atributos válidos, Microsft LDS o ADAM porque no está correctamente formado (son 2 y no lo permite el estándar).

Esa inyección funciona en el ejemplo de Sacha Faust porque usa un servidor SUN que permite la ejecución de dos filtros LDAP en una única consulta -como si fuesen independientes-, pero no en OpenLDAP o MS AD, ADAM o LDS. Todo esto está explicado en el artículo titulado Jugando con LDAP.

Como curiosidad, el componente IPWorks*ASP LDAP que usa Sacha, y que usamos nosotros en nuestro Reto Hacking IV y en la escritura del paper, realiza un borrado de todo aquello que está fuera del primer filtro, lo que provoca situaciones muy curiosas, como que las inyecciones LDAP que generan 2 filtros se anulen, y solo quede el primer filtro.

Implementaciones Microsoft y filtros compuestos

Sin embargo, si el filtro es uno compueto, es decir, que tiene más de un condicionante, con un operando AND u OR, entonces sí que se pueden hacer inyecciones en árboles LDAP de Microsoft, siempre y cuando generen un único filtro LDAP en una consulta.

Así, el ejemplo que ponía Andres Riancho sobre saltarse la autenticación en un árbol LDAP de Microsoft, se podría hacer, tal y como expliqué en el artículo or 1=1 en LDAP. En un filtro escrito por el programador como el siguiente:

(&(uid=valor_usuario)(webpassword=valor_password))

¿Cómo conseguir acceso con un usuario sin saber la password? Pues como no se pueden generar dos filtros en la inyección, hay que conseguir que se genere un único filtro. Para ello habría que introducir algo como:

Valor_usuario = admin)(!(&(|
Valor password = any))


El resultado tras esta inyección sería:

(&(uid= admin)(!(&(|)(webpassword= any))))

Y no como se plantea en el post con una inyección que genere algo como (&(user=andres)(&))(password=notimportant)). Esto solo sería válido si se está utilizando un componente como IPWorks*ASP LDAP, con un comportamiento tan peculiar como el explicado de borrar el segundo filtro, o si se está utilizando un árbol OpenLDAP.

En cualquier caso, si se usa el componente por defecto de ASP.NET para conectarse a un árbol LDAP sea el que sea, ese componente es seguro y no permite inyección. Así que, para que el ejemplo publicado tenga sentido se deberían cumplir las siguientes condiciones:

1) No se usa el componente LDAP por defecto de ASP.NET
2) Se está usando un componente que jamás envía los dos filtros al árbol LDAP

Sin embargo, la parte de detección del ataque sería totalmente cierta.

Si te gusta el tema del LDAP Injecction tienes más información aquí:

- Ataques a LDAP
- LDAP Injection and Blind LDAP Injection
- Jugando con LDAP
- Or 1=1 en LDAP
- LDAP Injector
- El listín de teléfonos
- Whitepaper LDAP Injection & Blind LDAP Injection [Inglés]

Saludos Malignos!

3 comentarios:

  1. SELECT * FROM items
    WHERE owner = 'hacker'
    AND itemname = 'name';

    DELETE FROM items;

    SELECT * FROM items WHERE 'a'='a';
    ---------------------------------
    searchlogin= "(&(uid="+user+")(userPassword={MD5}"+base64(pack("H*",md5(pass)))+"))";

    values:
    user=*)(uid=*))(|(uid=*
    pass=password

    ResponderEliminar
  2. Amigo, creo que te ha pasado que tanto leer la palabra inyección en inglés la has escrito mal en el artículo. Es con "y". A parte de eso, muy buen material. Gracias. Un saludo.

    ResponderEliminar
  3. @Winston Smith

    amigo, eso no funciona en AD ya que dos filtros dan error. Hax0r!

    Saludos!

    ResponderEliminar