Autor Tema: Rompiendo el captcha de Movistar (en 75 líneas de código)  (Leído 9442 veces)

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

Desconectado mxgxw

  • Global Moderator
  • The Communiter-
  • *
  • Mensajes: 5665
  • Starlet - 999cc
    • mxgxw
Rompiendo el captcha de Movistar (en 75 líneas de código)
« : diciembre 23, 2011, 10:52:49 pm »
Disclaimer: Este post se ha realizado con motivos únicamente EDUCACIONALES, se incluye una prueba de concepto. El uso que le den a este código no es mi responsabilidad. OK

¿Por qué? El formulario de envío de mensajes de Telefónica tiene un captcha sumamente sencillo, que puede ser "roto" utilizando librerías abiertas de OCR. Para esta prueba de concepto voy a utilizar la herramienta Tesseract que es un programita escrito en C que sirve para realizar OCR de texto.

¿Qué tenemos que hacer para romper el captcha?

1-Iniciar una sesión con la página de envío de SMS de telefónica.
2-Descargar la imágen utilizando el Cookie de sesión enviado por el servidor.
3-Convertir la imágen a monocromático.
4-Enviar la imágen a una biblioteca de OCR.
5-Desplegar el resultado.

Habiendo dicho esto, les dejo el código y luego explico los detalles:

Código: (Program.cs) [Seleccionar]
/*
 * Created by SharpDevelop.
 * Author: Mario Gomez
 * Date: 23/12/2011
 * Time: 08:27 p.m.
 * Este código está protegido bajo la licencia GNU/GPL 2.0 o posterior.
 */
using System;
using System.Net;
using System.Web;
using System.IO;
using System.Media;
using System.Drawing;
using tessnet2;
using System.Collections;
using System.Collections.Generic;

namespace MensajitoCSharp
{
class Program
{
public static void Main(string[] args)
{
WebClient client = new WebClient();
client.Headers.Add("User-Agent"," Mozilla/5.0 (Windows NT 6.1; WOW64; rv:8.0.1) Gecko/20100101 Firefox/8.0.1");

Console.WriteLine("Request headers:");
for(int i=0;i<client.Headers.Count;i++) {
Console.WriteLine(client.Headers.AllKeys[i]+":"+client.Headers[i]);
}
Console.WriteLine("URL: http://corporativo.telefonica.com.sv/EnviarSMSSV/faces/EnviarSMS.jsp");
TextReader reader = new StreamReader( client.OpenRead("http://corporativo.telefonica.com.sv/EnviarSMSSV/faces/EnviarSMS.jsp"));
reader.Close();

Console.WriteLine("Response headers:");
for(int i=0;i<client.ResponseHeaders.Count;i++) {
Console.WriteLine(client.ResponseHeaders.AllKeys[i]+":"+client.ResponseHeaders[i]);
}

client.Headers.Add("Cookie",client.ResponseHeaders["Set-Cookie"]);

Console.WriteLine("Request headers:");
for(int i=0;i<client.Headers.Count;i++) {
Console.WriteLine(client.Headers.AllKeys[i]+":"+client.Headers[i]);
}
Console.WriteLine("URL: http://corporativo.telefonica.com.sv/EnviarSMSSV/faces/EnviarSMS.jsp?vrClientId=form1:imageEx1");
client.DownloadFile("http://corporativo.telefonica.com.sv/EnviarSMSSV/faces/EnviarSMS.jsp?vrClientId=form1:imageEx1",@".\output.png");

Console.Read();

Bitmap img = new Bitmap(@".\output.png");

int x,y;
Color currentColor;
for(x=0;x<img.Width;x++) {
for(y=0;y<img.Height;y++) {
currentColor = img.GetPixel(x,y);
img.SetPixel(x,y,(currentColor.R<192 && currentColor.G<192 && currentColor.B<192) ? Color.Black : Color.White);
}
}

img.Save(@".\output_processed.png");

tessnet2.Tesseract ocr = new tessnet2.Tesseract();
ocr.SetVariable("tessedit_char_whitelist", "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ@/"); // If digit only
ocr.Init(@".\", "eng", false); // To use correct tessdata
List<tessnet2.Word> result = ocr.DoOCR(img, Rectangle.Empty);
foreach (tessnet2.Word word in result)
    Console.WriteLine("{0} : {1}", word.Confidence, word.Text);

}
}
}

Explico detalladamente:

1-Vamos a usar una clase del .NET Framework que resulta utilísima, esta es el WebClient. El WebClient simula un micro-navegador que nos ahorra el trabajo de abrir las conexiones leer los datos y demás. Para crear este objeto basta con que escribamos la siguiente línea de código:

Código: [Seleccionar]
WebClient client = new WebClient();

2-Luego de inicializar nuestro WebClient, lo vamos a "disfrazar" de Firefox, para hacer esto tenemos que establecer en nuestro encabezado un User-Agent. Realmente deberíamos de establecer otros encabezados, pero para fines prácticos solo voy a establecer el user agent. En los logs del servidor nuestra aplicación aparecerá como un Firefox más, a pesar de ser un bot.

Código: [Seleccionar]
client.Headers.Add("User-Agent"," Mozilla/5.0 (Windows NT 6.1; WOW64; rv:8.0.1) Gecko/20100101 Firefox/8.0.1");

3-Vamos a agregar un poco de información de debug para darnos una idea de que es lo que estamos enviando desde la consola:

Código: [Seleccionar]
Console.WriteLine("Request headers:");
for(int i=0;i<client.Headers.Count;i++) {
  Console.WriteLine(client.Headers.AllKeys[i]+":"+client.Headers[i]);
}
Console.WriteLine("URL: http://corporativo.telefonica.com.sv/EnviarSMSSV/faces/EnviarSMS.jsp");

4-Lo siguiente es hacer el Request. Para ello vamos a utilizar la función OpenRead. Por ahora no estamos interesandos en el output (HTML) de la página, simplemente en los encabezados, podríamos guardar la respuesta en un string si quisieramos luego revisar si se ha establecido alguna variable en el código que pudieramos utilizar. Mientras tanto solo vamos a leer la respuesta y vamos a cerrar nuestro reader.

Código: [Seleccionar]
TextReader reader = new StreamReader( client.OpenRead("http://corporativo.telefonica.com.sv/EnviarSMSSV/faces/EnviarSMS.jsp"));
reader.Close();

5-Para los curiosos, agregamos más información de debug que nos muestra los encabezados de la respuesta del servidor:
Código: [Seleccionar]

Console.WriteLine("Response headers:");
for(int i=0;i<client.ResponseHeaders.Count;i++) {
  Console.WriteLine(client.ResponseHeaders.AllKeys[i]+":"+client.ResponseHeaders[i]);
}

6-El siguiente paso es identificar los encabezados, estamos interesados en el encabezado "Set-Cookie", este encabezado le dice al navegador que cookies va a establecer. Recordemos que nuestro WebClient es un Micro-navegador, así que debemos especificarle que cookies son las que va a enviar para el siguiente Request.

Código: [Seleccionar]
client.Headers.Add("Cookie",client.ResponseHeaders["Set-Cookie"]);

7-Más información de debug, aquí deberían de ver la cookie que acabamos de establecer:

Código: [Seleccionar]
Console.WriteLine("Request headers:");
for(int i=0;i<client.Headers.Count;i++) {
Console.WriteLine(client.Headers.AllKeys[i]+":"+client.Headers[i]);
}
Console.WriteLine("URL: http://corporativo.telefonica.com.sv/EnviarSMSSV/faces/EnviarSMS.jsp?vrClientId=form1:imageEx1");

8-Ahora vamos a usar una función muy interesante, WebClient nos permite entre otras cosas descargar archivos. En esta ocasión vamos a descargar el PNG correspondiente al captcha generado para esa sesión, para descargar archivos vamos a usar la función DownloadFile, para utilizarla simplemente tenemos que especificar la URL y el archivo a donde queremos que se guarde. Para fines prácticos decidí utilizar "output.png"

Código: [Seleccionar]
client.DownloadFile("http://corporativo.telefonica.com.sv/EnviarSMSSV/faces/EnviarSMS.jsp?vrClientId=form1:imageEx1",@".\output.png");

9-Post proceso de la imagen. ¿Recuerdan que les dije que telefónica utiliza un captcha extremadamente sencillo. Esto es porque es una simple imágen con caractéres sobrepuesta a unas lineas grises. Así que para facilitar el trabajo del OCR, lo primero que vamos a hacer es... Eliminar las líneas grises.

¿Como hacemos esto? Vamos a hacer uso de la clase Bitmap, esta clase nos permite modificar los pixels de la imagen, lo que vamos a hacer es recorrer los pixels y todo lo que nos paresca gris lo vamos a hacer blanco, el resultado lo vamos a guardar en output_processed.png.

Código: [Seleccionar]
Bitmap img = new Bitmap(@".\output.png");

int x,y;
Color currentColor;
for(x=0;x<img.Width;x++) {
   for(y=0;y<img.Height;y++) {
currentColor = img.GetPixel(x,y);
img.SetPixel(x,y,(currentColor.R<192 && currentColor.G<192 && currentColor.B<192) ? Color.Black : Color.White);
}
}

img.Save(@".\output_processed.png");

Imagen original:


Imagen procesada:



OJO: Ese IF que puse solo funciona para escala de grises y convierte nuestra imagen en una versión monocromática, también elimina el anti-alias facilitando el proceso de OCR.

10-Por último, una vez con nuestra imágen procesada, simplemente pasamos el texto a nuestra biblioteca de OCR, en este caso estoy utilizando Tesseract-OCR 2.0 + el wrapper Tessnet2 para .NET.

Código: [Seleccionar]
tessnet2.Tesseract ocr = new tessnet2.Tesseract();
ocr.SetVariable("tessedit_char_whitelist", "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ@/");
ocr.Init(@".\", "eng", false);
List<tessnet2.Word> result = ocr.DoOCR(img, Rectangle.Empty);
foreach (tessnet2.Word word in result)
Console.WriteLine("{0} : {1}", word.Confidence, word.Text);

11-Compile y ejecute

Código: [Seleccionar]
PS C:\Users\Modem\Documents\SharpDevelop Projects\MensajitoCsharp\MensajitoCsharp\bin\Debug> .\MensajitoCsharp.exe
Request headers:
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64; rv:8.0.1) Gecko/20100101 Firefox/8.0.1
URL: http://corporativo.telefonica.com.sv/EnviarSMSSV/faces/EnviarSMS.jsp
Response headers:
Content-Language:en
Transfer-Encoding:chunked
Cache-Control:no-cache="set-cookie, set-cookie2"
Content-Type:text/html; charset=ISO-8859-1
Date:Sat, 24 Dec 2011 04:40:13 GMT
Expires:Thu, 01 Dec 1994 16:00:00 GMT
Set-Cookie:JSESSIONID=0000XaCFc9XxgmfG-CwHV75ZNYv:-1; Path=/
Server:WebSphere Application Server/6.1
Request headers:
Cookie:JSESSIONID=0000XaCFc9XxgmfG-CwHV75ZNYv:-1; Path=/
URL: http://corporativo.telefonica.com.sv/EnviarSMSSV/faces/EnviarSMS.jsp?vrClientId=form1:imageEx1

174 : pebR4

Screenshot:


Uploaded with ImageShack.us

+Info acerca de Tessnet2:
http://www.pixel-technology.com/freeware/tessnet2/

Para compilar y ejecutar van a necesitar descargar los siguientes archivos:
http://www.pixel-technology.com/freeware/tessnet2/bin.zip
http://code.google.com/p/tesseract-ocr/downloads/detail?name=tesseract-2.00.eng.tar.gz&can=2&q=

Gracias a naruto por haberme puesto a recordar viejos tiempos :) espero que esta info le sirva para su versión en PHP.


P.D.: OK realmente son menos de 75 líneas, el código necesario para realizar la decodificación del captcha solo son realmente como 15 líneas.. pero pues, hay que meter algo de info de debug tambien ;)

« Última Modificación: diciembre 23, 2011, 10:59:31 pm por mxgxw »


Desconectado wenner

  • Sv Vampire Team ®
  • Sv Full Member
  • ***
  • Mensajes: 835
Re: Rompiendo el captcha de Movistar (en 75 líneas de código)
« Respuesta #1 : diciembre 23, 2011, 10:55:31 pm »
Bien explicado mxgxw  :sur:

Desconectado Jarmandaros

  • -*-Miembro Eterno-*-
  • The Communiter-
  • *****
  • Mensajes: 3873
  • -^- Despicable Member -^-
    • Jarmandaros Blog
Re: Rompiendo el captcha de Movistar (en 75 líneas de código)
« Respuesta #2 : diciembre 23, 2011, 11:11:29 pm »
Para cuando la nueva version del XMR ?  :drinks:
Queres Vender o Comprar un producto X? unite al grupo del Tiangue! en Facebook, solo necesitas una cuenta en FB. EL Tiangue!
Visita mi Blog

Desconectado mxgxw

  • Global Moderator
  • The Communiter-
  • *
  • Mensajes: 5665
  • Starlet - 999cc
    • mxgxw
Re: Rompiendo el captcha de Movistar (en 75 líneas de código)
« Respuesta #3 : diciembre 23, 2011, 11:26:42 pm »
Saluditos a todos los SPAMMERS que han utilizado mi código de Mensajitos.php para enviar mensajitos no solicitados y que ahorita se están quebrando la cabeza pensando ¿Como hago para pasar esto a PHP? fkasldjfh flkjahfk jfa  :roll:


Desconectado mxgxw

  • Global Moderator
  • The Communiter-
  • *
  • Mensajes: 5665
  • Starlet - 999cc
    • mxgxw
Re: Rompiendo el captcha de Movistar (en 75 líneas de código)
« Respuesta #4 : diciembre 23, 2011, 11:30:42 pm »
Para cuando la nueva version del XMR ?  :drinks:

Ni idea, ya me retiré de esos bussiness :) ahora le toca a naruto y al hkadejo XD


Desconectado Jaru

  • The Communiter-
  • *
  • Mensajes: 13252
  • some text
Re: Rompiendo el captcha de Movistar (en 75 líneas de código)
« Respuesta #5 : diciembre 23, 2011, 11:32:33 pm »
hey te pelas mx, les das el tesoro pero dentro de una caja de acertijos :haha:
N/A

Desconectado hkadejo

  • Global Moderator
  • The Communiter-
  • *
  • Mensajes: 3345
Re: Rompiendo el captcha de Movistar (en 75 líneas de código)
« Respuesta #6 : diciembre 24, 2011, 02:15:54 pm »
Para cuando la nueva version del XMR ?  :drinks:

y vos que no te gusta la super pagina mas vergona del pais http://nubemensajera.com??  :sad:  :sad:  :rofl:  :rofl:

Este mgmsxjxkjasjkajkas me gano el mandado...porque iba a postear un post sobre eso...bueno lo hare luego solo que el mio es en Java y practicamente el proceso que describe es el que yo he utilizado con el detalle que la limpieza de la imagen no la realizo...en las pruebas que hice..el tesseract me leia correctamente la imagen sin necesidad de procesarla...no asi el caso del captcha de Claro ahi si tuve que limpiarlo bastante sino no descrifraba nada.

Y saludos a todos los webones que solo pusieron el script de mensajitos.php diciendo que era un desarrollo de ellos.... les vamos a botar su negocio..ofreciendo un sitio de mejor calidad y que si envia a Movistar  :drinks:

Desconectado Jaru

  • The Communiter-
  • *
  • Mensajes: 13252
  • some text
Re: Rompiendo el captcha de Movistar (en 75 líneas de código)
« Respuesta #7 : diciembre 24, 2011, 02:22:53 pm »
yo quebre el captcha con un webservice sin instalar nada, por ahi hay una paginita que me los resuelve :rofl:

yo no voy a poner mi codigo porque ando de grinch
N/A

Desconectado larg2009

  • Sv Member
  • ***
  • Mensajes: 295
Re: Rompiendo el captcha de Movistar (en 75 líneas de código)
« Respuesta #8 : diciembre 24, 2011, 02:51:42 pm »
ya probe la pag y esta bien :) solo que envie 3 veces el mensaje porque mandaba error al tercero si me llego a un numero telefonica..

Desconectado mxgxw

  • Global Moderator
  • The Communiter-
  • *
  • Mensajes: 5665
  • Starlet - 999cc
    • mxgxw
Re: Rompiendo el captcha de Movistar (en 75 líneas de código)
« Respuesta #9 : diciembre 24, 2011, 02:56:12 pm »
y vos que no te gusta la super pagina mas vergona del pais http://nubemensajera.com??  :sad:  :sad:  :rofl:  :rofl:

Este mgmsxjxkjasjkajkas me gano el mandado...porque iba a postear un post sobre eso...bueno lo hare luego solo que el mio es en Java y practicamente el proceso que describe es el que yo he utilizado con el detalle que la limpieza de la imagen no la realizo...en las pruebas que hice..el tesseract me leia correctamente la imagen sin necesidad de procesarla...no asi el caso del captcha de Claro ahi si tuve que limpiarlo bastante sino no descrifraba nada.

Y saludos a todos los webones que solo pusieron el script de mensajitos.php diciendo que era un desarrollo de ellos.... les vamos a botar su negocio..ofreciendo un sitio de mejor calidad y que si envia a Movistar  :drinks:

Naruto tiene la culpa!! Esque me dijo que le ayudara con la imagen de movistar (que por cierto todavía no encuentor pq a el no le funciona), y me dije a mi mismo... bueno hoy que ya la bajé veamos si le hacemos OCR faksjdfhaskl flkdfjasdf


Desconectado hkadejo

  • Global Moderator
  • The Communiter-
  • *
  • Mensajes: 3345
Re: Rompiendo el captcha de Movistar (en 75 líneas de código)
« Respuesta #10 : diciembre 24, 2011, 03:29:09 pm »
ya probe la pag y esta bien :) solo que envie 3 veces el mensaje porque mandaba error al tercero si me llego a un numero telefonica..

De nuevo problemas con mysql...ya le hice otro ajuste...hoy si al primer intento deberian irse los mensajes :D

Desconectado Balmossther

  • The Communiter-
  • *
  • Mensajes: 1078
  • Una alma Sana, Reside en una mente sana
Re: Rompiendo el captcha de Movistar (en 75 líneas de código)
« Respuesta #11 : diciembre 24, 2011, 03:57:07 pm »
De nuevo problemas con mysql...ya le hice otro ajuste...hoy si al primer intento deberian irse los mensajes :D
yo acabo de probar http://nubemensajera.com esta excelente super recomendadisima  :drinks:
███████████████████████████████████████████████████████████████

Desconectado darking

  • Sv Full Member
  • *
  • Mensajes: 548
Re: Rompiendo el captcha de Movistar (en 75 líneas de código)
« Respuesta #12 : diciembre 24, 2011, 05:01:08 pm »
yo acabo de probar http://nubemensajera.com esta excelente super recomendadisima  :drinks:
hey que buen trabajo ese el de nubemensajera...
sencillo y agradable...
solo 2 preguntas...
1-porque no dejar habilitado que se muestre el numero al que se envio el ultimo mensaje despues del envio?
digo esto porque a vecs se envian varios msjs a un numero y estar escribiendo el mismo numero molesta

2- sera que pronto habilitaran para el envio de msjs a la red DIGICEL?

Desconectado hkadejo

  • Global Moderator
  • The Communiter-
  • *
  • Mensajes: 3345
Re: Rompiendo el captcha de Movistar (en 75 líneas de código)
« Respuesta #13 : diciembre 24, 2011, 05:23:28 pm »
hey que buen trabajo ese el de nubemensajera...
sencillo y agradable...
solo 2 preguntas...
1-porque no dejar habilitado que se muestre el numero al que se envio el ultimo mensaje despues del envio?
digo esto porque a vecs se envian varios msjs a un numero y estar escribiendo el mismo numero molesta

Eso estaba viendo...creo que haremos eso

2- sera que pronto habilitaran para el envio de msjs a la red DIGICEL?

Pronto...despues de vacaciones navideñas :D

Desconectado Charlie

  • The Communiter-
  • *
  • Mensajes: 5592
Re: Rompiendo el captcha de Movistar (en 75 líneas de código)
« Respuesta #14 : diciembre 24, 2011, 05:26:15 pm »
Pues yo luego de probarlo solo hago dos recomendaciones.

1. Habilitar el autocompletado para que queden en la memoria del navegador los números ya utilizados, también seria útil el autocompletado en el campo del remitente.

Otra buena mejora seria que luego de enviar los mensajes se conserven los valores de estos dos campos hasta que los cambiemos por otros o hasta que abandonemos el sitio web, por aquello de si vamos a enviar varios mensajes o una respuesta al mismo numero que es lo mas usual.

2. Poner un limite al numero de caracteres que se pueden escribir si el servicio de la empresa a la que se envía tiene dicha limitación.

Por lo demás me gusta la interfaz minimalista del sitio web.