Monday, April 08, 2019

Troubleshooting NSM Virtualization Problems with Linux and VirtualBox

I spent a chunk of the day troubleshooting a network security monitoring (NSM) problem. I thought I would share the problem and my investigation in the hopes that it might help others. The specifics are probably less important than the general approach.

It began with ja3. You may know ja3 as a set of Zeek scripts developed by the Salesforce engineering team to profile client and server TLS parameters.

I was reviewing Zeek logs captured by my Corelight appliance and by one of my lab sensors running Security Onion. I had coverage of the same endpoint in both sensors.

I noticed that the SO Zeek logs did not have ja3 hashes in the ssl.log entries. Both sensors did have ja3s hashes. My first thought was that SO was misconfigured somehow to not record ja3 hashes. I quickly dismissed that, because it made no sense. Besides, verifying that intution required me to start troubleshooting near the top of the software stack.

I decided to start at the bottom, or close to the bottom. I had a sinking suspicion that, for some reason, Zeek was only seeing traffic sent from remote systems, and not traffic originating from my network. That would account for the creation of ja3s hashes, for traffic sent by remote systems, but not ja3 hashes, as Zeek was not seeing traffic sent by local clients.

I was running SO in VirtualBox 6.0.4 on Ubuntu 18.04. I started sniffing TCP network traffic on the SO monitoring interface using Tcpdump. As I feared, it didn't look right. I ran a new capture with filters for ICMP and a remote IP address. On another system I tried pinging the remote IP address. Sure enough, I only saw ICMP echo replies, and no ICMP echoes. Oddly, I also saw doubles and triples of some of the ICMP echo replies. That worried me, because unpredictable behavior like that could indicate some sort of software problem.

My next step was to "get under" the VM guest and determine if the VM host could see traffic properly. I ran Tcpdump on the Ubuntu 18.04 host on the monitoring interface and repeated my ICMP tests. It saw everything properly. That meant I did not need to bother checking the switch span port that was feeding traffic to the VirtualBox system.

It seemed I had a problem somewhere between the VM host and guest. On the same VM host I was also running an instance of RockNSM. I ran my ICMP tests on the RockNSM VM and, sadly, I got the same one-sided traffic as seen on SO.

Now I was worried. If the problem had only been present in SO, then I could fix SO. If the problem is present in both SO and RockNSM, then the problem had to be with VirtualBox -- and I might not be able to fix it.

I reviewed my configurations in VirtualBox, ensuring that the "Promiscuous Mode" under the Advanced options was set to "Allow All". At this point I worried that there was a bug in VirtualBox. I did some Google searches and reviewed some forum posts, but I did not see anyone reporting issues with sniffing traffic inside VMs. Still, my use case might have been weird enough to not have been reported.

I decided to try a different approach. I wondered if running VirtualBox with elevated privileges might make a difference. I did not want to take ownership of my user VMs, so I decided to install a new VM and run it with elevated privileges.

Let me stop here to note that I am breaking one of the rules of troubleshooting. I'm introducing two new variables, when I should have introduced only one. I should have built a new VM but run it with the same user privileges with which I was running the existing VMs.

I decided to install a minimal edition of Ubuntu 9, with VirtualBox running via sudo. When I started the VM and sniffed traffic on the monitoring port, lo and behold, my ICMP tests revealed both sides of the traffic as I had hoped. Unfortunately, from this I erroneously concluded that running VirtualBox with elevated privileges was the answer to my problems.

I took ownership of the SO VM in my elevated VirtualBox session, started it, and performed my ICMP tests. Womp womp. Still broken.

I realized I needed to separate the two variables that I had entangled, so I stopped VirtualBox, and changed ownership of the Debian 9 VM to my user account. I then ran VirtualBox with user privileges, started the Debian 9 VM, and ran my ICMP tests. Success again! Apparently elevated privileges had nothing to do with my problem.

By now I was glad I had not posted anything to any user forums describing my problem and asking for help. There was something about the monitoring interface configurations in both SO and RockNSM that resulted in the inability to see both sides of traffic (and avoid weird doubles and triples).

I started my SO VM again and looked at the script that configured the interfaces. I commented out all the entries below the management interface as shown below.

$ cat /etc/network/interfaces

# This configuration was created by the Security Onion setup script.
#
# The original network interface configuration file was backed up to:
# /etc/network/interfaces.bak.
#
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

# loopback network interface
auto lo
iface lo inet loopback

# Management network interface
auto enp0s3
iface enp0s3 inet static
  address 192.168.40.76
  gateway 192.168.40.1
  netmask 255.255.255.0
  dns-nameservers 192.168.40.1
  dns-domain localdomain

#auto enp0s8
#iface enp0s8 inet manual
#  up ip link set $IFACE promisc on arp off up
#  down ip link set $IFACE promisc off down
#  post-up ethtool -G $IFACE rx 4096; for i in rx tx sg tso ufo gso gro lro; do ethtool -K $IFACE $i off; done
#  post-up echo 1 > /proc/sys/net/ipv6/conf/$IFACE/disable_ipv6

#auto enp0s9
#iface enp0s9 inet manual
#  up ip link set $IFACE promisc on arp off up
#  down ip link set $IFACE promisc off down
#  post-up ethtool -G $IFACE rx 4096; for i in rx tx sg tso ufo gso gro lro; do ethtool -K $IFACE $i off; done
#  post-up echo 1 > /proc/sys/net/ipv6/conf/$IFACE/disable_ipv6

I rebooted the system and brought the enp0s8 interface up manually using this command:

$ sudo ip link set enp0s8 promisc on arp off up

Fingers crossed, I ran my ICMP sniffing tests, and voila, I saw what I needed -- traffic in both directions, without doubles or triples no less.

So, there appears to be some sort of problem with the way SO and RockNSM set parameters for their monitoring interfaces, at least as far as they interact with VirtualBox 6.0.4 on Ubuntu 18.04. You can see in the network script that SO disables a bunch of NIC options. I imagine one or more of them is the culprit, but I didn't have time to work through them individually.

I tried taking a look at the network script in RockNSM, but it runs CentOS, and I'll be darned if I can't figure out where to look. I'm sure it's there somewhere, but I didn't have the time to figure out where.

The moral of the story is that I should have immediately checked after installation that both SO and RockNSM were seeing both sides of the traffic I expected them to see. I had taken that for granted for many previous deployments, but something broke recently and I don't know exactly what. My workaround will hopefully hold for now, but I need to take a closer look at the NIC options because I may have introduced another fault.

A second moral is to be careful of changing two or more variables when troubleshooting. When you do that you might fix a problem, but not know what change fixed the issue.

Thursday, March 28, 2019

Thoughts on OSSEC Con 2019

Last week I attended my first OSSEC conference. I first blogged about OSSEC in 2007, and wrote other posts about it in the following years.

OSSEC is a host-based intrusion detection and log analysis system with correlation and active response features. It is cross-platform, such that I can run it on my Windows and Linux systems. The moving force behind the conference was a company local to me called Atomicorp.

In brief, I really enjoyed this one-day event. (I had planned to attend the workshop on the second day but my schedule did not cooperate.) The talks were almost uniformly excellent and informative. I even had a chance to talk jiu-jitsu with OSSEC creator Daniel Cid, who despite hurting his leg managed to travel across the country to deliver the keynote.

I'd like to share a few highlights from my notes.

First, I had been worried that OSSEC was in some ways dead. I saw that the Security Onion project had replaced OSSEC with a fork called Wazuh, which I learned is apparently pronounced "wazoo." To my delight, I learned OSSEC is decidedly not dead, and that Wazuh has been suffering stability problems. OSSEC has a lot of interesting development ahead of it, which you can track on their Github repo.

For example, the development roadmap includes eliminating Logstash from the pipeline used by many OSSEC users. OSSEC would feed directly into Elasticsearch. One speaker noted that Logstash has a 1.7 GB memory footprint, which astounded me.

On a related note, the OSSEC team is planning to create a new Web console, with a design goal to have it run in an "AWS t2.micro" instance. The team noted that instance offers 2 GB memory, which doesn't match what AWS says. Perhaps they meant t2.micro and 1 GB memory, or t2.small with 2 GB memory. I think they mean t2.micro with 1 GB RAM, as that is the free tier. Either way, I'm excited to see this later in 2019.

Second, I thought the presentation by security personnel from USA Today offered an interesting insight. One design goal they had for monitoring their Google Cloud Platform (GCP) was to not install OSSEC on every container or on Kubernetes worker nodes. Several times during the conference, speakers noted that the transient nature of cloud infrastructure is directly antithetical to standard OSSEC usage, whereby OSSEC is installed on servers with long uptime and years of service. Instead, USA Today used OSSEC to monitor HTTP logs from the GCP load balancer, logs from Google Kubernetes Engine, and monitored processes by watching output from successive kubectl invocations.

Third, a speaker from Red Hat brought my attention to an aspect of containers that I had not considered. Docker and containers had made software testing and deployment a lot easier for everyone. However, those who provide containers have effectively become Linux distribution maintainers. In other words, who is responsible when a security or configuration vulnerability in a Linux component is discovered? Will the container maintainers be responsive?

Another speaker emphasized the difference between "security of the cloud," offered by cloud providers, and "security in the cloud," which is supposed to be the customer's responsibility. This makes sense from a technical point of view, but I expect that in the long term this differentiation will no longer be tenable from a business or legal point of view.

Customers are not going to have the skills or interest to secure their software in the cloud, as they outsource ever more technical talent to the cloud providers and their infrastructure. I expect cloud providers to continue to develop, acquire, and offer more security services, and accelerate their competition on a "complete security environment."

I look forward to more OSSEC development and future conferences.

Wednesday, March 13, 2019

Thoughts on Cloud Security

Recently I've been reading about cloud security and security with respect to DevOps. I'll say more about the excellent book I'm reading, but I had a moment of déjà vu during one section.

The book described how cloud security is a big change from enterprise security because it relies less on IP-address-centric controls and more on users and groups. The book talked about creating security groups, and adding users to those groups in order to control their access and capabilities.

As I read that passage, it reminded me of a time long ago, in the late 1990s, when I was studying for the MCSE, then called the Microsoft Certified Systems Engineer. I read the book at left, Windows NT Security Handbook, published in 1996 by Tom Sheldon. It described the exact same security process of creating security groups and adding users. This was core to the new NT 4 role based access control (RBAC) implementation.

Now, fast forward a few years, or all the way to today, and consider the security challenges facing the majority of legacy enterprises: securing Windows assets and the data they store and access. How could this wonderful security model, based on decades of experience (from the 1960s and 1970s no less), have failed to work in operational environments?

There are many reasons one could cite, but I think the following are at least worthy of mention.

The systems enforcing the security model are exposed to intruders.

Furthermore:

Intruders are generally able to gain code execution on systems participating in the security model.

Finally:

Intruders have access to the network traffic which partially contains elements of the security model.

From these weaknesses, a large portion of the security countermeasures of the last two decades have been derived as compensating controls and visibility requirements.

The question then becomes:

Does this change with the cloud?

In brief, I believe the answer is largely "yes," thankfully. Generally, the systems upon which the security model is being enforced are not able to access the enforcement mechanism, thanks to the wonders of virtualization.

Should an intruder find a way to escape from their restricted cloud platform and gain hypervisor or management network access, then they find themselves in a situation similar to the average Windows domain network.

This realization puts a heavy burden on the cloud infrastructure operators. They major players are likely able to acquire and apply the expertise and resources to make their infrastructure far more resilient and survivable than their enterprise counterparts.

The weakness will likely be their personnel.

Once the compute and network components are sufficiently robust from externally sourced compromise, then internal threats become the next most cost-effective and return-producing vectors for dedicated intruders.

Is there anything users can do as they hand their compute and data assets to cloud operators?

I suggest four moves.

First, small- to mid-sized cloud infrastructure users will likely have to piggyback or free-ride on the initiatives and influence of the largest cloud customers, who have the clout and hopefully the expertise to hold the cloud operators responsible for the security of everyone's data.

Second, lawmakers may also need improved whistleblower protection for cloud employees who feel threatened by revealing material weaknesses they encounter while doing their jobs.

Third, government regulators will have to ensure no cloud provider assumes a monopoly, or no two providers assume a duopoloy. We may end up with the three major players and a smattering of smaller ones, as is the case with many mature industries.

Fourth, users should use every means at their disposal to select cloud operators not only on their compute features, but on their security and visibility features. The more logging and visibility exposed by the cloud provider, the better. I am excited by new features like the Azure network tap and hope to see equivalent features in other cloud infrastructure.

Remember that security has two main functions: planning/resistance, to try to stop bad things from happening, and detection/respond, to handle the failures that inevitably happen. "Prevention eventually fails" is one of my long-time mantras. We don't want prevention to fail silently in the cloud. We need ways to know that failure is happening so that we can plan and implement new resistance mechanisms, and then validate their effectiveness via detection and response.

Update: I forgot to mention that the material above assumed that the cloud users and operators made no unintentional configuration mistakes. If users or operators introduce exposures or vulnerabilities, then those will be the weaknesses that intruders exploit. We've already seen a lot of this happening and it appears to be the most common problem. Procedures and tools which constantly assess cloud configurations for exposures and vulnerabilities due to misconfiguration or poor practices are a fifth move which all involved should make.

A corollary is that complexity can drive problems. When the cloud infrastructure offers too many knobs to turn, then it's likely the users and operators will believe they are taking one action when in reality they are implementing another.

Saturday, February 09, 2019

Forcing the Adversary to Pursue Insider Theft

Jack Crook pointed me toward a story by Christopher Burgess about intellectual property theft by "Hongjin Tan, a 35 year old Chinese national and U.S. legal permanent resident... [who] was arrested on December 20 and charged with theft of trade secrets. Tan is alleged to have stolen the trade secrets from his employer, a U.S. petroleum company," according to the criminal complaint filed by the US DoJ.

Tan's former employer and the FBI allege that Tan "downloaded restricted files to a personal thumb drive." I could not tell from the complaint if Tan downloaded the files at work or at home, but the thumb drive ended up at Tan's home. His employer asked Tan to bring it to their office, which Tan did. However, he had deleted all the files from the drive. Tan's employer recovered the files using commercially available forensic software.

This incident, by definition, involves an "insider threat." Tan was an employee who appears to have copied information that was outside the scope of his work responsibilities, resigned from his employer, and was planning to return to China to work for a competitor, having delivered his former employer's intellectual property.

When I started GE-CIRT in 2008 (officially "initial operating capability" on 1 January 2009), one of the strategies we pursued involved insider threats. I've written about insiders on this blog before but I couldn't find a description of the strategy we implemented via GE-CIRT.

We sought to make digital intrusions more expensive than physical intrusions.

In other words, we wanted to make it easier for the adversary to accomplish his mission using insiders. We wanted to make it more difficult for the adversary to accomplish his mission using our network.

In a cynical sense, this makes security someone else's problem. Suddenly the physical security team is dealing with the worst of the worst!

This is a win for everyone, however. Consider the many advantages the physical security team has over the digital security team.

The physical security team can work with human resources during the hiring process. HR can run background checks and identify suspicious job applicants prior to granting employment and access.

Employees are far more exposed than remote intruders. Employees, even under cover, expose their appearance, likely residence, and personalities to the company and its workers.

Employees can be subject to far more intensive monitoring than remote intruders. Employee endpoints can be instrumented. Employee workspaces are instrumented via access cards, cameras at entry and exit points, and other measures.

Employers can cooperate with law enforcement to investigate and prosecute employees. They can control and deter theft and other activities.

In brief, insider theft, like all "close access" activities, is incredibly risky for the adversary. It is a win for everyone when the adversary must resort to using insiders to accomplish their mission. Digital and physical security must cooperate to leverage these advantages, while collaborating with human resources, legal, information technology, and business lines to wring the maximum results from this advantage.

Tuesday, January 29, 2019

Fixing Virtualbox RDP Server with DetectionLab

Yesterday I posted about DetectionLab, but noted that I was having trouble with the RDP servers offered by Virtualbox. If you remember, DetectionLab builds four virtual machines:

root@LAPTOP-HT4TGVCP C:\Users\root>"c:\Program Files\Oracle\VirtualBox\VBoxManage" list runningvms
"logger" {3da9fffb-4b02-4e57-a592-dd2322f14245}
"dc.windomain.local" {ef32d493-845c-45dc-aff7-3a86d9c590cd}
"wef.windomain.local" {7cd008b7-c6e0-421d-9655-8f92ec98d9d7}
"win10.windomain.local" {acf413fb-6358-44df-ab9f-cc7767ed32bd}

I was having a problem with two of the VMs sharing the same port for the RDP server offered by Virtualbox. This meant I could not access one of them. (Below, port 5932 has the conflict.)

root@LAPTOP-HT4TGVCP C:\Users\root\git\detectionlab\DetectionLab\Vagrant>"c:\Program Files\Oracle\VirtualBox\VBoxManage" showvminfo logger | findstr /I vrde | findstr /I address
VRDE:                        enabled (Address 0.0.0.0, Ports 5955, MultiConn: off, ReuseSingleConn: off, Authentication type: null)
VRDE property               : TCP/Address  = "0.0.0.0"

root@LAPTOP-HT4TGVCP C:\Users\root\git\detectionlab\DetectionLab\Vagrant>"c:\Program Files\Oracle\VirtualBox\VBoxManage" showvminfo dc.windomain.local | findstr /I vrde | findstr /I address
VRDE:                        enabled (Address 0.0.0.0, Ports 5932, MultiConn: off, ReuseSingleConn: off, Authentication type: null)
VRDE property               : TCP/Address = "0.0.0.0"

root@LAPTOP-HT4TGVCP C:\Users\root\git\detectionlab\DetectionLab\Vagrant>"c:\Program Files\Oracle\VirtualBox\VBoxManage" showvminfo wef.windomain.local | findstr /I vrde | findstr /I address
VRDE:                        enabled (Address 0.0.0.0, Ports 5932, MultiConn: off, ReuseSingleConn: off, Authentication type: null)
VRDE property               : TCP/Address = "0.0.0.0"

root@LAPTOP-HT4TGVCP C:\Users\root\git\detectionlab\DetectionLab\Vagrant>"c:\Program Files\Oracle\VirtualBox\VBoxManage" showvminfo win10.windomain.local | findstr /I vrde | findstr /I address
VRDE:                        enabled (Address 0.0.0.0, Ports 5981, MultiConn: off, ReuseSingleConn: off, Authentication type: null)
VRDE property               : TCP/Address = "0.0.0.0"

To fix this, I explicitly added port values to the configuration in the Vagrantfile. Here is one example:

      vb.customize ["modifyvm", :id, "--vrde", "on"]
      vb.customize ["modifyvm", :id, "--vrdeaddress", "0.0.0.0"]
      vb.customize ["modifyvm", :id, "--vrdeport", "60101"]

After a 'vagrant reload', the RDP servers were now listening on new ports, as I hoped.

root@LAPTOP-HT4TGVCP C:\Users\root\git\detectionlab\DetectionLab\Vagrant>"c:\Program Files\Oracle\VirtualBox\VBoxManage" showvminfo logger | findstr /I vrde | findstr /I address
VRDE:                        enabled (Address 0.0.0.0, Ports 60101, MultiConn: off, ReuseSingleConn: off, Authentication type: null)
VRDE property               : TCP/Address  = "0.0.0.0"

root@LAPTOP-HT4TGVCP C:\Users\root\git\detectionlab\DetectionLab\Vagrant>"c:\Program Files\Oracle\VirtualBox\VBoxManage" showvminfo dc.windomain.local | findstr /I vrde | findstr /I address
VRDE:                        enabled (Address 0.0.0.0, Ports 60102, MultiConn: off, ReuseSingleConn: off, Authentication type: null)
VRDE property               : TCP/Address = "0.0.0.0"

root@LAPTOP-HT4TGVCP C:\Users\root\git\detectionlab\DetectionLab\Vagrant>"c:\Program Files\Oracle\VirtualBox\VBoxManage" showvminfo wef.windomain.local | findstr /I vrde | findstr /I address
VRDE:                        enabled (Address 0.0.0.0, Ports 60103, MultiConn: off, ReuseSingleConn: off, Authentication type: null)
VRDE property               : TCP/Address = "0.0.0.0"

root@LAPTOP-HT4TGVCP C:\Users\root\git\detectionlab\DetectionLab\Vagrant>"c:\Program Files\Oracle\VirtualBox\VBoxManage" showvminfo win10.windomain.local | findstr /I vrde | findstr /I address
VRDE:                        enabled (Address 0.0.0.0, Ports 60104, MultiConn: off, ReuseSingleConn: off, Authentication type: null)
VRDE property               : TCP/Address = "0.0.0.0"

This is great, but I am still encountering a problem with avoiding port collisions when Vagrant remaps ports for services on the VMs.

root@LAPTOP-HT4TGVCP C:\Users\root\git\detectionlab\DetectionLab\Vagrant>vagrant status
Current machine states:

logger                    running (virtualbox)
dc                        running (virtualbox)
wef                       running (virtualbox)
win10                     running (virtualbox)

This environment represents multiple VMs. The VMs are all listed
above with their current state. For more information about a specific
VM, run `vagrant status NAME`.

root@LAPTOP-HT4TGVCP C:\Users\root\git\detectionlab\DetectionLab\Vagrant>vagrant port logger
The forwarded ports for the machine are listed below. Please note that
these values may differ from values configured in the Vagrantfile if the
provider supports automatic port collision detection and resolution.

    22 (guest) => 2222 (host)

root@LAPTOP-HT4TGVCP C:\Users\root\git\detectionlab\DetectionLab\Vagrant>vagrant port dc
The forwarded ports for the machine are listed below. Please note that
these values may differ from values configured in the Vagrantfile if the
provider supports automatic port collision detection and resolution.

  3389 (guest) => 3389 (host)
    22 (guest) => 2200 (host)
  5985 (guest) => 55985 (host)
  5986 (guest) => 55986 (host)

root@LAPTOP-HT4TGVCP C:\Users\root\git\detectionlab\DetectionLab\Vagrant>vagrant port wef
The forwarded ports for the machine are listed below. Please note that
these values may differ from values configured in the Vagrantfile if the
provider supports automatic port collision detection and resolution.

  3389 (guest) => 2201 (host)
    22 (guest) => 2202 (host)
  5985 (guest) => 2203 (host)
  5986 (guest) => 2204 (host)

root@LAPTOP-HT4TGVCP C:\Users\root\git\detectionlab\DetectionLab\Vagrant>vagrant port win10
The forwarded ports for the machine are listed below. Please note that
these values may differ from values configured in the Vagrantfile if the
provider supports automatic port collision detection and resolution.

  3389 (guest) => 2205 (host)
    22 (guest) => 2206 (host)
  5985 (guest) => 2207 (host)
  5986 (guest) => 2208 (host)

The entry in bold is the problem. Vagrant should not be mapping port 3389, which is already in use by the RDP server on the Windows 10 host, such that it tries to be available to the guest.

I tried telling Vagrant by hand in the Vagrantfile to map port 3389 elsewhere, but nothing worked. (I tried entries like the following.)

    config.vm.network :forwarded_port, guest: 3389, host: 5789

I also searched to see if there might be a configuration outside the Vagrantfile that I was missing. Here is what I found:

ds61@ds61:~/DetectionLab-master$ find . | xargs grep "3389" *
./Terraform/Method1/main.tf:    from_port   = 3389
./Terraform/Method1/main.tf:    to_port     = 3389
./Packer/vagrantfile-windows_2016.template:    config.vm.network :forwarded_port, guest: 3389, host: 3389, id: "rdp", auto_correct: true
./Packer/scripts/enable-rdp.bat:netsh advfirewall firewall add rule name="Open Port 3389" dir=in action=allow protocol=TCP localport=3389
./Packer/vagrantfile-windows_10.template:    config.vm.network :forwarded_port, guest: 3389, host: 3389, id: "rdp", auto_correct: true

I wonder if those Packer templates have anything to do with it, or if I am encountering a problem with Vagrant? I have seen many people experience similar issues, so I don't know.

It's not a big deal, though. Now that I can directly access the virtual screens for each VM on Virtualbox via the RDP server, I don't need to RDP to port 3389 on each Windows VM in order to interact with it.

If anyone has any ideas, though, I'm interested!

Monday, January 28, 2019

Trying DetectionLab

Many security professionals run personal labs. Trying to create an environment that includes fairly modern Windows systems can be a challenge. In the age of "infrastructure as code," there should be a simpler way to deploy systems in a repeatable, virtualized way -- right?

Enter DetectionLab, a project by Chris Long. Briefly, Chris built a project that uses Packer and Vagrant to create an instrumented lab environment. Chris explained the project in late 2017 in a Medium post, which I recommend reading.

I can't even begin to describe all the functionality packed into this project. So much of it is new, but this is a great way to learn about it. In this post, I would like to show how I got a version of DetectionLab running.

My build environment included a modern laptop with 16 GB RAM and Windows 10 professional. I had already installed Virtualbox 6.0 with the appropriate VirtualBox Extension Pack. I had also enabled the native OpenSSH server and performed all DetectionLab installation functions over an OpenSSH session.

Install Chocolatey

My first step was to install Chocolatey, a package manager for Windows. I wanted to use this to install the Git client I wanted to use to clone the DetectionLab repo. Commands I typed at each stage are in bold below.

root@LAPTOP-HT4TGVCP C:\Users\root>@"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -InputFormat None -ExecutionPolicy Bypass -Command "ie
x ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))" && SET "PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin"
Getting latest version of the Chocolatey package for download.
Getting Chocolatey from https://chocolatey.org/api/v2/package/chocolatey/0.10.11.
Downloading 7-Zip commandline tool prior to extraction.
Extracting C:\Users\root\AppData\Local\Temp\chocolatey\chocInstall\chocolatey.zip to C:\Users\root\AppData\Local\Temp\chocolatey\chocInstall...
Installing chocolatey on this machine
Creating ChocolateyInstall as an environment variable (targeting 'Machine')
  Setting ChocolateyInstall to 'C:\ProgramData\chocolatey'
WARNING: It's very likely you will need to close and reopen your shell
  before you can use choco.
Restricting write permissions to Administrators
We are setting up the Chocolatey package repository.
The packages themselves go to 'C:\ProgramData\chocolatey\lib'
  (i.e. C:\ProgramData\chocolatey\lib\yourPackageName).
A shim file for the command line goes to 'C:\ProgramData\chocolatey\bin'
  and points to an executable in 'C:\ProgramData\chocolatey\lib\yourPackageName'.

Creating Chocolatey folders if they do not already exist.

WARNING: You can safely ignore errors related to missing log files when
  upgrading from a version of Chocolatey less than 0.9.9.
  'Batch file could not be found' is also safe to ignore.
  'The system cannot find the file specified' - also safe.
chocolatey.nupkg file not installed in lib.
 Attempting to locate it from bootstrapper.
PATH environment variable does not have C:\ProgramData\chocolatey\bin in it. Adding...
WARNING: Not setting tab completion: Profile file does not exist at 'C:\Users\root\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1'.
Chocolatey (choco.exe) is now ready.
You can call choco from anywhere, command line or powershell by typing choco.
Run choco /? for a list of functions.
You may need to shut down and restart powershell and/or consoles
 first prior to using choco.
Ensuring chocolatey commands are on the path
Ensuring chocolatey.nupkg is in the lib folder

root@LAPTOP-HT4TGVCP C:\Users\root>choco
Chocolatey v0.10.11
Please run 'choco -?' or 'choco -?' for help menu.

Install Git

With Chocolatey installed, I could install Git.

root@LAPTOP-HT4TGVCP C:\Users\root>choco install git -params '"/GitAndUnixToolsOnPath"'
Chocolatey v0.10.11
Installing the following packages:
git
By installing you accept licenses for the packages.
Progress: Downloading git.install 2.20.1... 100%
Progress: Downloading chocolatey-core.extension 1.3.3... 100%
Progress: Downloading git 2.20.1... 100%

chocolatey-core.extension v1.3.3 [Approved]
chocolatey-core.extension package files install completed. Performing other installation steps.
 Installed/updated chocolatey-core extensions.
 The install of chocolatey-core.extension was successful.
  Software installed to 'C:\ProgramData\chocolatey\extensions\chocolatey-core'

git.install v2.20.1 [Approved]
git.install package files install completed. Performing other installation steps.
The package git.install wants to run 'chocolateyInstall.ps1'.
Note: If you don't run this script, the installation will fail.
Note: To confirm automatically next time, use '-y' or consider:
choco feature enable -n allowGlobalConfirmation
Do you want to run the script?([Y]es/[N]o/[P]rint): y

@{Inno Setup CodeFile: Path Option=CmdTools; PSPath=Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Git_
is1; PSParentPath=Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall; PSChildName=Git_is1; PSDrive=HKLM; PS
Provider=Microsoft.PowerShell.Core\Registry}
Using Git LFS
Installing 64-bit git.install...
git.install has been installed.
git.install installed to 'C:\Program Files\Git'
  git.install can be automatically uninstalled.
Environment Vars (like PATH) have changed. Close/reopen your shell to
 see the changes (or in powershell/cmd.exe just type `refreshenv`).
 The install of git.install was successful.
  Software installed to 'C:\Program Files\Git\'

git v2.20.1 [Approved]
git package files install completed. Performing other installation steps.
 The install of git was successful.
  Software install location not explicitly set, could be in package or
  default install location if installer.

Chocolatey installed 3/3 packages.
 See the log for details (C:\ProgramData\chocolatey\logs\chocolatey.log).

Clone DetectionLab

With Git installed, I can clone the DetectionLab repo from Github.

root@LAPTOP-HT4TGVCP C:\Users\root>mkdir git

root@LAPTOP-HT4TGVCP C:\Users\root>cd git

root@LAPTOP-HT4TGVCP C:\Users\root\git>mkdir detectionlab

root@LAPTOP-HT4TGVCP C:\Users\root\git>cd detectionlab

root@LAPTOP-HT4TGVCP C:\Users\root\git\detectionlab>git clone https://github.com/clong/DetectionLab.git
'git' is not recognized as an internal or external command,
operable program or batch file.

root@LAPTOP-HT4TGVCP C:\Users\root\git\detectionlab>refreshenv
Refreshing environment variables from registry for cmd.exe. Please wait...Finished..

root@LAPTOP-HT4TGVCP C:\Users\root\git\detectionlab>git clone https://github.com/clong/DetectionLab.git
Cloning into 'DetectionLab'...
remote: Enumerating objects: 1, done.
remote: Counting objects: 100% (1/1), done.
remote: Total 1163 (delta 0), reused 0 (delta 0), pack-reused 1162R
Receiving objects: 100% (1163/1163), 11.81 MiB | 12.24 MiB/s, done.
Resolving deltas: 100% (568/568), done.

Install Vagrant

Before going any further, I needed to install Vagrant.

root@LAPTOP-HT4TGVCP C:\Users\root\git\detectionlab>cd ..\..\

root@LAPTOP-HT4TGVCP C:\Users\root>choco install vagrant
Chocolatey v0.10.11
Installing the following packages:
vagrant
By installing you accept licenses for the packages.
Progress: Downloading vagrant 2.2.3... 100%

vagrant v2.2.3 [Approved]
vagrant package files install completed. Performing other installation steps.
The package vagrant wants to run 'chocolateyinstall.ps1'.
Note: If you don't run this script, the installation will fail.
Note: To confirm automatically next time, use '-y' or consider:
choco feature enable -n allowGlobalConfirmation
Do you want to run the script?([Y]es/[N]o/[P]rint): y

Downloading vagrant 64 bit
  from 'https://releases.hashicorp.com/vagrant/2.2.3/vagrant_2.2.3_x86_64.msi'
Progress: 100% - Completed download of C:\Users\root\AppData\Local\Temp\chocolatey\vagrant\2.2.3\vagrant_2.2.3_x86_64.msi (229.22 MB).
Download of vagrant_2.2.3_x86_64.msi (229.22 MB) completed.
Hashes match.
Installing vagrant...
vagrant has been installed.
Repairing currently installed global plugins. This may take a few minutes...
Installed plugins successfully repaired!
  vagrant may be able to be automatically uninstalled.
Environment Vars (like PATH) have changed. Close/reopen your shell to
 see the changes (or in powershell/cmd.exe just type `refreshenv`).
 The install of vagrant was successful.
  Software installed as 'msi', install location is likely default.

Chocolatey installed 1/1 packages.
 See the log for details (C:\ProgramData\chocolatey\logs\chocolatey.log).

Packages requiring reboot:
 - vagrant (exit code 3010)

The recent package changes indicate a reboot is necessary.
 Please reboot at your earliest convenience.

root@LAPTOP-HT4TGVCP C:\Users\root>shutdown /r /t 0

Installing DetectionLab

Now we are finally at the point where we can install DetectionLab. Note that in my example, I downloaded boxes already built by Chris. I did not build my own, in order to save time. You can follow his instructions to build boxes yourself.

I saw an error regarding the win10 host, but that did not appear to be a real problem.

root@LAPTOP-HT4TGVCP C:\Users\root\git\detectionlab\DetectionLab>powershell
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

PS C:\Users\root\git\detectionlab\DetectionLab> .\build.ps1 -ProviderName virtualbox -VagrantOnly
[preflight_checks] Running..
[preflight_checks] Checking if Vagrant is installed
[preflight_checks] Checking for pre-existing boxes..
[preflight_checks] Checking for vagrant instances..
[preflight_checks] Checking disk space..
[preflight_checks] Checking if vagrant-reload is installed..
The vagrant-reload plugin is required and not currently installed. This script will attempt to install it now.
Installing the 'vagrant-reload' plugin. This can take a few minutes...
Installed the plugin 'vagrant-reload (0.0.1)'!
[preflight_checks] Finished.
[download_boxes] Running..
[download_boxes] Downloading windows_10_virtualbox.box

[download_boxes] Downloading windows_2016_virtualbox.box
[download_boxes] Getting filehash for: windows_10_virtualbox.box
[download_boxes] Getting filehash for: windows_2016_virtualbox.box
[download_boxes] Checking Filehashes..
[download_boxes] Finished.
[main] Running vagrant_up_host for: logger
[vagrant_up_host] Running for logger
Attempting to bring up the logger host using Vagrant
[vagrant_up_host] Finished for logger. Got exit code: 0
[main] vagrant_up_host finished. Exitcode: 0
Good news! logger was built successfully!
[main] Finished for: logger
[main] Running vagrant_up_host for: dc
[vagrant_up_host] Running for dc
Attempting to bring up the dc host using Vagrant
[vagrant_up_host] Finished for dc. Got exit code: 0
[main] vagrant_up_host finished. Exitcode: 0
Good news! dc was built successfully!
[main] Finished for: dc
[main] Running vagrant_up_host for: wef
[vagrant_up_host] Running for wef
Attempting to bring up the wef host using Vagrant
[vagrant_up_host] Finished for wef. Got exit code: 0
[main] vagrant_up_host finished. Exitcode: 0
Good news! wef was built successfully!
[main] Finished for: wef
[main] Running vagrant_up_host for: win10
[vagrant_up_host] Running for win10
Attempting to bring up the win10 host using Vagrant
[vagrant_up_host] Finished for win10. Got exit code: 1
[main] vagrant_up_host finished. Exitcode: 1
WARNING: Something went wrong while attempting to build the win10 box.
Attempting to reload and reprovision the host...
[main] Running vagrant_reload_host for: win10
[vagrant_reload_host] Running for win10
[vagrant_reload_host] Finished for win10. Got exit code: 1
C:\Users\root\git\detectionlab\DetectionLab\build.ps1 : Failed to bring up win10 after a reload. Exiting
At line:1 char:1
+ .\build.ps1 -ProviderName virtualbox -VagrantOnly
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,build.ps1

[main] Running post_build_checks
[post_build_checks] Running Caldera Check.
[download] Running for https://192.168.38.105:8888, looking for
[download] Found at https://192.168.38.105:8888
[post_build_checks] Cladera Result: True
[post_build_checks] Running Splunk Check.
[download] Running for https://192.168.38.105:8000/en-US/account/login?return_to=%2Fen-US%2F, looking for This browser is not supported by Splunk
[download] Found This browser is not supported by Splunk at https://192.168.38.105:8000/en-US/account/login?return_to=%2Fen-US%2F
[post_build_checks] Splunk Result: True
[post_build_checks] Running Fleet Check.
[download] Running for https://192.168.38.105:8412, looking for Kolide Fleet
[download] Found Kolide Fleet at https://192.168.38.105:8412
[post_build_checks] Fleet Result: True
[post_build_checks] Running MS ATA Check.
[download] Running for https://192.168.38.103, looking for
[post_build_checks] ATA Result: True
[main] Finished post_build_checks

Checking the VMs

I used the Virtualbox command line program to check the status of the new VMs.

root@LAPTOP-HT4TGVCP c:\Program Files\Oracle\VirtualBox>VBoxManage list runningvms
"logger" {3da9fffb-4b02-4e57-a592-dd2322f14245}
"dc.windomain.local" {ef32d493-845c-45dc-aff7-3a86d9c590cd}
"wef.windomain.local" {7cd008b7-c6e0-421d-9655-8f92ec98d9d7}
"win10.windomain.local" {acf413fb-6358-44df-ab9f-cc7767ed32bd}

Interacting with Vagrant and the Logger Host

Next I decided to use Vagrant to check on the status of the boxes, and to interact with one if I could. I wanted to find the Bro and Suricata logs.

root@LAPTOP-HT4TGVCP C:\Users\root\git\detectionlab\DetectionLab>cd Vagrant

root@LAPTOP-HT4TGVCP C:\Users\root\git\detectionlab\DetectionLab\Vagrant>vagrant status
Current machine states:

logger                    running (virtualbox)
dc                        running (virtualbox)
wef                       running (virtualbox)
win10                     running (virtualbox)

This environment represents multiple VMs. The VMs are all listed
above with their current state. For more information about a specific
VM, run `vagrant status NAME`.


root@LAPTOP-HT4TGVCP C:\Users\root\git\detectionlab\DetectionLab\Vagrant>vagrant ssh logger

Welcome to Ubuntu 16.04.5 LTS (GNU/Linux 4.4.0-131-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

29 packages can be updated.
24 updates are security updates.


Last login: Sun Jan 27 19:24:05 2019 from 10.0.2.2

root@logger:~# /opt/bro/bin/broctl status
Name         Type    Host             Status    Pid    Started
manager      manager localhost        running   9848   27 Jan 17:19:15
proxy        proxy   localhost        running   9893   27 Jan 17:19:16
worker-eth1-1 worker  localhost        running   9945   27 Jan 17:19:17
worker-eth1-2 worker  localhost        running   9948   27 Jan 17:19:17

vagrant@logger:~$ ls -al /opt/bro
total 32
drwxr-xr-x 8 root root 4096 Jan 27 17:19 .
drwxr-xr-x 5 root root 4096 Jan 27 17:19 ..
drwxr-xr-x 2 root root 4096 Jan 27 17:19 bin
drwxrwsr-x 2 root bro  4096 Jan 27 17:19 etc
drwxr-xr-x 3 root root 4096 Jan 27 17:19 lib
drwxrws--- 3 root bro  4096 Jan 27 18:00 logs
drwxr-xr-x 4 root root 4096 Jan 27 17:19 share
drwxrws--- 8 root bro  4096 Jan 27 17:19 spool

vagrant@logger:~$ ls -al /opt/bro/logs
ls: cannot open directory '/opt/bro/logs': Permission denied

vagrant@logger:~$ sudo bash

root@logger:~# ls -al /opt/bro/logs/
2019-01-27/ current/

root@logger:~# ls -al /opt/bro/logs/current/
total 3664
drwxr-sr-x 2 root bro    4096 Jan 27 19:20 .
drwxrws--- 8 root bro    4096 Jan 27 17:19 ..
-rw-r--r-- 1 root bro     475 Jan 27 19:19 capture_loss.log
-rw-r--r-- 1 root bro     127 Jan 27 17:19 .cmdline
-rw-r--r-- 1 root bro   83234 Jan 27 19:30 communication.log
-rw-r--r-- 1 root bro 1430714 Jan 27 19:30 conn.log
-rw-r--r-- 1 root bro    1340 Jan 27 19:00 dce_rpc.log
-rw-r--r-- 1 root bro  185114 Jan 27 19:28 dns.log
-rw-r--r-- 1 root bro     310 Jan 27 17:19 .env_vars
-rw-r--r-- 1 root bro  139387 Jan 27 19:30 files.log
-rw-r--r-- 1 root bro  544416 Jan 27 19:30 http.log
-rw-r--r-- 1 root bro     224 Jan 27 19:05 known_services.log
-rw-r--r-- 1 root bro     956 Jan 27 19:19 notice.log
-rw-r--r-- 1 root bro       5 Jan 27 17:19 .pid
-rw-r--r-- 1 root bro      18 Jan 27 19:00 .rotated.capture_loss
-rw-r--r-- 1 root bro      18 Jan 27 19:00 .rotated.communication
-rw-r--r-- 1 root bro      18 Jan 27 19:00 .rotated.conn
-rw-r--r-- 1 root bro      18 Jan 27 19:00 .rotated.conn-summary
-rw-r--r-- 1 root bro      18 Jan 27 19:00 .rotated.dce_rpc
-rw-r--r-- 1 root bro      18 Jan 27 19:00 .rotated.dns
-rw-r--r-- 1 root bro      18 Jan 27 18:00 .rotated.dpd
-rw-r--r-- 1 root bro      18 Jan 27 19:00 .rotated.files
-rw-r--r-- 1 root bro      18 Jan 27 19:00 .rotated.http
-rw-r--r-- 1 root bro      18 Jan 27 19:00 .rotated.kerberos
-rw-r--r-- 1 root bro      18 Jan 27 19:00 .rotated.known_certs
-rw-r--r-- 1 root bro      18 Jan 27 19:00 .rotated.known_hosts
-rw-r--r-- 1 root bro      18 Jan 27 19:00 .rotated.known_services
-rw-r--r-- 1 root bro      18 Jan 27 18:00 .rotated.loaded_scripts
-rw-r--r-- 1 root bro      18 Jan 27 19:00 .rotated.notice
-rw-r--r-- 1 root bro      18 Jan 27 18:00 .rotated.packet_filter
-rw-r--r-- 1 root bro      18 Jan 27 18:00 .rotated.reporter
-rw-r--r-- 1 root bro      18 Jan 27 19:00 .rotated.smb_files
-rw-r--r-- 1 root bro      18 Jan 27 19:00 .rotated.smb_mapping
-rw-r--r-- 1 root bro      18 Jan 27 19:00 .rotated.software
-rw-r--r-- 1 root bro      18 Jan 27 19:00 .rotated.ssl
-rw-r--r-- 1 root bro      18 Jan 27 19:00 .rotated.stats
-rw-r--r-- 1 root bro      18 Jan 27 19:00 .rotated.weird
-rw-r--r-- 1 root bro      18 Jan 27 19:00 .rotated.x509
-rw-r--r-- 1 root bro    1311 Jan 27 19:24 smb_mapping.log
-rw-r--r-- 1 root bro   15767 Jan 27 19:30 ssl.log
-rw-r--r-- 1 root bro      58 Jan 27 17:19 .startup
-rw-r--r-- 1 root bro   11326 Jan 27 19:30 stats.log
-rwx------ 1 root bro      18 Jan 27 17:19 .status
-rw-r--r-- 1 root bro      80 Jan 27 19:00 stderr.log
-rw-r--r-- 1 root bro     188 Jan 27 17:19 stdout.log
-rw-r--r-- 1 root bro 1141860 Jan 27 19:30 weird.log
-rw-r--r-- 1 root bro    2799 Jan 27 19:20 x509.log

root@logger:~# cd /opt/bro/logs/

root@logger:/opt/bro/logs# ls
2019-01-27  current

root@logger:/opt/bro/logs# cd current

root@logger:/opt/bro/logs/current# ls

capture_loss.log   conn.log     dns.log    http.log            notice.log     smb_mapping.log  stats.log   stdout.log  x509.log
communication.log  dce_rpc.log  files.log  known_services.log  smb_files.log  ssl.log          stderr.log  weird.log

root@logger:/opt/bro/logs/current# jq  -c . dce_rpc.log  | head

{"ts":1548615615.836272,"uid":"CEmNr31qusp3G7GFg4","id.orig_h":"192.168.38.104","id.orig_p":49758,"id.resp_h":"192.168.38.102","id.resp_p":135,"named_pipe":
"135","endpoint":"epmapper","operation":"ept_map"}
{"ts":1548615615.83961,"uid":"CJO7xe4JUo43IjGG01","id.orig_h":"192.168.38.104","id.orig_p":49759,"id.resp_h":"192.168.38.102","id.resp_p":49667,"rtt":0.0003
57,"named_pipe":"49667","endpoint":"lsarpc","operation":"LsarLookupSids3"}
{"ts":1548615615.851544,"uid":"CJO7xe4JUo43IjGG01","id.orig_h":"192.168.38.104","id.orig_p":49759,"id.resp_h":"192.168.38.102","id.resp_p":49667,"rtt":0.000
596,"named_pipe":"49667","endpoint":"lsarpc","operation":"LsarLookupSids3"}
{"ts":1548615615.835628,"uid":"CgEcizh05xJ1ricP8","id.orig_h":"192.168.38.104","id.orig_p":49758,"id.resp_h":"192.168.38.102","id.resp_p":135,"named_pipe":"
135","endpoint":"epmapper","operation":"ept_map"}
{"ts":1548615615.839587,"uid":"CVV6WZ3vgpE673rl6a","id.orig_h":"192.168.38.104","id.orig_p":49759,"id.resp_h":"192.168.38.102","id.resp_p":49667,"rtt":0.000
382,"named_pipe":"49667","endpoint":"lsarpc","operation":"LsarLookupSids3"}
{"ts":1548615615.852193,"uid":"CVV6WZ3vgpE673rl6a","id.orig_h":"192.168.38.104","id.orig_p":49759,"id.resp_h":"192.168.38.102","id.resp_p":49667,"rtt":0.000
382,"named_pipe":"49667","endpoint":"lsarpc","operation":"LsarLookupSids3"}
{"ts":1548618003.200283,"uid":"CGYDww34wYz8eCYr96","id.orig_h":"192.168.38.103","id.orig_p":63295,"id.resp_h":"192.168.38.102","id.resp_p":135,"named_pipe":
"135","endpoint":"epmapper","operation":"ept_map"}
{"ts":1548618003.200403,"uid":"CrTZMz2nCXsiY5WOF8","id.orig_h":"192.168.38.103","id.orig_p":63295,"id.resp_h":"192.168.38.102","id.resp_p":135,"named_pipe":
"135","endpoint":"epmapper","operation":"ept_map"}

root@logger:~# head /var/log/suricata/fast.log

01/27/2019-17:19:08.133030  [**] [1:2013028:4] ET POLICY curl User-Agent Outbound [**] [Classification: Attempted Information Leak] [Priority: 2] {TCP} 10.0
.2.15:51574 -> 195.135.221.134:80
01/27/2019-17:19:08.292747  [**] [1:2013504:5] ET POLICY GNU/Linux APT User-Agent Outbound likely related to package management [**] [Classification: Not Su
spicious Traffic] [Priority: 3] {TCP} 10.0.2.15:55260 -> 99.84.178.103:80
01/27/2019-17:19:08.356618  [**] [1:2013504:5] ET POLICY GNU/Linux APT User-Agent Outbound likely related to package management [**] [Classification: Not Su
spicious Traffic] [Priority: 3] {TCP} 10.0.2.15:55260 -> 99.84.178.103:80
01/27/2019-17:19:08.432477  [**] [1:2013504:5] ET POLICY GNU/Linux APT User-Agent Outbound likely related to package management [**] [Classification: Not Su
spicious Traffic] [Priority: 3] {TCP} 10.0.2.15:46630 -> 91.189.95.83:80
01/27/2019-17:19:08.448249  [**] [1:2013504:5] ET POLICY GNU/Linux APT User-Agent Outbound likely related to package management [**] [Classification: Not Su
spicious Traffic] [Priority: 3] {TCP} 10.0.2.15:53932 -> 91.189.88.161:80
...trimmed...

Docker on the Logger Host

Chris is using Docker to provide some of the Logger host functions, e.g.:

root@logger:~# docker container ls
CONTAINER ID        IMAGE                    COMMAND                   CREATED             STATUS              PORTS                              NAMES
343c18f933d9        kolide/fleet:latest      "sh -c 'echo '\\n' | …"   3 hours ago         Up 3 hours          0.0.0.0:8412->8412/tcp             kolidequic
kstart_fleet_1
513cb0d61401        mysql:5.7                "docker-entrypoint.s…"    3 hours ago         Up 3 hours          3306/tcp, 33060/tcp                kolidequic
kstart_mysql_1
b0278855b130        mailhog/mailhog:latest   "MailHog"                 3 hours ago         Up 3 hours          1025/tcp, 0.0.0.0:8025->8025/tcp   kolidequic
kstart_mailhog_1
ddcd3e59dda2        redis:3.2.4              "docker-entrypoint.s…"    3 hours ago         Up 3 hours          6379/tcp                           kolidequic
kstart_redis_1

Troubleshooting Localhost Bindings

One of the issues I encountered involved the IP addresses to which VMs bound their Virtualbox Remote Display Protocol servers. The default configuration bound them to localhost on my Windows laptop. That was ok if I was interacting with that laptop in person, but I was doing this work remotely.

I could RDP to the laptop, and then RDP from the laptop to the VMs. This works, but it was a slight hassle to log into the Windows 2016 server which required a ctrl-alt-del sequence. This is a nuanced issue that can be solved by using the on screen keyboard (osk.exe) to enter the ctrl-alt-end sequence on the remote laptop, but I wanted an easier solution.

Dustin Lee, who has done a lot of work customized DetectionLab to include Security Onion (a future post maybe?) suggested I modify the Vagrantfile with the following bolded content. This example is for the wef host in the Vagrantfile.

    cfg.vm.provider "virtualbox" do |vb, override|
      vb.gui = true
      vb.name = "wef.windomain.local"
      vb.default_nic_type = "82545EM"
      vb.customize ["modifyvm", :id, "--vrde", "on"]
      vb.customize ["modifyvm", :id, "--vrdeaddress", "0.0.0.0"]
      vb.customize ["modifyvm", :id, "--memory", 2048]
      vb.customize ["modifyvm", :id, "--cpus", 2]
      vb.customize ["modifyvm", :id, "--vram", "32"]
      vb.customize ["modifyvm", :id, "--clipboard", "bidirectional"]
      vb.customize ["setextradata", "global", "GUI/SuppressMessages", "all" ]
    end
Basically, add the bold entries wherever you see a "virtualbox" option, to enable the VRDP server binding to 0.0.0.0 (which should be all IP addresses, to include the public IP, as I want).

Before I restarted the wef host, you can see below how the VRDE server is listening only on localhost on port 5932 (in bold).

root@LAPTOP-HT4TGVCP C:\Users\root\git\detectionlab\DetectionLab\Vagrant>"c:\Program Files\Oracle\VirtualBox\VBoxManage.exe" showvminfo wef.windomain.local
| findstr /I vrde

VRDE:                        enabled (Address 127.0.0.1, Ports 5932, MultiConn: off, ReuseSingleConn: off, Authentication type: null)
...trimmed...

After changing the Vagrant file, I restarted the wef host using Vagrant.

root@LAPTOP-HT4TGVCP C:\Users\root\git\detectionlab\DetectionLab\Vagrant>vagrant reload wef
==> wef: Attempting graceful shutdown of VM...
==> wef: Clearing any previously set forwarded ports...
==> wef: Fixed port collision for 3389 => 3389. Now on port 2201.
==> wef: Fixed port collision for 22 => 2222. Now on port 2202.
==> wef: Fixed port collision for 5985 => 55985. Now on port 2203.
==> wef: Fixed port collision for 5986 => 55986. Now on port 2204.
==> wef: Clearing any previously set network interfaces...
==> wef: Preparing network interfaces based on configuration...
    wef: Adapter 1: nat
    wef: Adapter 2: hostonly
==> wef: Forwarding ports...
    wef: 3389 (guest) => 2201 (host) (adapter 1)
    wef: 22 (guest) => 2202 (host) (adapter 1)
    wef: 5985 (guest) => 2203 (host) (adapter 1)
    wef: 5986 (guest) => 2204 (host) (adapter 1)
==> wef: Running 'pre-boot' VM customizations...
==> wef: Booting VM...
==> wef: Waiting for machine to boot. This may take a few minutes...
    wef: WinRM address: 127.0.0.1:2203
    wef: WinRM username: vagrant
    wef: WinRM execution_time_limit: PT2H
    wef: WinRM transport: negotiate
==> wef: Machine booted and ready!
==> wef: Checking for guest additions in VM...
    wef: The guest additions on this VM do not match the installed version of
    wef: VirtualBox! In most cases this is fine, but in rare cases it can
    wef: prevent things such as shared folders from working properly. If you see
    wef: shared folder errors, please make sure the guest additions within the
    wef: virtual machine match the version of VirtualBox you have installed on
    wef: your host and reload your VM.
    wef:
    wef: Guest Additions Version: 5.2.16
    wef: VirtualBox Version: 6.0
==> wef: Setting hostname...
==> wef: Configuring and enabling network interfaces...
==> wef: Mounting shared folders...

    wef: /vagrant =>  

The bolded entry about port 2201 means I can log into the wef host as user vagrant / password vagrant, over RDP, directly from another computer.


After restarting the wef host, I check to see what IP address and port the RDP server is listening (in bold):


root@LAPTOP-HT4TGVCP C:\Users\root\git\detectionlab\DetectionLab\Vagrant>"c:\Program Files\Oracle\VirtualBox\VBoxManage.exe" showvminfo wef.windomain.local
| findstr /I vrde
VRDE:                        enabled (Address 0.0.0.0, Ports 5932, MultiConn: off, ReuseSingleConn: off, Authentication type: null)
...trimmed...

This should allow me to access the "screen" of the VM via port 5932 and the IP of the host laptop. Unfortunately, there is some sort of conflict, as I saw the domain controller also reserved the same port for its VRDE.

root@LAPTOP-HT4TGVCP C:\Users\root>"c:\Program Files\Oracle\VirtualBox\VBoxManage.exe" showvminfo dc.windomain.local | findstr /I vrde

VRDE:                        enabled (Address 0.0.0.0, Ports 5932, MultiConn: off, ReuseSingleConn: off, Authentication type: null)
...trimmed...

I encountered a similar issue with the domain controller also failing to resolve a conflict with the host system RDP port.

root@LAPTOP-HT4TGVCP C:\Users\root\git\detectionlab\DetectionLab\Vagrant>vagrant reload dc
==> dc: Attempting graceful shutdown of VM...
==> dc: Clearing any previously set forwarded ports...
==> dc: Fixed port collision for 22 => 2222. Now on port 2200.
==> dc: Clearing any previously set network interfaces...
==> dc: Preparing network interfaces based on configuration...
    dc: Adapter 1: nat
    dc: Adapter 2: hostonly
==> dc: Forwarding ports...
    dc: 3389 (guest) => 3389 (host) (adapter 1)
    dc: 22 (guest) => 2200 (host) (adapter 1)
    dc: 5985 (guest) => 55985 (host) (adapter 1)
    dc: 5986 (guest) => 55986 (host) (adapter 1)

I haven't solved these problems yet. I wonder if it's a result of using pre-built VMs, which use the 5.x series of Virtualbox extensions, while my Virtualbox system runs 6.0?

Summary

These are minor issues, for the result of all this work is four systems offering Windows client and server features, plus instrumentation. That could be another topic for discussion. I'm also excited by the prospect of running all of this in the cloud. Furthermore, Dustin Lee has a fork of DetectionLab that replaces some of the instrumentation with Security Onion!