jueves, 30 de diciembre de 2010

Tres reglas en la administración de sistemas

Fuente original: http://www.thegeekstuff.com/2010/07/three-sysadmin-rules/

El borrador de este artículo trataba de las 7 costumbres de los administradores de sistemas. Tres de ellas destacaban realmente.

Si las costrumbres son buenas, a veces las reglas son incluso mejor, especialmente en el mundo de la administración de sistemas cuando se trata de un entorno de producción.


Regla #1: Haz copia de seguridad de todo ( y compruébala con regularidad )


Los administradores de sistemas experimentados saben que, independientemente de lo proactivo que seas, un sistema en producción fallará algún día. La mejor forma de estar preparado para esta situación es disponer de una copia de seguridad correcta.

Si no dispones de una copia de seguridad de tus sistemas críticos, deberías empezar a pensar en ello inmediatamente. Ten en cuenta lo siguiente:
  • ¿Qué software o script utilizarías para realizar la copia de seguridad?
  • ¿Dispones de suficiente espacio en disco para la copia de seguridad?
  • ¿Con qué frecuencia se actualizarán las copias de seguridad?
  • ¿Necesitarás copias de seguridad incrementales además de la copia de seguridad total?
  • ¿Cómo se ejecutaría la copia de seguridad, por ej. utilizando crontab o algún otro sistema de calendarizaje?
Si no tienes una copia de seguridad de tus sistemas críticos, deja de leer este artículo y ponte a trabajar. Comienza la planificación de tu copia de seguridad inmediatamente.

En una de las investigaciones realizadas por una compañía (no recuerdo cual), recuerdo que sólo el 70% de las aplicaciones en producción tenían copia de seguridad, y de ellas el 30% eran incorrectas o estaban corruptas.

Supongamos que Samuel realiza copia de seguridad regularmente de las aplicaciones críticas, pero no las comprueba. Por otro lado, Javier no realiza ninguna copia de seguridad de sus aplicaciones críticas. Se puede pensar que Samuel lo hace mejor que Javier, pero en mi opinión los dos están en una mala situación: Samuel no puede asegurar la restauración correcta de la copia de seguridad en caso de desastre.

Si eres un administrador de sistemas y no consideras esta regla de oro número 1, debes pensar seriamente en dejar de administrar sistemas y dedicarte al desarrollo de aplicaciones.


Regla #2: Domina la línea de comandos ( y evita las ventanas )


No hay una ni una tarea en un servidor Unix / Linux que no puedas realizar con la línea de comandos. Existen algunas aplicaciones de administración basadas en ventanas para hacerlo más fácil, pero realmente no las necesitas y deberías utilizar siempre la línea de comandos.

Si eres un administrador de sistemas Linux, debes dominar la línea de comandos.

En cualquier sistema, si quieres ser fluido y productivo, debes ser un maestro con la línea de comandos. La diferencia principal entre un administrador de sistemas de Windows y de Linux es: Interface gráfica vs. Línea de comandos. Los administradores de sistemas de Windows no se sienten muy cómodos con la línea de comandos, mientras que los administradores de sistemas de Línux si.

Aparte de utilizar la línea de comandos, también debes entender cómo funciona un servicio en particular. En muchos entornos de servidor en producción, los administradores de sistemas normalmente desinstalan los servicios y herramientas que utilizan la interface gráfica.

Si eres un administrador de sistemas de Unix / Linux y no te gusta esta regla, es posible que realmente te guste más la administración de sistemas de Windows.


Regla #3. Automatiza todo ( y hazte vago )

El mejor administrador es el vago.

No conozco a ningún administrador que rompa esta regla. Esta es la parte más vaga.

Piensa durante unos minutos en la lista de tareas rutinarias que tienes que hacer todos los días, semanas o mensualmente. Cuando tengas esa lista, piensa en cómo automatizarla. El mejor administrador de sistemas normalmente no está ocupado, todo lo contrario: está relajado y deja que el sistema haga el trabajo por él.

martes, 7 de diciembre de 2010

Exchange 2010: informe de buzones grandes

Objetivo: enviar informe por email (por ej. una vez por semana) con los tamaños de los 10 buzones Exchange 2010 más grandes y sus respectivos usuarios.

Requisitos: en un servidor Exchange 2010 lanzar el script una vez por semana mediante una tarea programada.

Observaciones: indicar en el script los campos adecuados del email del remitente, del destino y el servidor smtp de destino correspondiente.

---- comienzo del script --------

# top 10 en tamaño de buzones de Exchange 2010 vía email
# datos envío email

$remitente = "remitente@dominio.com" # origen email
$destino = "destinatario@dominio.com" # más de uno separados por coma
$asunto = "TOP 10 buzones de usuario"
$servidor_smtp_destino = "smtp.dominio.com" # servidor smtp destino

# extracción ordenada de tamaños de buzones

$buzones = Get-Mailbox |
get-mailboxstatistics |
select-object DisplayName, TotalItemSize |
sort TotalItemSize -Descending

# selección de los 10 primeros

$top10buzones = 0..9 | % {$buzones[$_]}

# elaboración del informe

$informe = "`n" # primera línea en blanco del texto del informe

$informe = $informe + " Tamaño Usuario" + "`n"
$informe = $informe + "-------- : ----------------------" + "`n"

foreach ($buzon in $top10buzones) # procesa los 10 buzones
{
$informe = $informe + "{0,5:n0}" -f ($buzon.TotalItemSize.value.ToGB()) + " GB" + " : " + $buzon.DisplayName + "`n"
}

# envía email con informe

$smtp = new-object Net.Mail.SmtpClient($servidor_smtp_destino)
$smtp.Send($remitente, $destino, $asunto, $informe)

---- fin del script --------


miércoles, 1 de diciembre de 2010

Exchange 2010: creación rápida de usuario y buzón

Con un único formulario, crea un usuario con buzón de correo en Exchange 2010 desde cualquier host conectado al dominio del Directorio Activo. Sólo es necesario tener instalado PowerShell 2 y .NET 3.5 en adelante.

Características:
  • Un sólo formulario.
  • Nombre de dirección de correo igual al nombre de inicio de sesión.
  • Inserción única de la contraseña.
  • Visualización del tamaño de las bases de datos de Exchange 2010 antes de elegirla.
  • Distinción entre cuenta personal y de servicio.
  • Inserción en grupos del Directorio Activo.
  • Inserción de los atributos más utilizados.
  • Visualización en la barra de estado del servidor Exchange 2010 conectado.
  • Gratuito.

Modo de empleo:
  • Ejecuta la herramienta "alta_usuario_mailbox_2010.exe" con un usuario que tenga privilegios para crear buzones en Exchange 2010.
  • Elige en el árbol de la izquierda la Unidad Organizativa donde quieres ubicar la nueva cuenta.
  • Rellena los campos que necesites (algunos son obligatorios).
  • Clica en "Dar de Alta" y si todo es correcto, el usuario (con todas las opciones indicadas en el formulario) y su buzón de correo aparecerán en su sitio.

Pantallazo:


sábado, 27 de noviembre de 2010

Directorio Activo: Informes de usuarios

Toca realizar consultas al Directorio Activo en busca de patrones que guardan los usuarios. Sólo vamos a utilizar PowerShell y .NET (sin más).

Un usuario de un dominio de un Directorio Activo es un objeto y tiene una serie de propiedades (también conocidas como atributos) que le hacen único para unas cosas y común para otras. Entre otras, las propiedades más conocidas de un usuario son: name, displayname, samaccountname, company, department, division, memberof y mail.

Como ejemplo a ilustrar, vamos a obtener un informe de todos los usuarios del grupo G_ADMON y cuya oficina (atributo physicalDeliveryOfficeName) sea Madrid. Primero pongo el código PowerShell y después lo explico:

----comienzo de script.ps1-------------

$rootdse = New-Object DirectoryServices.DirectoryEntry("LDAP://RootDSE")
$dominio = $rootdse.Properties["defaultNamingContext"]
$raiz_dominio = New-Object DirectoryServices.DirectoryEntry("LDAP://$dominio")

$busca = New-Object DirectoryServices.DirectorySearcher $raiz_dominio
$busca.Filter = "(&(objectClass=user)(objectCategory=person))"
$usuarios = $busca.findall()

$c=0

foreach ($usuario in $usuarios)
{
if (($usuario.properties.memberof -like '*G_ADMON*') -and
($usuario.properties.physicaldeliveryofficename -eq 'Madrid'))
{
$usuario.properties.name
$usuario.properties.mail
"-----------------------"
$c++
}
}
"$c usuarios encontrados."

----fin de script.ps1-------------

En las tres primeras líneas se crean tres objetos consecutivamente:

$rootdse: localiza la configuración principal del Directorio Activo.
$dominio: extrae el valor del dominio de la configuración de $rootdse.
$raiz_dominio: partiendo de $dominio, se ubica en su elemento raíz para realizar búsquedas.

Las tres siguientes líneas preparan y ejecutan la búsqueda de usuarios:

$busca: objeto que busca en $raiz_dominio.
$busca.Filter: es un filtro para que sólo busque usuarios y no otro tipo de objetos.
$usuarios = $busca.findall(): busca y encuentra a todos los usuarios que cumplan con el filtro y los deja en $usuarios.

Después se inicializa un contador a 0 y luego hay un bucle foreach que recorre todos los usuarios encontrados. Por cada usuario ($usuario) en $usuarios se busca con if a los usuarios cuyo campo memberof (grupos a los que pertenece el usuario) contenga lo que estamos buscando (el grupo G_ADMON) y cuyo campo physicaldeliveryofficename (oficina) sea Madrid. Si las dos condiciones anteriores se cumplen, mostramos el nombre y el email del usuario en cuestión; además se incrementa el contador. El informe finaliza con el número de usuarios encontrados que cumplen las condiciones.

Este es el armazón básico para realizar consultas a objetos de un Directorio Activo, en este caso han sido consultas a dos atributos de todos los usuarios, pero podemos consultar cualquier atributo de cualquier usuario u otro objeto. Sólo necesitamos saber cómo se llaman los atributos de los objetos para buscarlos. Para averiguar estos nombres de atributos aconsejo utilizar la herramienta AD Explorer de Mark Russinovich para ver el Directorio Activo por dentro, localizar los objetos y ver sus atributos.

Además, escribir código para estos menesteres es mucho más corto y rápido con PowerShell que con cualquier otro lenguaje que utilice .NET como VBasic o C#.


martes, 2 de noviembre de 2010

Acceso rápido a herramientas de Windows

El Panel de control de Windows tiene varias herramientas, pero hay otras importantes como los servicios y el visor de sucesos que no aparecen ahí.

Por otro lado, dependiendo de la versión de Windows, los nombres de algunas herramientas cambian, por ej. en Windows XP, Windows 2000 y Windows 2003 tenemos "Agregar o quitar programas", en Windows Vista, tenemos "Programas y características", y en Windows 7 tenemos "Desinstalar un programa" pero en este caso la barra de direcciones sigue haciendo referencia a "Programas y características", todo esto con la misma función recurrente: desinstalar programas.

Por estos motivos y por muchos otros, y porque un click es más rápido que dos, se me ocurrió hacer un menú (herramientas.exe) con categorías y botones donde cada uno inicializa una herramienta:


Este menú ha funcionado correctamente en:
  • Windows XP
  • Windows 2003
  • Windows 7
Y el ordenador que lo utiliza necesita el Framework 3.5 instalado (Windows 7 ya lo lleva puesto).

sábado, 30 de octubre de 2010

Nueva contraseña en tres pasos


Una de las tareas más recurrentes en la administración de un Directorio Activo es el cambio de contraseña de los usuarios.

Utilizar las típicas consolas de administración implican varios pasos para encontrar el usuario y cambiar su contraseña.

Para dejarlo sólo en tres pasos, he creado cambiapass.exe, y una vez abierto ...
  1. Introduce el nombre de la cuenta del usuario (sAMAccountName) y pulsa ENTER.
  2. Si existe, aparece la información suficiente para identificar al usuario.
  3. Introduce la nueva contraseña y pulsa ENTER.

Un vistazo:


Requisitos: Framework 3.5 en un ordenador miembro del dominio.


martes, 28 de septiembre de 2010

Altas rápidas de usuario con Exchange 2007

Cuando se da de alta un usuario en un Directorio Activo Win2003, normalmente también se necesita:
  • Buzón de correo
  • Atributos (organización, departamento, etc.)
  • Pertenencia a grupos
Y para esto son necesarias la consola de Exchange 2007 (creación del usuario y el buzón en este caso) y la consola de Administración de Usuarios y grupos del Directorio Activo (inserción de atributos y grupos).

Para no perder tanto tiempo utilizando dos consolas, he desarrollado una herramienta llamada alta_usuario.exe que ofrece un único formulario para crear un usuario+buzón, indicar toda la información mencionada y alguna cosa más:


Lo primero que debemos hacer es asegurarnos de que cumplimos los requisitos mínimos, que son tener instalado el siguiente software en el host donde ejecutemos alta_usuarios.exe:
Lo segundo es ejecutar alta_usuarios.exe con un usuario que tenga permisos suficientes para crear usuarios en el dominio y buzones en Exchange 2007.

Aparece el formulario, indicamos el nombre del dominio (por defecto DOMINIO) y le damos a Conectar. Esperamos un poco y si todo es correcto, aparecerá en la columna izquierda el árbol de OU's del dominio. Elegimos la OU correspondiente para el nuevo usuario, y ésta aparecerá arriba en el apartado Unidad Organizativa.

Después indicamos la información común de alta del usuario donde es obligatorio el nombre, el nombre de inicio de sesión, la contraseña y el grupo de almacenamiento de correo (los atributos son opcionales).

En el apartado Tipo de cuenta podemos elegir entre:
  • Cuenta personal: el usuario es una persona e indicamos sus apellidos.
  • Cuenta de servicio: el usuario no es una persona e indicamos el atributo Nombre para mostrar que queramos.
Una cuenta de servicio es aquella que utilizan uno o más usuarios, y la cual carece de apellidos. En el caso del atributo Nombre para mostrar de la cuenta personal será: apellido1 apellido2, nombre.

El penúltimo paso es añadir al nuevo usuario en los grupos que queramos del Directorio Activo, y si nos equivocamos también podemos quitarlos (tampoco es obligatorio).

Por último, le damos al botón Dar de Alta y el resultado lo tendremos más abajo.

Nota: esta herramienta está muy probada en producción, en el entorno indicado y funciona estupendamente, no obstante, si la pruebas y ves algún fallo o sugerencia, agradeceré me lo comuniques.

lunes, 13 de septiembre de 2010

Directorio Activo: grupos y miembros

Cuando un Directorio Activo alcanza su madurez, también alcanza un buen número de grupos que se utilizan para que sus miembros (usuarios y otros grupos) dispongan de otros recursos del Directorio Activo como carpetas compartidas, listas de distribución de email, permisos para realizar ciertas operaciones, etc.

En cualquier caso y a medida que pasa el tiempo, la creación de grupos disminuye y aumenta la necesidad de agregar/eliminar miembros de estos grupos.

Para que esta tarea sea más rápida y amena, he creado una herramienta llamada Gestión de miembros en grupos (gestion_grupos.exe) que hace lo siguiente:
  • Conecta con el dominio deseado previa indicación de su nombre.
  • Crea una lista desplegable con todos los grupos encontrados en el dominio indicado.
  • Elegido un grupo de la lista desplegable, aparecen sus miembros.
  • Para eliminar un miembro, lo seleccionamos de la lista y clicamos en "Eliminar".
  • Para agregar un miembro, escribimos su nombre de cuenta (samAccount) en el campo a la izquierda del botón "Agregar" y clicamos en él.
  • Los miembros pueden ser usuarios y/o grupos.
  • Requiere .NET Framework 3.5

Un pantallazo:

lunes, 19 de julio de 2010

Monitorizando colas de Exchange 2007


Get-Queue -server nombre_servidor_exchange2007

es el comando PowerShell que muestra una instantánea del número de mensajes de las colas del servidor de correo Exchange 2007.

Una buena mejora en la visualización de resultados de este comando sería que éstos aparecieran en una ventanita de Windows y se actualizara con cierta frecuencia:

Para conseguirlo, escribiremos una aplicación en C# que internamente ejecute nuestro comando en PowerShell y envíe su salida a un Listview con los resultados, todo en una ventanita.

Para que esto funcione, tanto en el desarrollo de la aplicación como en la ejecución posterior del .exe, es necesario utilizar un usuario que tenga permisos para visualizar las colas, por ej. el administrador de dominio.





Requisitos de software en el host de desarrollo:

- SharpDevelop
- Powershell 2
- Consola de administración de Exchange 2007
- .NET Framework 3.5

Instalado todo esto, abrimos SharpDevelop con el usuario que tenga permisos para ver las colas de Exchange 2007 y creamos en un proyecto nuevo una nueva aplicación de Windows que se llame "colas_correo", de esta forma:

Creada la aplicación, tendremos una ventana vacía que es el formulario por defecto "MainForm". A la derecha de la vista de diseño del formulario tenemos la columna de propiedades del elemento que tengamos seleccionado. Seleccionamos la ventana del formulario y en la lista de propiedades buscamos la propiedad "Text", y le ponemos el nombre que queramos para que aparezca como título de la ventana, por ej. "Colas Exchange".

Dentro del formulario creamos una etiqueta cuya propiedad (Name) sea "leyenda_form". La propiedad Text de esta etiqueta la modificaremos dinámicamente para visualizar la fecha/hora de la última consulta a las colas.

Debajo de la etiqueta creamos un ListView con dos columnas, seleccionamos el ListView creado, clicamos en la flechita que está cerca de la esquina superior derecha del ListView, clicamos en "Editar columnas" y agregamos un miembro 0 (columna izquierda) donde su propiedad (Name) debe tener el valor: cola_form, y la propiedad Text debe tener el valor: Cola. Después agregamos otro miembro 1 (columna derecha) donde su propiedad (Name) debe tener el valor: mensajes_form y la propiedad Text debe tener el valor: Mensaje.

Aceptamos ventanas y pasamos a picar código. Clicamos en la pestaña "Fuente" de abajo y podremos editar el código de este formulario que es el que utilizaremos. El archivo que contendrá este código es MainForm.cs y estará ubicado en la carpeta del proyecto.

También tienes disponible el código de MainForm.cs en este enlace.

En el comienzo del archivo MainForm.cs aparece por defecto una lista de directivas using que tenemos que completar dejándolas así:

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using System.Collections.ObjectModel;
using System.Management.Automation;
using System.Management.Automation.Host;
using System.Management.Automation.Runspaces;
using System.Text;

Para evitar errores en la compilación relacionados con la falta de referencias, seguramente sea necesario agregar las referencias correspondientes para alguno de estos using. Lo puedes hacer desde el menú Proyecto, Agregar Referencia, pestaña GAC, buscar la referencia correspondiente, seleccionarla y OK.

Después de la lista de los using, hay un namespace cuyo nombre da igual para nuestro propósito. Dentro de tal, tendremos un public partial class MainForm: Form que es la clase de nuestro formulario y dentro de ella hay métodos (funciones), entre ellos, el punto de entrada es el método public MainForm() que se encarga de iniciar el formulario.

Dentro de public MainForm(), lo primero es el método InitializeComponent() que se encarga de inicializar el formulario con las propiedades por defecto, y justo después crearemos un Timer para que nuestra aplicación saque datos cada minuto:

Timer timer1 = new Timer();
timer1.Interval = 60000; // un minuto
timer1.Enabled = true;
timer1.Tick += new System.EventHandler (OnTimerEvent);

Además, necesitamos un método
OnTimerEvent()
que tiene que ir al mismo nivel que public MainForm(), así:

public void OnTimerEvent(object source, EventArgs e)
{
saca_datos();
leyenda_form.Text = "Última actualización: " + DateTime.Now.ToLongTimeString();
}

leyenda_form
es el nombre de una etiqueta dentro del formulario que indica la última fecha/hora que se hizo la consulta a las colas (no olvides tenerla ubicada visualmente en el formulario con la propiedad (Name) adecuada).

saca_datos()
es el método que hará la invocación a PowerShell y sacará los datos de la cola. También debe ir al mismo nivel que public MainForm().

Importante:
el método saca_datos() debes editarlo para definir la variable "servidor" con el nombre DNS de tu servidor Exchange 2007.

El código del método saca_datos() es el siguiente:

private void saca_datos()
{
lista_form.Items.Clear();
// edita la siguiente línea con el nombre DNS de tu servidor de correo
string servidor = "el_nombre_de_tu_servidor_exchange";

RunspaceConfiguration rsConfig = RunspaceConfiguration.Create();
PSSnapInException snapInException = null;
PSSnapInInfo info = rsConfig.AddPSSnapIn
("Microsoft.Exchange.Management.PowerShell.Admin", out snapInException);
Runspace myRunSpace = RunspaceFactory.CreateRunspace(rsConfig);
myRunSpace.Open();
Pipeline pipeLine = myRunSpace.CreatePipeline();

// comando powershell
Command myCommand = new Command("Get-Queue");

//parámetros powershell
CommandParameter param_server = new CommandParameter("server", servidor);
myCommand.Parameters.Add(param_server);

//mete en la tubería de ejecución
pipeLine.Commands.Add(myCommand);

//ejecución
Collection commandResults = pipeLine.Invoke();

//resultados
string cola = "";
string mensajes = "";

foreach (PSObject cmdlet in commandResults)
{
cola = cmdlet.Properties["NextHopDomain"].Value.ToString();
mensajes = cmdlet.Properties["MessageCount"].Value.ToString();

//saca datos en lista
ListViewItem i = new ListViewItem();
i.Text = cola;
i.SubItems.Add(mensajes);
lista_form.Items.Add(i);
}
}


Y listo, con esto sólo queda darle a F5 para compilar y ejecutar la solución.

Si todo es correcto, el ejecutable colas_correo.exe lo encontrarás en la carpeta debug o release dentro de la carpeta bin del proyecto, el cual podrás utilizar directamente.



domingo, 23 de mayo de 2010

División entre dos

Si algo se parte en dos,
tendrás dos lugares distintos,
si ambos comprendes,
avanzarás.

sábado, 27 de marzo de 2010

Espacio libre

En un entorno con varios servidores en red, una de las cosas más importantes y que más suele pasar desapercibida es el espacio libre de sus discos duros.

Si una partición de un disco duro de un servidor comienza a quedarse sin espacio libre, las consecuencias suelen ser:
  • Caída del rendimiento del servidor que contenga la partición.
  • Caída del rendimiento de los servicios que utilicen tal servidor.
  • Con el tiempo, la interrupción de los servicios que utilicen tal servidor.
  • Si el servicio interrumpido se dedica a tareas de seguridad, mal vamos.
Para evitar esto de forma proactiva es conveniente conocer, por lo menos una vez a la semana, el espacio libre de cada partición de cada disco duro de cada servidor de la red, y si este espacio libre es menor que 1GB (por ejemplo), se avisaría al administrador del sistema para que remedie esta situación.

Automatizar lo anterior en un Directorio Activo con muchos servidores es posible utilizando Powershell y las Tareas Programadas en algún servidor.

Para ello, he escrito el script freespace.ps1 que busca en el Directorio Activo los nombres de todos sus servidores. Después, el script realiza las consultas adecuadas a los servidores dados, filtra resultados y si es necesario envía un email con la información pertinente al administrador del sistema para que pase a la acción.

freespace.ps1 debe estar ubicado en una carpeta de trabajo, por ejemplo, en c:\freespace

Ubicado freespace.ps1 en su sitio, es necesario editarlo y personalizar los valores de las siguientes variables que se encuentran al principio:

$limite = 1000000000 # con menos de un giga libre en una partición, se informa
$emailFrom = "pon_email_de@origen.es" # origen email

$emailTo = "pon_email_de@destino.es" # destino email

$smtpServer = "tu_servidor_smtp.tu_dominio.es" # servidor smtp de destino

$subject = "Particiones con menos de 1GB libre" # asunto


Una vez personalizadas las variables, guardamos los cambios del script y en la carpeta de trabajo creamos el archivo freespace.bat que debe contener la siguiente línea:

powershell c:\freespace\freespace.ps1

Por último, creamos una tarea programada que ejecute c:\freespace\freespace.bat una vez por semana. Los permisos de la tarea deben ser de un usuario que tenga acceso a todas las particiones de todos los servidores.

Un email enviado en un caso real es el siguiente:

sábado, 6 de marzo de 2010

Descubriendo troyanos 3/3

Ahora toca registrar las conexiones realizadas en Windows desde Windows.

Para ello, iniciamos Windows desde la máquina virtual e instalamos Wireshark. Abrimos Wireshark, elegimos el adaptador de red y comenzamos una captura de paquetes apuntando exactamente la hora y el minuto de inicio de la captura.

Ahora es el momento de abrir IE6 en Windows, navegar por páginas de dudosa reputación y aceptar todo lo que se ponga por delante. Cuanto más tiempo tenga la captura, más posibilidades tendremos de atrapar a algún troyano.

Cuando detengamos la captura de paquetes con Wireshark, exportamos los paquetes capturados mediante el menú File, Export, File..., y guardamos el archivo como export_w32.txt con formato de texto plano (plain text) en el directorio de trabajo.

El siguiente paso es extraer las IPs de las conexiones que se han realizado desde Windows hacia Internet, eliminar redundancias y mostrar más información de la IP (como ya hicimos con Ubuntu con el script conex_report.pl). Para ello, en el directorio de trabajo, ejecutaremos el script conex_report_w32.pl de la siguiente forma:

perl conex_report_w32.pl > windows.txt

Lo anterior genera el fichero windows.txt cuyo contenido será parecido a esto:



Ya tenemos todos los datos que necesitamos. Ahora tenemos que comparar los resultados de windows.txt y de ubuntu.txt para detectar sus diferencias. Para ello, copiamos el contenido de windows.txt, creamos otro windows.txt en el directorio de trabajo de Ubuntu y pegamos en él el contenido del primero.

La comparación de ambos ficheros la realizaremos con el script compara_conex_report.pl que ejecutaremos en el directorio de trabajo de Ubuntu donde también deben figurar los archivos ubuntu.txt y windows.txt

Conclusión y aclaraciones:

Como el procedimiento explicado en el segundo y tercer post depende de ciertos scripts para permitir la automatización de tal, la presentación en PDF del primer post muestra el concepto general, mientras que el procedimiento detallado paso a paso es el siguiente:
  1. En un ordenador conectado a Internet mediante un router con IP 192.168.1.1 instalamos Ubuntu 9.10 (Karmic Koala).
  2. Ubuntu debe tener la interface de red eth0 con la IP 192.168.1.33, máscara 255.255.255.0 y un par de DNS válidas.
  3. En Ubuntu, instalamos el módulo de Perl Net::Whois::IP con CPAN.
  4. En Ubuntu, instalamos VirtualBox.
  5. Creamos una máquina virtual en VirtualBox para Windows XP, configuramos el adaptador de red en modo bridged. Iniciamos la máquina virtual e instalamos en ella Windows XP.
  6. En Windows XP configuramos la IP fija 192.168.2.35, máscara 255.255.255.0 y las mismas DNS que tiene Ubuntu.
  7. En Windows XP instalamos Strawberry Perl y Wireshark (implica la instalación de Winpcap).
  8. En Windows XP, instalamos el módulo de Perl Net::Whois::IP con CPAN.
  9. Ya tenemos todo montado.
  10. En Ubuntu, creamos NAT para la red 192.168.2.0 permitiendo su tráfico de E/S e iniciamos el logeo para el tráfico de dicha red. Para ello, en Ubuntu podemos crear un directorio de trabajo, bajamos a él este script en bash: captura.sh y lo ejecutamos en un terminal.
  11. En Windows XP, iniciamos Wireshark y empezamos a capturar paquetes apuntando la fecha, la hora y el minuto de comienzo de la captura de paquetes.
  12. Iniciamos IE6 en Windows XP y navegamos por webs maliciosas abriendo todo lo que se ponga por delante.
  13. Después de un tiempo prudencial (cuanto más mejor), detenemos la captura de Wireshark, exportamos los resultados a un archivo de texto plano llamado export_w32.txt y lo guardamos en un directorio de trabajo junto con el script conex_report_w32.pl
  14. Iniciamos una shell en Windows (Inicio, Ejecutar, cmd), vamos al directorio de trabajo y ejecutamos: perl conex_report_w32.pl > windows.txt
  15. Abrimos windows.txt, seleccionamos su contenido, lo copiamos y lo pegamos en otro windows.txt nuevo, pero en el directorio de trabajo de Ubuntu.
  16. En el directorio de trabajo de Ubuntu, bajamos los scripts conex_report.pl y compara_conex_report.pl
  17. En el directorio de trabajo de Ubuntu, ejecutamos en un terminal: perl conex_report.pl, le proporcionamos el mes, el día, la hora, el minuto y el segundo de inicio que tenemos apuntados de la captura con Wireshark y después el mes, el día, la hora, el minuto y el segundo de fin de captura. El tiempo de inicio debe ser lo más exacto posible, mientras que el tiempo final mejor que vaya sobrado.
  18. El resultado del script anterior es el fichero ubuntu.txt que contiene las IPs de conexión únicas con la información de whois en el intervalo de tiempo dado.
  19. Por último, en un terminal de Ubuntu y en el directorio de trabajo, ejecutamos: perl compara_conex_report.pl. Las IPs resultantes con su correspondiente información son las de las conexiones que inició Windows, que han sido capturadas por Ubuntu y no han sido capturadas por Wireshark desde Windows, esto es: conexiones realizadas por rootkits troyanizados. En caso de que el resultado no indique ninguna IP, quiere decir que todas las IPs de windows.txt y ubuntu.txt coinciden y todo es correcto: no hay rootkits en Windows.

lunes, 15 de febrero de 2010

Descubriendo troyanos 2/3

El post anterior trata sobre registrar las conexiones que inicia un Windows hacia Internet. Tal operación se realiza con un Linux y una máquina virtual donde "enjaular" a Windows.

Una vez registradas las conexiones en /var/log/kern.log, hay que extraer las IPs remotas y averiguar más información sobre ellas. Como el número de conexiones a una misma IP puede ser muy elevado, conviene eliminar redundancias, obtener la lista de IPs únicas visitadas en un rango de tiempo que indicaremos y obtener más información mediante el servicio whois.

Para ello, he preparado un script en perl conex_report.pl, que hace todo el trabajo y nos saca esa lista junto con alguna información relevante de whois y lo deja en el archivo ubuntu.txt.

Un ejemplo de la ejecución del script:



Y su correspondiente informe de conexiones únicas del archivo ubuntu.txt



En la tercera entrega, veremos cómo hacer lo mismo pero con las conexiones registradas dentro de Windows.

sábado, 13 de febrero de 2010

Descubriendo troyanos 1/3

La mayoría de las veces, es infructuosa la búsqueda de troyanos en un Windows debido a los siguientes factores:
  • Se ocultan con Rootkits
  • Se propagan rápidamente vía web
  • Existe muchísima variedad y cada vez más
  • Muchos son 0-day que antes de ser descubiertos puede pasar mucho tiempo
Esto quiere decir que un Windows infectado por un rootkit que oculte a un troyano es garantía de pertenecer, con suerte, a una botnet y en el peor de los casos, tus datos personales incluyendo contraseñas y números de tarjeta de crédito (si has realizado compras por Internet) estarán en una base de datos lista para ser vendida.

La solución que propongo es enjaular un Windows en una máquina virtual, exponer a Windows como cebo para los troyanos (navegando con IE sin cuidado) y monitorizar las conexiones de red dentro de Windows y fuera de él (mediante el S.O. anfitrión) durante días.

Comparando ambos resultados, las conexiones remotas que estén registradas fuera de Windows y que no estén registradas dentro de Windows son, seguramente conexiones realizadas por rootkits troyanizados.

En esta presentación en PDF muestro cómo realizarlo con el siguiente software:
  • Ubuntu Linux 9.10
  • Virtual Box 3.0.8 para Linux
  • Windows, preferiblemente un XP pelado
  • Internet Explorer 6
  • WinPcap y WireShark