29 julio, 2017

Fuerza bruta en ficheros .kdbx de KeePassX

KeePassX es un aplicación para la gestión de contraseñas. Es un derivación de KeePass Password Safe pero en su versión GNU GPL. Creando un nuevo almacén (fichero base de datos), al que vincularemos con una contraseña maestra, podemos guardar usuarios y contrasañeas asociadas a determinados servicios, estos "almacenes" se guardan en un fichero .kdbx en el caso de KeePassX y ficheros .kdb en el caso de KeePass. De este modo con acordarnos de una única contraseña tendremos acceso a las de más.

Si tenemos la contraseña maestra podemos desempatear el fichero de la base datos y cargarlo correctamente en la aplicación para su uso y visualización de contraseñas.

La base de datos se cifra en AES o Twofish usando una clave de 256 bits. La base de datos KeePassX (kdbx) es compatible con KeePass Password Safe.

Aplicando técnicas de ataque brute-force en la que le pasaremos un wordlist, podemos extraer la contraseña maestra y tener acceso al fichero kdbx en este caso.

Una de las herramientas utilizadas será KeeCracker. Le pasaríamos un diccionario o wordlist, en este caso crearé uno con palabras concretas como prueba de concepto.

Figura 1: Fichero wordlist para PoC

Ejecutamos en una consola el binario KeeCracker.exe en el que le pasamos el diccionario con el argumento -w (lista.txt) y seguidamente la base de datos .kdbx de KeePassX.
KeeCracker.exe -w [fichero_wordlist] [fichero_kdbx]

Figura 2: PoC de KeeCracker

Como vemos la password maestra de la base de datos kdbx a sido encontrada. Dependerá del wordlist que tegamos pueda ser encontrada la password establecida en la base de datos kdbx. Esto influirá lógicamente, como todos los ataques de fuerza bruta, en la complejidad de la contraseña maestra que se establezca en la base de datos.

KeeCracker también puede ser usado con John the Ripper de forma incremental. Por ejemplo:
john --incremental --stdout | KeeCracker -w - KeePassDb.kdbx
Saludos!

18 julio, 2017

Automatizar copias de seguridad FTPS en Batch y Powershell con WinSCP, Taskschd y 7zip

Hace tiempo que quería comentar el tema de como hago mis copias de seguridad de la información personal. Intentaré explicar de forma detallada y clara todo el proceso.

Es recomendable y tendría que ser una práctica rutinaria realizar backups de la información importante. Sobretodo para no echarnos las manos a la cabeza llegado el momento de recuperar cierta información que por cualquier situación hubiésemos perdido.

Se pueden realizar copias de seguridad de una manera u otra. Ya sea copiando directamente la información algún medio extraíble, subiéndola algún servicio de almacenamiento cloud, copias redundantes en ambos medios, etc. A su vez, cuantas más medidas de seguridad se tomen para cada una de estas técnicas, más segura estará la información, pero también más "pasos" habrá que desencadenar para llegar a ella.

En este caso expondré la forma en la que personalmente realizo mis copias de seguridad. Intento no utilizar, siempre que sea posible, aplicaciones locales o almacenamientos cloud de terceros bien conocidos como pueden ser: GoogleDrive, OneDrive, Dropbox, etc. Ya que actualmente son los servicios más extendidos y usados, por lo que tienen un véctor de ataque continuo pero a su vez son servicios que están constantemente actualizándose, lo que los hacen ser "insuficientemente seguros".
En el caso de usar un servicio de terceros de almacenamiento cloud habría que intentar contratarlo en una empresa no tan extendida pero de confianza.

En mi caso tengo una carpeta con toda la información a respaldar, esta carpeta está ubicada en un disco duro extraible protegido con un cifrado BitLocker To Go. Es decir, que cuando conectamos el disco duro extraible a un puerto USB del equipo tenemos que introducir una password para desbloquearlo y así poder acceder a la información.  

Primera medida de seguridad es el disco duro extraible por lo que nunca tengo la información en el disco local del sistema ni en un segundo disco conectado directamente a ningún puerto SATA de la placa base. 

Segunda medida de seguridad es el cifrado por BitLocker To Go. De este modo puedo llevarme el disco duro extraíble a cualquier parte y conectarlo a cualquier equipo con un sistema operativo MS Windows que admita BitLocker, sin recurrir a ningún software de terceros para el cifrado del disco, por que como ya dije, prefiero utilizar mecanismos propios de los sistemas operativos y así garantizar la disponibilidad de la información en un entorno Windows de forma nativa. No es el caso que voy a comentar pero también estaría la posibilidad de cifrar una unidad de almacenamiento externo USB con VeraCrypt. Otra buena alternativa a BitLocker To Go.

Tercer paso sería garantizar esta información en caso de pérdida, tener una redundancia. ¿Que pasaría si en un futuro perdiese físicamente el disco duro extraible o no pudiese acceder a el porque hubiese sido dañado?. Pues esta redundancia la tendríamos en un sitio de ubicado geográficamente distinto, un sitio de terceros. Actualmente tengo contratado un servicio de almacenamiento cloud en una empresa de Hosting, la cual es de mi confianza. Este servicio me ofrece un espacio FTP con un certificado SSL/TLS, por lo que puedo usar el canal de control y el de data para transferir información de forma segura mediante FTPS "FTP over SSL" (no confundir con SFTP "SSH-FTP"). Al realizar una sincronización con WinSCP de forma incremental cada vez que se actualizan los datos de local al servidor, los tiempos de copia son rápidos.

Otra opción en este tercer paso sería crear un fichero comprimido protegido con contraseña, generar ambos logs tanto de la compresión como de la subida al servidor FTP. El comprimir la información y cifrarla nos da una seguridad extra pero también el proceso de backup será más costoso en tiempo.

Cuarto paso sería automatizar esta tarea. Generar un script que pudiese realizar por ejemplo, una copia semanalmente de toda esta carpeta y la transfiera de forma síncrona a este espacio de almacenamiento vía FTPS. En Windows existe la característica de habilitar el cliente FTP por línea de comandos, pero no podemos usar certificados sobre este cliente. Por lo que obté en usar la herramienta WinSCP, esta incorpora una utilidad en línea de comandos (winscp.com) la cual podemos generar un script en batch en integrarla perfectamente.

Quinto paso hacer una llamada a un script de PowerShell .ps1 el cual envía el log a un correo electrónico al finalizar todo el proceso de backup con la finalidad de tener un registro de copias.

Script para el proceso de Backup y transferencia de información al servidor FTP

Si no somos usuarios administradores en el equipo local por seguridad, si no que usamos un usuario raso para el uso habitual de nuestro equipo, lo que sería más adecuado, para no tener problemas con los privilegios en el momento de ejecutar el script y las acciones que este realice, en este caso trabajaré sobre el direcctorio por defecto de instalación de WinSCP: "C:\Program Files (x86)\WinSCP". Estableceremos los permisos de modificar o control total para el usuario local sobre el directorio.

Figura 1: Establecer permisos sobre el directorio donde se ejecutará el script batch.
Generamos un fichero por lotes .bat con el siguiente código:
@echo off

set ano=%date:~6,4%
set mes=%date:~3,2%
set dia=%date:~0,2%
set backup=backup_%dia%-%mes%-%ano%.log

if exist "backup*.log" ( del /F /Q "backup*.log" )

winscp.com /log="%backup%" /loglevel=2 /command "open ftp://USER:PASSWROD@IP_O_DNS_SERVER -explicit" "synchronize remote -delete -mirror -transfer=binary {PATH_LOCAL_ORIGEN} {PATH_REMOTO_DESTINO}" "close" "exit"
Figura 2: Script batch usando winscp.com para conexiones FTPS con sincronización de local a remoto.

Se establecen las variables con las que se obtendrán la fecha/hora actuales y otra (%backup%) para almacenar el nombre que tendrá el fichero con la estructura "backup_DD-MM-AAAA.log". Con un condicinal se comprueba que el fichero "backup*.log" exista. Si ya existiese de una copia pasada lo eliminaría. Esta comprobación sería opcional para aquellos que quieran incluír un fichero de log. En caso de incluírlo aconsejo esta comprobación inicial, este fichero al paso del tiempo suele alcanzar un tamaño considerable, en más de una ocasión antes de haber incluído esta condición en el script llegó a ocupar tamaños superiores a 500MB, y un volumen importante de registros por lo que se hacía finalmente ilegible.

Iniciamos la utilidad winscp.com con el argumento /log para obtener un registro de la actividad realizada incidándole la variable "%backup%" correspondiente al nombre establecido que en ese momento se le asigne al fichero con fecha/hora actuales. Podemos indicar el nivel de depuración del log con el parámetro /loglevel esto nos dará más detalles de log.

La ventaja de utilizar el parámetro /log con winscp.com es que la password utilizada para la autenticación de conexión con el servidor FTP no se muestra en texto plano en el fichero de log, sino que aparace con tres asteríscos "***" sea cual sea la longitud de la contraseña. A diferencia de si se utilizara winscp.exe donde le pasaríamos el script en un fichero de texto a parte pero le indicaríamos igualmente el parámetro /log por ejemplo: winscp.exe /console /script="script_backup.txt" /log="myscript.log" (ver la figura 12 de este artículo). En este caso la contraseña en el fichero de log si se mostraría en texto plano siendo claramente visible. 

A continuación indicaremos los parámetros realmente importantes, al usar winscp.com en un script batch tendremos que indicarle el modificador /command para que sepa que los próximos modificadores serán realizados en una sola instrucción. Podríamos crear un fichero a parte con los mismos modificadores del comando necesarios, en mi caso solamente realizo una única transferencia por lo que he optado por unificarlo en un mismo fichero de procesamiento por lotes .bat.

Abrimos la conexión al servidor FTP (open) y la invocamos de forma explícita (-explicit). De esta forma el cliente solicita de forma explícita la seguridad acordada para empezar la comunicación con el servidor FTP de modo que tanto el canal de control como el de data sean cifrados.
  • synchronize remote: Los cambios del directorio local se actualizan con los remotos.
  • -delete: Elimina archivos obsoletos.
  • -mirror: Modo espejo (sincroniza también archivos antiguos).
  • -transfer=binary: Modo de transferencia binario, necesario por ejemplo para transferir ficheros de tipo imagen, vídeo, pdf, etc.
  • J:\ADRIAN: Directorio local (en este caso).
  • /Backup: Directorio remoto (en este caso).
  • Finalmente cerramos la conexión (close) y salimos de la sesión (exit).


Diferencias entre FTPS Explícito (FTPES) y FTPS Implícito

AUTH TLS o FTPS Explícito (FTPES): Definido en el RFC 2228, el cliente se conecta al puerto habitual FTP (21) y comienza una sesión FTP sin crifrar. Explícitamente cambia a un modo seguro utilizando TSL o SSL para transferir la información.

FTPS Implícito: El cliente asume el modo seguro con TSL o SSL, desde el inicio de la conexión, se realiza la negociación SSL antes de que se realice la transferencia de información. Habitualmente se utiliza el puerto 990 en vez del habitual puerto 21. Más info.

Más información sobre WinSCP en command line:

Con esto conseguiremos que cada vez que se ejecute el script este solo hará un repaso a todos los ficheros tanto locales como remotos haciendo un espejo y adaptando solamente los cambios, con lo que conseguiremos una reducción de tiempo en futuras transferencias.

Otra opción del script para el proceso de backup

La otra opción que comentaba anteriormente para este paso y que nos dará un extra de seguridad pero más tiempo de espera en el proceso del backup, sería generar un fichero comprimido .zip con la herramienta de comandos que incorpora 7-zip. Incluir en una variable de entorno de Windows el path "%programfiles%\7-zip" para que desde cualquier ubicación se reconozca el binario ejecutable de comandos "7z.exe" y así no tener problemas en la ejecución del script.
  • Comprimir el directorio en un archivo protegido por contraseña en formato .zip. Indicar un destino temporal para el fichero comprimido creado y generar un log de este proceso.
  • Realizar la subida al servidor FTP del fichero comprimo, genarar otro log de este proceso.
  • Incluir los dos logs anteriores en un único fichero de log (el cual será el que se envíe por correo).
  • Eliminar los dos logs anteriores "sobrantes" y el fichero comprimido temporal de la copia.
@echo off

:: Fecha y Hora
set ano=%date:~6,4%
set mes=%date:~3,2%
set dia=%date:~0,2%
set hora=%time:~0,8%
set backup=backup_%dia%-%mes%-%ano%.log

:: Credenciales y Paths
set passwd7z=passwd7z
set pathTempFichero7z="pathTempFichero7z"
set pathLocalDatos="pathLocalDatos"
set pathRemotoFTP=pathRemotoFTP
set usuarioFTP=usuarioFTP
set passwdFTP=passwdFTP
set servidorFTP=servidorFTP
set conexionFTP=ftp://%usuarioFTP%:%passwdFTP%@%servidorFTP%

:: Comprobar si existen un backups log pasados
if exist "*backup*.log" ( del /F /Q "*backup*.log" )

:: Mostrar fecha y hora del comienzo del proceso al princpio del log
echo %dia%-%mes%-%ano% -- %hora% > %backup%
echo ----------------------

:: Comprimir datos, generar log zip, agregarlo al backup log final y mostrar una línea de separación.
7z a -tzip -p%passwd7z% -r %pathTempFichero7z% %pathLocalDatos% > zip%backup%
type zip%backup% >> %backup%
echo ############################################################## >> %backup%

:: Subir el fichero comprimido al servidor FTP, generar log FTP, añadirlo al log de backup y mostrar una línea de separación.
winscp.com /log="ftp%backup%" /loglevel=2 /command "open %conexionFTP% -explicit" "cd %pathRemotoFTP%" "put %pathTempFichero7z%" "close" "exit"
type ftp%backup% >> %backup%
echo ############################################################## >> %backup%

:: Eliminar ficheros temporales: logs y fichero temporal backup zip.
del /F /Q "zip*.log"
del /F /Q "ftp*.log"
del /F /Q %pathTempFichero7z%

:: Comprobar la eliminación de ficheros de log y fichero temporal backup zip, insertar el resultado en el log.
:: Log de la compresión zip.
if exist "zip*.log" (
    echo -- zip%backup% no se eliminó correctamente >> %backup%
    ) else (
       echo -- zip%backup% se eliminó correctamente >> %backup%
    )
:: Log del envío de datos al servidor FTP.
if exist "ftp*.log" (
    echo -- ftp%backup% no se eliminó correctamente >> %backup%
    ) else (
       echo -- ftp%backup% se eliminó correctamente >> %backup%
    )
:: Fichero temporal backup zip
if exist "D:\Backup.zip" (
    echo -- Backup.zip no se eliminó correctamente >> %backup%
    ) else (
       echo -- Backup.zip se eliminó correctamente >> %backup%
    )

:: Llamada al script Powershell para el envío del log vía Email.
powershell.exe -file "envio_log_email.ps1"

Los parámetros de compresión usando "7z.exe" dependerá de las opciones que cada uno quiera establecer, en mi caso.
  • a: añade información (comprime)
  • -t: indica el tipo de formato (zip en este caso)
  • -r: Recursividad en subdirectorios.
  • -p: Password para cifrar el fichero comprimido
Un ejemplo sería.

Figura 3: Otra opción para el proceso de backup. Comprimir la información, cifrarla, enviarla al FTP y borrar los ficheros temporales.

Realizará una comprobación de si existe ya algún fichero log pasado, si exite los eliminará y generará también dos log (temporales), uno para el proceso de compresión de la información y otro log para el proceso de transferencia de información al servidor FTP. Finalmente generará un único fichero con los dos logs anteriores juntos que será el que se envie por correo a través de la llamada al script de PowerShell el cual hará el proceso de envío (este punto está detallado en el último apartado de este artículo).

Inicialmente, justo antes de la compresión, añado la fecha y hora actual en el princpio del fichero de log principal para saber cuando se inició la copia, ya que el log de compresión con 7z.exe no muestra valores de tiempo en su proceso. Es el momento en el que se crea el fichero de log principal y final, que se enviará por correo.

Después eliminará los logs temporales creados y el fichero comprimido temporal cuando ya haya sido subido al servidor FTP.

Opcionalmente se hacen unas comprobaciones para saber si se eliminaron tanto los logs temporales como el fichero comprimido temporal y adjuntar este resultado al log de backup principal con formato de fecha actual. Finalmente se envía este fichero de log final a un correo electrónico (script PowerShell detallado al final de este artículo).

Comentar que para este estilo de copia (compresión de la información y subida al servidor sin usar sincronización con WinSCP) el tiempo total del backup desde la compresión del archivo a la subida al servidor FTP, es de unas 2 horas y 25 minutos aprox. (quizás algo menos dependiento el tipo de conexión que tengamos y los límites al servidor FTP si es que los hay) para un tamaño total de copia de unos 50GB.

Aquí dejo el repositorio en Github: https://github.com/adrianlois/Automatizar-Backups-FTPES-Batchfile

Crear una tarea programada para el proceso de backup

Una vez que tenemos generado el script, tendremos que ejecutarlo manualmente y eso no sería práctico, llegados a este punto lo mejor será automatizar este script para que por ejemplo se ejecute un día y hora en concreto de la semana.
Para no recurrir a herramientas de terceros usaremos el "Programador de tareas" de Windows (taskschd.msc).

Creamos una nueva tarea. Como descadenador será según una progamción, semanalmente los Domingos a las 22:00. En mi caso lo tengo así programado ya que se que ese día de la semana y a esa hora suelo tener equipo encendido.

Figura 4: Estableciendo el desencadenador de la tarea programada.

Las acción será iniciar un programa o script, indicamos el path de la ruta donde se encuentra el script. En mi caso no quería crear una variable de entorno de Windows por lo que tengo que indicarle al sistema donde se encuentra la utilidad winscp.com, por lo que le indico donde se debería iniciar el path en "Iniciar en".

Figura 5: Estableciendo la acción para ejecutar el script.

La configuración de la tarea programada la establecí del siguiente modo. Si la tarea no se ejecuta, reiniciarla cada 1 minuto durante un número de intentos de 5 veces y si sobrepasa las 12 horas de ejecución detener la tarea.

Figura 6: Configuración de la tarea programada.

Finalmente en la pestaña general designamos un nombre a la tarea programada. Una vez llegados a este punto tendremos dos opciones:

- Ejecutar solo cuando usuario haya iniciado sesión: En este caso veremos la vetana de la consola de Windows ejecutando todo el proceso.

- Ejecutar tanto si el usuario inició sesión como si no: En este caso la tarea se ejecutará de forma subyacente al usuario. Aconsejo esta opción ya que nos garantiza la ejecutación de la tarea tan solo con tener encendido el equipo. Por lo que pude comprobar al intentar ejecutar esta tarea de forma manual a través del programador de tareas puede que falle. Sin embargo, al ejecutarse automáticamente según la programación establecida se ejecutará sin problemas.

Si escogemos la primera opción no tendremos problemas. Pero si escogemos la segunda opción ya que puede darse el caso de que no estemos con la sesión iniciada en el equipo pero el equipo esté encendido (y con el BitLocker desbloqueado en este caso). Al intentar establecer la tarea nos dirá que "la cuenta de usuario especificada tenga derechos para iniciar sesión como trabajo por lotes". Esto ocurre por que en mi caso el usuario que habitualmente uso en el sistema por seguridad no está dentro del grupo Administradores, sino dentro del grupo Usuarios y por lo tanto no tiene los suficientes permisos como para llevar a cabo esta acción.

Figura 7: Ejecutar tarea programada tanto si el usuario inicia sesión como si no.

Para ello solamente tendremos que agregar la cuenta de usuario en el editor de directivas seguridad local (a través de la consola de Microsoft "gpedit.msc" o directamente "secpol.msc") buscamos "Iniciar sesión como proceso por lotes" y agregamos el usuario.

Figura 8: secpol.msc - Iniciar sesión como proceso por lotes para una tarea programada.

De este modo ya podremos autenticar con las credenciales del usuario local, independientemente de si se marca el checkbox de "No almacenar contraseña" como si no.

Más información: https://technet.microsoft.com/en-us/library/cc722152(v=ws.11).aspx

Figura 9: Autenticación de credenciales del usuario local para tarea programada.

Para poder hacer un seguimiendo de la ejecución de la tarea programada habilitamos el historial. Esta opción afectará a todas las tareas programadas que tengamos en la biblioteca.

Figura 10: Habilitar el historial de las tareas programadas.

Una vez se ejecute y concluya la tarea, en la pestaña de historial veremos la auditoria de información de tiempos. Para hacerse una idea, en mi caso, según mi conexión de DSL y el ancho de banda contratado con el Hosting que me proporciona el server FTP. En menos de 45 minutos se hicieron transferencias de un total aproximado de 50GB (aunque esto dependerá del tipo de conexión que tengamos así como si hay algún límite de súbida con el servidor FTP).

Figura 11: Historial de la tarea programada.

Si consultamos el fichero .log que creamos para el registro de actividad de conexiones y transferencias hacia el servidor FTPS. Vemos como la conexión se realiza de forma expícita solicitando el certificado al servidor FTP y finalmente se establece la conexión TLS.

Figura 12: Fichero de log de las transferencias realizadas al servidor FTPS.


Enviar el log por correo electrónico con un Script automatizado en PowerShell

Mencionar la posibilidad de poder auto-enviarse este log generado anteriormente a través de un correo electrónico y así tener un registro más clasificado por fechas.

Se me ocurrió crear un fichero .ps1 (PowerShell) que será el script que enviará el mensaje de correo electrónico con el fichero log como adjunto. E incluir una llamada a al fichero .ps1 al final del script batch que hace la copia de seguridad con WinSCP. De ese modo se garantiza que el fichero log esté finalizado. Con este método no se tendrá que modificar la tarea programada.

Para poder ejecutar scripts en PowerShell sin problemas, se tendrá que cambiar la política de ejecución (ExecutionPolicy). En un principio no están definidas y por seguridad vienen deshabilitados todos los tipos de ejecuciones para los scopes.

Existen varios modos de políticas de ejecución para definir en PowerShell:
Restricted: Bloquea todos los scripts en PowerShell y hace que todas las tareas deban ejecutarse de forma interactiva, nada automático.
AllSigned: Solo pueden ejecutarse paquetes y scripts firmados digitalmente.
RemoteSigned: Los paquetes descargados deben firmarse de forma remota antes de poder instalarlos, los locales no.
Unrestricted: Puede ejecutarse cualquier script, sin restricciones.

Para esta situación puede servir tanto el modo de ejecución RemoteSigned como Unrestricted.

Listamos el tipo de políticas de ejecución y esteblecemos el tipo de política para el scope LocalMachine como Unrestricted.
Get-ExecutionPolicy -List
Set-ExecutionPolicy Unrestricted -scope LocalMachine -Force
Figura 13: Estableciendo el modo de política de ejecución (ExecutionPolicy) para PowerShell

Una vez se puedan ejecutar scripts en PowerShell, se crea un documento de texto en el mismo directorio y se renombra con una extensión .ps1 (extensión usada por PowerShell) por ejemplo "envio_log_email.ps1". Se inserta el siguiente código:
# Variables
$fechaHoraActual = Get-Date -uformat "%d/%m/%Y - %H:%M:%S"
$usuarioEmail = "usuarioEmail"
$passwdEmail = "passwdEmail"
$asuntoEmail = "asuntoEmail"
$cuerpoEmail = "cuerpoEmail"
# Convertir password a un string seguro.
$secPasswdEmail = ConvertTo-SecureString $passwdEmail -AsPlainText -Force
$credencialesEmail = New-Object System.Management.Automation.PSCredential ($usuarioEmail, $secPasswdEmail)

# Enví­o del fichero log adjunto viía Email usando Gmail.
Send-MailMessage -From $usuarioEmail -To $usuarioEmail -Subject "$asuntoEmail - $fechaHoraActual" -Body "$cuerpoEmail - $fechaHoraActual" -Attachments "backup*.log" -SmtpServer smtp.gmail.com -UseSsl -Credential $credencialesEmail
exit
Un ejemplo de este script en Powershell ps1:

Figura 14: Script ps1 Powershell - Envío del fichero de log a una cuenta de correo Gmail.


Este script en Powershell auto-enviará un mensaje de correo a una misma cuenta de correo electrónico u otra si lo establecemos.

La variable "$fechaHoraActual" alamacena la función "Get-Date" usando el parámetro "-uformat" seguido de la estructura fecha y hora "DD/MM/AAAA - HH:MM:SS" esto se añadirá en el asunto y cuerpo del mensaje, después del nombre del fichero de log, reflejará el momento actual en el que ha sido enviado este adjunto. Se almacena también la contraseña en la variable "$passwd" en una función "ConvertTo-SecureString" que se pasará en una cadena de texto segura. La ventaja de inclurla la hora es que se puede calcular el tiempo transcurrido en el proceso de backup desde el momento en el que se ejecutó la tarea programada hasta el momento en el que se recibe el mensaje de correo electrónico. Esta información también se podría ver en el historial del programador de tareas como se puede observar en la figura 10 de este artículo. 

  • usuarioEmail: Se cambiará por el nombre de usuario de la dirección de correo electrónico correspondiente.
  • passwdEmail: Password del usuario (dirección del correo electrónico) necesaria para autenticarnos en el servidor de correo.
  • asuntoEmail: Texto del asunto del Email (-Subject).
  • cuerpoEmail: Texto del cuerpo del Email (-Body).
  • backup*.log: Nombre que corresponde al fichero de log adjunto a enviar en el mensaje.

En mi caso usaré Gmail como servidor SMTP. En un principio no va poder autenticarse aunque se le pasen correctamente las credenciales de usuario. Esto es debido a la protección de seguridad que implementa Gmail para evitar el inicio de sesión de aplicaciones de terceros menos seguras.

Para poder autenticarse con PowerShell en una cuenta Gmail tan solo se tendría que activar el acceso a "Aplicaciones menos seguras". En el siguiente enlace podemos acceder a esta sección: https://myaccount.google.com/lesssecureapps.

En el caso de tener activado un segundo factor de autenticación (2FA) con Google Authenticator, esta característica estaría deshabilitada y no se podría realizar este proceso.

Figura 15: Activar el acceso a aplicaciones menos seguras en una cuenta Gmail

En el script batch inicial donde se realiza el backup con WinSCP se añade al final la siguiente línea de código indicándole el que le ejecute con powershell, el argumento -file hará la llamada al script .ps1 desde un script .bat. De este modo no se tendrá que modificar la tarea programada.
powershell.exe -file "{PATH_FICHERO.ps1}"
Figura 16: Llamada a un fichero script .ps1 desde un script.bat.

Se puede ver el mensaje de correo electrónico que fue auto-enviado a uno mismo con un fichero adjunto "backup_DD-MM-AAAA.log" donde se muestra la fecha y hora de envío en el cuerpo del mensaje en formato "DD/MM/AAAA - HH:MM:SS".

Figura 17: Correo enviado con Powershell y recibido en Gmail con fecha y hora del log.

El procedimiento de enviarse el log por correo electrónico a través de PowerShell simplemente lo menciono por si es de interés para alguien. Personalmente en mis cuentas de correos Gmail, Hotmail, Yahoo. Tengo habilitado un segundo factor de autenticación, considero que es lo más seguro y que todo el mundo que quiera tener sus cuentas más seguras use, en la medida de lo posible, más de un factor de autenticación.

En el caso de tener una cuenta de correo Gmail por ejemplo con autenticaciones 2FA. Aconsejo crear una cuenta de correo exclusivamente para esta finalidad y configurar las opciones de reenvío de mensajes de esa cuenta para que reenvíe a otra cuenta más personal estos correos, en la que si se tenga habilitada la autenticación 2FA.

Script Powershell usando WinSCP y 7zip


Hice también un script muy similar en Powershell. Con dos diferencias (no muy relevantes):
  • No es posible generar el log del proceso de compresión de datos que realiza 7zip.
  • Si queremos establecer password al fichero comprimido, el formato de fichero debe ser .7z. El uso del cmdlet "Compress-7Zip" no permite establecer password a ficheros de formato .zip.
Primero de nada quitamos las restricciones de ejecución de scripts ejecutando como administrador una consola Powershell:
Set-ExecutionPolicy Unrestricted -scope LocalMachine -Force
Instalamos los modulos 7Zip4Powershell y WinSCP para Powershell.
Install-Module -Name 7Zip4Powershell -Verbose -Force
Install-Module -Name WinSCP -Verbose -Force
Por defecto estos módulos se instalan en "%systemdrive%:\Program Files\WindowsPowerShell\Modules".
  • Install-Module: instala definitivamente módulo para todo equipo. 
  • Import-Module: instala el módulo solo para la sesión actual de usuario de Powershell.
Script .ps1 Powershell
#################################
## Inicio Establecer Variables ##

# Fecha y hora
    $FechaActual = Get-Date -uformat "%d-%m-%Y"
    $FechaHoraActual = Get-Date -uformat "%d/%m/%Y - %H:%M:%S"
# Paths
    $PathLocalDatos = "PathLocalDatos"
    $PathRemotoFTP = "PathRemotoFTP"
    $PathTempFichero7z = "PathTemporalFichero7z"
    $NombreBackupTemp = "Backup_"
    $TempFichero7z = "$PathtempFichero7z$NombreBackupTemp$FechaActual.7z"
# Credenciales
    $Passwd7z = "PasswdFichero7z"
    $HostServidorFTP = "ftp.miweb.com"
    $UsuarioFTP = "UsuarioFTP"
    $PasswdFTP = "PasswdFTP"
    $UsuarioEmail = "UsuarioEmail@gmail.com"
    $PasswdEmail = "PasswdEmail"
# Asunto y cuerpo del Email
    $AsuntoEmail = "AsuntoEmail"
    $CuerpoEmail = "TextoCuerpoEmail"
# Get-Credencial automatizado no interactivo, convertir a string segura
    $SecPasswdFTP = ConvertTo-SecureString $PasswdFTP -AsPlainText -Force
    $CredencialesFTP = New-Object System.Management.Automation.PSCredential ($UsuarioFTP, $SecPasswdFTP)
    $SecPasswdEmail = ConvertTo-SecureString $PasswdEmail -AsPlainText -Force
    $CredencialesEmail = New-Object System.Management.Automation.PSCredential ($UsuarioEmail, $SecPasswdEMail)
# Log
    $LogBackupFTP = "$PathtempFichero7z$NombreBackupTemp$FechaActual.log"
# Comprobaciones Test-Path
    $TestBackup7z = "$PathTempFichero7z$NombreBackupTemp*.7z"
    $TestBackupLog = "$PathTempFichero7z$NombreBackupTemp*.log"

## Fin Establecer Varibles ##
#############################

# Comprobrar si ya existe algún fichero de log o backup anteriores
if (Test-Path ($TestBackup7z, $TestBackupLog)) {
    Remove-Item -Path ($TestBackup7z, $TestBackupLog) -Recurse -Force
    }

## Compresión de datos ##
Compress-7Zip -Path $pathLocalDatos -ArchiveFileName $TempFichero7z -Password $Passwd7z -EncryptFilenames

## Enviar backup al servidor FTP ##
    # Crear nueva sesión FTP
    New-WinSCPSession -SessionOption (New-WinSCPSessionOption -HostName $HostServidorFTP -Protocol Ftp -Credential $CredencialesFTP) -SessionLogPath $LogBackupFTP -DebugLogLevel 2
    # Subir el fichero comprimido de datos al servidor FTP
    Send-WinSCPItem -LocalPath $TempFichero7z -RemotePath $PathRemotoFTP
    # Cerrar sesión FTP
    Remove-WinSCPSession

## Enviar log de backup vía email Gmail ##
Send-MailMessage -From $UsuarioEmail -To $UsuarioEmail -Subject "$AsuntoEmail - $FechaHoraActual" -Body "$CuerpoEmail - $FechaHoraActual" -Attachments $LogBackupFTP -SmtpServer smtp.gmail.com -UseSsl -Credential $CredencialesEmail

## Eliminar logs ##
# Conservar el fichero de log, eliminar solo el fichero temporal backup 7z
Remove-Item -Path $TempFichero7z -Recurse -Force
# En el caso de querer eliminar también el log de backup, descomentar la siguiente línea
# Remove-Item -Path $logBackupFTP -Recurse -Force

# Salir
exit
Adaptamos el código modificando los valores resaltados en negrita de las variables. Lo guardmos en un fichero con extensión .psi y susituímos el batch incluído en la tarea programada de Windows por el script Powershell.

Figura 18: Script ps1 en Powershell. Backup completo + envío de log vía email.

Aquí dejo el repositorio en Github: https://github.com/adrianlois/Automatizar-Backups-FTP-PowerShell

Espero que algo de esto le resulte de utilidad o de ejemplo para aquell@s que quieran realizar sus propios métodos para sus copias de seguridad.

Saludos!

12 julio, 2017

Convertir disco VMDK a VDI y extender espacio en un disco VDI

VMDK y VDI son formatos de discos virtuales. Si trabajamos con Virtual Box y quisiésemos extender el tamaño de almacenamiento de un disco VMDK en el que ya esté instalado un sistema operativo, no podríamos. Tendríamos que convertir primero ese disco VMDK en un disco VDI (formato por defecto de Virtual Box) y después extender el espacio en este último.

La conversión de disco es necesaria por que para redimensionar el espacio de un disco virtual usaremos la utilidad de línea comandos "VBoxManage.exe" de Virtual Box, para este tipo de modificaciones esta solo trabaja con discos en formato VDI.

Convertir disco VMDK a VDI:

Nos aseguramos que la máquina no está corriendo en ese momento y después eliminamos todas las snapshots si las hubiese.

Abrimos una línea de comandos y nos situamos el path donde tengamos instalado Virtual Box. Por defecto: "%systemdrive%\Program Files\Oracle\VirtualBox". Una vez ahí tendremos acceso a la utilidad VBoxManage.exe por lo que clonamos el disco vmdk a un disco en formato vdi.
vboxmanage clonehd --format vdi c:\vms\DISCO_1.vmdk c:\vms\DISCO_2.vdi
Donde DISCO_1.vmdk será el disco orignal a clonar y DISCO_2.vdi será el disco de salida ya clonado en el nuevo formato. El directorio "c:\vms" tendría que ser creado con aterioridad o simplemente indicaríamos una salida a otro directorio que tuviésemos.

Una vez hecho lo anterior podremos extender el tamaño del disco a lo que deseemos.

Extender el tamaño de almacenamiento de un disco VDI:

Desde la misma consola ejecutamos lo siguiente para redimensionar el disco VDI recién clonado.
vboxmanage modifyhd "c:\vms\DISCO_2.vdi" --resize 35840
  • modifyhd: modifica el tamaño del disco duro.
  • --resize: tipo de modificación que queremos hacer (redimensionar).
  • 35840: tamaño que queremos extender el disco. En este ejemplo unos 35GB será su tamaño total no adicional del que ya tenga.

Se generará una nueva zona sin un sistema de ficheros asignado. Con el administrador de discos de Windows (diskmgmt.msc) podemos extender la partición primaria-activa actual de nuestro OS hacia la zona sin asignar.

Saludos!

11 julio, 2017

Ataque MITM: ARP Poisoning y DNS Spoof con ARPSpoof [Parte 2 de 2]


Esta vez comentaré prácticamente lo mismo pero realizando el ataque desde una terminal de forma manual, sin una GUI. Desde una distribución Kali Linux usando arpspoof y el plugin DNS_Spoof de Ettercap también desde la terminal.


El equipo atacante (KaliLinux) tendrá que "hacer de router" por lo que se tendrá que habilitar ip_forward para enrutar todo el tráfico que llegue a el. De modo que deje salir a la puerta de enlace original todo el tráfica de la víctima. Si esto no se hiciese la vícitma se daría cuenta de algo extraño sucede ya que se quedaría sin conexión a Internet.
Para este ejemplo el equipo atacante tendrá la dirección 192.168.100.20.
echo 1 >> /proc/sys/net_ipv4/ip_forward
Figura 1: Habilitar ip_forward para el enrutamiento de tráfico.

Con Nmap (integrado también en Kali) escanemos toda la red local disponible, en este caso una clase C con máscara 24. De todas las direcciones IP obtenidas.
Para este ejemplo la víctima será la 192.168.100.10.
nmap -sP [DIRECCIÓN_RED/CIDR]
Figura 2: Escaneando toda la red local con Nmap.

Envenenamos la tabla ARP del equipo atacado y le hacemos creer qu ela dirección MAC verdadera del equipo atacante (192.168.100.20) es la misma que la de su puerta de enlace (router: 192.168.100.1).
Inicio del ataque, especificamos la interfaz de salida con -i y con -t el target (víctima) seguido del equipo (router) en el que suplantaremos la dirección MAC para la víctima.
En la captura podemos ver como las direcciones MAC de la tabla ARP del equipo víctima (Windows) cambiaron después del ataque. La MAC del router es la misma que la del atacante.

Dejaremos esta terminal minimaza y siempre funcionando.
arpspoof -i [INTERFAZ_RED] -t [IP_VÍCTIMA] [IP_ROUTER]
Figura 3: arpspoof - Antes y después del ataque.

Empezamos a capturar tráfico en Wireshark desde el equipo atacante.
Como ejemplo ingresaré en una web con mi nombre de usuairo y contraseña.
Este sitio no utiliza HTTPS, por lo que toda la información que veamos o ingresemos en un formulario no irá cifrada y será visible en texto claro.

Figura 4: Ingresando credenciales en un formulario de un sitio que no utiliza HTTPS.

Una vez interceptado HTTP el tráfico en Wireshark, podemos ver la solicitud POST de login. Examinado este paquete vemos el nombre de usuario y la contraseña en texto introducidos por la víctima.

Figura 5: Captura de credenciales introducidas por la víctima en el sitio web.

Iremos un paso más allá incorporando el plugin dns_spoof de Ettercap.
Como se trata de redirigir las peticiones a direcciones DNS que solicite la víctima, crearemos una website (que puede ser una réplíca visualmente de un sitio web conocido: facebook.com, gmail.com, etc.). Para ello crearemos un servidor HTTP con Apache.
Creamos un documento HTML, en este ejemplo no replicaré ningún sitio ya que llevaría más trabajo y como prueba de concepto me basearé en la representación y entendimiento de la técnica más que en su elavoración.

Figura 6: Creación de un posible sitio web malintencionado.

Redirigimos las peticiones DNS a las direcciones IP que quereamos, en este caso al servidor Apache que estará sirviendo en la máquina del atacante.

Como ejemplo redirigeremos las peticiones que vayan hacia google.es hacia una dirección IP correspondiente a otro sitio web que se verá más adelante, facebook.com y a este blog se redirigirán al servidor Apache del atacante.

Editamos el fichero del plugin "dns_spoof" de Ettercap.
/etc/ettercap/etter.dns
Figura 7: Editando fichero etter.dns para redirección de peticiones DNS de la víctima.

Una vez creado el documento principal y redirigido las peticiones DNS a la dirección IP de nuestro servidor, arrancamos el servicio del servidor Apache (ya instalado por defecto en Kali).
service apache2 start
Figura 8: Iniciar el servicio del servidor Apache

Lanzamos el plugin dns_spoof a través de ettercap haciendo uso de la terminal. Estando la terminal de arpspoof funcionando. Abrimos una nueva terminal para ejecutar lo siguiente.
ettercap -T -q -i [INTERFAZ_RED] -M arp:remote -P dns_spoof //[IP_ROUTER]// //[IP_VÍCTIMA]//
Figura 9: Ejecución del plugin dns_spoof de Ettercap en la terminal.

Si observamos las siguientes capturas de pantalla, vemos como el cliente intenta acceder a facebook.com y este lo redirige a nuestro servidor Apache.
Es curioso que siendo sitios webs bien conocidos y que de forma automática redirigen estas solicitudes a conexiones HTTPS y no HTTP. Pero en ciertas ocasiones y también dependiendo de como tengamos de "limpio" los navegadores webs tanto en IE como MFirefox, en ambos casos redirigieron estas solicitudes a donde se esperaba.

En la mayoría de ocasiones esto no fue posible mostrarlo tal cual aparecen en las capturas, ya que como ya dije al final del post de la parte 1 existen técnicas (HSTS y HPKP) que evitan que esto pase así como tampoco sería efectivo con SSLStrip el cual veremos en una futura entrada de este blog.

De manera que en la gran mayoría de ocasiones (no en todas) tuve que forzar la petición por "HTTP://facebook.com" en la barra de direcciones del navegador. Estos sitios web están configurados para redireccionar de forma automática sus solicitudes HTTP a HTTPS. Aunque se acceda por algún enlace o se escriba solamente "facebook.com" estos websites siempre intentarán redirigir a su sitio seguro y comprobar su certificado.

En el caso de este blog al no disponer de HTTPS y menos de un certificado de confianza, vemos que no existe ningún problema en redirigir tráfico HTTP.

En el último caso la redirección de google.es hacía la dirección IP establecida vemos que ha funcionado. Lo cual no siempre fue así de las pruebas realizas, por la misma razón que comenté anteriormente, la redirección HTTP a HTTPS.

 Figura 10: Redirección de facebook.com hacia el servidor Apache del atacante.

Figura 11: Redirección de es.es.facebook.com hacia el servidor Apache del atacante.

Figura 12: Redirección de zonasystem.com al servidor Apache del atacante.

Figura 13: Redirección de google.es hacía la dirección IP establecida en etter.dns.

Con nslookup vemos la comprobación de redirecciones DNS en el equipo atacado. En este caso facebook.com redirige al servidor Apache del equipo atacante.

Figura 14: Comprobando las redirecciones DNS en el equipo atacado.

En próximas entradas comentaré para que como sirve y como usar SSLStrip. Las desventajas que actualmente existen y que posibilidades de redirigir tráfico HTTPS hacia HTTP.

Saludos!

09 julio, 2017

Ataque MITM: ARP Poisoning y DNS Spoof con Ettercap [Parte 1 de 2]



Existen múltiples utilidades para realizar técnicas de ataques Man In The Middle (MITM). Es un tema que está más que documentado en Internet. En una anterior entrada ya comentara en que consisten y como realizar estos ataques desde Cain & Abel en entornos Windows.

Con el fin de tener esto como un apunte personal más, comentaré como realizar un "ARP Poisoning" y incorporar el plugin "DNS_Spoof" con Ettercap, una utilidad gráfica que podemos descargar e instalar en cualquier entorno Linux. Por defecto también está disponible está disponible en Kali Linux.

Ettercap es muy sencillo de utilizar, por lo que no me extenderé explicando los detalles. Solamente con las capturas de pantalla se pueden seguir los pasos perfectamente y entender sus funciones.

Establecemos las librerías pcap. Sniff > Set pcap filter...

Figura 1: Set pcap filter Ettercap

Asignamos una interfaz de red para el sniffing. Sniff > Unified sniffing...

Figura 2: Asignar interfaz de red para la captura de paquetes.

Indicamos la interfaz de red, en este caso eth0.

Figura 3: Indicar interfaz de red

Escanemos los hosts disponibles de la red local. Scan for hosts...
Una realizado el escaneo listamos los hosts disponibles. Hosts list.

Figura 4: Escaneo de hosts disponibles de la red local.

En este escenario vemos dos hosts disponibles, el equipo que nos interesa atacar es el que corresponde a la dirección IP 192.168.100.10. Lo seleccionamos y realizamos el ARP Poisoning hacia este equipo. Mitm > ARP poisoning...

Figura 5: Selección de la víctima para ARP poisoning.

Nos interesa capturar las conexiones del equipo remoto por lo que seleccionamos Sniff remote connections.

Figura 6: Sniff para conexiones remotas.

En esta punto ya estaremos envenenado la tabla ARP de la víctima. Pero añadiremos el plugin "dns_spoof" que integra Ettercap. Esto nos servirá para suplantar peticiones DNS y así redirigir estas peticiones a la dirección IP que tengamos establecida en el fichero "/etc/ettercap/etter.dns".

Administramos los plugins disponibles en Ettercap. Plugins > Manage the plugins...

Figura 8: Administrar plugins en Ettercap.

Se abrirá una nueva pestaña en la que buscaremos y seleccionaremos el plugin dns_spoof.

Figura 9: Selección del plugin dns_spoof.

Por último solo restará modificar el fichero local /etc/ettercap/etter.dns (en Kali Linux) para redirigir las peticiones de nombres de dominio del equipo víctima hacia las direcciones IP que establezcamos. En este caso las redirigí al propio equipo local (atacante) que tiene la IP 192.168.100.20. En este equipo tengo un servidor Apache el cual podría almacenar una réplica de la website que estamos redirigiendo, de este modo podríamos "engañar" a la víctima haciendo creer que está hacciendo a facebook.com cuando realmente está accediendo en mi web indéntica de facebook.com alojada en mi servidor Apache.

Figura 10: Fichero etter.dns. Redirigiendo websites.

Tiempo atrás se podía realizar con éxito este ataque. Hoy en día gracias a las mejoras de seguridad existen mecanismos que dificultan los DNS Spoof como son HPKP y HSTS.
Estos pueden interceptar las comunicaciones, cookies y otros parámetros. Obligando el uso de protocolos seguros como HTTPS, redirigiendo los sitios webs a su lugar legítimo.

De forma informativa y educativa en posteriores entradas comentaré una de las técnicas que podemos utilizar para intentar bypasear este tipo de mecanismos de seguridad.

Saludos!
Entradas Relacionadas