Archivo de la etiqueta: debian

Desbanear IPs en fail2ban de forma correcta

Este post es más un recordatorio para mí pero sigue siendo un buen material de consulta para sysadmins.

Fail2ban es una herramienta bastante popular entre administradores de sistemas ya que nos permite añadir una capa de seguridad extra a nuestro servidor, viene con algunas reglas de seguridad pre configuradas para proteger servicios como ssh y apache, sin embargo es lo suficientemente flexible y fácil de utilizar para que nosotros creemos y agreguemos todas las que necesitemos, pero bueno este tutorial no es acerca de cómo crear esas reglas sino de cómo desbanear ciertas IPs que hayamos baneado por equivocación.

En el mejor de los casos

fail2ban utiliza la utilidad iptables, lo primero que haremos será encontrar que tipo de restricción se le aplico a la ip baneada

# iptables -L -n | less

2

Como podemos ver, la ip afectada es 187.240.213.48 y está dentro del JAIL fail2ban-ssh o simplemente ssh (quiten le la parte de fail2ban-*), fail2ban utiliza un sistema de JAILS (jaulas / prisiones / cárceles) bastante interesante con el cual podemos agrupar ips en grupos y aplicar ciertas reglas a todas ellas al mismo tiempo, les dejo más documentación al respecto: control de jails en fail2ban

Si queremos saber el nombre de todas las JAILS que está corriendo fail2ban actualmente lo haremos con el comando

# fail2ban-client status

4

Este comando nos sirve para corroborar el nombre de la JAIL que vamos a manipular, podemos observar que tenemos muchas más ademas de ssh, por ejemplo apache, apache-myadmin, apache-overflows, etc … continuamos.

Ahora que conocemos en detalle la IP y la JAIL vamos a remover la restricción utilizando:

# fail2ban-client get ssh actionunban 187.240.213.48

Para versiones más nuevas de fail2ban, digamos 0.9.x seria:

# fail2ban-client set ssh unbanip 187.240.213.48

Y listo, con esto nos aseguramos de remover las restricciones solo a una dirección IP en específico 🙂

Podemos revisar si efectivamente la IP fue removida con el comando:

# iptables -L -n | grep '187.240.213.48'

Si el comando no nos regresa nada significa que no pude encontrar una coincidencia de ‘187.240.213.48’ en el output del iptables y por lo tanto la IP ya no está baneada.

En el peor de los casos

Sin embargo, si la consola les muestra algo como esto:

6

Y tienen la mala suerte de estar trabajando con un fail2ban version 0.8.6 como yo, significa que la IP no pudo ser desbaneada, haciendo un poco de investigación se trata de un bug muy nefasto popular en esta versión, intentamos remover la restricción de nuevo, esta vez utilizando el debug

# fail2ban-client -vvv get ssh actionunban 187.240.213.48

error

Ahí observamos que la falla está en los comandos que se aplican, podemos solucionar esto de dos formas, la primera es actualizando el servicio y la segunda es removiendo la dirección IP de forma manual que fue lo que yo hice, no es tan complicado 🙂

# IP=187.240.213.48
# cat /var/log/fail2ban.log | grep -v $IP > /tmp/fail2ban.tmp
# cp /tmp/fail2ban.tmp /var/log/fail2ban.log
# iptables -D  fail2ban-ssh -s $IP -j DROP

Revisamos de nuevo si efectivamente la IP fue removida

# iptables -L -n | grep '187.240.213.48'

Y esta vez no debería de mostrarnos nada.

salu2

OOM en MySQL (cuando las bases de datos mueren)

devotion_to_duty

Durante 2014 estuve trabajando bastante con servidores virtuales de la compañía digitalocean.com, esta compañía tiene planes bastante económicos y accesibles (desde 5 dólares por mes) si lo que queremos es montar micro sitios web, ideales para paginas web de pequeñas compañías que reciben algunas miles de visitas por mes.

Sin embargo esta es un arma de doble filo, ya que si lo que quieren las empresas es ahorrarse unos cuantos dólares al año tienen que invertirlos en un buen administrador de sistemas que optimice sus servidores para aprovechar al máximo los recursos tan limitados del servidor

  • 512 MB Memory
  • 1 CoreProcessor
  • 20 GB SSD Disk
  • 1 TB Transfer

Uno de los problemas mas comunes que he visto es el llamado OOM (Out Of Memory) de Mysql, lo que ocasiona que los sitios web queden fuera de servicio … incluso durante días hasta que alguien se da cuenta.

Por lo regular nos damos cuenta que es un problema de memoria cuando se cayo el servicio e intentamos restablecerlo, y en la consola nos es desplegado un mensaje como el siguiente:

[email protected]:/# service mysql start
[FAIL] Starting MySQL database server: mysqld . . . . . . . . . . . . . . failed!

Podemos revisar los logs del servicio en los siguientes archivos:

  • /var/log/mysql.err – MySQL Error log file
  • /var/log/mysql.log – MySQL log file

También podemos revisar el estado de la memoria con el comando free:

[email protected]:/# free -m
             total       used       free     shared    buffers     cached
Mem:           497        467         29          0          8        146
-/+ buffers/cache:        312        184
Swap:          999          3        996

En este punto obviamente el servidor se esta cayendo a pedazos así que lo que tenemos que hacer es primeramente detectar las malas configuraciones de Mysql (configuraciones por default) y optimizarlas :D.

Existe una utilidad que nos hace la vida mas sencilla, un pequeño software llamado mysqltuner, así que lo instalamos.

[email protected]:/# apt-get install mysqltuner

Y lo ejecutamos con el comando mysqltuner, al inicio nos pedirá las credenciales de un usuario con privilegios de root, para después comenzar a realizar un análisis y sugerirnos varias configuraciones de acuerdo a los resultados

[email protected]:/# mysqltuner
perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
	LANGUAGE = "en_US:en",
	LC_ALL = (unset),
	LC_CTYPE = "UTF-8",
	LANG = "en_US.UTF-8"
    are supported and installed on your system.
perl: warning: Falling back to the standard locale ("C").

 >>  MySQLTuner 1.1.1 - Major Hayden
 >>  Bug reports, feature requests, and downloads at http://mysqltuner.com/
 >>  Run with '--help' for additional options and output filtering
Please enter your MySQL administrative login: root
Please enter your MySQL administrative password: 

-------- General Statistics --------------------------------------------------
[--] Skipped version check for MySQLTuner script
[OK] Currently running supported MySQL version 5.5.40-0+wheezy1-log
[OK] Operating on 64-bit architecture

-------- Storage Engine Statistics -------------------------------------------
[--] Status: +Archive -BDB -Federated +InnoDB -ISAM -NDBCluster 
[--] Data in MyISAM tables: 5M (Tables: 33)
[--] Data in InnoDB tables: 2M (Tables: 44)
[--] Data in PERFORMANCE_SCHEMA tables: 0B (Tables: 17)
[!!] Total fragmented tables: 52

-------- Security Recommendations  -------------------------------------------
[OK] All database users have passwords assigned

-------- Performance Metrics -------------------------------------------------
[--] Up for: 37m 4s (12K q [5.810 qps], 265 conn, TX: 24M, RX: 1M)
[--] Reads / Writes: 92% / 8%
[--] Total buffers: 192.0M global + 2.7M per thread (151 max threads)
[!!] Maximum possible memory usage: 597.8M (120% of installed RAM)
[OK] Slow queries: 0% (0/12K)
[OK] Highest usage of available connections: 1% (3/151)
[OK] Key buffer size / total MyISAM indexes: 16.0M/1.9M
[OK] Key buffer hit rate: 99.3% (148K cached / 998 reads)
[OK] Query cache efficiency: 63.4% (7K cached / 11K selects)
[OK] Query cache prunes per day: 0
[OK] Sorts requiring temporary tables: 0% (0 temp sorts / 446 sorts)
[OK] Temporary tables created on disk: 19% (152 on disk / 792 total)
[OK] Thread cache hit rate: 98% (3 created / 265 connections)
[OK] Table cache hit rate: 24% (123 open / 495 opened)
[OK] Open file limit used: 11% (120/1K)
[OK] Table locks acquired immediately: 100% (4K immediate / 4K locks)
[OK] InnoDB data size / buffer pool: 3.0M/128.0M

-------- Recommendations -----------------------------------------------------
General recommendations:
    Run OPTIMIZE TABLE to defragment tables for better performance
    MySQL started within last 24 hours - recommendations may be inaccurate
    Reduce your overall MySQL memory footprint for system stability
    Enable the slow query log to troubleshoot bad queries

[email protected]:/# 

En este ejemplo mysqltuner nos arrojo problemas con algunas tablas fragmentadas y una configuración por default de memoria ram que permite que el gestor utilice el 120% de la memoria del sistema! (y así quieren que no se muera el servicio x.x), entonces, con esta información ya tenemos algunas pistas acerca de por donde comenzar a resolver y optimizar.

salu2

Análisis y solución de un wargame de Criptografia

Bueno no se si sera exactamente criptografia x’D (mas bien es como resolver el acertijo), les comento lectores, ayer sábado estaba terminando algunos pendientes del trabajo y quise hechar un vistazo a ver como iba la comunidad de diosdelared, para los que no lo saben diosdelared es una comunidad de seguridad informatica con la característica de que tiene incluido un sistema de rangos y wargames, conforme vas solucionando mas retos vas avanzando de rango :).

Tengo mi cuenta ahi desde algunos meses o años ya.

Recordando la sección de retos informáticos (wargames) me apeteció ponerme a resolver uno antes de salir al cine a ver capitan america :p, como tenia algo de ganas de pensar en logica elegi el que se llama Valid Token, hasta aqui quiero comentarles que mostrare paso por paso como se soluciona el reto, así que si eres miembro ya de la comunidad o te gustaría serlo y pasar los retos intelectuales te recomiendo que lo intentes por ti mismo en un principio :).

Como ya es característico, el reto comienza con un texto que te hace sentir como si fueras algún ciber agente de la NSA o de la CIA xD (Murder siempre tan dramático).

Ok las instrucciones dicen lo siguiente:

Tenemos acceso al E-Mail de un administrador de SafePoint. Hemos podido recuperar su usuario y contraseña y una serie de Tokens.
El problema es que estas tokens se caducan tras ser usadas y según hemos confirmado, el algoritmo de generación cambia mensualmente.
Por si te sirve, hemos encontrado lo siguiente.
Ayudanos a generar un token valido y recibirás tu recompensa.
El usuario y contraseña que conseguimos es:
$email == ‘[email protected]’ && $password == ‘one2one’

Suerte en tu misión.

mas abajo hay un link que nos dirige al siguiente panel de login:

En las instrucciones se nos proporciona un usuario y una contraseña, pero nos falta un token (como sacamos el maldito token x’D?), entonces procedemos a descargar el archivo, que se supone es un archivo robado del generador de tokens :p

<?php
class Crypt0reto
  {
  private $prefix_token = 'ddlr-';
  private $valid_algorithm = '56-101-52-51-56';
  private function TokenCalculate($string)
    {
    $md5_1 = md5($string[0]);
    $md5_2 = md5($string[1]);
    $md5_3 = md5($string[2]);
    $md5_4 = md5($string[3]);
    $md5_5 = md5($string[4]);
    $token = ord($md5_1).'-'.ord($md5_2).'-'.ord($md5_3).'-'.ord($md5_4).'-'.ord($md5_5);
    return $token;
    }
  private function DebugToken($token)
    {
    $string_explode_array = explode($this->prefix_token, $token);
    $string = $string_explode_array[1];
    return $string;
    }
  public function CheckToken($token)
    {
    $test_token = $this->TokenCalculate($this->DebugToken($token));
    if($test_token == $this->valid_algorithm)
      {
      echo "verdadero";
      return true;
      }
    else
      {
      echo "falso";
      return false;
      }
    }
  }

Y comenzamos el análisis del código.

Vemos que tenemos 3 metodos en la clase, 2 privados (DebugToken, TokenCalculate ) y el otro publico (CheckToken), partimos del hecho de que como es publica sera la función que nos diga si nuestro token es valido o no (ademas el nombre es muy obvio no xd?).

public function CheckToken($token)
    {
    $test_token = $this->TokenCalculate($this->DebugToken($token));
    if($test_token == $this->valid_algorithm)
      {
      echo "verdadero";
      return true;
      }
    else
      {
      echo "falso";
      return false;
      }
    }

La función recibe un parametro que después es pasado al metodo privado DebugToken, veamos su código entonces.

private function DebugToken($token)
    {
    $string_explode_array = explode($this->prefix_token, $token);
    $string = $string_explode_array[1];
    return $string;
    }

Al igual que el primer metodo este tambien recibe un parametro solamente, comenzando tenemos una variable que recibe el valor resultante aplicar la función explode, para los que no saben explode te permite cortar una cadena en varias partes utilizando una expresion como delimitador, en este caso $this->prefix_token, al inicio de la clase esta declarada esta variable:

 private $prefix_token = 'ddlr-'; 

Llegados a este punto sabemos que el token contiene si o si la sub cadena ddlr- :p, ¿por que? pues por que en la función DebugToken después de utilizar explode se le asigna a la variable $string el contenido del arreglo $string_explode_array en la posición 1, la posición 0 quedo vacía puesto que no había nada antes de ddlr- al final $string es devuelto un nivel mas arriba, ósea a la función CheckToken.

Recordemos que teníamos algo así como

$test_token = $this->TokenCalculate($this->DebugToken($token));

Entonces el resultado de DebugToken ($string) es pasado directamente a TokenCalculate, veamos el metodo.

private function TokenCalculate($string)
    {
    $md5_1 = md5($string[0]);
    $md5_2 = md5($string[1]);
    $md5_3 = md5($string[2]);
    $md5_4 = md5($string[3]);
    $md5_5 = md5($string[4]);
    $token = ord($md5_1).'-'.ord($md5_2).'-'.ord($md5_3).'-'.ord($md5_4).'-'.ord($md5_5);
    return $token;
    }

Al igual que los 2 metodos anteriores recibe solo un parámetros, del cual extra los caracteres individualmente y obtiene su hash en md5, después de eso guarda el resultado de todos las variable que contiene el md5 de cada caracter en la variable $token y les asigna un ‘-‘ entre cada valor.

Hay vemos algo interesante, mientras se hace la concatenación se le aplica el metodo ord, lo que hace ord es tomar el primer caracter de una cadena y regresar su equivalente en ascii, al final la cadena $token es regresada.

Regresando a nuestro metodo original (CheckTone), ya ven que esto es como inception x’D, el resultado de todo eso es asignado en $test_token y abajo hay una comparación interesante

if($test_token == $this->valid_algorithm)

Nos esta diciendo que si nuestra cadena resultante es $this->valid_algorithm, que al inicio es declarado

private $valid_algorithm = '56-101-52-51-56';

Entonces nuestro token es valido, de lo contrario es invalido :).

Ahora, después de este análisis ¿por donde comenzamos?, ¿nuestro $test_token tiene que ser igual a $this->valid_algoritm verdad?, una vez que sabemos como se construye la cadena y como funciona el algoritmo procedemos a aplicar ingeniería inversa o resolver el acertijo … vaya :).

Lo primero que tenemos que hacer es ver cual es el valor de los números ascii, ¿por que?, pues como ya habíamos dicho arriba, si no recuerdas regresa a leer xd, el ultimo paso era aplicar la función ord que devuelve el ascii del primer caracter de una cadena, en este caso los hash en md5.

Los valores son:

  /*

  56-101-52-51-56

  56 = 8
  101 = e
  52 = 4
  51 = 3
  56 = 8

  8-e-4-3-8

  */

¿Ahora que hacemos? tenemos que confiar en que el creador del wargame no se paso mucho de listo y generar todos los md5 que comiencen con dichos caracteres (8-e-4-3-8), usando las letras del abecedario y los números del 0-9 (por eso dije que no se haya pasado de listo y haya utilizando caracteres raros jaj)

Tengo un arreglo ya preparado

$abc = array('@','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','[',']','^','`','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','{','|','}','~');

Imprimo las cadenas hash resultantes que coincidan con nuestro patron de búsqueda.

for($i = 0; $i < count($abc); $i++)
  {
    switch(substr(md5($abc[$i]),0,1))
    {
      case '8':
      echo $abc[$i]." : ".md5($abc[$i])."<br/>";
      break;
      
      case 'e':
      echo $abc[$i]." : ".md5($abc[$i])."<br/>";
      break;
      
      case '4':
      echo $abc[$i]." : ".md5($abc[$i])."<br/>";
      break;
      
      case '3':
      echo $abc[$i]." : ".md5($abc[$i])."<br/>";
      break;
    }

Y el resultado es (ya organizados)

/*
8-e-4-3-8

= 8 = 

F : 800618943025315f869e4e1f09471012
N : 8d9c307cb7f3c4a32822a51922d1ceaa
[ : 815417267f76f6f460a4a61f9db75fdb
` : 833344d5e1432da82ef02e1301477ce8
d : 8277e0910d750195b448797616e091ad
f : 8fa14cdd754f91cc6554c9e71929cce7
i : 865c0c0b4ab0e063e5caa3387c1a8741
k : 8ce4b16b22b58894aa86c421e8759df3
p : 83878c91171338902e0fe0fb97a8c47a

= e =

R : e1e1d3d40573127e9ee0480caf1283d6
e : e1671797c52e15f763380b45e841ec32
t : e358efa489f58062f10dd7316b65649e

= 4 =

P : 44c29edb103a2872f519ad0c9a0fdaaa
U : 4c614360da93c0a041b22e537de151eb
c : 4a8a08f09d37b73795649038408b5f33
r : 4b43b0aee35624cd95b910189b3dc231
y : 415290769594460e2e485922904f345d
~ : 4c761f170e016836ff84498202b99827

= 3 =

E : 3a3ea00cfc35332cedf6e5e9a32e94da
j : 363b122c528f54df4a0446b6bab05515
*/

Hagamos cuentas para ver cuantas contraseñas posibles podríamos generar x’D, 9 * 3 * 6 * 2 = 324 contraseñas posibles xD, no podemos utilizar fuerza bruta por que el server nos banearia así que, una vez mas una prueba de fe, armamos nuestra cadena que corresponda a 8-e-4-3-8 tomando los primeros resultados y queda

/*
8 = F
e = R
4 = P
3 = E
8 = N (la segunda letra correspondiente a los hash que comienzan con 8)

FRPEN
*/

Por ultimo le agregamos el ‘ddlr-‘ quedando ‘ddlr-FRPEN‘.

Ahora probamos, tan solo le pasamos el token que creemos es el correcto al metodo de la clase.

 $testing = new Crypt0reto();
 $testing->CheckToken("ddlr-FRPEN");

Y voilà el metodo nos regresa verdadero :), lo probamos en el formulario junto con el correo y la contraseña y efectivamente nos deja entrar al panel y superamos el reto :).

salu2

PD
Este tipo de retos me gustan mucho, me tomo 12 minutos entenderle y hacer la ing inversa, tal vez algunos lo hicieron mas rapido y mas lento, eso no importa lo importantes es tener algo para ejercitar la mente x’D

PD 2
Cada reto dice el numero de personas que lo han superado, este wargames han sido alrededor de 40 personas los que lo han pasado, quiero pensar que es por que no saben programar jeje

Regresando de Campus Party

Uff despues de una larga semana y algunos dias porfin estamos de regreso :), ¿que como describiria mi experiencia en campus party en 1 sola palabra? … Increible, asi es, simplemente fue increible, conoci bastante gente muy interesante, asisti a ponencias de gran nivel he hice nuevos amigos :).

Llegue el miercoles 20 a las 4 am al evento x’D (por cuestiones de trabajo), donde ya me estaban esperando @Zagrevyum y @uhgy3k (que no tenian camping x’D y pues ya les di 2 pases VIP :D), como ya era casi de dia pues ¿para que dormir? asi que emprendimos un dia maratoniano manteniendonos despiertos durante 2 dias y medio seguidos jajaja.

De las personas mas interesantes que conoci y con las cuales me tome algunas fotos fueron @_hkm, @cibercrimen, Jon Maddog, @xianur0, @nitr0usmx, @only_oCrA, @paulinocaIderon, Umberto121, @_soldier, @adrianmtzb, @tachuela, @tachuelaa, @bucio, @xrandy, @sucubus_vampire, son los que vienen a mi mente ahora (una disculpa si olvido alguno )

Las mejores conferencias sin duda fueron las de seguridad permitral y configuracion de honeypots, la de informatica forence, la de dotdotFUA (dotdoypwn)de @nitr0usmx, la de los routers de @_hkm, la herramienta fhttp de @Xianur0 y ya mas aca en la comunidad underground x’D la de creacion de scripts para nmap de @paulinocaIderon, bypasseando sistemas de seguridad biometricos de @xianur0, la conferencia de Napa sobre biohacking y enfermedades terminales (realizo una investigación muy completa e impresionante) y la de Umberto121 quien descifró el algoritmo de generación de contraseña de los routers Huawei Hg xD.

Sin duda ahi nos veremos el año que viene 🙂

A continuación les dejo algunas fotografias que tome 🙂

PD el año que viene me compro una mejor cámara jaja.

salu2

Activar compositing manager en backtrack 5


Hola lectores, en esa ocasión les traigo no un tutorial si no mas bien un breve tip, resulta que en la empresa donde actualmente trabajo (si esa donde desarrollo aplicaciones móviles y web) ahora esta comenzando proyectos de seguridad de la mano de PROSA xD y pues la verdad tenia ya algunos meses que no hacia algo de hacking.

Tengo otra laptop con ubuntu 10.04 dije, manos a la obra pero me pedía actualizar así que opte por mejor des instalar esa distribución e instalar backtrack (se que trae muchas herramientas que tal vez no utilizare), una distribución mas acorde a los fines que tengo que realizar, como soy un usuario de gnome algo que me agrado es que ahora backtrack trae de forma nativa ese escritorio :), instale el sistema operativo, lo actualice y voila.

Aun habían algunas cosas que tenia que arreglar antes, algo que me agrado mucho es que a diferencia de distribuciones pasadas era un lio primero hacer que las interfaces de red funcionaran, después la tarjeta de video etc, solo me resto activar el compositing manager, para los que no sepan que es, son esos pequeños efectos del gestor de ventanas Metacity que hacen que nuestro escritorio se vea un poco mejor, sin sacrificar recursos de la computadora (sombras en las ventanas, transparencias, etc).

Una vez que tenemos todos los paquetes actualizados

[email protected]:~# apt-get upgrade

tan simple como:

[email protected]:~# apt-get install xcompmgr

Después tan solo ejecuten el comando xcompmgr y listo

[email protected]:~# xcompmgr

Como es muy molesto estar escribiendo el comando cada vez que inicia Backtrack hay varias maneras para ejecutarlo al iniciar el sistema operativo, una seria crear un script en /etc/init.d/miScript o añadirlo a la lista de comandos en el archivo /etc/rc.local, etc. Pero para mas fácil tan solo nos vamos a System > Preferences > Startup Applications, seleccionamos Add (indicando que queremos añadir una nueva tarea) y en comando escribimos xcompmgr y listo 🙂 compositing-manager activado.

salu2