Table of Contents
Übersicht
During a recent engagement, I observed a lot of members of a particular organization authenticating with remote systems and services over the commandline with username and password in plaintext. This ranged from domain administrators using the net user command to create user accounts and updated passwords to database administrators managing their instances with commandline tools.
The security operations team had configured the active directory connected systems to record 4688 logs and ship those off to a centralized server. This resulted in a consolidated repository of all applications executed in the environment along with the commandline arguments. This is great for threat detection; however, it can also be leveraged by adversaries to find plaintext credentials.
Examples
Here are a few examples of credentials being passed to applications in plaintext. Some applications take in positional arguments such as net.exe. Programs that take in positional arguments will require prior knowledge of their use and formatting since we’ll have to essentially parse out the right token.
Other applications such as wmic.exe use named parameters (e.g. /password) to provide credentials. These are more generalizable, so we can build a regular expression to extract passwords provided through named parameters so long as the application adheres to a common naming scheme (e.g. -p, /p, /password, –password).
So, what does scraping event logs for credentials buy us?
You already have to have admin access to the network to read events from the Security Event Log, but it can get you a few things:
- It could yield domain admin credentials for privilege escalation, but you’d have to be pretty lucky to land on a domain admin box
- It gives you plaintext credentials to add to your password list for cracking
- Most importantly, it can capture credentials for other services such as databases or non-active directory connected systems
Tools Utilized
- PowerShell
- Wevtapi
- Regular Expressions
- SpecterInsight v3.1.0
- Get Credentials From Event Log SpecterScript
Creating a Script to Scrape Credentials from Event Logs
Step 1: Define the Parameter Block
The first step of building a script to scrape credentials is to define the parameter block. This will create a nice UI for the operator to use in the SpecterInsight interactive session. We want to be able to provide options for scraping localhost and remote systems and for authenticating with impersonation or explicit credentials. We satisfy these requirements with three parameters across two parameter sets:
Parameter Set 1: Impersonation
- ComputerName: The system to scrape events logs for credentials. The default is “localhost.”
Parameter Set 2: Username and Password
- ComputerName: The system to scrape events logs for credentials. The default is “localhost.”
- Username: The fully qualified username to authenticate with (e.g. [email protected]).
- Password: The password associated with the specified user.
Step 2: Load Dependencies
We are going to leverage a few high-performance cmdlets from the SpecterInsight EventLog post-exploitation module. Specifically, the Get-Events cmdlet runs about 100 times faster than the Get-WinEvent cmdlet that is bundled with PowerShell.
The “load” command instructs the implant to download and import the EventLog.dll module from the C2 server.
#Load dependencies
load EventLog;
Step 3: Define Regular Expressions for Extracting Credentials
The first thing we are going to need is a regex for detecting passwords from commandline arguments. This expression is going to get a little messy, so I’m going to try and break it down into chunks. First, let’s take a look at what we’re trying to match against. That is, what are some examples of passwords as commandline args?