jueves, 26 de diciembre de 2013

Entendiendo el protocolo de Snapchat y sus vulnerabilidades


Ya sabéis el especial interés que nos ha dado últimamente con la seguridad de aplicaciones de mensajería que están diseñadas para los dispositivos móviles. En este caso hablaremos de snapchat, que te permite enviar fotos y videos a uno o más amigos. La diferencia con otras aplicaciones normales de mensajería de texto o con WhatsApp está en que los mensajes de Snapchat tienen una duración definida. Cuando las fotos o videos que has enviado a una persona alcanzan su duración límite, esas imágenes se borrarán del teléfono móvil de la persona que los recibió de manera automática.

El grupo de seguridad Gibson Security ya estuvo investigando el funcionamiento interno de la aplicación, su API y buscando vulnerabilidades hace unos meses, y publicaron un interesante informe, mostrando sus descubrimientos.

Ayer volvieron a la carga, mostrando un documento mucho más técnico y extenso basado en la última release de snapchat, la 4.1.01.



AUTENTICACIÓN

La autenticación a través de la API se realiza gracias a un token que se envía en cada una de las peticiones, con el nombre de req_token.

Veamos un ejemplo en Python que implementa el hash del token en cuestión:

Hay algunos detalles curiosos:
      - La variable secret tiene el valor fijo iEk21fuwZApXlz93750dmW22pw389dPwOk
      - Hay que calcular el valor de dos hash utilizando sha256
             - first: sha256 (secret + auth_token)
             - second: sha256 (timestamp + secret)
      - El patron de bits pattern tiene un significado concreto
             - 0: toma el valor correspondiente de esa posición en fist
             - 1: toma el valor correspondiente de esa posición en second

Para hacer poder autenticarse en la plataforma, necesitamos calcular el valor de auth_token, que se calcula de la siguiente forma:
      - Utilizamos el token estatico m198sOkJEn37DjqZ32lpRu76xmw288xSQ9
      - Utilizamos el timestamp correspondiente
      - Ejecutamos la función request_token(static_token, timestamp)

Para acceder al sistema es necesario realizar una petición a través de la API (/bq/login):
      {
          username: "tu_cuenta",
          timestamp: [timestamp_correspondiente],
          req_token: create_token(static_token, 1373207221),
          password: "tu_password"

      }

Si el proceso anterior fue correcto, nos devolverá algo como esto:
      {
          bests: ["someguy"],
          score: 0,
          number_of_best_friends: 1,
          received: 0,
          logged: true,
          added_friends: [
              {ts: 1384417608610, name: "somedude", display: "", type: 0},
              {ts: 1385130955168, name: "random", display: "", type: 1}
          ],
          beta_expiration: 0,
          beta_number: -1,
          requests: [{display: "", type: 1, ts: 1377613760506, name: "randomstranger"}],
          sent: 0,
          story_privacy: "FRIENDS",
          username: "youraccount",
          snaps: [
              {id: "894720385130955367r", sn: "someguy", ts: 1385130955367, sts: 1385130955367, m: 3, st: 1},
              {id: "116748384417608719r", sn: "randomdude", ts: 1384417608719, sts: 1384417608719, m: 3, st: 1},
              {id: "325924384416555224r", sn: "teamsnapchat", t: 10, ts: 1384416555224, sts: 1384416555224, m: 0, st: 1}
          ],
          friends: [
              {can_see_custom_stories: true, name: "teamsnapchat", display": Team Snapchat", type: 0},
              {can_see_custom_stories: true, name: "someguy", display: "Some Guy", type: 0},
              {can_see_custom_stories: true, name: "youraccount", display: "", type: 1}
          ],
          device_token: "",
          feature_settings: {},
          snap_p: 1,
          mobile_verification_key: "MTMzNzpnaWJzb24=",
          recents: ["teamsnapchat"],
          added_friends_timestamp: 1385130955168,
          notification_sound_setting: "OFF",
          snapchat_phone_number: "+15557350485",
          auth_token: "85c32786-0c71-44bf-9ba0-77bf18c61db2",
          image_caption: false,
          is_beta: false,
          current_timestamp: 1385378822645,
          can_view_mature_content: false,
          email: "[email protected]",
          should_send_text_to_verify_number: true,
          mobile: ""
      }


CIFRADO DE FICHEROS MULTIMEDIA

A todos los archivos multimedia (imágenes y vídeos) enviados a través de Snapchat se les aplica el padding utilizando PKCS#5 y son cifrados utilizando AES/ECB con una clave simétrica con el valor M02cnQ51Ji97vwT4.


CIFRADO DE MENSAJES

A las historias que se envían se les aplica:
      - Padding utilizando PKCS#7
      - Cifrado utilizando AES/CBC con un único IV y clave por cada fragmento de mensaje (es posible encontrar media_key y media_iv dentro de los valores de respuesta en /bq/stories)

El siguiente fragmento de código nos dará una idea de como realizar el descifrado:


VULNERABILIDADES

Existen dos pruebas de concepto de errores de seguridad en Snapchat.

El primero de ellos permite, una vez dentro del sistema, conocer si un número de teléfono está asociado a alguna cuenta utilizando la llamada a /ph/find_friends. Esto error fue reportado hace ya casi 4 meses, y aún no ha sido solucionado por la compañia.

Utilizando un ataque de fuerza bruta contra el sistema podrían llegar a obtenerse los datos de 292 millones de número de teléfono al mes utilizando tan sólo un servidor.

El siguiente script utilizará una lista de números de teléfono y realizará la comprobación:


El segundo permite registrar de forma automatizada tantas cuentas como queramos utilizando las llamadas a /bq/register y /ph/registeru, técnica que puede ser utilizada por ejemplo para vender perfiles falsos:


Para ello, el formato del fichero accounts.txt debe ser:
      account1:password1:[email protected]
      account2:password2:[email protected]
      account3:password3:[email protected]


CONCLUSIÓN

Al parecer este problema podría ser resuelto por parte del equipo de Snapchat con unas pocas líneas de código, por lo que veremos si finalmente se animan a resolver estos problemas.

A esta investigación, tendremos que sumar las ya existentes sobre como desde el punto de vista técnico no es posible asegurar que algo sea borrado de forma permanente. No olvidemos que existen aplicaciones paralelas, como SnapHack, que permite guardar las imágenes recibidas sin que el remitente sea consciente.

Además, por cuestiones de seguridad, las autoridades policiales con una orden judicial puede acceder a los snaps no leídos y utilizarlos en sus investigaciones.

Por todo esto, se puede decir con absoluta claridad que Snapchat no es una plataforma tan segura, que los mensajes no tiene porque ser borrados después de un tiempo.

Recordad que cuando algo está en la Red, sea potencialmente para vuestra reputación online o no, es muy probable que se quede en Internet para siempre, a pesar de lo que prometan algunas aplicaciones.