public/Connect-TNServer.ps1
function Connect-TNServer { <# .SYNOPSIS Connects to a Nessus or tenable.sc server .DESCRIPTION Connects to a Nessus or tenable.sc server .PARAMETER ComputerName The network name or IP address of the Nessus or tenable.sc server .PARAMETER Port The port of the Nessus or tenable.sc server. Defaults to 8834 which is the default port for Nessus. .PARAMETER Credential The credential object (from Get-Credential) used to log into the target server. Specifies a user account that has permission to send the request. .PARAMETER UseDefaultCredential Indicates that the command uses the credentials of the current user to send the web request. This can't be used with Authentication or Credential and may not be supported on all platforms. .PARAMETER AcceptSelfSignedCert Accept self-signed certs .PARAMETER Type The type of server .PARAMETER EnableException By default, when something goes wrong we try to catch it, interpret it and give you a friendly warning message. This avoids overwhelming you with 'sea of red' exceptions, but is inconvenient because it basically disables advanced scripting. Using this switch turns this 'nice by default' feature off and enables you to catch exceptions with your own try/catch. .EXAMPLE PS C:\> $secman = Get-Credential secman PS C:\> Connect-TNServer -ComputerName securitycenter -Type tenable.sc -Credential $secman Connects to a tenble.sc host with the hostname "securitycenter" using the secman username. This is similar to going to https://securitycenter .EXAMPLE PS C:\> Connect-TNServer -ComputerName nessus -Credential admin Connects to a Nessus host with the hostname "nessus" using the admin username. This is similar to going to https://nessus:8834 .EXAMPLE PS C:\> Connect-TNServer -ComputerName nessus -Port 8080 -Credential admin Connects to a Nessus host with the hostname "nessus" and the port 8080 using the admin username. This is similar to going to https://nessus:8080 #> [CmdletBinding()] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [string[]]$ComputerName, [int]$Port, [Management.Automation.PSCredential]$Credential, [switch]$UseDefaultCredential, [switch]$AcceptSelfSignedCert, [ValidateSet("tenable.sc", "Nessus")] [string]$Type, [switch]$InitialConnect, [switch]$NoWait, [switch]$EnableException ) begin { if (-not $PSBoundParameters.Credential) { $UseDefaultCredential = $true } if ($PSVersionTable.PSEdition -eq 'Core') { if ($AcceptSelfSignedCert) { $PSDefaultParameterValues['Invoke-RestMethod:SkipCertificateCheck'] = $true } } else { if ($AcceptSelfSignedCert -and [System.Net.ServicePointManager]::CertificatePolicy.ToString() -ne 'IgnoreCerts') { $Domain = [AppDomain]::CurrentDomain $DynAssembly = New-Object System.Reflection.AssemblyName('IgnoreCerts') $AssemblyBuilder = $Domain.DefineDynamicAssembly($DynAssembly, [System.Reflection.Emit.AssemblyBuilderAccess]::Run) $ModuleBuilder = $AssemblyBuilder.DefineDynamicModule('IgnoreCerts', $false) $TypeBuilder = $ModuleBuilder.DefineType('IgnoreCerts', 'AutoLayout, AnsiClass, Class, Public, BeforeFieldInit', [System.Object], [System.Net.ICertificatePolicy]) $TypeBuilder.DefineDefaultConstructor('PrivateScope, Public, HideBySig, SpecialName, RTSpecialName') | Out-Null $MethodInfo = [System.Net.ICertificatePolicy].GetMethod('CheckValidationResult') $MethodBuilder = $TypeBuilder.DefineMethod($MethodInfo.Name, 'PrivateScope, Public, Virtual, HideBySig, VtableLayoutMask', $MethodInfo.CallingConvention, $MethodInfo.ReturnType, ([Type[]] ($MethodInfo.GetParameters() | ForEach-Object { $_.ParameterType }))) $ILGen = $MethodBuilder.GetILGenerator() $ILGen.Emit([Reflection.Emit.Opcodes]::Ldc_I4_1) $ILGen.Emit([Reflection.Emit.Opcodes]::Ret) $TypeBuilder.CreateType() | Out-Null # Disable SSL certificate validation [System.Net.ServicePointManager]::CertificatePolicy = New-Object IgnoreCerts } } # Force usage of TSL1.2 as Nessus web server only supports this and will hang otherwise # Source: https://stackoverflow.com/questions/32355556/powershell-invoke-restmethod-over-https [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 if (-Not $Type) { if ($Port -eq 443) { $Type = "tenable.sc" } else { $Type = "Nessus" } } if ($Type -and -not $Port) { if ($Type -eq "tenable.sc") { $Port = "443" } else { $Port = "8834" } } if ($Type -eq "tenable.sc") { $sc = $true } else { $sc = $false } } process { foreach ($computer in $ComputerName) { if ($Type -ne "tenable.sc" -and -not $NoWait) { $null = Wait-TNServerReady -ComputerName $computer -Port $Port -SilentUntil 5 -AcceptSelfSignedCert:$AcceptSelfSignedCert } if ($Type -eq "tenable.sc") { $uri = "https://$($computer):$Port/rest" $fulluri = "$uri/token" if ($PSBoundParameters.Credential -and -not $InitialConnect) { $body = @{ username = $Credential.UserName password = $Credential.GetNetworkCredential().Password releaseSession = "FALSE" } | ConvertTo-Json } elseif ($PSBoundParameters.Credential -and $InitialConnect) { try { $first = Invoke-NonAuthRequest -ComputerName $computer -Path "/rest/system" -Port $Port -Method Get } catch { Stop-PSFFunction -EnableException:$EnableException -Message "Failure connecting to $computer" -ErrorRecord $_ -Continue } if ($nonauthsession) { $cookietoken = $nonauthsession.Cookies.GetCookies("https://$computer").Value } $body = @{ username = "admin" password = "admin" a = $first.timestamp b = $cookietoken } | ConvertTo-Json } else { $body = @{ releaseSession = "FALSE" } | ConvertTo-Json } $headers = @{"HTTP" = "X-SecurityCenter" } $RestMethodParams = @{ Headers = $headers ContentType = "application/json" Method = 'POST' URI = $fulluri Body = $body ErrorVariable = 'NessusLoginError' SessionVariable = 'websession' } } else { $Uri = "https://$($computer):$Port" $fulluri = "$uri/session" if ($PSBoundParameters.Credential) { $body = @{'username' = $Credential.UserName; 'password' = $Credential.GetNetworkCredential().password } } else { $body = $null } $RestMethodParams = @{ Method = 'Post' URI = $fulluri Body = $body ErrorVariable = 'NessusLoginError' SessionVariable = 'websession' } } try { $token = Invoke-RestMethod @RestMethodParams -ErrorAction Stop } catch { $msg = Get-ErrorMessage -Record $_ if ($msg -eq "The remote server returned an error: (401) Unauthorized") { $msg = "The remote server returned an error: (401) Unauthorized. This is likely due to a bad username/password" } Stop-PSFFunction -EnableException:$EnableException -Message "$msg $_" -ErrorRecord $_ -Continue } if ($token) { if ($PSBoundParameters.Credential) { $username = $Credential.UserName } else { $username = $null } $usertoken = $token.token if (-not $usertoken) { $usertoken = $token.response.token } if ($sc) { $headers = @{ "X-SecurityCenter" = $usertoken } } else { $headers = @{ "X-Cookie" = "token=$usertoken" } } $session = [PSCustomObject]@{ URI = $uri UserName = $username ComputerName = $computer Credential = $Credential Token = $usertoken Headers = $headers SessionId = $script:NessusConn.Count WebSession = $websession Sc = $sc Bound = $PSBoundParameters ServerType = $Type ServerVersion = $null ServerVersionMajor = $null MultiUser = $null } $oldsession = $script:NessusConn | Where-Object { $PSItem.Uri -eq $uri -and $PSItem.Username } if ($oldsession) { $null = $script:NessusConn.Remove($oldsession) } $null = $script:NessusConn.Add($session) $info = Get-TNServerInfo -SessionId $id $script:NessusConn[$($script:NessusConn.Count) - 1].MultiUser = ($info.capabilities.multi_user -eq 'full' -or $sc) $script:NessusConn[$($script:NessusConn.Count) - 1].ServerVersion = $info.UIVersion $script:NessusConn[$($script:NessusConn.Count) - 1].ServerVersionMajor = ([version]($info.UIVersion | Select-Object -First 1)).Major $session | Select-DefaultView -Property SessionId, UserName, URI, ServerType } } } } |