Part 1: Intro to Threat Hunting – Setting up the environment

In this blog post series, I am documenting my novice pursuit for knowledge to become a threat hunter. This series has a strong focus on utilizing OSQuery to hunt for different techniques used by adversaries. The first post of this series, will consist of instructions to set up a lab environment. The second post of this series will be walking through red team scenarios with Powershell Empire, and MITRE’s cyber adversary emulation system called Caldera.

The third post in this series, will utilize OSQuery to hunt red team activity by discovering artifacts and modifications made to the system. The fourth post in this series, will integrate our successful hunts into Graylog for logging and alerting. Lastly, this series will be generating threat-hunting playbooks and scoring our detection capabilities using Cyb3rWard0g’s system.

Requirements

  • Hypervisor with the following hardware:
    • CPU: Quad-core
    • Ram: 16GBs
    • HDD: 160GBs
  • Some Ansible experience
  • Some Linux experience
  • Some Windows Group policy and server system administration experience
  • ISOs
    • Ubuntu Server 16.04 64-bit
    • Windows 10 64-bit 1511

Network diagram

Setup environment

VM creation

  1. Windows Server 2016
    1. Services: AD + DNS, WinRM, RDP
    2. Description: This server will be used as a domain controller for central auth and Group Policy
    3. Hardware
      1. CPU: 2 cores
      2. RAM: 4GBs
      3. HDD: 40GBs
  2. Windows 10 client x2
    1. Version: 1511
      1. Some of the red teaming tactics require an older version that is vulnerable 🙂
    2. Services: WinRM
    3. Description: Client computers that will be attacked by Powershell Empire and Caldera
    4. Client 1 – Machine that will be initially compromised
    5. Client 2 – Machine that is pivoted to from client 1
    6. Hardware
      1. CPU: 2 cores
      2. RAM: 4GBs
      3. HDD: 40GBs
  3. Ubuntu Server 16.04 Graylog
    1. Services: Graylog, SSH
    2. Description: Used for OSQuery log aggregation and alerting via Slack
    3. Hardware
      1. CPU: 4 cores
      2. RAM: 4GBs
      3. HDD: 40GBs
  4. Ubuntu Server 16.04 Kolide Fleet manager
    1. Services: Kolide + Nginx, SSH
    2. Description: Used to manage/query OSQuery agents in the environment
    3. Hardware
      1. CPU: 2 cores
      2. RAM: 4GBs
      3. HDD: 40GBs

Initial setup

  1. pip install pywinrm
  2. pip install ansible
  3. git clone https://github.com/CptOfEvilMinions/ThreatWaffle.git
  4. cd ThreatWaffle

Windows Server 2016

Setup domain controller

  1. Set hostname of the
  2. server to “WinDC”
  3. Open Powershell as Administrator
    1. Run this command: powershell -NoProfile -ExecutionPolicy Bypass -Command "iex ((new-object net.webclient).DownloadString('https://github.com/ansible/ansible/raw/devel/examples/scripts/ConfigureRemotingForAnsible.ps1'))"
  4. mv group_vars/all.example group_vars/all
  5. vim group_vars/all and set:
    1. base_domain
    2. timezone
    3. slack(Optional)
    4. cert info
  6. mv group_vars/win_dc.example group_vars/win_dc
  7. vim group_vars/win_dc and set:
    1. ad_domain_name (by default set to base_domain)
    2. ad_safe_mode_password
  8. vim group_vars/windows and set :
    1. asnsible_user
    2. ansible_password
  9. vim hosts set IP address for [win_dc]
  10. ansible-playbook -i hosts deploy_windows_dc.yml

Setup DNS

Create DNS reverse zone

  1. Open Server Manager
  2. Select “Tools” then “DNS”
  3. WinDC > Reverse Lookup Zone
  4. Right-Click “Reverse Lookup Zone” and select “New zone”
    1. Select “Primary zone” for the type of zone
    2. Select “To all DNS servers running on domain controllers in domain” for data replication
    3. Select “IPv4 reverse lookup zone” for the type of reverse zone
    4. Enter “10.100.3” for the Network ID
    5. Select “Allow only secure dynamic updates” for dynamic updates
    6. Select “Finish”

DNS entries

  1. WinDC > Forward Lookup Zone > hackinglab.beer
  2. Select “Action” then “New Host(A)”
    1. Enter graylog for Name
    2. Enter “<IP addr of Graylog>” for IP address
    3. Check “Create associated pointer (PTR) record” if UNchecked
    4. Select “Add host”
  3.  Repeat for Kolide

Group Policy settings

Enable RDP through the firewall

  1. Select “Tools” then “Group policy manager”
  2. Expand: Group policy manager > Forest: hackinglab.beer > Domains > hackinglab.beer
  3. Right-click “Default Domain Policy”
  4. Computer Configuration > Policies > Administrative Templates > Network > Network Connections > Windows Firewall > Domain Profile
    1. Enable “Allow inbound Remote Desktop exceptions” and set IP addresses to “*”

Powershell script block logging

  1. Computer Configuration > Policies > Administrative Templates -> Windows Components -> Windows PowerShell
    1. Enable “Turn on PowerShell Script Block Logging”

Process creation logging

  1. Computer Configuration > Windows Settings > Security Settings > Advanced Audit Policy Configuration > Audit Policies > Detailed Tracking
    1. Enable for successful “Audit Process Creation”

SMB access for PSexec

  1. Computer Configuration > Policies > Windows Settings > Security Settings > Windows Firewall with Advanced Security > Windows Firewall with Advanced Security LDAP
  2. Right-click “Inbound Rules” and select “New Rule”
    1. Select “Port” for rule type
    2. Select “TCP” for protocol and enter “445” for port
    3. Select “Allow the connection”
    4. Select all profiles
    5. Enter “Allow PSexec” for name

Create domain users(non-admin)

  1. Open server manager
  2. Select “Tools” then “Active Directory Users and Computers”
  3. Expand: hackinglab.beer > Users
  4. Select “Users” on the left
  5. Select “Action” then “New User”
    1. User info
      1. Enter “Bill” for Firstname
      2. Enter “Gates” for the Last Name
      3. Enter “Bgates” for logon
    2. Password
      1. Enter a password for user
      2. UNcheck “User must change password at next logon”
  6. Select “Users” on the left
  7. Select “Action” then “New User”
    1. User info
      1. Enter “Steve” for Firstname
      2. Enter “Jobs” for the Last Name
      3. Enter “Sjobs” for logon
    2. Password
      1. Enter a password for user
      2. UNcheck “User must change password at next logon”
  8. Shutdown and create snapshot

Ubuntu Server 16.04 Graylog

Install/Setup Graylog

  1. Set DNS server to WinDC
  2. vim group_vars/all and set “graylog_hostname”
  3. mv group_vars/graylog.example group_vars/graylog
  4. vim group_vars/graylog set:
    1. graylog_admin_password
      1. graylog_admin_password can not contain the following special characters: )(;
  5. vim hosts and set:
    1. IP address for [graylog]
  6. ansible-playbook -i hosts deploy_graylog.yml -u <username>

Setup/Configure Graylog input

  1. Browse to https://<graylog FQDN – MUST  BE accessed via FQDN> and login
    1. User: admin
    2. Pass: {{ graylog_admin_password }}
  2. Select “System” then “Inputs”
  3. Select “Beats” for input than “Launch new input”
    1. Select “<node>” for Node
    2. Enter “Beats” for title
    3. Leave the default for bind-address
    4. Leave the default for port
    5. Select “save”
  4. Shutdown and create snapshot

Ubuntu Server 16.04 Kolide Fleet

Kolide terms

  • Node– A single machine
  • Fleet – All the machines controlled and owned by an enterprise
  • Queries – A query runs a set of tasks on a fleet of machines on a specified interval
  • Distributed queries – An on the fly query
  • Packs –  Group queries into packs to perform ongoing monitoring.

Install/Setup Kolide Fleet

  1. Set DNS server to WinDC
  2. openssl rand -base64 32
  3. Copy the output from above
  4. vim group_vars/all and set “fleet_hostname”
  5. mv group_vars/kolide.example group_vars/kolide
  6. vim group_vars/kolide and set:
    1. kolide_jwt_key to output from above
    2. Set username and password for Kolide, MySQL
  1. vim hosts
    1. Set management IP address under [kolide]
  2. ansible-playbook -i hosts deploy_kolide.yml -u <ubuntu local user>

Setup/Configure webGUI

  1. https://<Hostname/IP addr of Kolide>
    1. Setup user
      1. Enter “admin” for username
      2. Enter a password
      3. Enter an e-mail for the admin user
      4. Select “Submit”
    2. Setup organization
      1. Enter an organization name
      2. Enter the organizations URL
        1. DO NOT enter the same URL to access Kolide
      3. Select “Submit”
    3. Set Kolide URL
      1. Enter the Kolide FQDN into “Kolide web address” 
      2. Select “Submit”

  1. Shutdown and create snapshot

Deploy OSQuery agents

Initial setup

  1. Browse to https://<Hostname/IP addr of Kolide>
  2. Select “Add new host” in top right
  3. Select “Reveal secret” and copy the string
  4. mv group_vars/agents.example group_vars/agents
  5. vim group_vars/agents
    1. set osquery_enroll_secret with string from Kolide

Client 1

  1. Change hostname to client1
  2. Install trial of Office 365
  3. Open Powershell as Administrator
    1. Run this command powershell -NoProfile -ExecutionPolicy Bypass -Command "iex ((new-object net.webclient).DownloadString('https://github.com/ansible/ansible/raw/devel/examples/scripts/ConfigureRemotingForAnsible.ps1'))"

Client 2

  1. Change hostname to client2
  2. Install trial of Office 365
  3. Place some “intellectual property”(IP) like a Microsoft Word document in the user’s home directory
  4. Open Powershell as AdministratorRun this command powershell -NoProfile -ExecutionPolicy Bypass -Command "iex ((new-object net.webclient).DownloadString('https://github.com/ansible/ansible/raw/devel/examples/scripts/ConfigureRemotingForAnsible.ps1'))"

Install/Setup OSQuery

  1. Copy contents of /etc/nginx/ssl/kolide.crt for Kolide server
  2. mv conf/agents/certificate.example conf/agents/certificate.crt
  3. vim conf/agents/certificate.crt and paste the contents from above
  4. mv group_vars/win_agents.example group_vars/win_agents
  5. vim group_vars/win_agents and set:
    1. ansible_user
    2. Ansible_password
  6. vim hosts
    1. Add hosts to win_agents
  7. Browse to “https://<Hostname/IP addr of Kolide>” and login
  8. Select “Add new host in the top right”
    1. Copy the secret key
  9. mv group_vars/agents.example group_vars/agents
  10. vim group_vars/agents and set osquery_enroll_secret to the key from above
  11. ansible-playbook -i hosts deploy_windows_osquery_agents.yml
  12. Shutdown each host and snapshot

Future road map

In this blog post, we created a lab environment to perform red teaming activities for us to hunt. Before I start talking about the future, let’s understand our environment. This environment is predominantly Windows machines and they will be our targets, more specifically Windows client 1 and 2. The Windows domain controller provides central authentication and Group Policy management for our Windows clients. Next, we have our Ubuntu servers running Kolide and Graylog.

Kolide is our OSQuery fleet manager for our OSQuery agents, and also provides the ability to run specified configs on a particular interval, or the ability to ask our environment a question on the fly(distributed query). We will use this tool and techniques from the MITRE ATT&CK matrix to hunt for our red teaming activity. Once we have identified malicious activity from our hunts, we will create an OSQuery pack(multiple queries) that will run on a specified interval. OSQuery agents will keep track of each query’s output and will only send results when the query state changes. Next, we will ingest the changes sent by OSQuery agents into Graylog.

Graylog will be configured to ingest these logs and alert based on certain conditions. This part is essential because we want to automate our hunts and move from a threat hunting role to an incident response role. By moving our hunts to an incident response role, we will have more time to search for more advanced threats that haven’t been discovered within our environment. Furthermore, we will use Cyb3rWard0g’s threat-hunting playbook template to create our own threat-hunting playbooks. It’s important to document all hunts and our criteria for determining malicious activity. Finally, we will evaluate our hunts using Cyb3rWard0g scoring system.

Resources/Sources

4 thoughts on “Part 1: Intro to Threat Hunting – Setting up the environment

  1. Alex Sara says:

    Hi.

    I am trying to follow your steps to deploy the osquery on Windows 10 and to enroll them to Kolide, however I do not understand what you mean in Deploy OSQuery agents -> Initial Setup -> Step 4 -> vim group_vars/agents -> set osquery_enroll_secret with string from Kolide.

    Where is this group_vars? It is really confusing this Deployment steps, could you please clarify?

    Thanks.

    • spartan2194 says:

      The directions have been updated to include:
      4. mv group_vars/agents.example group_vars/agents
      5. vim group_vars/agents

  2. ralph23 says:

    I have difficulty understanding the lingo here.

    mv group_vars/all.example group_vars/all
    mv group_vars/win_agents.example group_vars/win_agents
    vim group_vars/win_agents

    mv ==> move
    group_vars/all.example ==> [folder/file.example] ==> group_vars/all [folder] ?

    Do i make a file name group_vars with a file name all.example?
    What is vim an editor. Do i create a file in folder groups_vars name
    win_agents? My understanding of linux goes off the rails here. Can you please
    provide some explanation. I would like to try your method in my personal lab.

    • spartan2194 says:

      Hey ralph23,

      The move(mv) command within Linux can be used to move files OR rename files, like done above. The files within the current group_vars directory end with a “.example” extension. But Ansible is looking for a file called “group_vars/all”, which does not contain the extension. Continue reading if you want to know why I do this :).

      Files within the “group_vars” directory may contain sensitive information. To avoid pushing code with potentially sensitive information, I make a copy of each group_var file and call it .example with fake/blank values. Next, I add “group_vars” files WITHOUT the “.example” extension to my “.gitignore” file. This ensures I don’t accidentally push code to Github with sensitive values such as a Slack token.

      Happy Hunting!

Leave a Reply

Your email address will not be published. Required fields are marked *