Загрузка данных


# IRCollector.ps1
# Сохранить в кодировке UTF-8 с BOM

#requires -version 5.1

[Console]::InputEncoding = [System.Text.Encoding]::UTF8
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
$OutputEncoding = [System.Text.Encoding]::UTF8

$ErrorActionPreference = "Continue"
$ProgressPreference = "SilentlyContinue"

$TimeStamp = Get-Date -Format "yyyy-MM-dd_HH-mm-ss"
$Root = "C:\IR\$($env:COMPUTERNAME)_$TimeStamp"

$Paths = @{
    Logs        = Join-Path $Root "Журналы Windows"
    Processes   = Join-Path $Root "Процессы"
    Network     = Join-Path $Root "Сеть"
    Tasks       = Join-Path $Root "Задачи планировщика"
    Services    = Join-Path $Root "Службы и драйверы"
    Registry    = Join-Path $Root "Реестр"
    Users       = Join-Path $Root "Пользователи"
    System      = Join-Path $Root "Система"
    Defender    = Join-Path $Root "Защитник Windows"
    Persistence = Join-Path $Root "Автозагрузка"
    Artifacts   = Join-Path $Root "Артефакты"
    Browsers    = Join-Path $Root "Браузеры"
    Errors      = Join-Path $Root "Ошибки"
}

New-Item -Path $Root -ItemType Directory -Force | Out-Null

foreach ($Path in $Paths.Values) {
    New-Item -Path $Path -ItemType Directory -Force | Out-Null
}

$ErrorLog = Join-Path $Paths.Errors "Ошибки сбора.txt"

function Write-CollectionError {
    param(
        [Parameter(Mandatory = $true)]
        [string]$Message
    )

    $Line = "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] $Message"
    $Line | Out-File -FilePath $ErrorLog -Encoding UTF8 -Append
}

function Copy-SingleArtifact {
    param(
        [Parameter(Mandatory = $true)]
        [string]$Source,

        [Parameter(Mandatory = $true)]
        [string]$Destination
    )

    try {
        if (-not (Test-Path -LiteralPath $Source)) {
            Write-CollectionError "Файл не найден: ${Source}"
            return
        }

        New-Item -Path $Destination -ItemType Directory -Force | Out-Null

        Copy-Item `
            -LiteralPath $Source `
            -Destination $Destination `
            -Force `
            -ErrorAction Stop
    }
    catch {
        Write-CollectionError "Копирование ${Source}: $($_.Exception.Message)"
    }
}

function Copy-FolderContents {
    param(
        [Parameter(Mandatory = $true)]
        [string]$Source,

        [Parameter(Mandatory = $true)]
        [string]$Destination
    )

    try {
        if (-not (Test-Path -LiteralPath $Source)) {
            Write-CollectionError "Папка не найдена: ${Source}"
            return
        }

        New-Item -Path $Destination -ItemType Directory -Force | Out-Null

        $Items = Get-ChildItem `
            -LiteralPath $Source `
            -Force `
            -ErrorAction Stop

        foreach ($Item in $Items) {
            try {
                Copy-Item `
                    -LiteralPath $Item.FullName `
                    -Destination $Destination `
                    -Recurse `
                    -Force `
                    -ErrorAction Stop
            }
            catch {
                Write-CollectionError "Копирование $($Item.FullName): $($_.Exception.Message)"
            }
        }
    }
    catch {
        Write-CollectionError "Чтение ${Source}: $($_.Exception.Message)"
    }
}

Clear-Host

Write-Host "==============================================" -ForegroundColor Cyan
Write-Host "       WINDOWS INCIDENT RESPONSE COLLECTOR" -ForegroundColor Cyan
Write-Host "==============================================" -ForegroundColor Cyan
Write-Host ""
Write-Host "Компьютер: $env:COMPUTERNAME"
Write-Host "Пользователь: $env:USERDOMAIN\$env:USERNAME"
Write-Host "Папка сбора: $Root"
Write-Host ""

# ============================================================
# 1. ПРОЦЕССЫ
# ============================================================

Write-Host "[1/12] Собираю процессы..." -ForegroundColor Yellow

try {
    Get-CimInstance Win32_Process |
        Select-Object ProcessId, ParentProcessId, Name, ExecutablePath, CommandLine, CreationDate |
        Export-Csv `
            -Path (Join-Path $Paths.Processes "Процессы.csv") `
            -NoTypeInformation `
            -Encoding UTF8
}
catch {
    Write-CollectionError "Win32_Process: $($_.Exception.Message)"
}

try {
    tasklist.exe /V /FO CSV |
        Out-File `
            -FilePath (Join-Path $Paths.Processes "Tasklist.csv") `
            -Encoding UTF8
}
catch {
    Write-CollectionError "Tasklist: $($_.Exception.Message)"
}

try {
    Get-Process |
        Select-Object Id, ProcessName, Path, StartTime, CPU, Handles, WorkingSet64 |
        Export-Csv `
            -Path (Join-Path $Paths.Processes "Get-Process.csv") `
            -NoTypeInformation `
            -Encoding UTF8
}
catch {
    Write-CollectionError "Get-Process: $($_.Exception.Message)"
}

# ============================================================
# 2. СЕТЬ
# ============================================================

Write-Host "[2/12] Собираю сетевую активность..." -ForegroundColor Yellow

try {
    netstat.exe -abno |
        Out-File `
            -FilePath (Join-Path $Paths.Network "Netstat ABNO.txt") `
            -Encoding UTF8
}
catch {
    Write-CollectionError "Netstat: $($_.Exception.Message)"
}

try {
    Get-NetTCPConnection |
        Select-Object LocalAddress, LocalPort, RemoteAddress, RemotePort, State, OwningProcess |
        Export-Csv `
            -Path (Join-Path $Paths.Network "TCP соединения.csv") `
            -NoTypeInformation `
            -Encoding UTF8
}
catch {
    Write-CollectionError "TCP-соединения: $($_.Exception.Message)"
}

try {
    Get-NetUDPEndpoint |
        Select-Object LocalAddress, LocalPort, OwningProcess |
        Export-Csv `
            -Path (Join-Path $Paths.Network "UDP соединения.csv") `
            -NoTypeInformation `
            -Encoding UTF8
}
catch {
    Write-CollectionError "UDP-соединения: $($_.Exception.Message)"
}

try {
    Get-DnsClientCache |
        Export-Csv `
            -Path (Join-Path $Paths.Network "DNS-кэш.csv") `
            -NoTypeInformation `
            -Encoding UTF8
}
catch {
    Write-CollectionError "DNS-кэш: $($_.Exception.Message)"
}

try {
    ipconfig.exe /all |
        Out-File `
            -FilePath (Join-Path $Paths.Network "IPConfig.txt") `
            -Encoding UTF8
}
catch {
    Write-CollectionError "IPConfig: $($_.Exception.Message)"
}

try {
    arp.exe -a |
        Out-File `
            -FilePath (Join-Path $Paths.Network "ARP.txt") `
            -Encoding UTF8
}
catch {
    Write-CollectionError "ARP: $($_.Exception.Message)"
}

try {
    route.exe print |
        Out-File `
            -FilePath (Join-Path $Paths.Network "Маршруты.txt") `
            -Encoding UTF8
}
catch {
    Write-CollectionError "Маршруты: $($_.Exception.Message)"
}

# ============================================================
# 3. ЖУРНАЛЫ WINDOWS
# ============================================================

Write-Host "[3/12] Экспортирую журналы Windows..." -ForegroundColor Yellow

try {
    $EventLogs = & wevtutil.exe el

    $EventLogs |
        Out-File `
            -FilePath (Join-Path $Paths.Logs "Список журналов.txt") `
            -Encoding UTF8

    foreach ($Log in $EventLogs) {
        try {
            $SafeName = $Log -replace '[\\/:*?"<>|]', "_"
            $OutputFile = Join-Path $Paths.Logs "$SafeName.evtx"

            & wevtutil.exe epl "$Log" "$OutputFile" /ow:true 2>$null

            if ($LASTEXITCODE -ne 0) {
                Write-CollectionError "Не экспортирован журнал: ${Log}"
            }
        }
        catch {
            Write-CollectionError "Журнал ${Log}: $($_.Exception.Message)"
        }
    }
}
catch {
    Write-CollectionError "Экспорт журналов: $($_.Exception.Message)"
}

# ============================================================
# 4. ЗАДАЧИ ПЛАНИРОВЩИКА
# ============================================================

Write-Host "[4/12] Собираю задания планировщика..." -ForegroundColor Yellow

try {
    schtasks.exe /query /fo LIST /v |
        Out-File `
            -FilePath (Join-Path $Paths.Tasks "Задачи.txt") `
            -Encoding UTF8
}
catch {
    Write-CollectionError "Schtasks: $($_.Exception.Message)"
}

try {
    Get-ScheduledTask |
        Select-Object TaskPath, TaskName, State, Author, Description |
        Export-Csv `
            -Path (Join-Path $Paths.Tasks "Задачи.csv") `
            -NoTypeInformation `
            -Encoding UTF8
}
catch {
    Write-CollectionError "Get-ScheduledTask: $($_.Exception.Message)"
}

try {
    $TaskActions = foreach ($Task in Get-ScheduledTask) {
        foreach ($Action in $Task.Actions) {
            [PSCustomObject]@{
                TaskPath         = $Task.TaskPath
                TaskName         = $Task.TaskName
                Execute          = $Action.Execute
                Arguments        = $Action.Arguments
                WorkingDirectory = $Action.WorkingDirectory
            }
        }
    }

    $TaskActions |
        Export-Csv `
            -Path (Join-Path $Paths.Tasks "Действия задач.csv") `
            -NoTypeInformation `
            -Encoding UTF8
}
catch {
    Write-CollectionError "Действия задач: $($_.Exception.Message)"
}

# ============================================================
# 5. СЛУЖБЫ И ДРАЙВЕРЫ
# ============================================================

Write-Host "[5/12] Собираю службы и драйверы..." -ForegroundColor Yellow

try {
    Get-CimInstance Win32_Service |
        Select-Object Name, DisplayName, State, StartMode, StartName, PathName, ProcessId |
        Export-Csv `
            -Path (Join-Path $Paths.Services "Службы.csv") `
            -NoTypeInformation `
            -Encoding UTF8
}
catch {
    Write-CollectionError "Службы: $($_.Exception.Message)"
}

try {
    sc.exe query state= all |
        Out-File `
            -FilePath (Join-Path $Paths.Services "SC Query.txt") `
            -Encoding UTF8
}
catch {
    Write-CollectionError "SC Query: $($_.Exception.Message)"
}

try {
    driverquery.exe /V /FO CSV |
        Out-File `
            -FilePath (Join-Path $Paths.Services "Драйверы.csv") `
            -Encoding UTF8
}
catch {
    Write-CollectionError "Driverquery: $($_.Exception.Message)"
}

try {
    Get-CimInstance Win32_SystemDriver |
        Select-Object Name, DisplayName, State, StartMode, PathName |
        Export-Csv `
            -Path (Join-Path $Paths.Services "Системные драйверы.csv") `
            -NoTypeInformation `
            -Encoding UTF8
}
catch {
    Write-CollectionError "Системные драйверы: $($_.Exception.Message)"
}

# ============================================================
# 6. АВТОЗАГРУЗКА И РЕЕСТР
# ============================================================

Write-Host "[6/12] Собираю автозагрузку и реестр..." -ForegroundColor Yellow

try {
    Get-CimInstance Win32_StartupCommand |
        Select-Object Name, Command, Location, User |
        Export-Csv `
            -Path (Join-Path $Paths.Persistence "Автозагрузка.csv") `
            -NoTypeInformation `
            -Encoding UTF8
}
catch {
    Write-CollectionError "Автозагрузка: $($_.Exception.Message)"
}

$RegistryKeys = @{
    "HKLM Run" = "HKLM:\Software\Microsoft\Windows\CurrentVersion\Run"
    "HKLM RunOnce" = "HKLM:\Software\Microsoft\Windows\CurrentVersion\RunOnce"
    "HKLM WOW64 Run" = "HKLM:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Run"
    "HKCU Run" = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run"
    "HKCU RunOnce" = "HKCU:\Software\Microsoft\Windows\CurrentVersion\RunOnce"
    "Winlogon" = "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Winlogon"
    "AppInit DLLs" = "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Windows"
    "Image File Execution Options" = "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options"
    "Silent Process Exit" = "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\SilentProcessExit"
    "LSA" = "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa"
    "BAM" = "HKLM:\SYSTEM\CurrentControlSet\Services\bam\State\UserSettings"
    "DAM" = "HKLM:\SYSTEM\CurrentControlSet\Services\dam\State\UserSettings"
}

foreach ($Item in $RegistryKeys.GetEnumerator()) {
    try {
        Get-ItemProperty `
            -Path $Item.Value `
            -ErrorAction Stop |
            Format-List * |
            Out-File `
                -FilePath (Join-Path $Paths.Registry "$($Item.Key).txt") `
                -Encoding UTF8
    }
    catch {
        Write-CollectionError "Реестр $($Item.Key): $($_.Exception.Message)"
    }
}

try {
    & reg.exe export `
        "HKLM\SYSTEM\CurrentControlSet\Services" `
        (Join-Path $Paths.Registry "Службы.reg") `
        /y 2>$null
}
catch {
    Write-CollectionError "Экспорт реестра Services: $($_.Exception.Message)"
}

try {
    & reg.exe export `
        "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" `
        (Join-Path $Paths.Registry "HKLM Run.reg") `
        /y 2>$null
}
catch {
    Write-CollectionError "Экспорт HKLM Run: $($_.Exception.Message)"
}

try {
    & reg.exe export `
        "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" `
        (Join-Path $Paths.Registry "HKCU Run.reg") `
        /y 2>$null
}
catch {
    Write-CollectionError "Экспорт HKCU Run: $($_.Exception.Message)"
}

try {
    & reg.exe export `
        "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" `
        (Join-Path $Paths.Registry "Winlogon.reg") `
        /y 2>$null
}
catch {
    Write-CollectionError "Экспорт Winlogon: $($_.Exception.Message)"
}

# ============================================================
# 7. ПОЛЬЗОВАТЕЛИ И СЕАНСЫ
# ============================================================

Write-Host "[7/12] Собираю пользователей и сеансы..." -ForegroundColor Yellow

try {
    whoami.exe /all |
        Out-File `
            -FilePath (Join-Path $Paths.Users "Текущий пользователь.txt") `
            -Encoding UTF8
}
catch {
    Write-CollectionError "Whoami: $($_.Exception.Message)"
}

try {
    $QuserPath = Join-Path $env:SystemRoot "System32\quser.exe"

    if (Test-Path -LiteralPath $QuserPath) {
        & $QuserPath |
            Out-File `
                -FilePath (Join-Path $Paths.Users "Активные сеансы.txt") `
                -Encoding UTF8
    }
    else {
        Write-CollectionError "Файл quser.exe не найден"
    }
}
catch {
    Write-CollectionError "Активные сеансы: $($_.Exception.Message)"
}

try {
    net.exe user |
        Out-File `
            -FilePath (Join-Path $Paths.Users "Локальные пользователи.txt") `
            -Encoding UTF8
}
catch {
    Write-CollectionError "Net user: $($_.Exception.Message)"
}

try {
    Get-LocalUser |
        Export-Csv `
            -Path (Join-Path $Paths.Users "Локальные пользователи.csv") `
            -NoTypeInformation `
            -Encoding UTF8
}
catch {
    Write-CollectionError "Get-LocalUser: $($_.Exception.Message)"
}

try {
    Get-LocalGroup |
        Export-Csv `
            -Path (Join-Path $Paths.Users "Локальные группы.csv") `
            -NoTypeInformation `
            -Encoding UTF8
}
catch {
    Write-CollectionError "Get-LocalGroup: $($_.Exception.Message)"
}

try {
    $AdministratorsGroup = Get-LocalGroup -SID "S-1-5-32-544"

    Get-LocalGroupMember -Group $AdministratorsGroup.Name |
        Export-Csv `
            -Path (Join-Path $Paths.Users "Локальные администраторы.csv") `
            -NoTypeInformation `
            -Encoding UTF8
}
catch {
    Write-CollectionError "Группа администраторов: $($_.Exception.Message)"
}

# ============================================================
# 8. СИСТЕМА
# ============================================================

Write-Host "[8/12] Собираю сведения о системе..." -ForegroundColor Yellow

try {
    systeminfo.exe |
        Out-File `
            -FilePath (Join-Path $Paths.System "Сведения о системе.txt") `
            -Encoding UTF8
}
catch {
    Write-CollectionError "Systeminfo: $($_.Exception.Message)"
}

try {
    hostname.exe |
        Out-File `
            -FilePath (Join-Path $Paths.System "Имя компьютера.txt") `
            -Encoding UTF8
}
catch {
    Write-CollectionError "Hostname: $($_.Exception.Message)"
}

try {
    Get-Date |
        Out-File `
            -FilePath (Join-Path $Paths.System "Дата и время.txt") `
            -Encoding UTF8
}
catch {
    Write-CollectionError "Дата и время: $($_.Exception.Message)"
}

try {
    Get-TimeZone |
        Format-List * |
        Out-File `
            -FilePath (Join-Path $Paths.System "Часовой пояс.txt") `
            -Encoding UTF8
}
catch {
    Write-CollectionError "Часовой пояс: $($_.Exception.Message)"
}

try {
    Get-HotFix |
        Sort-Object InstalledOn -Descending |
        Export-Csv `
            -Path (Join-Path $Paths.System "Обновления.csv") `
            -NoTypeInformation `
            -Encoding UTF8
}
catch {
    Write-CollectionError "Обновления: $($_.Exception.Message)"
}

try {
    Get-CimInstance Win32_OperatingSystem |
        Format-List * |
        Out-File `
            -FilePath (Join-Path $Paths.System "Операционная система.txt") `
            -Encoding UTF8
}
catch {
    Write-CollectionError "Операционная система: $($_.Exception.Message)"
}

try {
    Get-CimInstance Win32_ComputerSystem |
        Format-List * |
        Out-File `
            -FilePath (Join-Path $Paths.System "Компьютер.txt") `
            -Encoding UTF8
}
catch {
    Write-CollectionError "Компьютер: $($_.Exception.Message)"
}

try {
    auditpol.exe /get /category:* |
        Out-File `
            -FilePath (Join-Path $Paths.System "Политика аудита.txt") `
            -Encoding UTF8
}
catch {
    Write-CollectionError "Политика аудита: $($_.Exception.Message)"
}

# ============================================================
# 9. УСТАНОВЛЕННЫЕ ПРОГРАММЫ
# ============================================================

Write-Host "[9/12] Собираю установленные программы..." -ForegroundColor Yellow

$UninstallKeys = @(
    "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*",
    "HKLM:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*",
    "HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*"
)

try {
    Get-ItemProperty $UninstallKeys |
        Where-Object { $_.DisplayName } |
        Select-Object DisplayName, DisplayVersion, Publisher, InstallDate, InstallLocation, InstallSource, UninstallString |
        Sort-Object DisplayName |
        Export-Csv `
            -Path (Join-Path $Paths.System "Установленные программы.csv") `
            -NoTypeInformation `
            -Encoding UTF8
}
catch {
    Write-CollectionError "Установленные программы: $($_.Exception.Message)"
}

# ============================================================
# 10. ЗАЩИТНИК WINDOWS И БРАНДМАУЭР
# ============================================================

Write-Host "[10/12] Собираю данные Защитника Windows..." -ForegroundColor Yellow

try {
    Get-MpComputerStatus |
        Format-List * |
        Out-File `
            -FilePath (Join-Path $Paths.Defender "Состояние Защитника.txt") `
            -Encoding UTF8
}
catch {
    Write-CollectionError "Состояние Защитника: $($_.Exception.Message)"
}

try {
    Get-MpThreatDetection |
        Format-List * |
        Out-File `
            -FilePath (Join-Path $Paths.Defender "Обнаруженные угрозы.txt") `
            -Encoding UTF8
}
catch {
    Write-CollectionError "Обнаружения Защитника: $($_.Exception.Message)"
}

try {
    Get-MpPreference |
        Format-List * |
        Out-File `
            -FilePath (Join-Path $Paths.Defender "Настройки Защитника.txt") `
            -Encoding UTF8
}
catch {
    Write-CollectionError "Настройки Защитника: $($_.Exception.Message)"
}

try {
    netsh.exe advfirewall show allprofiles |
        Out-File `
            -FilePath (Join-Path $Paths.Network "Профили брандмауэра.txt") `
            -Encoding UTF8
}
catch {
    Write-CollectionError "Профили бран