Skip to content

Instantly share code, notes, and snippets.

@zaneGittins
Last active August 18, 2020 16:42
Show Gist options
  • Save zaneGittins/ea7f1179f37d9632de52d05d71756bf4 to your computer and use it in GitHub Desktop.
Save zaneGittins/ea7f1179f37d9632de52d05d71756bf4 to your computer and use it in GitHub Desktop.
#Requires -Version 5.0
<#
.SYNOPSIS
Reads in JSON file from https://haveibeenpwned.com/
Checks if the breach involved a users password, outputs
a CSV which contains ad information for each user.
.PARAMETER Path
Path to haveibeenpwned json file.
.PARAMETER Output
Path to save CSV output to.
.NOTES
Author: Zane Gittins (@0wlSec)
Last Updated: 8/18/2020
#>
param([Parameter(Mandatory=$true)][string]$Path,
[Parameter(Mandatory=$false)][string]$Output)
if($PSBoundParameters['Verbose']) { $ErrorActionPreference = "Continue"}
else { $ErrorActionPreference = "SilentlyContinue" }
$Banner = "
___ ___ _
| _ \__ __ ___ _ | _ \___ __ _ __| |___ _ _
| _/\ V V / ' \| / -_) _` / _` / -_) '_|
|_| \_/\_/|_||_|_|_\___\__,_\__,_\___|_|
Author: Zane Gittins (@0wlSec)
"
Write-Host $Banner
class Account {
[string]$Name
[string]$EmailAddress
[string]$Department
[string]$Enabled
[string]$LockedOut
[string]$BreachPasswordCount
[string]$BadLogonCount
[string]$AdPasswordLastSet
[string]$LastLogonDate
[string]$MostRecentPasswordBreach
[string]$MostRecentBreachTitle
}
$global:ReturnData = @()
Write-Verbose ("[+] Reading content from: " + $Path)
$Hashtable = Get-Content $Path | ConvertFrom-Json
Write-Verbose("[+] Getting active directory information.")
[int]$i = 0
$AllUsers = Get-ADUser -Filter * -Properties *
foreach($Record in $Hashtable.BreachSearchResults) {
$i += 1
[int]$p = ($i / $Hashtable.BreachSearchResults.Count) * 100
[string]$EmailAddress = $Record.Alias + "@" + $Record.DomainName
$ADUser = $AllUsers | Where-Object{$_.mail -like $EmailAddress}
if($null -ne $ADUser) {
[string]$ADName = $ADUser.Name.ToString()
[string]$Enabled = $ADUser.Enabled.ToString()
[datetime]$PasswordLastSet = [datetime]::FromFileTime($ADUser.pwdlastset)
[string]$BadLogonCount = $ADUser.BadLogonCount.ToString()
[string]$Department = $ADUser.Department.ToString()
[string]$LastLogonDate = $ADUser.LastLogonDate.ToString()
[string]$LockedOut = $ADUser.LockedOut.ToString()
[nullable[datetime]]$MostRecentPasswordBreach = $null
[nullable[string]]$MostRecentBreachTitle = $null
[int]$BreachPasswordCount = 0
foreach($BreachRecord in $Record.Breaches) {
[datetime]$BreachData = [datetime]::parseexact($BreachRecord.BreachDate, 'yyyy-mm-dd', $null)
foreach($BreachType in $BreachRecord.DataClasses) {
if($BreachType -eq "Passwords" -and $BreachData -gt $PasswordLastSet) {
$BreachPasswordCount += 1
if($BreachRecord.BreachDate -gt $MostRecentPasswordBreach) {
$MostRecentPasswordBreach = $BreachRecord.BreachDate
$MostRecentBreachTitle = $BreachRecord.Title
}
}
}
}
if($BreachPasswordCount -gt 0)
{
$NewAccount = [Account]::new()
$NewAccount.Name = $ADName
$NewAccount.EmailAddress = $EmailAddress
$NewAccount.Department = $Department
$NewAccount.Enabled = $Enabled
$NewAccount.LockedOut = $LockedOut
$NewAccount.BreachPasswordCount = $BreachPasswordCount.ToString()
$NewAccount.BadLogonCount = $BadLogonCount
$NewAccount.AdPasswordLastSet = $PasswordLastSet
$NewAccount.LastLogonDate = $LastLogonDate
$NewAccount.MostRecentPasswordBreach = $MostRecentPasswordBreach.ToString()
$NewAccount.MostRecentBreachTitle = $MostRecentBreachTitle
$global:ReturnData += $NewAccount
}
}
Write-Progress -Activity "Parsing and validating data" -Status "$p% Complete:" -PercentComplete $p;
}
if($PSBoundParameters.ContainsKey("Output") -ne $true) {
$Output = "pwnreader-" + (Get-Date -Format "MM_dd_yyyy_HHtt").ToString() + ".csv"
}
Write-Host ("[+] Writing output to: " + $Path)
$global:ReturnData | Export-Csv -NoTypeInformation -Delimiter "," -Path $Output
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment