viernes, 13 de diciembre de 2013

Honeypot, Firewall, IPS HomeMade con Powershell.

En el artículo de hoy vamos a trabajar con algunos conceptos básicos de Powershell.

El Script que os presento se basa en el registro del firewall de un equipo Windows 7 o superior.
Como vimos en esta entrada, es necesario configurar el detalle del log del servicio de firewall.

La idea del script es trabajar un poco con Powershell, y ya de paso, proporcionar un servicio a nuestra infraestructura.
Pido perdón de antemano a los expertos en Powershell o programación en general ya que soy de sistemas, y la programación para mi es un mundo desconocido.

El script nos pregunta por pantalla por un número de puerto. Con el número introducido levantamos un socket a la escucha para ese puerto. Esto actuaria como Honeypot, ya que es un puerto para un servicio que realmente no estamos ofreciendo. La idea es que en un ambiente de red local, dejar ese puerto a la escucha, por ejemplo un servidor SSH en el puerto 22, siempre y claro que no lo usemos legítimamente. Mediante el log del firewall de Windows voy a detectar intentos de conexión, que voy a permitir. Cada cierto tiempo incluiré una regla en el firewall denegando todas las conexiones entrantes para la ip que se ha intentado conectar al puerto emulado. Si publicamos ese honeypot hacia internet tendríamos protección ( ip baneada) solo para ese servidor. En el caso de tener varios servidores Windows ofreciendo servicios públicos, deberíamos añadir la capacidad de replicar esta regla al resto de servidores. También se me ocurre que mediante orquestación y automatización mediante SYSTEM CENTER 2012 Orchestrator podríamos lanzar un comando ssh hacia nuestro Firewall perimetral no-windows ( o cualquier sistema de comunicación que nos ofrezca el firewall) para banear la ip en todos los servicios expuestos, sean Windows o cualquier otro.

Este es el script primera versión, que aunque operativo, tiene mucho que mejorar.


[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing") 
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") 

$objForm = New-Object System.Windows.Forms.Form 
$objForm.Text = "Baneador IP.kinomakino"
$objForm.Size = New-Object System.Drawing.Size(300,200) 
$objForm.StartPosition = "CenterScreen"

$objForm.KeyPreview = $True
$objForm.Add_KeyDown({if ($_.KeyCode -eq "Banear") 
    {$x=$objTextBox.Text;$objForm.Close()}})
$objForm.Add_KeyDown({if ($_.KeyCode -eq "Cancelar") 
    {$objForm.Close()}})

$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Size(75,120)
$OKButton.Size = New-Object System.Drawing.Size(75,23)
$OKButton.Text = "OK"
$OKButton.Add_Click({$x=$objTextBox.Text;$objForm.Close()})
$objForm.Controls.Add($OKButton)

$CancelButton = New-Object System.Windows.Forms.Button
$CancelButton.Location = New-Object System.Drawing.Size(150,120)
$CancelButton.Size = New-Object System.Drawing.Size(75,23)
$CancelButton.Text = "Cancela"
$CancelButton.Add_Click({$objForm.Close()})
$objForm.Controls.Add($CancelButton)

$objLabel = New-Object System.Windows.Forms.Label
$objLabel.Location = New-Object System.Drawing.Size(10,20) 
$objLabel.Size = New-Object System.Drawing.Size(280,20) 
$objLabel.Text = "Introduce el puerto que quieres monitorizar:"
$objForm.Controls.Add($objLabel) 

$objTextBox = New-Object System.Windows.Forms.TextBox 
$objTextBox.Location = New-Object System.Drawing.Size(10,40) 
$objTextBox.Size = New-Object System.Drawing.Size(260,20) 
$objForm.Controls.Add($objTextBox) 

$objForm.Topmost = $True

$objForm.Add_Shown({$objForm.Activate()})
[void] $objForm.ShowDialog()

$x = $objTextBox.Text
#Toda la parte de arriba es para mostrar el textbox y almacenarlo en $x

$Honeypot = [System.Net.Sockets.TcpListener][int]$x;
$Honeypot.Start();
#Abre el socket con el puerto indicado en el Textbox
while($true)
{
sleep -s 300
#comprueba cada 5minutos si ha habido intento de conexión mediante el log del Firewall.

$logPath="C:\Windows\System32\LogFiles\Firewall\pfirewall.log"
$blackListPath= "C:\Windows\System32\LogFiles\Firewall\blacklist.txt"
$blacklist = Get-Content $blackListPath

$header=(Select-String -Path $logPath -Pattern "^#Fields").Line.Split(" ") | select -Skip 1
$ips=Get-Content $logPath | select -Skip 4 | 
ConvertFrom-Csv -Delimiter " " -Header $header |
where {$_."dst-port" -eq $x -and $_.path -eq "RECEIVE" -and $blacklist -notcontains $_."src-ip"} |
select -ExpandProperty "src-ip" 
$ips
$ips | Add-Content $blacklistPath
foreach ($ip in $ips){
  New-NetFirewallRule -DisplayName "Ip Bloqueada $ip" -Direction Inbound -Action Block -RemoteAddress $ip
   #si encuentra algún registro contra el puerto indicado, envia un correo.
                 $smtpserver = “smtp.gmail.com”
                 $msg = new-object Net.Mail.MailMessage
                 $smtp = new-object Net.Mail.SmtpClient($smtpServer )
                 $smtp.EnableSsl = $True
                 $smtp.Credentials = New-Object System.Net.NetworkCredential(“nick gmail sin @gmail, “clavegmail”); 
                 $msg.From = “correo origen
                 $msg.To.Add(”correo destino”)
                 $msg.Subject = “Ip baneada”
                 $msg.Body = “La ip $ip ha sido baneada por intento de conexión al honeypot”
                 $smtp.Send($msg)
                      }
                  
                        }
           
Para poder utilizarlo debes activar el detalle en el firewall de Windows así. En el mismo directorio debes crear un fichero vacio llamado blacklist.txt. Cambia los datos del correo y listo.

Una vez ejecutado comprobamos que el puerto introducido está a la escucha: netstat -ano


Ahora desde un equipo realizo un intento de conexión al puerto indicado, en este caso un scan completo.
Si todo ha ido bien, y esperando 5 minutos al menos, volvemos a realizar el scan y vemos que estamos baneados por el firewall.


En las reglas del Firewall de Windows compruebo que se ha creado la regla.


En unos segundos el sonido del correo en el móvil me indica que esto también ha ido bien.

En el fichero Blacklist almacenaremos las IP baneadas, que podemos usar como fuente de información en el supuesto de tener un firewall perimetral, por ejemplo pasándolo por ssh en un array de IP Baneadas.

Parsear el log para detectar el scan de puertos hubiera sido factible, pero si solo tengo publicado un servicio ( puerto) de este server no tendría ninguna manera, por eso lo del honeypot.

El lenguaje es bastante sencillo, y es muy fácil empezar a programar en Powershell. Este script lo he hecho mirando por la world wide web y con la ayuda de Dirk74 (technet forum).

Espero poder trabajar mas en esta idea, y añadir alguna mejora y capacidades nuevas, en próximas entregas de Inseguros lo intentaré.

Como siempre, espero que os guste, y gracias por leerme !!!