Simulating Users for Fun and Profit

Users are the main ingredient in every corporate environment; they perform most of the important actions, create a majority of the day to day network traffic, and provide a significant attack surface for malicious actors. When setting out to develop our penetration testing labs, it was important to us that they be as realistic as possible, so incorporating prominent user behaviors was a must. From that, Invoke-UserSimulator.ps1 was born! Let's dive right in to the main functionality...

Internet Browsing

By emulating internet browsing, we can create a significant amount of DNS, HTTP, and HTTPS network traffic. This is useful for practicing packet capture techniques on lab workstations and makes the use of tools like Wireshark and tcpdump look much more realistic.

We accomplish our internet browsing by creating an Internet Explorer object. We then browse to one of several hardcoded URLs (Google News, CNN, etc.), parse the page for additional links, and choose one of those to browse to next. The link depth browsed (number of pages away from the original) and time between page loads are configurable in an XML file.

Invoke-UserSimulator -StandAlone -IE

Mapping Shares

Anytime a network share is accessed, Windows will send credentials across the wire in the form of NTLMv2 (mostly) hashes. These are a prime target for attackers located on the physical network or with an already established network foothold. Tools like Responder or Inveigh can answer LLMNR and NetBIOS requests for unknown network resources and capture these credentials. This is a very effective method of gaining Windows Domain credentials during a penetration test and can be difficult to effectively mitigate in some environments.

To create this traffic, we generate a random file share name then attempt to map it to a drive. Since the resource we attempt to map does not exist, the system should send out a broadcast to the local subnet requesting details on the system and opening itself up to Responder style attacks.

Invoke-UserSimulator -StandAlone -Shares

Opening Email

Email is potentially the largest source of pain for security teams, as it poses one of the biggest threats to organizations in the form of phishing attacks. Phishing campaigns are increasingly common and rely on convincing users to open malicious links or attachments embedded in emails. In our own campaigns, we’ve been able to achieve click rates of well over 50% and establish double digit numbers of command and control channels. It’s important for security assessors to be able to practice and carry out effective phishing simulations so that their customers know what a real attack looks like and how to defend against one.

To simulate users falling for phishing scams, and opening email in general, we first create an Outlook COM object. Next, we iterate through any unread mail objects. Mail is parsed for links as well as attachments. For any links, we create an IE object and browse to the link. For any attachment, we first save the attachment in a trusted directory and then execute the file. This allows us to bypass any prompts to enable macro execution, and automatically runmacros embedded in Office documents.

Invoke-UserSimulator -StandAlone -Email

Host Configuration

Depending on how the tool is used, hosts may require a bit of configuration. The tool supports two modes of operation: standalone and remote.


When executing the script in -StandAlone mode on a local machine, no configuration is needed to use internet browsing or share mapping features (aside from having Internet Explorer installed). To use the email opening functionality, you’ll need to configure your Outlook client. First, ensure Outlook has a working email account signed in that can receive emails. Secondly, you’ll need to allow programmatic access to Outlook. This can be achieved by running Outlook with Administrator privileges, browsing to File -> Options -> Trust Center -> Trust Center Settings -> Programmatic Access, and selecting “Never warn me about suspicious activity (not recommended)”.


Alternatively, you can be prepared to manually allow access when prompted. After these configurations have been made, you should be able to simulate an active user on your local machine! No administrative privileges are required (unless permanently allowing programmatic access).


In many scenarios, you may run to run the script simultaneously on numerous remote hosts. You can manually perform the same configuration described above on each host, however this quickly becomes a tedious and cumbersome task. So, we’ve included a function to handle the majority of remote host configuration: Invoke-ConfigureHosts. This function takes an XML file as input (-ConfigXML flag) which contains parameters for the script execution and configuration. We’ve highlighted the important part of the config below, and you can see a full example config file on the GitHub here:


For remote configuration, you’ll want to include a block of <client> parameters for each host you want to run the script on. This includes the hostname of the machine and a domain, username, password combination of the user to simulate.

The configuration function performs four actions: adds the specified user to the Remote Desktop Users group, creates and/or writes an Outlook registry key allowing programmatic access on 32-bit systems, creates and/or writes an Outlook registry key allowing programmatic access on 64-bit systems, and creates and/or writes an Internet Explorer registry key to ignore the “First Run” prompt. The Outlook registry keys will be written regardless of system type, but they shouldn’t conflict with each other. To remotely configure your target systems, run the function as a user who has Local Administrator rights to the systems in your configuration file.

After running the configuration script, the only manual configuration required for full tool functionality is to ensure Outlook clients are configured with working accounts (ideally accounts belonging to the users specified in the configuration file). You should get the following output after running the Invoke-ConfigureHosts function:


After configuring your remote hosts, you can get on with simulating your users! If you want to beef up the realism of your lab, grab our tool from GitHub and give it a go:

Check out the video below for a demonstration!