├── LICENSE ├── README.md ├── delete-remote-deployment-files ├── README.md └── delete-remote-deployment-files.ps1 ├── password-expiration-report ├── README.md └── password-expiration-report.ps1 ├── printer-auth-report ├── README.md └── printer-auth-report.ps1 ├── printer-telnet-ftp-report ├── README.md └── printer-telnet-ftp-report.ps1 └── remote-bitlocker-encryption-report ├── README.md └── remote-bitlocker-encryption-report.ps1 /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # netsec-ps-scripts 2 | Collection of PowerShell network security scripts for system administrators. 3 | 4 | All scripts were tested in PowerShell 5.1 on Windows 10 unless specified. Please let me know if you encounter any issues on other systems. 5 | 6 | **Please read the README file in each folder before running any scripts.** 7 | 8 | ## Scripts 9 | #### [delete-remote-deployment-files](delete-remote-deployment-files) 10 | * Find and delete leftover deployment files with potential passwords. 11 | 12 | #### [password-expiration-report](password-expiration-report) 13 | * Audit accounts that never expire, password expiration dates and password last set dates. 14 | 15 | #### [printer-auth-report](printer-auth-report) 16 | * Find network printers that don't require authentication to the admin web interface. 17 | 18 | 19 | #### [printer-telnet-ftp-report](printer-telnet-ftp-report) 20 | * Find network printers that have telnet or FTP enabled. 21 | 22 | #### [remote-bitlocker-encryption-report](remote-bitlocker-encryption-report) 23 | * Bitlocker hardware encryption vulnerability mitigation. (CVE-2018-12038) 24 | 25 | ## Contribution 26 | 27 | Contributions are welcomed! Simply do a pull request and it will be reviewed. 28 | 29 | If you're creating a new script, create a folder and respect the current naming convention. 30 | 31 | **Please submit any features or ideas you would like to see implemented as an issue! Feedback is always welcomed.** 32 | -------------------------------------------------------------------------------- /delete-remote-deployment-files/README.md: -------------------------------------------------------------------------------- 1 | # delete-remote-deployment-files 2 | 3 | This script will look for files that were not deleted properly during Windows images deployments from MDT and delete them. 4 | 5 | **Use the `-Verbose` parameter for verbose output** 6 | 7 | ## Possible security issue with MDT deployments 8 | 9 | The MDT deployment process creates the `C:\MININT` folder during the Windows imaging process which contains an `unattend.xml` file. This file can contain the following passwords: 10 | * An [AdministratorPassword](https://docs.microsoft.com/en-us/windows-hardware/customize/desktop/unattend/microsoft-windows-shell-setup-useraccounts-administratorpassword) element. 11 | * A [Password](https://docs.microsoft.com/en-us/windows-hardware/customize/desktop/unattend/microsoft-windows-shell-setup-useraccounts-localaccounts-localaccount-password) element which specifies the password for a [LocalAccount](https://docs.microsoft.com/en-us/windows-hardware/customize/desktop/unattend/microsoft-windows-shell-setup-useraccounts-localaccounts-localaccount) to be created. 12 | * A [Password](https://docs.microsoft.com/en-us/windows-hardware/customize/desktop/unattend/microsoft-windows-shell-setup-autologon-password) element for the [AutoLogon](https://docs.microsoft.com/en-us/windows-hardware/customize/desktop/unattend/microsoft-windows-shell-setup-autologon) account. 13 | 14 | The [PlainText](https://docs.microsoft.com/en-us/windows-hardware/customize/desktop/unattend/microsoft-windows-shell-setup-autologon-password-plaintext) element (which applies to all elements mentionned above) can be set to `true` or `false`. But even if it is set to `false`, the password is not actually encrypted. It is simply encoded as a Base64 string which can easily be decoded. 15 | 16 | Normally, this folder should be deleted at the end of the imaging process. In reality, many system administrators have reported certain deployments failing to delete this folder. 17 | 18 | This script attempts to remediate this issue by scanning a list of hosts for the `C:\MININT` folder and deleting it if you wish. It will then generate a CSV report. 19 | 20 | ## How to use 21 | 22 | Simply run the script with administrator credentials. 23 | 24 | ```PowerShell 25 | ./delete-remote-deployment-files.ps1 26 | [-ComputerList] 27 | [-ReportPath] 28 | [-DeleteFolder] 29 | ``` 30 | 31 | ### Parameters 32 | All the following parameters are optional. 33 | 34 | `-ComputerList` : Path of the list of computers to scan. Defaults to `computers.txt` in the script's folder. 35 | 36 | `-ReportPath` : Path where to output the report. Defaults to `report.csv` in the script's folder. 37 | 38 | `-DeleteFolder` : Use this flag to delete `C:\MININT`. By default it will not be deleted. 39 | -------------------------------------------------------------------------------- /delete-remote-deployment-files/delete-remote-deployment-files.ps1: -------------------------------------------------------------------------------- 1 | # Parameters 2 | param( 3 | [string] $ComputerList = $(Join-Path -Path $PSScriptRoot -ChildPath "computers.txt"), # Path to the list of computers 4 | [string] $ReportPath = $(Join-Path -Path $PSScriptRoot -ChildPath "report.csv"), # Path to the report to output 5 | [switch] $DeleteFolder = $false # Whether to delete MININT or not 6 | ) 7 | 8 | # Constants 9 | $ErrorActionPreference = 'Stop' 10 | $Computers = Get-Content $ComputerList 11 | 12 | # Initialise the report array, including the first line 13 | $report = @() 14 | $report += ,@("Hostname","Could Connect?", "Found MININT?", "Deleted MININT?") 15 | 16 | # Loop through each computer 17 | $Computers | ForEach-Object{ 18 | 19 | Write-Verbose -Verbose -Message "Connecting to $_ ..." 20 | 21 | # Initialise variables 22 | $could_connect = $null 23 | $found_minint = $null 24 | $deleted_minint = $null 25 | 26 | # Find C:\MININT 27 | Try{ 28 | $minint_folder = Get-ChildItem -Force \\$_\c$ -ErrorAction Stop | Where-Object { $_.Name -eq "MININT"} # Try Get-Childitem remotely 29 | $could_connect = $true # If it succeeds, set $could_connect to $true 30 | } 31 | Catch { # If it fails, we know we can't connect 32 | $could_connect = $false # Set $could_connect to $false 33 | } 34 | 35 | if($minint_folder -eq $null -or $could_connect -eq $false){ # If we didn't find C:\MININT or couldn't connect 36 | $found_minint = $false # Set $found_minint to $false 37 | } 38 | else{ # If we found C:\MININT 39 | $found_minint = $true # Set $found_minint to $true 40 | } 41 | 42 | # Delete C:\MININT 43 | if($could_connect -and $DeleteFolder){ # If we could connect and the DeleteFolder parameter is set 44 | Try{ 45 | Write-Verbose -Verbose -Message "Deleting C:\MININT folder ..." 46 | Remove-Item \\$_\c$\MININT -Force # Delete C:\MININT 47 | $deleted_minint = $true # If it worked 48 | } 49 | Catch{ 50 | $deleted_minint = $false # If it failed 51 | } 52 | } 53 | else{ 54 | $deleted_minint = $false 55 | } 56 | 57 | # Append report with data 58 | $report += ,@($_,$could_connect, $found_minint, $deleted_minint) 59 | 60 | Write-Verbose -Verbose -Message "Done with $($_)." 61 | } 62 | 63 | # Output CSV 64 | Add-Content $ReportPath -Value "SEP=," # Write out the first line 65 | $report | % { $_ -join ","} | Out-File $ReportPath -Append # Write out the rest of the report 66 | -------------------------------------------------------------------------------- /password-expiration-report/README.md: -------------------------------------------------------------------------------- 1 | # password-expiration-report 2 | 3 | This script will generate an audit report on accounts with passwords that never expire, password expiration dates and password last set dates. 4 | 5 | This script can be used to audit password policies and make sure they are applied properly. It can also be used to audit users in groups with special password policies in your organization, such as users used by specific softwares or Exchange mailboxes for example. 6 | 7 | **This script is currently a WIP.** 8 | - Needs to be cleaned up 9 | - Needs more comments 10 | - Verbose will be added soon (currently the only output is the report) 11 | 12 | ## How to use 13 | 14 | Simply run the script with admin credentials. 15 | 16 | ```PowerShell 17 | ./password-expiration-report.ps1 18 | [-ADGroup] 19 | [-ReportPath] 20 | ``` 21 | 22 | ### Parameters 23 | All the following parameters are optional. 24 | 25 | `-ADGroup` : The AD group you want to run the report on. Defaults to all of Active Directory. (Optional) 26 | 27 | `-ReportPath` : Path where to output the report. Defaults to `report.csv` in the script's folder. (Optional) 28 | -------------------------------------------------------------------------------- /password-expiration-report/password-expiration-report.ps1: -------------------------------------------------------------------------------- 1 | # Parameters 2 | param( 3 | [string] $ADGroup, # Path to the report to output 4 | [string] $ReportPath = $(Join-Path -Path $PSScriptRoot -ChildPath "report.csv") # Path to the report to output 5 | ) 6 | 7 | $report = @() 8 | $report += ,@("Name", "SamAccountName", "PasswordNeverExpires", "PasswordExpired", "PasswordLastSet") 9 | $total_accounts = 0 10 | $never_expires = 0 11 | 12 | # Whether we're applying to one group or all of Active Directory 13 | If(-not $ADGroup){ 14 | $user_list = Get-ADUser -Filter * -Properties * 15 | } 16 | Else{ 17 | $user_list = Get-ADGroupMember $ADGroup | Get-ADUser -Properties * 18 | } 19 | 20 | 21 | $user_list | Select Name, SamAccountName, PasswordNeverExpires, PasswordExpired, PasswordLastSet | ForEach-Object{ 22 | 23 | $report += ,@("`"$($_.Name)`"", $_.SamAccountName, $_.PasswordNeverExpires, $_.PasswordExpired, $_.PasswordLastSet) 24 | 25 | $total_accounts += 1 26 | if($_.passwordNeverExpires -eq "true"){ 27 | $never_expires += 1 28 | } 29 | 30 | 31 | } 32 | 33 | 34 | $report += ,@() 35 | $report += ,@("Number of accounts",$total_accounts) 36 | $report += ,@("Accounts never expiring",$never_expires) 37 | $report += ,@("Percentage never expiring",$(($never_expires / $total_accounts) * 100 )) 38 | 39 | Add-Content $ReportPath -Value "SEP=," # Write out the first line 40 | $report | % { $_ -join ","} | Out-File $ReportPath -Append # Write out the rest of the report 41 | -------------------------------------------------------------------------------- /printer-auth-report/README.md: -------------------------------------------------------------------------------- 1 | # printer-auth-report 2 | 3 | Find network printers that don't require authentication to the configuration web interface. 4 | 5 | **Use the `-Verbose` parameter for verbose output** 6 | 7 | **Requires PowerShell Core 6** ⚠️ 8 | 9 | ## How it works 10 | 11 | First, the script will get all the printers from the servers in the file supplied by the optional `-PrintServerList` parameter through a WMI request. 12 | 13 | It will then test if the configuration web interface requires authentication on each printer. Different printers having different configuration interfaces, we need to test them all. It does so by doing an unauthenticated web request on all web paths in the file supplied by the optional `-TestPathList` parameter. This file is simply the list of login pages for each printer models in your network (see example at the bottom). 14 | 15 | **The script expects each printers to return at least one `401 Unauthorized` HTTP return code to consider the printer as secured.** It will consider the printer to be unsecured if it receives any `200 OK` HTTP status codes. Certain printer models don't have any pages that would return a 401 code, so those would be marked as "Needs manual review" in the final report. 16 | 17 | After having scanned all printers, it will output the hostname, IP, whether the printer is reachable and whether it is secured as a CSV file to the path supplied by `-ReportPath`. 18 | 19 | ## How to use 20 | 21 | Simply download the script and run it from the PowerShell command line like so : 22 | 23 | ```PowerShell 24 | ./printer-auth-report.ps1 25 | [-PrintServerList] 26 | [-TestPathList] 27 | [-ReportPath] 28 | [-UseHTTPS] 29 | ``` 30 | 31 | Here's an example : 32 | ```PowerShell 33 | ./printer-auth-report.ps1 -PrintServerList ./servers.txt -TestPathList ./testpath.txt 34 | ``` 35 | 36 | You will need the rights to do WMI requests on each print servers to run the script. 37 | 38 | ### Parameters 39 | 40 | `-PrintServerList` : The list of print servers to get printers from. (Required) 41 | 42 | `-TestPathList` : The list of web paths to be tested. (Required) 43 | 44 | `-ReportPath` : The path of the CSV report to output. The default is `./report.csv` (Optional) 45 | 46 | `-UseHTTPS` : You can supply this parameter to force the requests to be done over HTTPS instead of HTTP. (Optional) 47 | 48 | ### Text file examples 49 | 50 | Here are some examples of what the text files needed could look like. 51 | 52 | #### `-PrintServerList ` 53 | ``` 54 | printserv1 55 | printserv2 56 | ``` 57 | #### `-TestPathList ` 58 | ``` 59 | login.html 60 | config/index.html?content=security 61 | webAccess/adminpanel.htm 62 | ``` 63 | 64 | ### Report example 65 | 66 | Here's an example of what the CSV report will look like : 67 | 68 | ``` 69 | Server,Hostname,IP,Reachable?,Requires authentication? 70 | printserv1,printer_1,10.0.0.2,TRUE,Secure 71 | printserv2,printer_2,10.0.0.3,FALSE,Unreachable 72 | ``` 73 | -------------------------------------------------------------------------------- /printer-auth-report/printer-auth-report.ps1: -------------------------------------------------------------------------------- 1 | # Parameters 2 | param( 3 | [Parameter(Mandatory=$True)] [string] $PrintServerList, # Path to the list of print servers 4 | [Parameter(Mandatory=$True)] [string] $TestPathList, # Path 5 | [string] $ReportPath = $(Join-Path -Path $PSScriptRoot -ChildPath "report.csv"), # Path to the report to output 6 | [switch] $UseHTTPS = $false 7 | ) 8 | 9 | # Constants 10 | $PrintServers = Get-Content $PrintServerList 11 | $TestPaths = Get-Content $TestPathList 12 | If($UseHTTPS){ 13 | $Protocol = "https" 14 | } 15 | Else{ 16 | $Protocol = "http" 17 | } 18 | 19 | # Initialise the report array, including the first line 20 | $report = @() 21 | $report += ,@("Server","Hostname","IP", "Reachable?", "Requires authentication?") 22 | 23 | # Get list of printers 24 | $printers = @() 25 | Try{ 26 | $PrintServers | ForEach-Object{ 27 | $server = $_ 28 | Get-CimInstance -ClassName Win32_Printer -ComputerName $server | ForEach-Object{ 29 | $printers += , @($_.Name, $($_.PortName).Replace('..','.'), $server) 30 | } 31 | } 32 | } 33 | Catch{ 34 | Write-Error $_ 35 | } 36 | 37 | # Test all printers 38 | $printers | Foreach-Object{ 39 | 40 | $printer_name, $printer_ip, $printer_server = $_ 41 | $printer_reachable = $null 42 | $printer_secured = $null 43 | $return_codes = @() 44 | 45 | Write-Verbose -Verbose -Message "=== Testing $printer_name at $printer_ip ===" 46 | 47 | If(Test-Connection -Computername $printer_ip -Count 1 -Quiet -InformationAction Ignore ){ 48 | Write-Verbose -Verbose -Message "Reached $printer_name at $printer_ip" 49 | $printer_reachable = $true 50 | 51 | # Test all web paths 52 | $TestPaths | ForEach-Object{ 53 | 54 | 55 | $query_url = "$($Protocol)://$printer_ip/$_" 56 | Write-Verbose -Verbose -Message "Testing $printer_name at $query_url" 57 | 58 | try { 59 | $response = Invoke-WebRequest -URI $query_url -SkipCertificateCheck -MaximumRedirect 0 60 | $status_code = [int]$response.StatusCode 61 | if($status_code -eq 0){ 62 | $status_code = 200 63 | } 64 | } 65 | catch { 66 | $status_code = [int]$_.Exception.Response.StatusCode 67 | } 68 | 69 | $return_codes += , $status_code 70 | Write-Verbose -Verbose -Message "$query_url returned HTTP $status_code" 71 | 72 | } 73 | 74 | If($return_codes.Contains(401)){ 75 | $printer_secured = 'Secure' 76 | } 77 | Elseif($return_codes.Contains(200)){ 78 | $printer_secured = 'Unsecured' 79 | } 80 | Else{ 81 | $printer_secured = 'Needs Manual Review' 82 | } 83 | 84 | } 85 | Else{ 86 | Write-Verbose -Verbose -Message "Couldn't reach $printer_name at $printer_ip" 87 | $printer_reachable = $false 88 | $printer_secured = 'Unreachable' 89 | } 90 | 91 | $report += ,@($printer_server, $printer_name,$printer_ip, $printer_reachable, $printer_secured) 92 | } 93 | 94 | Write-Verbose -Verbose -Message "=== Generating CSV report to $ReportPath ===" 95 | # Create the CSV report 96 | Add-Content $ReportPath -Value "SEP=," # Write out the first line 97 | $report | % { $_ -join ","} | Out-File $ReportPath -Append # Write out the rest of the report 98 | Write-Verbose -Verbose -Message "Done!" 99 | $printer_reachable = $true 100 | 101 | # Test all web paths 102 | $TestPaths | ForEach-Object{ 103 | 104 | 105 | $query_url = "$($Protocol)://$printer_ip/$_" 106 | Write-Verbose -Verbose -Message "Testing $printer_name at $query_url" 107 | 108 | try { 109 | $response = Invoke-WebRequest -URI $query_url -SkipCertificateCheck -MaximumRedirect 0 110 | $status_code = [int]$r.StatusCode 111 | if($status_code -eq 0){ 112 | $status_code = 200 113 | } 114 | } 115 | catch { 116 | $status_code = [int]$_.Exception.Response.StatusCode 117 | } 118 | 119 | $return_codes += , $status_code 120 | Write-Verbose -Verbose -Message "$query_url returned HTTP $status_code" 121 | 122 | } 123 | 124 | If($return_codes.Contains(401)){ 125 | $printer_secured = 'Secure' 126 | } 127 | Elseif($return_codes.Contains(200)){ 128 | $printer_secured = 'Unsecured' 129 | } 130 | Else{ 131 | $printer_secured = 'Needs Manual Review' 132 | } 133 | 134 | } 135 | Else{ 136 | Write-Verbose -Verbose -Message "Couldn't reach $printer_name at $printer_ip" 137 | $printer_reachable = $false 138 | $printer_secured = 'Unreachable' 139 | } 140 | 141 | $report += ,@($printer_server, $printer_name,$printer_ip, $printer_reachable, $printer_secured) 142 | } 143 | 144 | Write-Verbose -Verbose -Message "=== Generating CSV report to $ReportPath ===" 145 | # Create the CSV report 146 | Add-Content $ReportPath -Value "SEP=," # Write out the first line 147 | $report | % { $_ -join ","} | Out-File $ReportPath -Append # Write out the rest of the report 148 | Write-Verbose -Verbose -Message "Reported created to $ReportPath !" 149 | -------------------------------------------------------------------------------- /printer-telnet-ftp-report/README.md: -------------------------------------------------------------------------------- 1 | # printer-telnet-ftp-report 2 | 3 | Find network printers that have telnet or FTP services enabled. These services should normally be turned off unless they're required, to prevent unauthorized access to the printers. 4 | 5 | **Use the `-Verbose` parameter for verbose output** 6 | 7 | ## How it works 8 | 9 | First, the script will get all the printers from the servers in the file supplied by the optional `-PrintServerList` parameter through a WMI request. 10 | 11 | It will then test if the printers have Telnet or FTP enabled and generate a CSV report. 12 | 13 | ## How to use 14 | 15 | Simply download the script and run it from the PowerShell command line like so : 16 | 17 | ```PowerShell 18 | ./printer-telnet-ftp-report.ps1 19 | [-PrintServerList] 20 | [-ReportPath] 21 | ``` 22 | 23 | Here's an example : 24 | ```PowerShell 25 | ./printer-telnet-ftp-report.ps1 -PrintServerList ./servers.txt 26 | ``` 27 | 28 | You will need the rights to do WMI requests on each print servers to run the script. 29 | 30 | ### Parameters 31 | 32 | `-PrintServerList` : The list of print servers to get printers from. (Required) 33 | 34 | `-ReportPath` : The path of the CSV report to output. The default is `./report.csv` (Optional) 35 | 36 | ### Text file examples 37 | 38 | Here are some examples of what the text files needed could look like. 39 | 40 | #### `-PrintServerList ` 41 | ``` 42 | printserv1 43 | printserv2 44 | ``` 45 | 46 | ### Report example 47 | 48 | Here's an example of what the CSV report will look like : 49 | 50 | ``` 51 | Server,Hostname,IP,Reachable?,Telnet Enabled?,FTP Enabled? 52 | printserv1,printer_1,10.0.0.2,TRUE,TRUE,TRUE 53 | printserv2,printer_2,10.0.0.3,FALSE,FALSE,FALSE 54 | ``` 55 | -------------------------------------------------------------------------------- /printer-telnet-ftp-report/printer-telnet-ftp-report.ps1: -------------------------------------------------------------------------------- 1 | param( 2 | [Parameter(Mandatory=$True)] [string] $PrintServerList, # Path to the list of print servers 3 | [string] $ReportPath = $(Join-Path -Path $PSScriptRoot -ChildPath "report.csv") # Path to the report to output 4 | ) 5 | 6 | # Pull list of printers from print servers supplied by -PrintServerList 7 | $printers = @() 8 | Try{ 9 | Get-Content $PrintServerList | ForEach-Object{ 10 | $server = $_ 11 | Get-CimInstance -ClassName Win32_Printer -ComputerName $server | ForEach-Object{ 12 | $printers += , @($_.Name, $($_.PortName).Replace('..','.'), $server) # Some IPs have two dots for some reason, I use a .Replace() for that (ex: 10..10.10.10) 13 | } 14 | } 15 | } 16 | Catch{ 17 | Write-Error $_ 18 | } 19 | 20 | # Create report 21 | $report = @() 22 | $report += ,@("Server","Hostname","IP", "Reachable?", "Telnet Enabled?", "FTP enabled?") 23 | 24 | 25 | # Loop through all printers 26 | $printers | Foreach-Object{ 27 | 28 | # Set initial variables 29 | $printer_name, $printer_ip, $printer_server = $_ 30 | 31 | # Reset 32 | $printer_reachable = $null 33 | $printer_telnet = $null 34 | $printer_ftp = $null 35 | 36 | # Ping Test 37 | If(Test-Connection -ComputerName $printer_ip -Quiet -Count 1 -InformationAction Ignore){ 38 | 39 | $printer_reachable = $true 40 | 41 | 42 | # Test Telnet connectivity 43 | $telnet_test = Test-NetConnection -ComputerName $printer_ip -Port 23 44 | 45 | If($telnet_test.TcpTestSucceeded){ 46 | $printer_telnet = $true 47 | } 48 | Else{ 49 | If($telnet_test.PingSucceeded){ 50 | 51 | $printer_telnet = $false 52 | } 53 | Else{ 54 | 55 | $printer_telnet = $false 56 | } 57 | } 58 | 59 | # Test FTP connectivity 60 | Try 61 | { 62 | $client = New-Object System.Net.Sockets.TcpClient($printer_ip, 21) 63 | $client.Close() 64 | $printer_ftp = $true 65 | } 66 | Catch 67 | { 68 | $printer_ftp = $false 69 | } 70 | } 71 | Else{ 72 | # If printer is unreachable, set all to false 73 | $printer_reachable = $false 74 | $printer_telnet = $false 75 | $printer_ftp = $false 76 | } 77 | 78 | # Append report 79 | $report += ,@($printer_server,$printer_name,$printer_ip,$printer_reachable,$printer_telnet, $printer_ftp) 80 | Write-Verbose -Verbose -Message "Scanned $printer_name at $printer_ip on $printer_server" 81 | 82 | } 83 | 84 | Add-Content $ReportPath -Value "SEP=," # Write out the first line 85 | $report | % { $_ -join ","} | Out-File $ReportPath -Append # Write out the rest of the report 86 | Write-Verbose -Verbose -Message "Reported created to $ReportPath !" 87 | -------------------------------------------------------------------------------- /remote-bitlocker-encryption-report/README.md: -------------------------------------------------------------------------------- 1 | # remote-bitlocker-encryption-report 2 | This PowerShell script takes a list of PC as input, gets their BitLocker encryption type remotely, and outputs the list as a CSV file to help mitigate against CVE-2018-12038. 3 | 4 | **Use the `-Verbose` parameter for verbose output** 5 | 6 | ⚠️ **Beware of Bitlocker based on TPM chips as they can be vulnerable!** [More info in this blog post.](https://pulsesecurity.co.nz/articles/TPM-sniffing) 7 | 8 | ## Prevent CVE-2018-12038 vulnerability 9 | Description of CVE-2018-12038 from NIST : 10 | >An issue was discovered on Samsung 840 EVO and 850 EVO devices (only in "ATA high" mode, not vulnerable in "TCG" or "ATA max" mode), Samsung T3 and T5 portable drives, and Crucial MX100, MX200 and MX300 devices. Absence of a cryptographic link between the password and the Disk Encryption Key allows attackers with privileged access to SSD firmware full access to encrypted data. 11 | 12 | [More here ...](https://nvd.nist.gov/vuln/detail/CVE-2018-12037) 13 | 14 | Along with applying patches on SSD firmware, [CERT advises not to use hardware BitLocker encryption.](https://kb.cert.org/vuls/id/395981/) 15 | 16 | This script helps network administrators mitigate this vulnerability by generating a CSV report listing computers and their BitLocker encryption method using the [manage-bde](https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/manage-bde) command remotely. This report can be used by system administrators to identify workstations that need to have their encryption type changed. Network administrators can then manually change this encryption type or [remotely through GPO](https://blogs.technet.microsoft.com/dubaisec/2016/03/04/bitlocker-aes-xts-new-encryption-type/). 17 | 18 | ## How to use 19 | 20 | Simply run the script with admin credentials. 21 | 22 | ```PowerShell 23 | ./remote-bitlocker-encryption-report.ps1 24 | [-ComputerList] 25 | [-ReportPath] 26 | ``` 27 | 28 | ### Parameters 29 | All the following parameters are optional. 30 | 31 | `-ComputerList` : Path of the list of computers to scan. Defaults to `computers.txt` in the script's folder. 32 | 33 | `-ReportPath` : Path where to output the report. Defaults to `report.csv` in the script's folder. 34 | -------------------------------------------------------------------------------- /remote-bitlocker-encryption-report/remote-bitlocker-encryption-report.ps1: -------------------------------------------------------------------------------- 1 | # Parameters 2 | param( 3 | [string] $ComputerList = $(Join-Path -Path $PSScriptRoot -ChildPath "computers.txt"), # Path to the list of computers 4 | [string] $ReportPath = $(Join-Path -Path $PSScriptRoot -ChildPath "report.csv") # Path to the report to output 5 | ) 6 | 7 | # Constants 8 | $Computers = Get-Content $ComputerList 9 | 10 | # Initialise the report array, including the first line 11 | $report = @() 12 | $report += ,@("Hostname","Encryption Method") 13 | 14 | # Get the encryption type for each PC 15 | $Computers | ForEach-Object{# Loop through each computer 16 | $computer = $_ 17 | Write-Verbose -Verbose -Message "Connecting to $computer ..." 18 | Try{ 19 | $bitlocker_status = manage-bde -status -computername $computer | Where {$_ -match "Encryption Method:"} # Run manage-bde remotely and match the "Encryption Method" line 20 | $bitlocker_status = $bitlocker_status.Replace("Encryption Method:","").Trim() # Remove "Encryption Method:" header from the line 21 | $report += , @($computer,$bitlocker_status) # Add the PC and Bitlocker encryption type to the report 22 | Write-Verbose -Verbose -Message "Done with $($computer)." 23 | } 24 | Catch{ # If the computer is not reachable 25 | $report += , @($computer,"UNREACHABLE") # Output UNREACHABLE to the report 26 | Write-Verbose -Verbose -Message "Couldn't connect to $computer" 27 | } 28 | } 29 | 30 | # Create the CSV report 31 | Add-Content $ReportPath -Value "SEP=," # Write out the first line 32 | $report | % { $_ -join ","} | Out-File $ReportPath -Append # Write out the rest of the report 33 | --------------------------------------------------------------------------------