Desarrollo de un Script para detectar sesiones sospechosas con PowerShell

Hola este tema me pareció interesante desarrollar debido a que uno no sabe quien esta conectado en tu maquina ya que puede ser una conexión remota, tal ves alguien de tu misma red, algún virus que abrió un puerto o el administrador de la red revisando alguna cosas, espero les interese.

Preparación del Entorno

Este documento esta basado en la versión 5.0 de PowerShell y fue probado también en la versión 4.0, para verificar con que versión de PowerShell esta trabajando utilizar el siguiente comando:

 PS C:\> Get-host

En caso de tener una versión inferior, descargar e instalar NetFramework.
Es necesario habilitar la ejecución de Script en Powershell, para ello se debe de verificar la política de ejecución, el siguiente comando permite verificar la política:

 PS D:\> Get-ExecutionPolicy Restricted (Resultado, significa que tenemos bloqueada esta política)

Si el comando anterior da como resultado Restricted, hay que cambiarlo a Unrestricted solo para el usuario actual, el siguiente comando realiza dicha tarea:

PS D:\> Set-ExecutionPolicy -Scope CurrentUser Unrestricted

Conocimientos Previos

Ahora para crear un Script tenemos que conocer algunos comandos importantes:

  • Foreach, recorre una array, información sobre loops.
  •  if(p1 -ne p2), condicional que evalúa que p1 sea diferente a p2.  Para conocer mas operadores de comparacion utilizar el siguiente enlace.
  • if(p1 -And p2), condicional que evalúa p1 and p2, también se puede usar -Or
  • try{}catch{}, ejecuta un proceso y si ocurre un error lo envía a catch.
  • Para conocer como manipular variables y array revisar el siguiente enlace

CMDLET en PowerShell

Para desarrollar el script se va a utilizar los siguientes cmdlet (combinación entre comando y objeto):

  • Get-NetTCPConnection,  permite obtener información sobre las conexiones TCP en el equipo.
  • Get-DnsClientCache, permite hacer búsquedas dentro del cache DNS.
  • Get-Process, permite obtener información sobre los procesos.
  • Y la función GetHostEntry

La forma de trabaja con los 3 cmdlet es similar, por eso solo vamos a probar con Get-NetTCPConnection, en el script final, ya se utiliza los 3.
Se utilizará cmdlet  Get-NetTCPConnection, para que liste las conexiones en el equipo actual, mas información.

PS D:\> Get-NetTCPConnection 

Esta función devolverá todas las conexiones TCP que tiene el equipo, la información mostrada es básica, existe mas información que se puede extraer para ello podemos utilizar el siguiente comando:

PS D:\> Get-NetTCPConnection | Format-List -Property *
Ahora la información es muy extensa y es difícil poder revisar la información, PowerShell tiene la capacidad de poder exportar la información a Excel, el siguiente comando permite eso:

 PS D:\> Get-NetTCPConnection | Export-Csv -Path "d:\data1.csv"
Para poder filtrar la información, especifique la cabecera que tiene la información seguida del valor a filtrar, en el siguiente ejemplo se realizara un filtro todas la conexiones que tiene como puerto destino 443. 

 PS D:\> Get-NetTCPConnection -RemotePort 443
Para personalizar las columnas a mostrar se puede utilizar comando select o select-object, es similar a una consulta SQL.

 PS D:\>Get-NetTCPConnection -RemotePort 443 | select RemoteAddress, RemotePort, State
PowerShell permite hacer filtro al igual que SQL, usando el argumento Where-Object o su alias Where, se puede especificar el parámetro y el cambio a filtrar, para mas información revisar el siguiente enlace.
Conociendo los campos del cmdlet Get-NetTCPConnection se puede filtrar también su contenido, en el siguiente ejemplo filtra todas la conexiones al puerto 443 y de un proceso especifico.

 PS D:\> Get-NetTCPConnection |? {($_.RemotePort -eq '443') -And ($_.OwningProcess -eq '3928')}

Determinar si una IP se encuentra en una BlackList

Este me parece un punto muy importante, ya nos permite saber si la IP que esta conectada a nosotros se encuentra en una blacklist, para ello se encontró en Internet un script muy interesante, que se utilizo, solo se realizo algunas modificaciones, este es el enlace:
https://www.saotn.org/powershell-blacklist-check-script

Ahora juntando todas las partes, este seria el codigo completo, también se puede descargar el Script desde la siguiente URL:





#Generar una clave en httpbl.org y colocarlo entre las doble comillas

[string]$httpBL = ""

$subnetIP = Get-NetTCPConnection | ? {($_.RemoteAddress -ne "0.0.0.0") -And ($_.RemoteAddress -ne "::") -And ($_.RemoteAddress -ne "127.0.0.1")} | Sort-Object -Property RemoteAddress | Select-Object RemoteAddress,RemotePort,OwningProcess -Unique
#$subnetIP = Get-NetTCPConnection | ? {($_.RemoteAddress -eq "172.217.8.69") } | Sort-Object -Property RemoteAddress | Select-Object RemoteAddress,RemotePort,OwningProcess -Unique
 foreach ($IPRemote in $subnetIP){
  $StrDNS = ""
  $StrCacheDNS =""
  $iphost = $IPRemote.RemoteAddress
   try { 
    $StrCacheDNS = Get-DnsClientCache | ? {($_.Data -eq $iphost)}
    $blackList=FNDNSResolve($iphost)
    if (!$blackList) { $blackList="Limpio" } else{ write-host $blackList}
                $StrDNS = [System.Net.Dns]::GetHostEntry($iphost) | select-object HostName,AddressList
   }catch{
    write-host "Error con IP $iphost"
    }
    Get-Process -PID $IPRemote.OwningProcess | select ProcessName, Id, @{Name ="RemoteAddr";Expression={$IPRemote.RemoteAddress}}, @{Name ="RemotePort";Expression={$IPRemote.RemotePort}},@{Name ="BlackList";Expression={$blackList}},@{Name ="DNS";Expression={$StrDNS.HostName}},@{Name ="CacheDNS";Expression={$StrCacheDNS.Entry}} | Format-Table
 }

Function FNDNSResolve($ip){
$RSblackList =""
$ipParts = $ip.Split('.')
[array]::Reverse($ipParts)
$ipParts = [string]::Join('.', $ipParts)
$blacklists = "dnsbl.httpbl.org", `
 "cbl.abuseat.org", `
 "dnsbl.sorbs.net", `
 "bl.spamcop.net", `
 "zen.spamhaus.org", `
 "b.barracudacentral.org", `
 "bad.psky.me"

    foreach ( $blacklist in $blacklists ) {
     if ( $blacklist -contains "dnsbl.httpbl.org" ) {
      # Add your httpBL API-key from Project Honey Pot
      $lookupAddress = $httpBL + "." + $ipParts + ".dnsbl.httpbl.org."
     }
     else {
      $lookupAddress = $ipParts + ".$blacklist."
     }
     try {
      $RSblackList = $RSblackList + [System.Net.Dns]::GetHostEntry($lookupAddress) | select-object HostName,AddressList
     }
     catch {
      #Write-Host "No blacklisting for $ip found in $blacklist"
     }
    }
    Return $RSblackList
}





Bibliografia

https://www.saotn.org/powershell-blacklist-check-script
https://jongrassley.wordpress.com/2016/09/22/get-nettcpconnection/
https://stackoverflow.com/questions/39630404/inner-join-in-powershell-without-sql
http://www.itprotoday.com/management-mobility/powershell-basics-filtering-objects
https://docs.microsoft.com/es-es/powershell/module/Microsoft.PowerShell.Utility/Select-Object?view=powershell-6


Comentarios