miércoles, 21 de enero de 2026

WINDOWS. PS IOC


 Propósito

Dada una palabra o un ejecutable, buscar un IOC (Indicador de compromiso) en un Host.

Introduces las palabras clave y el script analiza:

  • Procesos
  • Servicios
  • Tareas programadas
  • Carpetas sospechosas
  • Claves RUN / RUNONCE
  • Servicios en el registro
  • Búsqueda de binarios en AppData / Temp
  • Exportación CSV
  • Programas instalado
  • Ejecución en RAM

·         Startup del usuario y del sistema


Pasos

Para ejecutar: powershell.exe -ExecutionPolicy Bypass -File .\BuscasIOC.ps1

<#

    Detect-Strings-Extended.ps1

    Autor: Guillermo

    Objetivo:

        Script INFORMÁTICO que analiza el equipo para encontrar cualquier rastro

        de cadenas sospechosas en:

 

            • Programas instalados

            • Procesos en RAM

            • Servicios

            • Tareas programadas

            • Carpetas sospechosas

            • Entradas en RUN / RUNONCE

            • Servicios en el Registro

            • Archivos en AppData / Temp

            • Programas configurados en el inicio de Windows

 

        NO modifica nada. NO detiene nada. NO elimina nada.

#>

 

Write-Host "======================================================" -ForegroundColor Cyan

Write-Host "   ANALIZADOR DE INDICADORES - MODO INFORMATIVO"       -ForegroundColor Cyan

Write-Host "======================================================" -ForegroundColor Cyan

 

# 1) Pedir cadenas al usuario

$input = Read-Host "Introduce las cadenas a buscar (separadas por coma). Ej: updater, malware, test"

$patterns = $input.Split(",") | ForEach-Object { $_.Trim() } | Where-Object { $_ -ne "" }

 

if ($patterns.Count -eq 0) {

    Write-Host "No se han introducido cadenas. Saliendo..." -ForegroundColor Red

    exit

}

 

Write-Host "`nCadenas a buscar:" -ForegroundColor Yellow

$patterns | ForEach-Object { Write-Host " - $_" -ForegroundColor Green }

 

# Convertir a regex OR

$regex = ($patterns -join "|")

 

$results = New-Object System.Collections.Generic.List[object]

 

function Add-Result($Tipo,$Ruta,$Detalle) {

    $results.Add([pscustomobject]@{

        Tipo    = $Tipo

        Ruta    = $Ruta

        Detalle = $Detalle

    })

}

 

# =====================================================================

# [0] PROGRAMAS INSTALADOS (Add/Remove Programs)

# =====================================================================

Write-Host "`n========== [0] PROGRAMAS INSTALADOS ==========" -ForegroundColor Cyan

 

$installedApps = Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*, `

                                  HKLM:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*, `

                                  HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* `

                    -ErrorAction SilentlyContinue

 

foreach ($app in $installedApps) {

    if ($app.DisplayName -match $regex) {

        Add-Result "Programa Instalado" $app.DisplayName $app.DisplayVersion

        Write-Host "Programa detectado: $($app.DisplayName)" -ForegroundColor Green

    }

}

 

# =====================================================================

# [1] PROCESOS

# =====================================================================

Write-Host "`n========== [1] PROCESOS ==========" -ForegroundColor Cyan

Get-Process -ErrorAction SilentlyContinue |

    Where-Object { $_.Name -match $regex } |

    ForEach-Object {

        Add-Result "Proceso" ($_.Path) ($_.Name)

        $_

    }

 

# =====================================================================

# [2] SERVICIOS

# =====================================================================

Write-Host "`n========== [2] SERVICIOS ==========" -ForegroundColor Cyan

Get-Service -ErrorAction SilentlyContinue |

    Where-Object { $_.Name -match $regex -or $_.DisplayName -match $regex } |

    ForEach-Object {

        Add-Result "Servicio" $_.Name $_.DisplayName

        $_

    }

 

# =====================================================================

# [3] TAREAS PROGRAMADAS

# =====================================================================

Write-Host "`n========== [3] TAREAS PROGRAMADAS ==========" -ForegroundColor Cyan

Get-ScheduledTask -ErrorAction SilentlyContinue |

    Where-Object { $_.TaskName -match $regex -or $_.Description -match $regex } |

    ForEach-Object {

        Add-Result "Tarea Programada" $_.TaskName $_.Description

        $_

    }

 

# =====================================================================

# [4] CARPETAS HABITUALES

# =====================================================================

Write-Host "`n========== [4] CARPETAS HABITUALES ==========" -ForegroundColor Cyan

$paths = @(

    "$env:LOCALAPPDATA",

    "$env:LOCALAPPDATA\Programs",

    "$env:APPDATA",

    "$env:TEMP",

    "$env:ProgramFiles",

    "$env:ProgramFiles(x86)"

)

 

foreach ($base in $paths) {

    if (Test-Path $base) {

        Get-ChildItem $base -Recurse -ErrorAction SilentlyContinue |

            Where-Object { $_.Name -match $regex } |

            ForEach-Object {

                Add-Result "Archivo/Carpeta" $_.FullName "Coincidencia en nombre"

                Write-Host "Encontrado: $($_.FullName)" -ForegroundColor Green

            }

    }

}

 

# =====================================================================

# [5] RUN / RUNONCE

# =====================================================================

Write-Host "`n========== [5] RUN / RUNONCE ==========" -ForegroundColor Cyan

$runKeys = @(

    "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run",

    "HKCU:\Software\Microsoft\Windows\CurrentVersion\RunOnce",

    "HKLM:\Software\Microsoft\Windows\CurrentVersion\Run",

    "HKLM:\Software\Microsoft\Windows\CurrentVersion\RunOnce"

)

 

foreach ($rk in $runKeys) {

    if (Test-Path $rk) {

        $vals = Get-ItemProperty $rk -ErrorAction SilentlyContinue

        foreach ($prop in $vals.PSObject.Properties) {

            if ($prop.Name -notlike "PS*" -and (

                $prop.Name -match $regex -or ($prop.Value -as [string]) -match $regex

            )) {

                Add-Result "RunKey" $rk "$($prop.Name) = $($prop.Value)"

                Write-Host "[RUN] $rk → $($prop.Name) = $($prop.Value)" -ForegroundColor Green

            }

        }

    }

}

 

# =====================================================================

# [6] SERVICIOS DEL REGISTRO

# =====================================================================

Write-Host "`n========== [6] SERVICIOS DEL REGISTRO ==========" -ForegroundColor Cyan

Get-ChildItem "HKLM:\SYSTEM\CurrentControlSet\Services" -ErrorAction SilentlyContinue |

    Where-Object { $_.Name -match $regex } |

    ForEach-Object {

        Add-Result "RegistroServicio" $_.Name "Coincidencia en nombre de clave"

        $_.Name

    }

 

# =====================================================================

# [7] INICIO DE WINDOWS (Startup)

# =====================================================================

Write-Host "`n========== [7] PROGRAMAS EN EL INICIO ==========" -ForegroundColor Cyan

 

$startupPaths = @(

    "$env:APPDATA\Microsoft\Windows\Start Menu\Programs\Startup",

    "$env:ProgramData\Microsoft\Windows\Start Menu\Programs\Startup"

)

 

foreach ($sp in $startupPaths) {

    if (Test-Path $sp) {

        Get-ChildItem $sp -ErrorAction SilentlyContinue |

            Where-Object { $_.Name -match $regex } |

            ForEach-Object {

                Add-Result "Inicio Windows" $_.FullName "Coincidencia en acceso directo"

                Write-Host "En inicio: $($_.FullName)" -ForegroundColor Yellow

            }

    }

}

 

# =====================================================================

# [8] BINARIOS EN APPDATA / TEMP

# =====================================================================

Write-Host "`n========== [8] BINARIOS APPDATA / TEMP ==========" -ForegroundColor Cyan

$binroots = @("$env:LOCALAPPDATA","$env:APPDATA","$env:TEMP")

 

foreach ($br in $binroots) {

    if (Test-Path $br) {

        Get-ChildItem $br -Recurse -ErrorAction SilentlyContinue |

            Where-Object { $_.Name -match $regex } |

            ForEach-Object {

                Add-Result "Binario" $_.FullName "Coincidencia en nombre"

                Write-Host "Binario detectado: $($_.FullName)" -ForegroundColor Green

            }

    }

}

 

# =====================================================================

# RESUMEN + EXPORTACIÓN

# =====================================================================

 

Write-Host "`n==============================================" -ForegroundColor Cyan

Write-Host "                 RESUMEN" -ForegroundColor Cyan

Write-Host "==============================================" -ForegroundColor Cyan

 

$results | Format-Table -AutoSize

 

# Nombre con fecha y hora

$timestamp = (Get-Date).ToString("yyyy-MM-dd_HH-mm-ss")

$output = "C:\Temp\Deteccion-Resultado_$timestamp.csv"

 

New-Item -ItemType Directory -Path (Split-Path $output) -Force | Out-Null

$results | Export-Csv -Path $output -NoTypeInformation -Encoding UTF8

 

Write-Host "`nArchivo exportado: $output" -ForegroundColor Yellow

Write-Host "`n--- ANÁLISIS FINALIZADO ---" -ForegroundColor Cyan

 







No hay comentarios: