The Poor Man’s Honeypot; howto flag password spraying in a homelab

Rich
8 min readSep 22, 2022

TL;DR one way to flag password spraying in the lab by using a honeypot account.

Welcome to Part IV of our Back to the Basics Series!

Part I: NTDS.dit vs SAM

Part II: Ownership Matters

Part III: Recovering from a Crash

Part IV: Setting up a Simple Honeypot Account

Part V: Automating DC Deployment

Part VI: Sometimes it’s the dumbest thing

Part VII: Merry Christmas, macros, & Base64

Part VIII: Why old 0 Days make great teaching tools

Part IX: PowerShell & PS1s without PowerShell.exe

Part X: Ownership & so called “effective permissions”

Part XI: Windows Event Forwarding & SACLs

Part XII: Poorly planned honeypots & other Bad Ideas

Part XIII: Setting up a simple honey token

Part XIV: Smartcards and Pass-the-Hash

Part XV: Forwarding logs to Sentinel & basic alerts

Background

Here at test.local we realized that we have been heavy on prevention and light on detection. This is mostly due to the fact that we are ‘Windows Guys’, not SIEM gurus. We are also focused on Windows domains, hybrid AD, and transitioning to AAD.

However as Dr Eric Cole so famously put it “prevention is ideal, but detection is a must”. Therefore we decided to give a detection idea a shot. It was also a great learning experience in topics we don’t normally do like password spraying, querying event logs, and creating scheduled tasks.

Boring theory part

Attackers realized awhile back that one of their best ways to get an initial foothold in a Windows domain was to take advantage of user behavior, hence the prevalence of phishing. Another of those behaviors is picking passwords that meet the complexity requirements but are easy to remember. Sadly some organizations actually make this worse by continuing to push the decades old practice of requiring frequent password changes.

If the password requires at least 3 of the following:

  • One uppercase
  • One lowercase
  • One number
  • One special character

Additionally it must be changed every 3 months and password history is enabled with, oh let’s say 12.

What’s a user going to do?

They will use “Summer2022”. They will change it to “Fall2022”, followed by “Winter2022”, followed by … well you get the idea. This meets the default password length, complexity, and history requirements.

Attackers know this.

Therefore they use password spraying to throw 4 attempts at each username, figuring they will stay under the typical account lockout threshold of 5. Given user behavior they are almost bound to get lucky.

The honeypot account

Hence we will create an account, set the password to “Summer2022”, and set a trigger on it. Upon login the account will lock, set an account description with the details, and shoot an email to an administrator with the event log details.

Create the honeypot account:

New-ADUser -DisplayName “Test Dummy” -SamAccountName “test.dummy” -UserPrincipalName “test.dummy@test.local” -Path ‘ou=user accounts,dc=test,dc=local’ -AccountPassword(Read-Host -AsSecureString “Input Password”) -Enabled $true

Next run the following on the PDC:

Set the trigger:

$ErrorActionPreference = “SilentlyContinue”do
{
if(Get-EventLog -LogName Security -InstanceId 4624 -Message “*test.dummy*” -Newest 1 | Where-Object {$_.TimeGenerated -ge (Get-Date).AddHours(-.5)}){
#Lock the account & email the event to an admin
$Offender = (Get-EventLog -LogName Security -InstanceId 4624 -Message “*test.dummy*” -Newest 1 | Select-Object TimeWritten,@{Name=”OffenderIP”;Expression={ $_.ReplacementStrings[18]}},EventID,MachineName).OffenderIPSet-ADUser -Identity “test.dummy” -Enabled $false -Description “Potential Password Spraying detected! Logged by DC $env:computername. The offender’s IP is $Offender”$EmailBody = Get-EventLog -LogName Security -InstanceId 4624 -Message “*test.dummy*” -Newest 1 | Select-Object -Property *Send-MailMessage -From ‘PowerShell@test.local’ -To ‘mishky@test.local’ -Subject ‘Potential Password Spraying detected!’ -Body “$EmailBody”Write-Host “Hide your kids, hide your WiFi! Exiting …”
break
}
else{Write-Host “Nothing found yet” ; Start-Sleep -Seconds 120
}
}
while($true)

Then jump on Kali and password spray:

crackmapexec smb 192.168.0.104 -u /home/kali/Downloads/Wordlists/pwdspray.txt -p Summer2022 — continue-on-success

Alternatively one could also use hydra with a username list and a password list that only contains 4 passwords:

hydra -t 1 -V -f -L <user list> -P <pwd list> <IP address> smb

Voila

Some screenshots redacted IOT omit kid’s real names

Basically this polls the event log every two minutes, looking for login activity to the honeypot account. If it finds any within the last 30 minutes it triggers.

I simply tested this out on my PDC. One can use Group Policy and a scheduled task to easily push it to all DCs.

I do not have an Exchange server running in the lab yet, so the email is a placeholder at this time. Getting a M365 license for Mishka and setting up hybrid Exchange is a future project. If we get that working I can re-visit this project and improve it.

How we pulled the Offender’s IP address from the log

This part took more effort than creating the trigger.

PowerShell uses objects, everyone and their brother knows this. Coming from BASH I had to wrap my head around this. I kept trying to use

<query> | Out-String -Stream | Select-String “<thing we’re looking for>” -Context <however many lines you need>

Because I was used to piping to grep.

This is horribly inefficient, sacrifices kittens, and wastes the true potential of PowerShell.

However there are a few things in Windows that don’t fit so neatly into the object. The message in the event log is one of these. You can easily pull the EventID, MachineName, DTG, etc from the log but we wanted to put the offender’s IP address into stuff like the alert as well.

A kindly guru on spiceworks had shown the way already. CW6 Google led us to their words of wisdom. We leveraged their example into our query, then used a bit of trickery.

The key here:

Get-EventLog -LogName Security -InstanceId 4624 -Message “*test.dummy*” -Newest 1 | Select-Object TimeWritten,@{Name=”OffenderIP”;Expression={ $_.ReplacementStrings[18]}},EventID,MachineName

You can pull other data points from the message using the same method. But how do you know what the ReplacementStrings number is?

This is where the trickery came in. We tweaked something Mishky wrote a few months ago when she wanted the computer to count for her and used it to basically brute force the event log and find what we wanted.

#Find the ReplacementStrings number you are looking for via brute force :P$x = 0
$z = 30
do
{
$x = $x + 1
$x
Get-EventLog -LogName Security -InstanceId 4624 -Message “*test.dummy*” -Newest 1 | Select-Object TimeWritten,@{Name=”Network Information”;Expression={ $_.ReplacementStrings[$x]}},EventID,MachineName
}
while ($x -lt $z)

This may come in handy in the future if we need to pull data from a different EventID as it will show you what data point corresponds to the number in a given EventID.

Just pick the number you want, put it in the query, pass it to a variable, and use said variable in whatever form of alert you want, for example:

$LogonType = (Get-EventLog -LogName Security -InstanceId 4624 -Message “*test.dummy*” -Newest 1 | Select-Object TimeWritten,@{Name=”LogonType”;Expression={ $_.ReplacementStrings[8]}},EventID,MachineName).LogonType

A nice explanation of EvenID 4624 with the corresponding LogonTypes and what they are is here.

Sidenote on a different trigger method

I initially tried creating a scheduled task on the DC that would trigger on EventID 4624 for the honeypot account. However I was getting a migraine trying to get it to trigger reliably. After watching me bang my head against the proverbial wall for awhile Mishky said “bro, WTH are you doing!? Just use a loop. There’s a handy example right here in the book PowerShell for Sysadmins.”

Mishky hard at work debugging something I screwed up

Summary

This is one of those lab projects that is really just a good learning experience. SIEMs, IDSs, etc should be in use and should be setup to flag this stuff. Additionally that decades old password policy really shouldn’t be used. It only encourages users to pick passwords that meet the requirement yet are easy to remember and/or write the password down on a sticky note that’s on their monitor.

Everyone knows this, a 6 year old knows this, and the attackers damn sure know this.

AAD has some nice features to help mitigate some of this, for example the banned password list. We will have to dive into that in a future project. Of course AAD supports many forms of MFA and we are already using that for Mishka, her day to day non-privileged account. This is currently the only account that is synced between AD & AAD.

Administrators ideally should not be affected by any of this as they should

  • Be required to use smart cards
  • Be put in the Protected Users group
  • Be set to not allow delegation
  • Utilize a mere user account for day to day stuff like email, asking CW6 Google how to do their job, etc

Do smartcards cost money? Sure, but so does a breach. Smartcards can also function as a physical employee ID, a badge for physical doors, and a 2FA method. Don’t assume they stop PTH, set AD to roll their hashes, take the steps above to stop PTT, and they help a lot.

Oh, and when we finally fire our employee named “Malicious Insider” who keeps taking advantage of misconfigurations in these lab exercises, again and again, we can simply revoke their smartcard. Even if they are disgruntled and don’t return the thing it will no longer open doors or work for logging in.

They won’t have a password to sell to $LAPSUS either.

References

Dr Eric Cole on detection: https://www.sans.org/cyber-security-courses/advanced-security-essentials-enterprise-defender/

Password spraying AD: https://www.ired.team/offensive-security-experiments/active-directory-kerberos-abuse/active-directory-password-spraying

Default AD password complexity: https://learn.microsoft.com/en-us/answers/questions/615313/active-directory-password-policy-complexity-enable.html

tools for pwd spraying: https://resources.infosecinstitute.com/topic/top-tools-for-password-spraying-attacks-in-active-directory-networks/

howto pwd spray with crackmapexec: https://wiki.porchetta.industries/smb-protocol/password-spraying

Hydra cheatsheet: https://github.com/frizb/Hydra-Cheatsheet

Hybrid Exchange explained: https://codersera.com/blog/set-up-a-hybrid-exchange-office-365-environment/#:~:text=In%20a%20hybrid%20exchange%20environment,a%20number%20of%20unique%20factors.

Event ID 4624 & login types: https://www.ultimatewindowssecurity.com/securitylog/encyclopedia/event.aspx?eventID=4624

Send email via PS: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/send-mailmessage?view=powershell-7.2

Parsing Windows Get-EventLog messages for specific strings: https://community.spiceworks.com/topic/598706-parsing-the-message-field-in-security-event-log-to-pull-the-username

NIST has spoken — Death to Complexity, long live the passphrase: https://www.sans.org/blog/nist-has-spoken-death-to-complexity-long-live-the-passphrase/

$LAPSUS simply bought credentials for initial access: https://krebsonsecurity.com/2022/03/a-closer-look-at-the-lapsus-data-extortion-group/

--

--

Rich

I work various IT jobs & like Windows domain security as a hobby. Most of what’s here is my notes from auditing or the lab.