SAM.DoDCyberExchange.psm1
# [Variables] ----------------------------------------------------------------------------------------------------- $SAMRoot = $PSScriptRoot $SAMHtmlAgilityPackDllPath = [IO.Path]::Combine("$SAMRoot", 'Libraries', 'HTMLAgilityPack', 'Net45', 'HtmlAgilityPack.dll') $DoDCyberExchangeUrls = @{ DocumentLibrary = "https://public.cyber.mil/stigs/downloads/" SCAPs = "https://public.cyber.mil/stigs/scap/" STIGTools = "https://public.cyber.mil/stigs/srg-stig-tools/" Compilations = "https://public.cyber.mil/stigs/compilations/" GPOs = "https://public.cyber.mil/stigs/gpo/" Automation = "https://public.cyber.mil/stigs/supplemental-automation-content/" CCI = "https://public.cyber.mil/stigs/cci/" Sunset = "https://public.cyber.mil/stigs/sunset-products/" } $certCallback = @" using System; using System.Net; using System.Net.Security; using System.Security.Cryptography.X509Certificates; public class ServerCertificateValidationCallback { public static void Ignore() { if(ServicePointManager.ServerCertificateValidationCallback ==null) { ServicePointManager.ServerCertificateValidationCallback += delegate ( Object obj, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors ) { return true; }; } } } "@ # [Functions] ----------------------------------------------------------------------------------------------------- function Get-CECompilation { <# .SYNOPSIS Get current STIG Compilation from public.cyber.mil .DESCRIPTION Get current STIG Compilation from public.cyber.mil. If you need the CUI Compilation you will need to log into the website to download. .EXAMPLE PS C:\> Get-CECompilation This example demonstrates how to pull the STIG compilations for DoD Cyber Exchange. #> [CmdletBinding()] [OutputType([System.Management.Automation.PSCustomObject])] param ( # Skips certificate validation checks. This includes all validations such as expiration, revocation, trusted root authority, etc. Using this parameter is not secure and is not recommended. This switch is only intended to be used against known hosts using a self-signed certificate for testing purposes or a trusted website with an expired certificate. Use at your own risk. [Parameter()] [Switch] $SkipCertificateCheck ) end { $params = @{ Section = 'Compilations' } if ($PSBoundParameters.SkipCertificateCheck) { $params.add('SkipCertificateCheck', $true) } Get-CEItem @params | Where-Object { $_.FileName -and $_.FileType -eq "zip" } } } function Get-CEComplianceChecker { <# .SYNOPSIS Retrieve list of available downloads for SCAP Compliance Checker (SCC) .DESCRIPTION Retrieve list of available downloads for SCAP Compliance Checker (SCC). .EXAMPLE PS C:\> Get-CEComplianceChecker -Type Windows This example demonstrates how to pull the Windows SCC files from DoD Cyber Exchange. .EXAMPLE PS C:\> Get-CEComplianceChecker -Type Windows -OtherFiles Checksums This example demonstrates how to pull the Windows SCC files and the Checksums from DoD Cyber Exchange. .EXAMPLE PS C:\> Get-CEComplianceChecker -Type All -OtherFiles All This example demonstrates how to pull All SCC Installs and Support Files from DoD Cyber Exchange. #> [CmdletBinding()] [OutputType([System.Management.Automation.PSCustomObject])] param ( # Specify the SCAP Compliance Checker (SCC) Type to download. Options are All, Windows, Redhat, Ubuntu, Mac, Solaris, and Raspbian [Parameter()] [ValidateSet('Windows', 'Redhat', 'Ubuntu', 'Mac', 'Solaris', 'Raspbian', 'All')] [String[]] $Type, # Specify additional support files to download. Options are Unlocker Bundle, Checksums, UnixRemoteScanningPlugin, ReleaseNotes, Readme, RPM-GPG-KEY. [Parameter()] [ValidateSet('UnlockerBundle', 'Checksums', 'UnixRemoteScanningPlugin', 'ReleaseNotes', 'Readme', 'RPM-GPG-KEY', 'All')] [String[]] $OtherFiles, # Skips certificate validation checks. This includes all validations such as expiration, revocation, trusted root authority, etc. Using this parameter is not secure and is not recommended. This switch is only intended to be used against known hosts using a self-signed certificate for testing purposes or a trusted website with an expired certificate. Use at your own risk. [Parameter()] [Switch] $SkipCertificateCheck ) begin { $items = @() $params = @{ Section = 'SCAPs' } if ($PSBoundParameters.SkipCertificateCheck) { $params.add('SkipCertificateCheck', $true) } $files = Get-CEItem @params } process { $items += $Type | ForEach-Object { switch ($_) { 'Windows' { $files | Where-Object { $_.FileName.ToLower() -match "^scc-\d.\d_windows" } } 'Redhat' { $files | Where-Object { $_.FileName.ToLower() -match "^scc-\d.\d_rhel" } } 'Ubuntu' { $files | Where-Object { $_.FileName.ToLower() -match "^scc-\d.\d_ubuntu" } } 'Mac' { $files | Where-Object { $_.FileName.ToLower() -match "^scc-\d.\d_mac" } } 'Solaris' { $files | Where-Object { $_.FileName.ToLower() -match "^scc-\d.\d_solaris" } } 'Raspbian' { $files | Where-Object { $_.FileName.ToLower() -match "^scc-\d.\d_raspbian" } } 'All' { $files | Where-Object { $_.FileName.ToLower() -match "^scc-\d.\d_(windows|ubuntu|rhel|mac|raspbian|sol)" } } } } } end { $items += $OtherFiles | ForEach-Object { switch ($_) { 'UnlockerBundle' { $files | Where-Object { $_.FileName.ToLower() -match "^scc(-|_)\d.\d_unlocker" } } 'Checksums' { $files | Where-Object { $_.FileName.ToLower() -match "^scc(-|_)\d.\d_checksums" } } 'UnixRemoteScanningPlugin' { $files | Where-Object { $_.FileName.ToLower() -match "^scc(-|_)\d.\d_unix_remote" } } 'ReleaseNotes' { $files | Where-Object { $_.FileName.ToLower() -match "^scc(-|_)\d.\d_releasenotes" } } 'Readme' { $files | Where-Object { $_.FileName.ToLower() -match "^scc(-|_)\d.\d_readme" } } 'RPM-GPG-KEY' { $files | Where-Object { $_.FileName.ToLower() -match "^rpm-gpg-key-scc" } } 'All' { $files | Where-Object { $_.FileName.ToLower() -match "^rpm-gpg-key-scc|^scc(-|_)\d.\d_(unlocker|checksums|unix_remote|releasenotes|readme)" } } } } Write-Output $items } } function Get-CEItem { <# .SYNOPSIS Retrieve list of all files from a specific Cyber Exchange URL. .DESCRIPTION Retrieve list of all files from a specific Cyber Exchange URL. The function calls the URL and looks for any tables on the page that would list files. This function only works with the public.cyber.mil website, for items that require a CAC to download you will have to log in via the web browser and download manually. Useful URLS Document Library: https://public.cyber.mil/stigs/downloads/ SCAPs: https://public.cyber.mil/stigs/scap/ STIG/SRG Tools: https://public.cyber.mil/stigs/srg-stig-tools/ Compilations: https://public.cyber.mil/stigs/compilations/ GPOs: https://public.cyber.mil/stigs/gpo/ Automation: https://public.cyber.mil/stigs/supplemental-automation-content/ CCI: https://public.cyber.mil/stigs/cci/ Sunset: https://public.cyber.mil/stigs/sunset-products/c= .EXAMPLE PS C:\> Get-CEItem This example demonstrates how to call the function in its default configuration. When called by itself, the function will query the downloads section of DoD Cyber Exchange. .EXAMPLE PS C:\> Get-CEItem -Section compilations This example demonstrates how to pull the STIG compilations for DoD Cyber Exchange. #> [CmdletBinding()] [OutputType([System.Management.Automation.PSCustomObject])] param ( # Specifies the Cyber.Mil Site Section to retrieve file list from. The default value is 'DocumentLibrary' which is the main list of items to download. Other options are "SCAPs","STIGTools","Compilations","GPOs","Automation","CCI","Sunset". [Parameter()] [ValidateSet( "DocumentLibrary", "SCAPs", "STIGTools", "Compilations", "GPOs", "Automation", "CCI", "Sunset" )] [String] $Section = 'DocumentLibrary', # Skips certificate validation checks. This includes all validations such as expiration, revocation, trusted root authority, etc. Using this parameter is not secure and is not recommended. This switch is only intended to be used against known hosts using a self-signed certificate for testing purposes or a trusted website with an expired certificate. Use at your own risk. [Parameter()] [Switch] $SkipCertificateCheck ) begin { Import-HtmlAgilityPack } end { try{ $params = @{ URI = $DoDCyberExchangeUrls.$Section Method = 'Get' ErrorAction = 'Stop' } if ($PSBoundParameters.SkipCertificateCheck) { if ($PSVersionTable.PSVersion.Major -gt 5) { $params.Add('SkipCertificateCheck', $true) } else { Add-Type $certCallback [ServerCertificateValidationCallback]::Ignore() } } Write-Verbose "Retrieving list from: $($params.URI)" $response = Invoke-WebRequest @params if ($response.StatusCode -eq '200') { $htmlDoc = New-Object HtmlAgilityPack.HtmlDocument $htmlDoc.LoadHtml($response.rawcontent) $htmlDoc.DocumentNode.SelectNodes('//tr[@class="file"]') | ForEach-Object { [XML]$list = $($_.OuterHtml -replace "—| ") [String]$uri = "" [String]$fileType = "" [String]$fileName = "" [String]$msg = "" $link = $list.SelectNodes("//td[@class='title_column']").A.href $size = $list.SelectNodes("//td[@class='size_column']").'#Text' # When looking through list it was found that some items that dont have downloads, have a message nested in the title. if ($link) { $uri = $link.Trim() $fileType = $($link -split "/")[-1].Split('.')[-1] $fileName = $($link -split "/")[-1] } else { $msg = $list.SelectNodes("//td[@class='title_column']").div."#text".Trim() } [PSCustomObject]@{ Name = $list.SelectNodes("//td[@class='title_column']/span[@style='display:none;']").'#text'.Trim() URI = $uri FileName = $fileName FileType = $fileType Size = $(If ($size.Length -gt "0") { $size.trim() }else { "---" }) Published = $list.SelectNodes("//td[@class='updated_column']").div."#text" Message = $msg } } } else { Throw $response.StatusCode } }catch{ Throw $_ } } } function Get-CEScapBenchmark { <# .SYNOPSIS Retrieves a list of SCAP Benchmarks from Cyber.mil .DESCRIPTION Retrieves a list of SCAP Benchmarks from Cyber.mil using the Get-CEItem function. .EXAMPLE PS C:\> Get-CEScapBenchmark | Save-CEItem -Destination C:\Temp\SCAPS This example shows the default method to call the function. It pipes the output to Save-CEItem to download the file. #> [CmdletBinding()] [OutputType([System.Management.Automation.PSCustomObject])] param ( # Skips certificate validation checks. This includes all validations such as expiration, revocation, trusted root authority, etc. Using this parameter is not secure and is not recommended. This switch is only intended to be used against known hosts using a self-signed certificate for testing purposes or a trusted website with an expired certificate. Use at your own risk. [Parameter()] [Switch] $SkipCertificateCheck ) end { $params = @{ Section = 'DocumentLibrary' } if ($PSBoundParameters.SkipCertificateCheck) { $params.add('SkipCertificateCheck', $true) } Get-CEItem @params | Where-Object { $_.FileType -eq "zip" -and $_.FileName -Like "*_Benchmark.zip" } } } function Get-CEStig { <# .SYNOPSIS Retrieves a list of STIG/SRG List from public.cyber.mil. .DESCRIPTION Retrieves a list of STIG/SRG List from public.cyber.mil using the Get-CEItem function. This function also includes all the Sunset STIGs. .EXAMPLE PS C:\> Get-CEStig | Save-CEItem -Destination C:\Temp\STIGs This example shows the default method to call Get-CEStig. It pipes the output to Save-CEItem to download the file. #> [CmdletBinding()] [OutputType([System.Management.Automation.PSCustomObject])] param ( # Skips certificate validation checks. This includes all validations such as expiration, revocation, trusted root authority, etc. Using this parameter is not secure and is not recommended. This switch is only intended to be used against known hosts using a self-signed certificate for testing purposes or a trusted website with an expired certificate. Use at your own risk. [Parameter()] [Switch] $SkipCertificateCheck ) end { $exclude = "UNIX_Remote_Scanning|RPM-GPG-KEY|scc-|Draft|Overview|BENCHMARK|STIGViewer|STIGApplicabilityGuide|CCI|Library|Ansible|GPO|Configuration_Files|Audit|Chef|Test" $params = @{ Section = 'DocumentLibrary' } if ($PSBoundParameters.SkipCertificateCheck) { $params.add('SkipCertificateCheck', $true) } Get-CEItem @params | Where-Object { $_.FileName -and $_.FileName.ToLower() -notmatch $exclude.ToLower() -and $_.FileType -eq "zip" } } } function Get-CEStigViewer { <# .SYNOPSIS Get Current STIGViewer Published. .DESCRIPTION Get-Current STIGViewer Published. DISA has produced standalone versions of STIG Viewer for the Windows, Linux, and macOS platforms on 64-bit x86 processors. With the end of free support for Java 8 in early 2019, Oracle Corporation changed the licensing and distribution model for Java software. Users without supported Java 8 SE environments should use the standalone versions of STIG Viewer. Users with supported Java 8 SE environments may still use the current JAR file. .EXAMPLE PS C:\> Get-CEStigViewer This example demonstrates how to pull the current STIGViewer for DoD Cyber Exchange. Name : STIG Viewer 2.14 URI : https://dl.dod.cyber.mil/wp-content/uploads/stigs/zip/U_STIGViewer_2-14.zip FileName : U_STIGViewer_2-14.zip FileType : zip Size : 712.99 KB Published : 22 Apr 2021 Message : .EXAMPLE PS C:\> Get-CEStigViewer -Type All -IncludeUserGuide | Save-CEItem -Destination C:\Temp This example demonstrates how to pull all types along with the StigViewer User Guide. Once the list is pulled its passed to Save-CEItem to download the files. #> [CmdletBinding()] [OutputType([System.Management.Automation.PSCustomObject])] param ( # Specify the STIGViewer Type to download. Default is the Java version. If Java is not installed on the end devices then select either Windows, Mac, or Linux. These distributions have java packaged with them so there is not need to install java. If you require all versions select all. [Parameter()] [ValidateSet('Windows', 'Linux', 'Mac', 'All', "Java")] [String] $Type = "Java", # Specify if the user guides should be downloaded as well. [Parameter()] [Switch] $IncludeUserGuide, # Skips certificate validation checks. This includes all validations such as expiration, revocation, trusted root authority, etc. Using this parameter is not secure and is not recommended. This switch is only intended to be used against known hosts using a self-signed certificate for testing purposes or a trusted website with an expired certificate. Use at your own risk. [Parameter()] [Switch] $SkipCertificateCheck ) end { $items = @() $params = @{ Section = 'STIGTools' } if ($PSBoundParameters.SkipCertificateCheck) { $params.add('SkipCertificateCheck', $true) } $files = Get-CEItem @params switch ($Type) { "Java" { $items += $files | Where-Object { $_.FileName -match "U_STIGViewer_\d{1,2}-\d{1,2}.zip" }} "Windows" { $items += $files | Where-Object { $_.FileName -match "U_STIGViewer_\d{1,2}-\d{1,2}_Win64.zip" }} "Mac" { $items += $files | Where-Object { $_.FileName -match "U_STIGViewer_\d{1,2}-\d{1,2}_Mac.zip" }} "Linux" { $items += $files | Where-Object { $_.FileName -match "U_STIGViewer_\d{1,2}-\d{1,2}_Linux.zip" }} "All" { $items += $files | Where-Object { $_.FileName -match "U_STIGViewer_\d{1,2}-\d{1,2}(|_Linux|_Mac|_Win64).zip"}} } if ($IncludeUserGuide) { $items += $files | Where-Object { $_.FileName -match "U_STIG_Viewer_\d{1,2}-x_User_Guide_V\d{1,2}R\d{1,2}.pdf" } } Write-Output $items } } function Save-CEItem { <# .SYNOPSIS Save a file from Cyber Exchange .DESCRIPTION Takes the object from Get-CEItem and saves it to a location specified. .EXAMPLE PS C:\> Save-CEItem -Destination "C:\Temp" -URI "https://dl.dod.cyber.mil/wp-content/uploads/stigs/zip/U_STIGViewer_2-14.zip" This example shows how to call Save-CEItem and Save a file. .EXAMPLE PS C:\> Get-CEItem -Section GPOs | Save-CEItem -Destination "C:\Temp" This example shows the Get-CEItem function pulling a list of GPOs and it pipes the output to Save-CEItem to download the files. #> [CmdletBinding()] [OutputType([System.Void])] param ( # Specifies the destination to save the file to. [Parameter(Mandatory, Position = 0)] [String] $Destination, # Specifies the URL for the file to download from public.cyber.mil [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [string[]] $URI, # Skips certificate validation checks. This includes all validations such as expiration, revocation, trusted root authority, etc. Using this parameter is not secure and is not recommended. This switch is only intended to be used against known hosts using a self-signed certificate for testing purposes or a trusted website with an expired certificate. Use at your own risk. [Parameter()] [Switch] $SkipCertificateCheck ) begin { $currentProgressPreference = $ProgressPreference $ProgressPreference = 'SilentlyContinue' if (-not (Test-Path $Destination)) { New-Item -Path $Destination -ItemType Directory | Out-Null } } process { $URI | ForEach-Object { $fileName = ($_ -split "/")[-1] $saveTo = Join-Path -Path $Destination -ChildPath $fileName $params = @{ URI = $_ OutFile = $saveTo } if ($PSBoundParameters.SkipCertificateCheck) { if ($PSVersionTable.PSVersion.Major -gt 5) { $params.Add('SkipCertificateCheck', $true) } else { Add-Type $certCallback [ServerCertificateValidationCallback]::Ignore() } } Invoke-WebRequest @params } } end { $ProgressPreference = $currentProgressPreference } } function Import-HtmlAgilityPack { <# .SYNOPSIS Imports HtmlAgilityPack Assembly .DESCRIPTION Checks to see if HtmlAgilityPack is loaded and if not it imports the Assembly. This function is not ment to be call by a user, its best to call this function in the begin block. .LINK https://html-agility-pack.net .EXAMPLE Begin{ Import-HtmlAgilityPack } This example shows how the private function can be used within functions that require the HtmlAgilityPack. #> [CmdletBinding()] [OutputType([System.Void])] param () # Added to support Pester Testing of Private functions if ($MyInvocation.MyCommand.Module) { $dllPath = $SAMHtmlAgilityPackDllPath } else { $rootPath = Split-Path -Path $PSScriptRoot -Parent $dllPath = [IO.Path]::Combine("$rootPath", 'Libraries', 'HTMLAgilityPack', 'Net45', 'HtmlAgilityPack.dll') } $assemblies = [System.AppDomain]::CurrentDomain.GetAssemblies() | Where-Object { $_.Location } if ($assemblies.locations -notcontains $dllPath) { Add-Type -Path $dllPath } } |