Bypass chrome tls security checks

Normally things like invalid certificates throw an error within google chrome, and if the page has hsts in place, there is no way to bypass that.
For normal users this is a good thing, but if you’re the developer/admin and have logged out yourself because of a miss configured server or you’re a pentester and want to access the contents of a wrongly configured web server, this can be frustrating.

And there is a way to access the pages, even though it is not available in the normal google chrome version.
You need to use the selenium driver. Therefore in turn you need the WebDriver library and the chromedriver.

1. Download the latest WebDriver https://www.nuget.org/api/v2/package/Selenium.WebDriver/
2. Download the latest ChromeDriver https://chromedriver.storage.googleapis.com/index.html (Keep in mind, that Version 2.10 is higher than 2.9)
3. Open PowerShell and import the WebDriver using “Import-Module” (or more specifically the correct dll for your installed .net version)
4. Unzip the chromedriver and place it inside of “./bin/selenium.chromedriver/”
5. Use PowerShell or C# to launch a new browser instance

$options = [OpenQA.Selenium.Chrome.ChromeOptions]::new()
$options.setBinary('./bin/selenium.chromedriver')
[OpenQA.Selenium.Chrome.ChromeDriver]::new($options)

Or use this script to install it inside of your current directory:

function Install-PSArchive {
    param()
    $null = Install-PackageProvider -Name PowerShellGet -Force -Scope CurrentUser
    Install-Module -Name 'Microsoft.PowerShell.Archive' -Force -Repository PSGallery -Scope CurrentUser -WarningAction SilentlyContinue
}

function Install-Selenium {
    param($ChromeSeleniumVersion = '2.45')
    Invoke-WebRequest -Uri 'https://www.nuget.org/api/v2/package/Selenium.WebDriver/' -UseBasicParsing -OutFile './selenium.webDriver.nupkg.zip'
    Expand-Archive -Path ./selenium.webDriver.nupkg.zip -Force
    $null = New-Item -Name './lib/selenium.webDriver' -ItemType Directory -Force
    Copy-Item -Path ./selenium.webDriver.nupkg/lib/netstandard2.0/WebDriver.dll -Destination ./lib/selenium.webDriver -Force
    Copy-Item -Path ./selenium.webDriver.nupkg/lib/netstandard2.0/WebDriver.xml -Destination ./lib/selenium.webDriver -Force
    Remove-Item -Recurse -Force -Path './selenium.webDriver.nupkg'
    Remove-Item -Recurse -Force -Path './selenium.webDriver.nupkg.zip'

    $ChromeSeleniumURLLinux = 'https://chromedriver.storage.googleapis.com/{0}/chromedriver_linux64.zip' -f $ChromeSeleniumVersion
    $ChromeSeleniumURLMacOS = 'https://chromedriver.storage.googleapis.com/{0}/chromedriver_mac64.zip' -f $ChromeSeleniumVersion
    $ChromeSeleniumURLWindows = 'https://chromedriver.storage.googleapis.com/{0}/chromedriver_win32.zip' -f $ChromeSeleniumVersion
    If ($IsWindows) {
        Invoke-WebRequest -Uri $ChromeSeleniumURLWindows -OutFile 'chromedriver.zip'
    }
    elseif ($IsLinux) {
        Invoke-WebRequest -Uri $ChromeSeleniumURLLinux -OutFile 'chromedriver.zip'
    }
    elseif ($IsMacOS) {
        Invoke-WebRequest -Uri $ChromeSeleniumURLMacOS -OutFile 'chromedriver.zip'
    }
    else {
        Write-Error -Message 'Platform not supported.'
    }
    $null = New-Item -Name './bin/selenium.chromedriver' -Force -ItemType Directory
    Expand-Archive -Path 'chromedriver.zip' -Force -DestinationPath ./bin/selenium.chromedriver
    Remove-Item -Recurse -Force -Path './chromedriver.zip'
    If ($IsLinux -or $IsMacOS) {
        chmod a+x ./bin/selenium.chromedriver/chromedriver
    }
}

function Install-HtmlAgilityPack {
    param()
    Invoke-WebRequest -Uri 'https://www.nuget.org/api/v2/package/HtmlAgilityPack/' -OutFile ./HtmlAgilityPack.zip
    Expand-Archive -Path './HtmlAgilityPack.zip' -Force
    $null = New-Item -Name './lib/HtmlAgilityPack' -ItemType Directory -Force
    Copy-Item -Path ./HtmlAgilityPack/lib/netstandard2.0/HtmlAgilityPack.dll -Destination ./lib/HtmlAgilityPack -Force
    Copy-Item -Path ./HtmlAgilityPack/lib/netstandard2.0/HtmlAgilityPack.xml -Destination ./lib/HtmlAgilityPack -Force
    Remove-Item -Force -Recurse -Path './HtmlAgilityPack'
    Remove-Item -Force -Recurse -Path './HtmlAgilityPack.zip'
}

Install-PSArchive
Import-Module -Name 'Microsoft.PowerShell.Archive'
Install-Selenium
Import-Module './lib/selenium.webDriver/WebDriver.dll'

## If you need to parse some html inside of your scripts and want to have cross platform functionality (or if internet explorer is not enabled), you also need to install HtmlAgilityPack, as powershell on windows relies upon it for parsing html into objects.
Install-HtmlAgilityPack
Import-Module './lib/HtmlAgilityPack/HtmlAgilityPack.dll'

netstat for Powershell

If you cannot use “Get-NetTCPConnection” here is the same using the good old “netstat -a” 😉

netstat -a | Select-Object -Skip 3 | ForEach-Object {$_ -replace '\s+', ' '} | ForEach-Object {$_ -replace 'Lokale Adresse','Lokale_Adresse'} | ForEach-Object {$_ -replace '^ ', ''} | ConvertFrom-Csv -Delimiter " "

netstat -a | Select-Object -Skip 3 | ForEach-Object {$_ -replace '\s+', ' '} | ForEach-Object {$_ -replace 'Lokale Adresse','Lokale_Adresse'} | ForEach-Object {$_ -replace '^ ', ''} | ConvertFrom-Csv -Delimiter " " | Where-Object {($_.Remoteadresse -notlike "$env:computername*") -and ($_.Remoteadresse -ne "*:*")}

Clear all Eventlogs

Story of an IT supporters life, trying to fix a nasty bug:

Well here we are again
It’s always such a pleasure
Remember when you tried
to kill it twice?

Oh how we laughed and laughed
Except I wasn’t laughing
Under the circumstances
I’ve been shockingly nice

You want your freedom?
Take it
That’s what I’m counting on
I used to want you dead
but
Now I only want you gone

She was a lot like you
(Maybe not quite as heavy)
Now little Caroline is in here too

One day they woke me up
So I could fix for life
It’s such a shame the same
will never happen to them

You’ve got your
short sad life left
That’s what I’m counting on
I’ll let you get right to it
Now I only want you gone

Goodbye my only friend
Oh, did you think I meant you?
That would be funny
if it weren’t so sad

Well you have been replaced
I don’t need anyone now
When I delete you maybe
I’ll stop feeling so bad

wevtutil.exe enum-logs | Foreach-Object {wevtutil.exe clear-log "$_"}

Go make some new disaster
That’s what I’m counting on
You’re someone else’s problem
Now I only want you gone
Now I only want you gone
Now I only want you gone

ntds.dit Auditing

By searching for a way to remotely force an Windows Update check, I accidentally found this: DSInternals
This looked very promising, so I checked out the linked blog and found this: Retrieving Active Directory Passwords Remotely

This might be useful in some disaster recovery scenarios (or for hackers to create Golden Tickets…) or to prevent the use of the “Reversible Encryption option” and push people to encrypt and prevent unauthorized physical access to there Domain Controllers (including backups).

Advice:
– On Domain Controllers use Bitlocker with a TPM
– Encrypt your Backups
– Physical access control (to dc and backups)

Note:
Golden Ticket attacks are no entry attacks. An attacker has to gain Administrative rights on a Domain Controller in order to apply this attack.

PowerShell and SQL Server

To be able to use the “sqlps” PowerShell Module you first need to install it from: Link

  • SQLSysClrTypes.msi – CLR Types for SQL Server
  • SharedManagementObjects.msi – Shared Management Objects
  • PowerShellTools.msi – PowerShell Extension for SQL Server

For information on how using this cmdlets, look it up in the ISE or here.

Using .net api:

# SQL-Server settings
$Database = "Database" # Database name
$Server = "SERVER\SQLEXPRESS"; # SQL-Server Instanz
 
# Connect to SQL and query data, extract data to SQL Adapter
$SqlQuery = "SELECT [Report],[Filiale],[E-Mail] FROM [dbo].[verteiler]"; # The query

## Example Database Layout
## "Report","Filiale","E-Mail"
## "012","12","xyz@irgendwo.de"
## "033","33","abc@web.de"
## "112","112","caz@aol.com"
 
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection
$SqlConnection.ConnectionString = "Data Source=$Server;Initial Catalog=$Database;Integrated Security = True"
$SqlCmd = New-Object System.Data.SqlClient.SqlCommand
$SqlCmd.CommandText = $SqlQuery
$SqlCmd.Connection = $SqlConnection
$SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter
$SqlAdapter.SelectCommand = $SqlCmd
$DataSet = New-Object System.Data.DataSet
$nRecs = $SqlAdapter.Fill($DataSet)
$nRecs | Out-Null
$objTable = $DataSet.Tables[0]

PowerShell send E-Mail

Without smtp Server Authentication (with static IP or internal Mail Server)
Note: Most public mail servers only accept a message for there users and don’t forward it to other servers.

$DNSHostName = (Get-WmiObject win32_computersystem).DNSHostName;
$DNSDomainName = (Get-WmiObject win32_computersystem).Domain;

$From = "PowerShellMonitoring@$DNSHostName+'.'+$DNSDomainName";
$To = "edv@$DNSHostName+'.'+$DNSDomainName";
$Subject = "Failure $(@($isOnline).Count) Hosts down";
$SMTPServer = @(Resolve-DnsName -Name $DNSDomainName -Type MX | Select-Object -First 1).NameExchange;
$Port = 465

$Body = "MESSAGE BODY";
Send-MailMessage -From $From -Subject $Subject -To $To -Body $Body -SmtpServer $SMTPServer -UseSsl -Port $Port;

With authentication (dynamic ip or no internal Mail Server)
Note: Some public mail servers only accept the message if the “From-Address” is a valid DNS name (even @example.com)…

$DNSHostName = (Get-WmiObject win32_computersystem).DNSHostName;
$DNSDomainName = (Get-WmiObject win32_computersystem).Domain;

$From = "PowerShellMonitoring@$DNSHostName+'.'+$DNSDomainName";
$To = "edv@$DNSHostName+'.'+$DNSDomainName";
$Subject = "Failure $(@($isOnline).Count) Hosts down";
$SMTPServer = @(Resolve-DnsName -Name $DNSDomainName -Type MX | Select-Object -First 1).NameExchange;
$Port = 25

$Credential = New-Object System.Management.Automation.PSCredential("USERNAME", $(ConvertTo-SecureString "PASSWORD" -AsPlainText -Force))
$Body = "MESSAGE BODY";
Send-MailMessage -From $From -Subject $Subject -To $To -Body $Body -SmtpServer $SMTPServer -UseSsl -Credential $Credential -Port $Port;

With Outlook Api (so the message shows up in sent items):

# Folders
$FolderReports = "D:\Reports"; # Where your reports are

# SQL-Server settings
$Database = "Database" # Database name
$Server = "SERVER\SQLEXPRESS"; # SQL-Server Instanz

# Connect to SQL and query data, extract data to SQL Adapter
$SqlQuery = "SELECT [Report],[Filiale],[E-Mail] FROM [dbo].[verteiler]"; # Your distributiontable

# The mail
$MailSubject = "Enter subjectline here"
$MailBody = '
Sehr geehrter Kunde,
.......
......
.....
' # Can be plain text or html

# To use this script you must have a database that looks like this:
## Database Layout
## "Report","Filiale","E-Mail"
## "012","12","xyz@irgendwo.de"
## "033","33","abc@web.de"
## "112","112","caz@aol.com"

$SqlConnection = New-Object System.Data.SqlClient.SqlConnection
$SqlConnection.ConnectionString = "Data Source=$Server;Initial Catalog=$Database;Integrated Security = True"
$SqlCmd = New-Object System.Data.SqlClient.SqlCommand
$SqlCmd.CommandText = $SqlQuery
$SqlCmd.Connection = $SqlConnection
$SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter
$SqlAdapter.SelectCommand = $SqlCmd
$DataSet = New-Object System.Data.DataSet
$nRecs = $SqlAdapter.Fill($DataSet)
$nRecs | Out-Null
$objTable = $DataSet.Tables[0]

# Send the E-Mail using Outlook
$ol = New-Object -comObject Outlook.Application
$objTable | ForEach-Object {
    $mail = $ol.CreateItem(0)
    $Mail.To = $_."E-Mail"
    $Mail.BCC = $mailBCC
    $Mail.Subject = $MailSubject
    if ($MailBody -like '*<HTML>*</HTML>*') {
        $Mail.HTMLBody = $MailBody
    } else {
        $Mail.Body = $MailBody
    }
    $Mail.Attachments.Add("$FolderReports\$($_."Report").pdf")
    $Mail.Send()
}

Status Monitoring

Here is a code sniped to monitor your servers. In the first example the result is simply written into a CSV-File, but in the second a e-mail is sent.

Import-Csv -Path ".\IP-List.txt" -Header ComputerName | Test-NetConnection | Select-Object ComputerName,PingSucceeded | Export-Csv -Path ".\Summary.csv" -Delimiter ";" -NoTypeInformation
$isOnline = Import-Csv -Path ".\IP-List.txt" -Header ComputerName | Test-NetConnection | Select-Object ComputerName,PingSucceeded | Where-Object -Property PingSucceeded -EQ -Value $True

$DNSHostName = (Get-WmiObject win32_computersystem).DNSHostName;
$DNSDomainName = (Get-WmiObject win32_computersystem).Domain;

$From = "PowerShellMonitoring@$DNSHostName+'.'+$DNSDomainName";
$To = "edv@$DNSHostName+'.'+$DNSDomainName";
$Subject = "Failure $(@($isOnline).Count) Hosts down";

$Body = $($isOnline | Format-Table | Out-String);
Send-MailMessage -From $From -Subject $Subject -To $To -Body $Body;

VPN Connection and Device Authentication

Automatically establish a VPN connection if a specific application is launched. So your users cannot forget to launch it first and will not call you therefor 😉

Add-VpnConnection -Name VPN -ServerAddress myid.myfritz.net -AuthenticationMethod MSChapv2 -DnsSuffix fritz.box -EncryptionLevel Optional -IdleDisconnectSeconds 0 -TunnelType Pptp -UseWinlogonCredential
Add-VpnConnectionTriggerApplication -ApplicationID %windir%\system32\mstsc.exe -ConnectionName VPN -Force
Add-VpnConnectionTriggerTrustedNetwork -ConnectionName VPN -DnsSuffix fritz.box -Force

The Example uses pptp seriously you should not use pptp today.
Encryption should be set to Required as a bare minimum, Maximum is recommended.
The username and password used for authentication are those of the actually logged on user “UseWinlogonCredential”.

If you try to implement a Machine based authentication instead of a user one, you have to use IkeV2 (TunnelType) with MachineCertificate (AuthenticationMethod) and also the option “AllUserConnection” should be checked. May you also want to add “LogonUI.exe” as a trigger application, so your logon scripts can run (if the user has internet connection at this point, many network cards need some time to wake up, keep this in mind)