Powershell: объединение проверенных элементов в список для отправки по электронной почте - PullRequest
0 голосов
/ 05 мая 2020

Краткое описание проблемы: я пытаюсь написать сценарий PowerShell для обнаружения исходящих открытых портов с сервера, а затем отправляю по электронной почте имя сервера и массив портов, определенных как открытые.

Что я могу сделать на момент: Просканируйте и протестируйте список исходящих портов (1-1024 портов). Отправьте электронное письмо с описанием того, какая машина задействована.

Что я хочу сделать: отправлять электронную почту только тогда, когда любой из 1024 портов указан как «открытый». Перечислите порты, которые были обнаружены открытыми, игнорируя порты, которые были закрыты.

Вот мой код (без зазрения совести украденный из https://www.blackhillsinfosec.com/poking-holes-in-the-firewall-egress-testing-with-allports-exposed/):

1..1024 | % {$test= new-object system.Net.Sockets.TcpClient; 
$wait = $test.beginConnect("allports.exposed",$_,$null,$null);
($wait.asyncwaithandle.waitone(250,$false)); 
if($test.Connected){echo "$_ open"}else{echo "$_ closed"}} | select-string " "
Send-MailMessage -From OutboundScanning@domain.com -To Myself@domain.com -SmtpServer mysmtp.domain.com -Subject "$env:computername site has exposed outbound ports" -Body "Please contact NOC and NetSec to correct site of $env:computername . Outgoing ports $openedarray are available for outbound connectivity."

1 Ответ

2 голосов
/ 06 мая 2020

Я собираюсь дать небольшое назидание, но в вашей следующей поездке сюда будут применяться следующие правила:

Как мне задать хороший вопрос?

Как создать минимальный воспроизводимый пример

Почему «Кто-нибудь может мне помочь?» не актуальный вопрос?

# Refactor and fixes to make this more readable
1..1024 | 
ForEach {
    <#
    Unless you are using a legacy version of PowerShell, why are you using the .Net 
    namespace vs using the built-in PowerShell cmdlet ... 

    # Get specifics for a module, cmdlet, or function
    (Get-Command -Name Test-NetConnection).Parameters
    (Get-Command -Name Test-NetConnection).Parameters.Keys
    Get-help -Name Test-NetConnection -Examples
    <#
    # Results

    Test-NetConnection -InformationLevel "Detailed"
    Test-NetConnection -Port 80 -InformationLevel "Detailed"
    Test-NetConnection -ComputerName "www.contoso.com" -InformationLevel "Detailed"
    Test-NetConnection -ComputerName www.contoso.com -DiagnoseRouting -InformationLevel Detailed
    Test-NetConnection -ComputerName "www.contoso.com" -ConstrainInterface 5 -DiagnoseRouting -InformationLevel "Detailed"

    Get-help -Name Test-NetConnection -Full
    Get-help -Name Test-NetConnection -Online    
    #>

Ваше исправление состоит в том, чтобы поместить параметр «Отправить почту» в оператор if.

Тем не менее, вы говорите «если есть», что означает, что при первом открытом обращении вам нужно выйти из l oop.

$test = new-object system.Net.Sockets.TcpClient

$wait = $test.beginConnect("allports.exposed",$_,$null,$null)
($wait.asyncwaithandle.waitone(250,$false))

if($test.Connected)
{
    "$PSItem open"

    $SendMailMessageSplat = @{
    From       = "OutboundScanning@domain.com"
    To         = "Myself@domain.com"
    SmtpServer = "mysmtp.domain.com"
    Subject    = "$env:computername site has exposed outbound ports" 
    Body       = "Please contact NOC and NetSec to correct site of $env:computername. 
                 Outgoing ports $openedarray are available for outbound connectivity."
    }

Send-MailMessage @SendMailMessageSplat

Break
}
else{"$PSItem closed"}
}

Вы можете выполнить рефакторинг, используя обычный Командлеты PowerShell, к этому ...

$SendMailMessageSplat = @{
    From       = "OutboundScanning@domain.com"
    To         = "Myself@domain.com"
    SmtpServer = "mysmtp.domain.com"
    Subject    = "$env:computername site has exposed outbound ports" 
    Body       = "Please contact NOC and NetSec to correct site of $env:computername. 
                  Outgoing ports $openedarray are available for outbound connectivity."
}

1..1024 | 
ForEach{
    If (Test-NetConnection -ComputerName $env:COMPUTERNAME -Port $PSItem)
    {
        # Using Write-Host because of using colorized text, otherwise not really needed, since output to the screen is the PowerShell default.
        Write-Host "Port $PSItem on the target host open. Sending email notification and exiting." -ForegroundColor Red
        # Send-MailMessage @SendMailMessageSplat
        Break
    }
}

Чтобы сделать это как коллекцию ($ openarray), вам нужно установить ее так, что вы вообще не показываете. Это также будет очень медленным, просто к вашему сведению ...

Итак, что-то вроде этого ...

$OpenPorts = @()
$SendMailMessageSplat = @{
    From       = "OutboundScanning@domain.com"
    To         = "Myself@domain.com"
    SmtpServer = "mysmtp.domain.com"
    Subject    = "$env:computername site has exposed outbound ports" 
    Body       = "Please contact NOC and NetSec to correct site of $env:computername. 
                  Outgoing ports $OpenPorts are available for outbound connectivity."
}


1..1024 | 
ForEach{
    If (Test-NetConnection -ComputerName $env:COMPUTERNAME -Port $PSItem)
    {
        Write-Host "Port $PSItem on the target host open. Continnuing collection" -ForegroundColor Red
        $OpenPorts += ,$PSItem
    }
}


If ($OpenPorts -ge 1)
{
    Write-Warning -Message "A total of $($OpenPorts.Count) ports discovered as open. Sending email notificaiton and exiting."
    # Send-MailMessage @SendMailMessageSplat
}

Зачем вам отправлять сотни портов в теле email?

Было бы разумнее создать отчет txt / csv / excel, который вы можете просто отправить. Если вы действительно хотите, чтобы это было по электронной почте, вам нужно сгенерировать это как таблицу, используя HTML body.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...