Improving Your Simple Windows Domain for Offensive Testing: Elastic Defend EDR
By Red Siege | July 7, 2026
by Justin Palk
A couple of years ago, I put together a series on standing up a simple Windows AD domain in a lab environment. This is the start of a new series on adding additional capabilities to make the lab an even more useful environment for practicing tradecraft.
As originally designed, the environment was a simple AD domain with a domain controller, a couple of servers and a couple of workstations. This was great for practicing reconnaissance and basic AD attacks, but it wasn’t great for practicing evasion, because the only thing to evade was basic Windows Defender, which isn’t nothing, but it lacks a lot of the capabilities of more advanced EDR.
Getting a proper EDR in a lab environment is challenging because, frankly, it costs money, and some vendors may not want to let you set up an environment where you’re trying to figure out how to evade their product. Enter Elastic Defend, a capable, free EDR solution which you can self-host. The free version provides malware detection and prevention, as well as event collection. You can choose to activate a 30-day free trial which will enable features such as memory analysis, malicious behavior detection, and attack surface reduction. Elastic has a page where you can request a 30-day extension to a trial license, but I don’t know how many times they’ll do that before saying “no more.”
To add Elastic Defend to our lab, we’re going to need to add two Linux servers to the environment. I’m using a pair of Debian 13 hosts each with 60 GB of hard drive space, and one with 8GB of RAM and one with 2GB. The former will run Elastic and Kibana, the latter will run Fleet. I’m going to leave standing up the VMs as an exercise for the reader, though I will note that they need to be in the same network as the rest of your lab environment, and should either have a static DHCP lease, or just a static IP. In my case, I put my Elastic/Kibana server at 10.1.0.4 and the Fleet server at 10.1.0.5.
WARNING: Just as I am not an AD admin, neither am I an Elastic admin. DO NOT use these instructions to attempt to set up Elastic Stack in a production environment. These instructions are to help one set up a bare-bones Elastic installation sufficient for using Elastic Defend in a small lab environment and ignore many details one should address in a production environment.
The first step is to prepare the Elastic Stack/Kibana server at 10.1.0.4. Elastic Stack has decent installation instructions, which I’ll summarize here. One caveat, though: do not use the quick installer. For reasons I’ve not been able to figure out, a data view that’s necessary to run Elastic Defend doesn’t appear to get created when using the quick installer. This setup uses the Debian packages instead.
Up-to-date instructions are available from Elastic here, the below are provided for reference.
First, we need to install the public signing key by downloading it using wget, then dearmoring and saving it using gpg, as shown below.
wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo gpg --dearmor -o /usr/share/keyrings/elasticsearch-keyring.gpg
To install from the APT repository, we need to ensure apt-transport-https is installed, save the repository definition to the /etc/apt/sources.list.d/ directory, then install with apt, using the following commands:
1sudo apt-get install apt-transport-https
2echo "deb [signed-by=/usr/share/keyrings/elasticsearch-keyring.gpg] https://artifacts.elastic.co/packages/9.x/apt stable main" | sudo tee /etc/apt/sources.list.d/elastic-9.x.list
3sudo apt-get update && sudo apt-get install elasticsearch && sudo apt-get install kibana
Elastic has some specific configuration needs related to system resource management, most of which will be handled by the package installer. There are some things you’ll need to address manually, however. The first is disabling swapping on the host, as Elastic really doesn’t like it when the system swaps. The easiest way to do this is to comment out the swap filesystem in /etc/fstab, as shown below then reboot the host.

Swap Filesystem Disabled in /etc/fstab
Elastic used Java Native Access (JNA) to execute some platform-dependent code. So, if your /tmp directory has the noexec option on it in /etc/fstab, you will need to either remove that option then reboot the host, or create an alternative such as /usr/share/elasticsearch/temp and change the Elastic service file in /usr/lib/systemd/system/elasticsearch.service to use that directory. You can do this by adding the following line to the [Service] section of the elasticsearch.service file:
Environment=ES_TMPDIR/usr/share/elasticsearch/tmp
Elastic also needs to have the available virtual memory on the host increased, which can be set by adding a file vm.max_mem_count.conf file to /etc/sysctl.d with the following contents:
vm.max_mem_count = 1048576
For Kibana, we need to make the web management port accessible to other hosts on the network. Edit the /etc/kibana/kibana.yml file and add the following line:
server.host: 0.0.0.0
Also, to enable the Fleet integration, which we use to manage Elastic Agents and is a prerequisite for running Elastic Defend, we’ll need to configure Kibana object encryption. To generate the encryption keys, execute the following command:
sudo /usr/share/kibana/bin/kibana-encryption-keys generate
As shown below, this will produce a set of lines which you will need to add to the end of the /etc/kibana/kibana.yml configuration file.

Generating Kibana Encryption Keys
Now, we can enable and start the services:
systemctl daemon-reload
systemctl enable elasticsearch.service
systemctl enable kibana.service
systemctl start elasticsearch.service
systemctl start kibana.service
In order to access Kibana, we need to check Kibana’s status by executing systemctl status kibana. In the log entries, you should see an instruction telling you where to access the server to finish configuration. In my case, that was https://10.1.0.21:5601?code=475302, where you’ll be prompted for a login token as shown below.

Prompting for Enrollment Token
If we’d manually started Elastic on the command line, we’d have received the token then. But since we started it as a service, we need to generate one using the following command:
/usr/share/elasticsearch/bin/elasticsearch-create-token -s kibana
Enter the resulting token into the web page, and, as shown below, you’ll be prompted to add integrations.

Add Integrations
We’re going to need two integrations: Fleet for centralized management of Elastic Agents, and Defend, which is the actual EDR component. We’ll start with Fleet. Click the Add Integrations button, enter fleet in the search bar on the Integrations page, and select the Fleet Server integration.

Fleet Server Integration
You’ll be prompted to provide some basic details about your Fleet Integration. You need to name your Fleet server and the agent policy, but the rest of the details are optional.
When prompted to add Elastic Agents to your host, choose to do that later, as we still have some Fleet setup to finish.

Add Elastic Agent Later
Specifically, we need to add a Fleet server, which you have an option to do on the Agent Policy page you can reach by clicking the Add Elastic Agent later.

Add Fleet Server
When configuring your fleet server, leave your Agent Policy as Agent policy 1, select Quick Start for the deployment mode, and specify the host you’ll be running the Fleet server on. This will be the second Debian host we created at the beginning. In my case, I haven’t given this host a DNS record yet, so I’m just using the IP address. You can disregard the Authentication options, then click Add Host.

Setting Fleet Server Host
You should then be presented with confirmation you’ve added a Fleet Server, and get prompted to generate a service token. Do so.

Fleet Server Added
Save the token somewhere secure, and then go to Install Fleet Server to a centralized host. In the architecture options bar, select the expanded menu at the far right and select Linux X86_64. The DEB x86_64 option may look tempting, but the .deb versions of the agent aren’t self-updating.

Setting Elastic Agent Installer
You can then take the commands Elastic provides and use them to install the Elastic Agent. IMPORTANT: you MUST add the --insecure flag to the ./elastic-agent install command. This will permit the agent to communicate with the Elasticsearch server, which in our lab environment is running with a self-signed certificate. Note that the install command will interrupt you with a request for you to confirm you really want to install this service, so, be on the lookout for that.

Specifying –insecure Flag to Allow Self-Signed Certificates
Hopefully, at the end, you should receive a message that the agent has been installed successfully. You may need to reboot the Fleet server before it properly reports in at the Elasticsearch server. Once your Fleet server is reporting as healthy, we can move on to installing the Elastic Defend integration and one or more Elastic Agents on our lab hosts. In the search bar at the top of the page, start typing in integrations until the Integrations page appears in the search results.

Integrations
Click the go to button and you’ll be taken back to the integrations page, where searching for defend will bring up Elastic Defend. Note, we’re not using Defend for Containers, as there are no containers in our lab.

Selecting Elastic Defend Integration
Select the Elastic Defend integration, and on the next page, hit the Add Elastic Defend button. You’ll need to configure a name for the integration, write a short description, set the integration configuration, and create an agent policy. I chose to create a new policy as the only other Elastic Agent I have deployed is the one running the Fleet server, and for purposes of this lab, I don’t need that running Defend.

Configuring Defend Integration
With the Defend integration configured, now it’s time to put the Elastic Agent on one or more hosts in the environment. You can either click the Add Elastic Agent to your hosts button, or go to the Integration Policies tab of the Defend integration page and click Add agent.

Adding Agent to Elastic Defend
In the Add agent screen, leave the enrollment token defaults in place, and then under the install section, use the menu in the far right tab to select Windows x86_64, and copy all but the final command displayed into an administrator shell on the intended host.

Selecting Elastic Agent Installer
As when installing the Elastic Agent for the Fleet server, you must append the --insecure flag to the final install command, or it will fail when it encounters the server’s self-signed certificate.

Installing Elastic Agent with –insecure Flag
Shortly after running the install command, you should receive back a notification that the agent has successfully called back to the Fleet server. At this point we can test to confirm that Defend is working. I have a Kali VM in my lab environment, so I used scp to copy Mimikatz from /usr/share/windows-resources/mimikatz/x64 over to the host I’d just installed the Elastic Agent on, in this case rsl-wks-2.rslabs.lan.

Copying Mimikatz.exe to Elastic Defend-Protected Host
The transfer appeared to have succeeded, but looking in C:\temp on rsl-wks-2, there’s nothing there.

Mimikatz not in Destination Folder
To see what happened, I select the Security>Alerts item in the hamburger menu in the upper left corner of the page.

Accessing the Security > Alerts Dashboard
The Alerts dashboard reveals that there’s a new malware prevention alert. Clicking on the expand icon at the left of the row will show more details.

The details pane gives a lot more information, including a text summary of why the Defend raised the alert, as well as the username, process and rule name involved in the alert, as shown below.

Alert Details
As I mentioned at the beginning, Elastic offers a 30-day trial license that will give you access to all of Defend’s features and capabilities. To activate the trial license, once you have everything installed, search for License Management in the main search bar, and hit the Start Trial button on the license management page to start the process.

Starting Elastic Free Trial
Congratulations – you now have a full-featured EDR against which you can test your tooling and payloads. Happy hacking!

Justin Palk has more than 16 years of experience in IT and information security, and has worked in the academic, federal civilian government and health research sectors. He has held a variety of roles including system administrator, developer, auditor, assessment team lead and web application penetration tester. He regularly competes in CTFs in the U.S. and Europe.
Certifications:
GCIH, GWAPT, GPEN, GMOB, GDSA
Related Stories
View MoreBy Red Siege | September 3, 2026
by Justin Palk A couple of years ago, I put together a series on standing up a simple Windows AD domain in a lab environment. This article is part of […]
Learn MoreBy Red Siege | August 13, 2026
by Justin Palk A couple of years ago, I put together a series on standing up a simple Windows AD domain in a lab environment. This article is part of […]
Learn MoreBy Red Siege | June 11, 2026
EDD: PowerView’s .NET Cousin By Jason Downey If you’ve done any Active Directory enumeration, you’ve probably used PowerView. It for a bunch of years was the gold standard, so much […]
Learn More