Curso de Seguridad Ofensiva

W. Owen Redwood profesor de la Universidad del Estado de Florida ha publicado el material de la clase que imparte junto a Prof. Xiuwen Liu sobre seguridad ofensiva.
Esta clase está pensada para ser impartida en unas 15 semanas, aproximadamente, a un ritmo de una lección semanal. Os dejo aquí el temario de las clases por si alguien se anima y los link's a los vídeos de Youtube de aquellas clases que los tienen.
  1. Intro / Overview
    1. Intro, Ethics, & Overview
    2. Linux Overview
  2. Overview / Code Auditing
    1. Windows Overview
    2. Rootkits; Code Auditing
  3. Reverse Engineering Workshop Week
    1. x86 Reverse engineering
    2. x86 Reverse engineering 2
  4. Exploit Development
    1. Fuzzing and Exploit Development 101
    2. Shellcode and Exploit Development 102
  5. Exploit Dev / Networking
    1. Exploit Development 103: SEH Exploitation, Heap Sprays, and Executable Security Mechanisms
    2. Networking 101: Data Layer, Link Layer, and IP layer
  6. Networking / Web Application Hacking
    1. Networking 102: TCP layer, Important Protocols, Services, Portscanning, ARP
    2. Web application Hacking 101
  7. Web Application Hacking
    1. Web Application Hacking 102: Big picture of topics so far, SQLi, XSS
    2. Web Application Hacking 103: SSL attacks, advanced techniques
  8. Web Application Hacking / Exploit dev
    1. Web Application Hacking 104: Exploit Development 104
    2. Midterm review: Exploit Development 105 (ROP)
  9. Special Topics
    1. The Modern History of Cyber Warfare
    2. Social Engineering
  10. Metaspl0it
    1. Metasploit
  11. Post Exploitation and Forensics
    1. Meterpreter and Post Exploitation
    2. Volatility and Incident Response
  12. Physical Security
    1. Physical Security Workshop: Lockpicking, USB mischief, and BacNET/SCADA system security
  13. Malware / Student Presentations
    1. Advanced Malware Techniques
  14. Student Presentations
Casi todas las clases están grabadas en vídeo, pero sino siempre están a mano las diapositivas. A mayores, según la clase también está disponible más material y link's de interés.
A mayores de todo este material, también están disponibles los deberes del curso. Para aquellos interesados en hacerlos, los pueden ver desde aquí,

Si te gusta la seguridad informática, no dudes en ver estas clases!
Leer más

Bind9, denegación de servicio

ICS, Internet System Consortium, encargada de desarrollar el famoso servidor DNS BIND ha liberado una nueva versión del mismo que corrige un fallo de seguridad. Este fallo de seguridad puede provocar una denegación de servicio ante una consulta especialmente manipulada.
Dicha vulnerabilidad, calificada como crítica, tiene asignado el código CVE-2013-4854 y fue reportada por Maxim Shudrak a través del programa de Zero Day Initiative de HP. Afecta a las versiones de las ramas 9.7, 9.8 y 9.9 del servidor. La rama 9.6 no está afectada y la rama 9.10 tampoco. Para el resto de las ramas, existe ya un parche oficial, a excepción de la 9.7, que ICS avisó en un comunicado que no aplicaría el parche por estar descontinuada.
El fichero que contiene el fallo es el lib/dns/rdata/generic/keydata_65533.c y el parche aplicado es muy sencillo,
...
    isc_buffer_activeregion(source, &sr);
-   if (sr.length < 4)
+   if (sr.length < 16)
       return (ISC_R_UNEXPECTEDEND);
...
Para servidores Debian en versión stable o oldstable ya está el parche aplicado y sólo debemos actualizar para no vernos afectados.
Más información:
La entrada Bind9, denegación de servicio la puedes leer en Puppet Linux.
Leer más

Compilar Zabbix-Agent para Windows

El software de monitorización Zabbix es estupendo y ya hablamos de él más veces en este blog. Una de las ventajas más grandes que presenta es que tiene un agente (pequeño código escrito en C) que permite tener "algo" en los equipos para enviar información del estado de los mismos. Quien dice del estado de los mismos, también dice del poder ejecutar comandos remotos, por ejemplos.
Desde la web oficial del proyecto nos ofrecen siempre una versión para sistemas Unix y otra para sistemas Windows y a mayores todo el código fuente. Si nos interesa modificar algo del agente, o simplemente compilar nuestras propias fuentes, hacerlo en sistemas GNU/Linux es muy simple, pero la cosa cambia en entornos Windows.
Hoy vamos a explicar cómo compilar Zabbix para Windows. Para ello partimos de una instalación de Windows 7 sobre la que instalaremos el Windows SDK for Windows 7 (disponible aquí) y también el Visual Studio 2010 Express (disponible para descarga aquí). Cuando tengamos ambos paquetes instalados, simplemente descargamos el código fuente de Zabbix y los extraemos en una carpeta. Para simplificar todo, yo de dejaré en C:\zabbix-2.0.6 (última versión estable a fecha de escribir esta entrada).
  • Versión de 32 bits
    Esta es la versión para la mayoría de los Windows, así que será por la que empecemos. Antes de nada, debemos de establecer las variables de entorno que necesitamos. Para ello ejecutamos,
    msdos> C:\Program Files\Microsoft Visual Studio 10.0\VC\bin\vcvars32.bat
    
    Una vez tengamos ya el entorno listo, simplemente debemos navegar hasta la carpeta que contiene el proyecto y compilarlo. Para ello, todo desde msdos,
    msdos> cd "C:\zabbix-2.0.6\build\win32\project"
    msdos> copy ..\include\config.h ..\..\..\include\
    msdos> nmake Makefile_agent
    msdos> nmake Makefile_get
    msdos> nmake Makefile_sender
    
  • Versión de 64 bits
    Si vamos a la carpeta del proyecto de 64 bits, nos manda a la carpeta de 32, puesto que el código es el mismo. La única diferencia a la hora de compilar este entorno es que debemos de cargar las variables del entorno de 64. Así que,
    msdos> C:\Program Files\Microsoft Visual Studio 10.0\VC\bin\vcvars64.bat
    
    Una vez tengamos esto, el resto de pasos sin idénticos a la versión de 32, por lo que no los vamos a repetir.
Si durante la compilación os salta el siguiente error,
...
zbxconf.c
 rc.exe /d "ZABBIX_AGENT" /d _WINDOWS /d "NDEBUG" /d "_VC80_UPGRADE=0x0600
/l 0x419 /fo"zabbix_agent.res" resource.rc
Microsoft (R) Windows (R) Resource Compiler Version 6.1.7600.16385
Copyright (C) Microsoft Corporation.  All rights reserved.

resource.rc(10) : fatal error RC1015: cannot open include file 'afxres.h'.
NMAKE : fatal error U1077: '"C:\Program Files\Microsoft SDKs\Windows\v7.0A\bin\rc.exe"' : código devuelto '0x1'
Stop.
La solución es editar el fichero zabbix-2.0.6/build/win32/project/resource.rc y en la línea 10 cambiar,
...
//
#include "afxres.h"
...
por
...
//
#include "windows.h"
...
Ahora volvemos a compilar y ya todo debería de ir perfectamente. Al finalizar la compilación nos dejará los nuevos binarios en la carpeta bin de la raíz.

La entrada Compilar Zabbix-Agent para Windows la puedes leer en Puppet Linux.
Leer más

Instalar SaltStack minion

El otro día comenzamos con al instalación del servidor de SaltStack y hoy vamos a ver cómo realizar la instalación de un cliente SaltStack. La instalación del cliente será sobre un sistema Debian, pero es el mismo procedimiento cualquier sistemas de la familia Unix.
Al igual que hicimos para la instalación del servidor, vamos a crear el cliente el siguiente fichero, /etc/apt/sources.list.d/salt.list con,
deb http://debian.saltstack.com/debian wheezy-saltstack main
Tras ello y siguiendo los mismos pasos que para el servidor, importamos la clave GPG y actualizamos el listado de paquetes disponibles.
shell> wget -q -O- "http://debian.saltstack.com/debian-salt-team-joehealy.gpg.key" | apt-key add -
shell> apt-get update
Ahora, antes de instalar el cliente, vamos a hacer un pequeño truco que nos simplificará la vida a la hora de comenzar a trabajar. Por defecto el nuevo minion al arrancar se conecta a un servidor llamado salt. Si tenemos un DNS en nuestra red, es hora de crear esta entrada en él y que apunte a la IP del servidor. En caso contrario, podemos hacer el truco de crear una entrada en el fichero /etc/hosts apuntando a dicha IP.
192.168.1.50   salt   salt.domain.com
Ahora ya estamos en condiciones de instalar el software que necesitamos. Para ello,
shell> apt-get install salt-minion
Puesto que en nomenclatura SaltStack un cliente es un minion el paquete adoptó dicho nombre. Durante la instalación resolverá las dependencias necesarias, entre ellas todos los temas de Python que necesitemos.
Al finalizar la instalación el software quedará ejecutándose y habrá realizar ya la primera conexión al servidor (si hemos creado la entrada apuntando al nombre salt) y ya estamos listos para comenzar a trabajar. En la próxima entrada, veremos cómo dar los primeros pasos con Salt.

Más información en la documentación oficial de SaltStack.

La entrada Instalar SaltStack minion la puedes leer en Puppet Linux.
Leer más

OpenSSH User Enumeration Time-Based Attack

A finales de la semana pasada saltó a la luz un ataque por fuerza bruta contra servidores SSH que permite realizar de forma sencilla una enumeración de usuarios activos en el equipo. Aunque no es 100% fiable, sí ofrece una forma rápida, y la verdad que tras probarla, bastante eficaz de enumerar los usuarios de un equipo.
La prueba de concepto (pequeño script en Python), lo podemos descargar desde IT Security Blog. Para saber si un usuario está o no presente en un equipo llega con hacer una conexión contra dicho equipo. En función del tiempo de respuesta (con contraseña no válida), el script hace una pequeña estimación de si el usuario está o no presente en el equipo.
Aunque este ataque realiza una enumeración de usuarios, no de la tupla user+passwd, no deja de ser grave. El fallo afecta a las versiones 5.x y 6.x de OpenSSH (presentes en la mayoría de los equipos actuales).
La prueba de concepto está disponible para descarga y a mayores es necesario el típico fichero de diccionario,
javier:javier
test:test
Para lanzarlo únicamente,
shell> python ssh_time.py user.list 127.0.0.1:22 5
  Connecting test:test@127.0.0.1:22 
  Error:  Authentication failed.
  Connecting javier:javier@127.0.0.1:22 
  Error:  Authentication failed.
***********************************************************
Found:  ('javier:javier', '127.0.0.1', 22)
***********************************************************
Y efectivamente el usuario javier que existe en el equipo sale en la lista de usuarios.
Mientras esperamos una solución a nivel del servidor SSH para el control de esos tiempos de respuesta, lo mejor es asegurarse de tener claves SEGURAS en las máquinas expuestas, pues la enumeración de usuarios reduce considerablemente el tiempo en ataques por fuerza bruta.


Leer más

Instalar SaltStack server

Hace unos 15 días comencé a mirar cosas nuevas acerca de orquestación y aprovisionamiento de equipos. Ya es conocido Puppet, del que tengo hablado más de una vez en este blog. Sin embargo, a Puppet le falta alguna solución para la ejecución de comandos remotos. Si bien es cierto que gracias a MCollective esos problemas se pueden solucionar, hay que añadir algo que en su origen no era nativo y que por defecto suele ser bastante complejo.
Para solucionar este problema, y también cambiando un poco la forma de trabajar, vamos a comenzar por dar unas nociones básicas de SaltStack. Próximamente dedicaremos un post más extenso y teórico acerca de las bondades y diferencias entre SaltStack vs. Puppet, pero primero vamos a ejercer de técnicos y realizar una instalación y configuración se un servicio basado en Salt. Hoy será de la parte del servidor.
Si tenemos un equipo con Ubuntu, Salt está disponible en los repositorios oficiales (paquete salt-master), sino podemos emplear los paquetes que nos ofrece el desarrollador, contando así con la última versión disponible. Para ello, en sistemas Debian, creamos el fichero /etc/apt/sources.list.d/salt.list con el siguiente contenido (actual versión estable).
deb http://debian.saltstack.com/debian wheezy-saltstack main
A continuación procedemos a instalar el servidor. Para ello,
shell> wget -q -O- "http://debian.saltstack.com/debian-salt-team-joehealy.gpg.key" | apt-key add -
shell> apt-get update
shell> apt-get install salt-master
Ya tenemos el servidor instalado. La clave GPG que importamos es la del repositorio de saltstack.com. Si no lo hacemos, simplemente nos dará un error de confianza de clave.
Salt está escrito en Python, por lo que necesitará instalar varias dependencias de éste para funcionar, tanto en la parte del cliente como lógicamente en la del servidor.

Si te parece interesante la instalación del servidor SaltStack, mira cómo instalar un cliente (o minion) en GNU/Linux.

Más información en la documentación oficial de SaltStack.

La entrada Instalar SaltStack server está disponible en Puppet Linux.
Leer más

Instalar Metasploit en Debian Wheezy

Hace ya algún tiempo escribí un artículo sobre cómo instalar Metasploit en Debian (squeeze). Hoy, después de un tiempo sin arrancar Metasploit, tras actualizarlo, obtengo el siguiente error,
Metasploit requires the Bundler gem to be installed
Tras investigar un poco, veo que el problema es que el framework ha evolucionado y ahora necesita una versión de Ruby superior, así que no me queda más remedio que actualizar. Así que paso mi sistema de Squeeze (old-stable) a Wheezy (stable). Tarde o temprano lo había que hacer, así que manos a la obra.
Tras los típicos update, upgrade y dist-upgrade ya tengo el sistema en la última versión estable de Debian y listo para arrancar Metasploit.
Ahora voy a hacer un pequeño inciso para aquella gente es esté comenzando a usar Metasploit y lo quiera instalar desde cero. Lógicamente si ya lo tienes instalado, estos pasos no son necesarios.
Lo primero que hay que hacer es instalar los paquetes básicos,
shell> apt-get install git-core postgresql curl ruby1.9.3
shell> apt-get install nmap
Tras ello, ya podemos comenzar a instalar las pequeñas dependencias de Metasploit. Puesto que la mayoría de código está escrito en Ruby, para instalar dependencias lo podemos hacer automáticamente con gem. Para ello,
shell> gem install wirble sqlite3 bundler
Ahora que ya tenemos instalado el software necesario vamos a clonar la última versión estable del framwork. Ejecutamos lo siguiente,
shell> cd /opt
shell> git clone https://github.com/rapid7/metasploit-framework.git
shell> cd metasploit-framework
Hasta aquí son los pasos para la instalación básica. Ahora vienen las complicaciones, por llamarlo de alguna manera. En la última versión de Metasploit, el framework al arrancar comprueba que todos los paquetes necesarios están instalados y en caso contrario los instala automáticamente. Esto lo hace gracias a bundle y siempre sacando la información de rubygems.org (excepto que se indique lo contrario). Como también lo podemos ejecutar nosotros manualmente, nos posicionamos sobre la carpeta donde esté instalado y ejecutamos,
shell> bundle install
...
Your bundle is complete!
Si tenemos todas las dependencias instaladas, esto tardará un poquito en terminar, pero no tendríamos que tener ningún error. Si nos da algún error al instalar algún paquete, lo más seguro es que nos falte alguna dependencia. Estas son las dependencias necesarias. Asegúrate de tener todos los paquetes instalados.
shell> apt-get install make \
                       libpq-dev \
                       libxml2-dev \
                       libxslt1-dev \
                       libpcap-dev
Al finalizar la instalación de las dependencias, volvemos a ejecutar bundle,
shell> bundle install
Si todo finalizó correctamente ya podemos arrancar Metasploit,
shell> ./msfconsole

Durante la instalación de los paquetes vía bundle puede dar alguno de los siguientes errores. En caso de que alguno de ellos aparezca es que falta alguna de las dependencias que hay que tener instaladas.
Error 1:
...
Installing json (1.7.7) 
Gem::Installer::ExtensionBuildError: ERROR: Failed to build gem native extension.

        /usr/bin/ruby1.9.1 extconf.rb 
creating Makefile

make
sh: 1: make: not found
Error 2:
...
Installing pg (0.15.1) 
Gem::Installer::ExtensionBuildError: ERROR: Failed to build gem native extension.

        /usr/bin/ruby1.9.1 extconf.rb 
checking for pg_config... yes
checking for libpq-fe.h... no
Can't find the 'libpq-fe.h header
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of
necessary libraries and/or headers.  Check the mkmf.log file for more
details.  You may need configuration options.
Error 3:
...
Installing nokogiri (1.5.9) 
Gem::Installer::ExtensionBuildError: ERROR: Failed to build gem native extension.

        /usr/bin/ruby1.9.1 extconf.rb 
checking for libxml/parser.h... no
-----
libxml2 is missing.  please visit http://nokogiri.org/tutorials/installing_nokogiri.html for help with installing dependencies.
-----
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of
necessary libraries and/or headers.  Check the mkmf.log file for more
details.  You may need configuration options.
Error 4:
Installing nokogiri (1.5.9) 
Gem::Installer::ExtensionBuildError: ERROR: Failed to build gem native extension.

        /usr/bin/ruby1.9.1 extconf.rb 
checking for libxml/parser.h... no
-----
libxml2 is missing.  please visit http://nokogiri.org/tutorials/installing_nokogiri.html for help with installing dependencies.
-----
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of
necessary libraries and/or headers.  Check the mkmf.log file for more
details.  You may need configuration options.
Error 5:
...
Installing pcaprub (0.11.3) 
Gem::Installer::ExtensionBuildError: ERROR: Failed to build gem native extension.

        /usr/bin/ruby1.9.1 extconf.rb 

[*] Running checks for pcaprub code...
platform is i486-linux
checking for pcap_open_live() in -lpcap... no
checking for pcap_setnonblock() in -lpcap... no
creating Makefile

make
compiling pcaprub.c
pcaprub.c:8:18: fatal error: pcap.h: No such file or directory
compilation terminated.
make: *** [pcaprub.o] Error 1

La entrada Instalar Metasploit en Debian Wheezy la puedes leer en El mundo en bits.
Leer más

Zabbix-API y tiempo de ejecución

En la entrada de hoy voy a comentar una cosa curiosa que me sucedió y a la que le sigo dando vueltas. El software empleado es Zabbix con algunas pequeñas modificaciones que le había aplicado, para tener unos mapas con un poco más de información.
Pongámonos en situación. Zabbix, desde la versión 1.8 trae un API de consulta bastante potente y de la que ya hablamos en otras ocasiones aquí. El propio interfaz gráfico hace uso de ella para obtener sus datos. Especialmente en la versión 2.0 de Zabbix, el uso del API es cada vez más extendido en el frontend. El problema es saber cómo trabajar con un API. No el API de Zabbix, sino cualquier API. ¿Debemos hacer muchas consultas pequeñas? ¿Sólo una y más grande? Mi conclusión, cuando menos para Zabbix, es más óptimo sacar los datos en cuantas menos consultas mejor.
Veamos un ejemplo del fallo.
...
$options = array(
   'nodeids' => get_current_nodeid(true),
   'hostids' => $hostids,
   'output' => array('status'),
   'nopermissions' => true,
   'preservekeys' => true,
   'selectScreens' => API_OUTPUT_COUNT,
);
$hosts = API::Host()->get($options);
foreach ($hosts as $db_element) {
 ...
 if ($db_element['elementtype'] == SYSMAP_ELEMENT_TYPE_HOST) {
  $options = array(
     'hostids' => $db_element["elementid"],
     'output' => array('value', 'description'),
     'nopermissions' => true,
     'filter' => array('value_flags' => null),
     'monitored' => true,
     'skipDependent' => true,
     'only_true' => 1
  );
  $triggers = API::Trigger()->get($options);
  if(count($triggers) > 0) {
   ...
  }
 ...
 }
...
Esta es la parte del código original de Zabbix, en el fichero include/maps.inc.php. Aunque aquí se presenta de forma simplificada, la idea es que se hace una consulta al API (API::Host()) de la que se obtienen los datos de estado de un listado de equipos. Esos equipos son los que pertenecen a un mapa. Después de trabajar con ellos, para un añadido propio, se hace una nueva llamada al API, en la que para cada elemento de tipo HOST se hace una nueva llamada al API de la que se sacan los trigger's que tenga activo el host en cuestión.
Hasta aquí todo correcto y funciona a la perfección. Con un mapa de 10 elementos, por ejemplo, todo es correcto. El problema viene cuando el mapa comienza a tener más de 20 elementos de tipo HOST.  Si el número de elementos (hablando siempre de tipo HOST) es de 7, las llamadas al API será 7, si son 12, 12 y así siempre. Esto es lógico, ¿no?
La lógica también dice que si una llamada tarda en ejecutarse 0.1 segundos, 10 llamadas tardarán 1 segundo. Que yo sepa, el API de Zabbix no hace ningún tipo de filtrado por llamadas excesivas ni nos bloquea por demasiadas peticiones, por lo tanto, lo que me pasó es algo muy curioso.
Si el número de equipos de tipo HOST que tenía en un mapa pasaba de 15, en sacar los datos tardaba entorno a ~20 segundos. Lo normal sería que tardase 2 segundos, podemos asumir incluso 5 segundos, pero si los mapas tenían entorno a 20 equipos, el tiempo no era proporcional al número de llamadas, sino que se disparaba. Esto no entraba dentro de lo esperado, para nada.
Por suerte, la solución fue sencilla y mucho más óptima en cuando a número de llamadas, pero siempre quedará ahí patente el por qué de la tardanza en la ejecución. La base de datos no tenía problema, al servidor web no le subía la carga. Es y quizás seguirá siendo un misterio.

Puede que la informática no siempre sea determinista o que los algoritmos de basen, no siempre sean así.

La entrada Zabbix-API y tiempo de ejecución la puedes leer en Puppet Linux.
Leer más

Zabbix 2.0 API - host.create

Aunque ya hace tiempo que no hablaba acerca de cómo emplear el API de Zabbix, eso no quiere decir que no la estuviese usando, más bien todo el contrario. Durante este tiempo hice numerosas cosas con ella, y la más especial, emplear la versión escrita en Python para interactuar con ella. Puesto que tuve que escribir código en Python, aproveché para recordar y ver cómo evolucionó este lenguaje de programación.
Por si alguien lo necesita, voy a hacer una serie/mini-tutorial acerca de cómo manejar el API de Zabbix (en su versión 2.0), esta vez desde Python.
Lo primero que necesitamos para ello es obtener el código para hablar con el API de Zabbix. Existen varios port's a Pyhton, yo personalmente opté por éste, que es el port a Python de la librería Ruby oficial. Para comenzar a trabajar, lo que necesitamos es crear una carpeta y descargar el código Python necesario (un único fichero). En dicha carpeta también crearemos los script's que vayamos haciendo, para así evitar problemas con las rutas (por simplificar).
shell> mkdir scripts_zabbix
shell> cd scripts_zabbix
shell> wget https://raw.github.com/gescheit/scripts/master/zabbix/zabbix_api.py
Ahora que ya tenemos todo listo, sólo nos queda escribir el pequeño código necesario para crear/actualizar host's en Zabbix. Puesto que deseamos ser ordenados, crearemos un primer fichero de conexión y configuración. Luego un segundo fichero que hará los cálculos y las llamadas. El primer fichero, zabbix_conf.py tendrá el siguiente código.
#!/usr/bin/env python
from zabbix_api import ZabbixAPI

user = 'admin'
password = 'zabbix'
url = 'http://localhost/'
zabbix = ZabbixAPI(server = url)
zabbix.login(user = user, password = password)

templatesList = {
  'windows': '1', # id del template Windows
  'linux': '2',   # id del template Linux
}
soList = {
  'windows': '1', # id del hostgroup Windows
  'linux': '2',   # id del hostgroup Linux
}
Lógicamente, cada uno que adapte la URL, el nombre de usuario y la contraseña a la de su sistema. Acordaros que el usuario que empleéis debe tener acceso a la API. Ahora creamos el segundo fichero, zabbix_host.py que tendrá la siguiente forma,
#!/usr/bin/env python
from zabbix_conf import *
import sys
import getopt
import traceback
import csv
from optparse import OptionParser

use = "Usage: %prog [options]"
parser = OptionParser(usage = use)

parser.add_option("-a", "--add", dest="add", action="store_true", default=False, help="Insert host.")

options, args = parser.parse_args()

if options.add:
  file = csv.reader(open('hosts.list', 'r'), delimiter=' ')
  for index, row in enumerate(file):
    try:
      temporal = {
        "name": row[0].strip(),
        "dns": row[0].strip() + "your_network.net",
        "pais": row[1].strip().upper(),
        "so": row[2].strip()
      }
      groups = [{"groupid": soList[temporal["so"]]}]
      templates = [{"templateid": templatesList[temporal["so"]}]
      profile = {
        "site_country": temporal["pais"],
        "os_full": temporal["so"]
      }
      print str(index + 1) + ":", temporal["name"]
      print "\tGrupos:", groups
      print "\tTemplates:", templates
      print "\tPerfil:", profile

    except:
      print "\tFallo:", data
      continue

    hosts = zabbix.host.get({'filter': {'name': temporal["name"]}, 'output': "extend"})
    if hosts:
      host = {
        'hostid': hosts[0]["hostid"], # línea importante para actualizar
        'host': temporal["name"],
        'groups': groups,
        'templates': templates,
        'inventory': profile,
        'inventory_mode': 0
      }
      r = zabbix.host.update(host);
      if r:
        print "Actualizado correctamente"
      else:
        print "Fallo al actualizar"

    else:
      host = {
        'host': temporal["name"],
        'interfaces': [{'type': 1, 'ip': "0.0.0.0", 'port': 10050, 'useip': 0, 'main': 1, 'dns': temporal["dns"]}],
        'groups': groups,
        'templates': templates,
        'inventory': profile,
        'inventory_mode': 0
      }
      r = zabbix.host.create(host);
      if r:
        print "Añadido correctamente"
      else:
        print "Fallo al crear"
Pues que la idea es automatizar la creación de host's, como podéis observar, al principio del script se lee un fichero, hosts.list, que contiene la siguiente información,
host_1 España Windows
host_2 España Linux
host_3 EE.UU. Linux
Modificar el comportamiento del script no es muy complejo y espero que a alguien le sirva como referencia para comenzar a emplear el API de Zabbix de manera útil.

PD: Recordar que en Python la identación es MUY importante!

La entrada Zabbix 2.0 API - host.create la puedes leer el Puppet Linux.
Leer más

Instalación del framework Volatility en Debian

Vamos a comenzar a realizar algún artículo de análisis forense y para ello, antes de comenzar, debemos de preparar el laboratorio de software que vamos a emplear.
Por circunstancias de la vida, tuve que hacer un pequeño análisis de un volcado de memoria RAM de un Windows, para saber qué tenía y de qué se había infectado. Para trabajar con este tipo de casos, lo mejor es emplear el framework Volatility. Cómo se hizo y qué datos obtuvimos lo vamos a dejar para otra entrada. En esta primera vamos a ver cómo instalar Volatility en nuestra distribución preferida y dejarlo listo para trabajar.
  1. Instalación de dependencias
    En este primer paso vamos a instalar todo el software que necesitamos para poder efectuar correctamente los siguientes pasos. Puesto que algunos de los paquetes que a continuación vamos a instalar no están disponibles en Debian/Ubuntu, tendremos que instalar software de compilación, que posteriormente no será necesario.
    Las dependencias necesarias a instalar,
    shell> apt-get install pcregrep \
                           libpcre++-dev \
                           python-dev \
                           unzip \
                           g++ \
                           python-crypto
    
  2. Instalación de diStorm
    Ahora que ya tenemos todo lo necesario instalado, podemos comenzar la instalación del software que realmente vamos a emplear con Volatility.
    Lo primero, diStorm, una pequeña librería que nos ayudará al desensamblado de datos de la memoria. Desde la web oficial del proyecto nos podemos descargar la última versión de la librería e instalarla.
    shell> wget https://distorm.googlecode.com/files/distorm3.zip
    shell> unzip distorm3.zip
    shell> cd distorm3/
    shell> python setup.py build
    shell> python setup.py build install
    
    Si todo sale correcto, la instalación será satisfactoria.
  3. Instalación de Yara/Yara-Python
    Seguimos instalando librerías. Ahora es el turno de Yara y la versión de Yara para Python. Yara es una librería que permite buscar, identificar y extraer trozos de código malware. Más información en la web oficial del proyecto.
    shell> wget https://yara-project.googlecode.com/files/yara-1.7.tar.gz
    shell> tar -zxvf yara-1.7.tar.gz
    shell> cd yara-1.7/
    shell> ./configure
    shell> make
    shell> make install
    
    Y ahora el turno de la librería Python,
    shell> wget https://yara-project.googlecode.com/files/yara-python-1.7.tar.gz
    shell> tar -zxvf yara-python-1.7.tar.gz
    shell> cd yara-python-1.7
    shell> python setup.py build
    shell> python setup.py build install
    
    Si todo está correcto, ya sólo nos queda el último paso, instalar Volatility
  4. Instalación de Volatility
    Vamos a instalar finalmente el framework con el que trabajaremos. Para ello nos descargamos la última versión desde la web oficial y la instalamos.
    shell> wget https://volatility.googlecode.com/files/volatility-2.2.tar.gz
    shell> tar -zxvf volatility-2.2.tar.gz
    shell> cd volatility-2.2/
    shell> python setup.py install
    
Si todo ha salido correctamente, tendremos un nuevo comando en nuestro sistema, vol.py, que nos abrirá nuestro nuevo framework de análisis forense.
shell> vol.py -h
Volatile Systems Volatility Framework 2.2
Usage: Volatility - A memory forensics analysis platform.
...

La entrada Instalación del framework Volatility en Debian la puedes leer en Puppet Linux.
Leer más

Desactivar pitido consola GNU/Linux

Por defecto los sistemas GNU/Linux traen activado un pequeño beep para determinados eventos del sistema. Por defecto, para muchos eventos de la consola, este beep se lanza y puede llegar a ser incluso "un poco" molesto, especialmente si trabajas con más gente a tu lado.
Si lo deseas desactivar/eliminar, simplemente:

shell> set bell-style none
Dicho molesto sonido es producido por un módulo del kernel de Linux, pcspkr, por lo que descargando dicho módulo del kernel, también se evitará el sonido. La forma de hacerlo:
shell> rmmod pcspkr
Y para evitar que se cargue en el inicio, agregamos el módulo al fichero /etc/modprobe.d/blacklist.conf la siguiente línea,
blacklist pcspkr
Espero que os sea de ayuda.

La entrada Desactivar pitido consola GNU/Linux la puedes leer en Puppet Linux.
Leer más

Agregando información extra a los mapas de Zabbix

Aunque lo fuerte de Zabbix no es exactamente el diseño de mapas, sí es cierto que éstos permiten poner de forma visible una gran cantidad de información. Sin mucho esfuerzo podemos crear un mapa con un equipo y que muestre información en tiempo real del mismo. El mapa permite una mejor visualización y la información importante allí mostrada, facilita y de qué forma, saber el estado del mismo. A mayores, si el equipo tiene un fallo, éste también estará presente en el mapa, lo cual ya nos da más información.
Sin embargo, una de las cosas que faltaba en los mapas de Zabbix era que sobre equipos con algún fallo se nos mostrase dicho fallo al pasar por encima con el ratón, por ejemplo. De esta forma los errores se pueden visualizar, pero sólo si nos interesa. En caso contrario no se mostrarán. Con un ejemplo gráfico que se entenderá mejor.

En la parte izquierda tenemos un equipo con información, siempre en tiempo real y con dos errores. La forma de saber cuales son esos errores, tal como está ahí en el mapa es ir a la pestaña trigger's de ese equipo y ver cuales están disparados. Sin embargo, tras la modificación que veremos a continuación, tenemos la imagen de la derecha. En ella se observa un pequeño popup que aparece al pasar el ratón por encima de la imagen y que nos muestra la descripción de los trigger's disparados con el color que le corresponde. Esta información no es molesta, puesto que sólo aparece cuando pasamos el ratón por encima del equipo, sino permanece oculta.
Si te interesa aplicar esta pequeña mejora, simplemente debes de editar el fichero include/maps.inc.php y agregar las siguientes líneas (en negrita) al final de la función getActionMapBySysmap.
...
if (!empty($menus)) {
 $r_area->addAction('onclick', 'javascript: '.$menus);
}

if ($db_element['elementtype'] == SYSMAP_ELEMENT_TYPE_HOST) {
 $options = array(
    'hostids' => $db_element["elementid"],
    'output' => array('value', 'description'),
    'nopermissions' => true,
    'filter' => array('value_flags' => null),
    'monitored' => true,
    'skipDependent' => true,
    'only_true' => 1,
 );
 $triggers = API::Trigger()->get($options);
 if(count($triggers) > 0) {
  $text = "";
  $isTable = false;
  foreach($triggers as $t) {
   if($t["value"] == 1) {
    $isTable = true;
    switch ($t['priority']) {
     case 0: $class="normal"; break;
     case 1: $class="information"; break;
     case 2: $class="warning"; break;
     case 3: $class="average"; break;
     case 4: $class="high"; break;
     case 5: $class="disaster"; break;
     }
    $text .= "<tr><td class='".$class."'>".$t['description']."</td></tr>";
   }
  }
  if($isTable) {
   $text = "<div class='nowrap ui-corner-all ui-widget-header header move'>Triggers</div><table class='tableinfo'>".$text."</table>";
   $r_area->addAction('onmouseover', 'hintBox.HintWraper(event, this, '.zbx_jsvalue($text).', \'\', \'\');');
  }
 }
}
$action_map->addItem($r_area);
...
La idea desarrollada es muy simple. Crear una nueva área oculta con javascript y que ante el evento onmouseover aparezca y contenga la información que no interesa. Lo mismo que el popup que salta al pinchar sobre un equipo y que permite ejecutar comandos, pero con otra información.

La entrada Agregando información extra a los mapas de Zabbix la puedes leer en Puppet Linux.
Leer más

MySQL FULL PROCESSLIST

Fijo que muchos de vosotros os habéis preguntado alguna vez cómo obtener el proceso completo que se está ejecutando un MySQL. Por defecto, esto se consigue con 'show processlist', pero este comando, si el proceso ocupa más de un límite corta la línea, evitando así que veamos query's completas si éstas son muy grandes.
Por poner un ejemplo,
mysql> SHOW PROCESSLIST;
+----+------+-----------+-----+---------+------+-------+-----------------
| Id | User | Host      | db  | Command | Time | State | Info            
+----+------+-----------+-----+---------+------+-------+-----------------
| 10 | web  | localhost | web | Sleep   |  118 |       | NULL            
| 14 | web  | localhost | web | Query   |    0 | NULL  | SHOW PROCESSLIST
+----+------+-----------+-----+---------+------+-------+-----------------
2 rows in set (0.01 sec)
Como podemos observar, ahora que no hay ninguna query compleja, la salida es correcta y completa. Sin embargo, si ejecutamos alguna query grande y volvemos a ver los procesos, el resultado cambia sustancialmente.
mysql> SHOW PROCESSLIST;
+----+------+-----------+-----+---------+------+---------+---------------
| Id | User | Host      | db  | Command | Time | State   | Info          
+----+------+-----------+-----+---------+------+---------+---------------
| 10 | web  | localhost | web | Sleep   |  118 |         | NULL            
| 14 | web  | localhost | web | Query   |    0 | NULL    | SHOW PROCESSLIST
| 17 | webb | localhost | web | Query   |    0 | Sending | SELECT t.*,i.hostid FROM triggers t,items i,ho |
+----+------+-----------+-----+---------+------+--------------+----------
3 rows in set (0.01 sec)
En este caso, el proceso con Id: 17, un "SELECT" no está completo y por lo tanto no sabemos qué query es la que se está lanzando. Puede que esta información no sea necesaria, o puede que sí. En caso de que sí la necesites ver, el comando 'show' tiene la posibilidad de decirle que se ejecute con la salida completa y por lo tanto nos mostrará las query's. Para ello,
mysql> SHOW FULL PROCESSLIST;
+----+------+-----------+-----+---------+------+--------------+----------
| Id | User | Host      | db  | Command | Time | State        | Info     
+----+------+-----------+-----+---------+------+--------------+----------
| 10 | web  | localhost | web | Sleep   |  118 |              | NULL     
| 14 | web  | localhost | web | Query   |    0 | NULL         | SHOW PROCESSLIST
| 17 | webb | localhost | web | Query   |    0 | Sending data | SELECT t.*,i.hostid FROM triggers t,items i,hosts h WHERE h.hostid=t.hostid AND h.hostid=i.hostid AND h.hostid="15" h.status="0"
+----+------+-----------+-----+---------+------+--------------+----------
3 rows in set (0.01 sec)
Como vemos ahora el comando ya está al completo, que era justamente lo que buscábamos.

La entrada MySQL FULL PROCESSLIST la puedes leer en Puppet Linux.
Leer más

Formulario de contacto

Nombre

Correo electrónico *

Mensaje *

Últimos comentarios