17 mayo 2011

phpot, honeypot web minimalista escrito en PHP

Desde hace tiempo andaba con la idea en la cabeza de implantar un honeypot web minimalista, con lo básico, y personalizable según el escenario de implantación. Como no podía ser de otra manera, un honeypot así tendría que ser un login web, un sitio en el que a todo el mundo le gusta curiosear, poner un 1234 por aquí, una comilla por allá ...

Como no encontré nada convincente y a muchos de nosotros nos encanta el 'Do It Yourself', pues eso, nos lo hemos hecho nosotros mismos y hoy toca compartirlo.

phpot está escrito en PHP, utiliza MySQL para guardar los datos y consta de 88 líneas de código en un único fichero (comentarios incluidos).

De cara al visitante se muestra de la siguiente forma:



Como podemos ver, es una apariencia muy simple que puede ser modificada para darle el aspecto del login de una cámara web, un router, o por qué no, de un aire acondicionado.

La parte no visible proporciona al administrador los siguientes datos del atacante:

  • IP
  • País de origen, determinado por la IP
  • User-Agent, navegador
  • Fecha y hora de la visita

El software guarda los datos tanto en caso de visita, como en caso de intento de login. En el segundo caso también se guardará usuario y login que se ha intentado.

Podemos diseccionar las partes interesantes brevemente.

Sólo se utiliza una tabla en la base de datos, que tiene la siguiente estructura:

mysql> describe tries;
+---------+--------------+------+-----+---------+-------+
| Field   | Type         | Null | Key | Default | Extra |
+---------+--------------+------+-----+---------+-------+
| id      | varchar(50)  | NO   | PRI | NULL    |       |
| ip      | varchar(50)  | YES  |     | NULL    |       |
| country | varchar(5)   | YES  |     | NULL    |       |
| uagent  | varchar(200) | YES  |     | NULL    |       |
| user    | varchar(200) | YES  |     | NULL    |       |
| pass    | varchar(200) | YES  |     | NULL    |       |
| date    | varchar(35)  | YES  |     | NULL    |       |
| type    | varchar(5)   | YES  |     | NULL    |       |
+---------+--------------+------+-----+---------+-------+
8 rows in set (0.00 sec)

La query que guarda los datos el atacante es la siguiente:

mysql_query("insert into tries values ('" . time() . "', '" . mysql_real_escape_string($_SERVER['REMOTE_ADDR']) . "', '" .
mysql_real_escape_string($country) . "', '" . mysql_real_escape_string($_SERVER['HTTP_USER_AGENT']) . "', '" .
mysql_real_escape_string($_POST["user"]) . "', " . "'" . mysql_real_escape_string($_POST["passwd"]) . "', '" .
date("r") . "', 'login');", $db_conn);

Podemos ver que todos los datos no generados en el propio código están escapados para evitar errores. Ésta es la query en caso de login, en caso de visita es parecida pero no se guarda usuario ni password, y el valor type es visit en lugar de login.

Para conseguir el país a través de la IP del visitante se utiliza el servicio de hostip.info a través de su API, la función para ésto es la siguiente:

function ip_2_country($ip) {
  return file_get_contents("http://api.hostip.info/country.php?ip=" . $ip);
}

Como añadido para confundir y distraer al atacante, la web tarda siempre un segundo añadido en responder, ya sea en una visita o en un intento de login.

Además, el error que muestra en el caso de que se intenten inyectar sentencias SQL es diferente, algo que puede distraer a un atacante inexperto.

if (strpos($_POST["user"], "'") !== false || strpos($_POST["passwd"], "'") !== false) {
  $error = "Query error, bad syntax";
}
else {
  $error = "Invalid username or password";
}

Esta vez no hemos puesto un servidor público para que se pueda probar, ya que al recopilar tantos datos del usuario puede que alguien lo visite por error y se moleste.

Podéis descargar el software desde el repositorio de SbD:

- Descargar

8 comments :

Madrikeka dijo...

Hoy me viene que ni pintado.....por que tengo un server...que lo necesita!!!

me sacáis demasiadas herramientas!! 

mcklaw dijo...

 Pregunta, ¿porque no "capturar" las pantallas más habituales de login (que atacan), sus URL y mostrarlas si son solicitadas para que el engaño sea más efectivo (lo típico, la pagina de login del OWA, del webadmin, etc)?

Alberto Ortega dijo...

Eso sería lo ideal, pero lleva mucho trabajo. Lo proporcionado aquí es lo básico, a partir de ahí que cada cual se lo adapte a sus necesidades.Sin ir mas lejos, he implantado hace poco este mismo software pero con la apariencia del login de un conocido CMS :)Un saludo!

Juanma dijo...

Justo estaba pensando escribir uno para aprender de los ataques nuevos, pero no pierdo tiempo y uso este :)
Gracias!

Xetix dijo...

Genial! Llevo MUCHO TIEMPO buscando algo parecido y que funcione! Muchísimas gracias!

Pack44 dijo...

Pregunta tonta...
Lo copié en el directorio por defecto de Apache, y creé una BD con el nombre proporcionado en el código (además del usuario y la contraseña).
¿Es necesario algo más para hacerlo funcionar? Porque no hace nada...

Pack44 dijo...

El no leer pasa factura...
Nombre de la tabla: tries

Solucionado.

crear1web dijo...

Mm pero esto lo puedes hacer con un script que guarde la ip y algunos datos mas