DNS/TCP Monitoring in Qubes

DNS/TCP Monitoring in QubesOS

.7.5. ………its-always-dns…….)……… …..^..f. // DNS

Detection is gaining more and more (management) attention. Corporations are aware that hardening is not enough and monitoring/logging is crucial to detect the intruder or at least identify activities after an incident has occurred.

In my opinion this does not only apply to our clients but also to our own operational and local infrastructure.

This article is just one example how to create a local logging infrastructure in QubesOS. So let’s start this series with the first milestone traffic collection to detect odd behaviors.

Sources and impact

Before diving into the how it makes sense to categorize and name additional event sources first. This figure is just a rough overview and by no means holistic, but can be used as a starting point:

Endpoint logging sources (within the Qube):

  • Syscalls, executed commands
  • OS Logs
  • Audit of specific folders/files/configurations
  • Application specific Logs
  • Agents / Engines

Traffic Logging Sources:

  • Metadata
  • Full Package capture

External Logs (Destination of a connection):

  • DNS Server
  • Proxys
  • Application server

Analytic Tools:

  • Can enrich the data (e.g. IP to country)
  • Correlate or filter data
  • Can create context or timelines

Why starting with network traffic first ?

For larger corporation the priority list from Florian Roth can be used for reference. However, starting with Traffic analysis in Qubes OS have some benefits:

  • Through the separation of applications into different qubes / trusts the network traffic should look very homogenous.
  • Traffic Analysis is transparent to the qube, so no configuration within the qube is neccessary. Furthermore traffic monitoring cannot easily be idenitfied from within the qube.
  • Every Implant need to establish a C2 channel to receive further commands. The area of detection is therefore more focusing on C2 communication and lateral movement attempts.

Battleground & Roadmap

The only advantage that you have is: You can craft and modify the battleground in your favor. So let’s take a look what will be covered in this article:

Mission Logging source Difficulty Description
I. Collect Network Metadata Traffic easy Metadata analyze of network traffic
I. Collect Full Packet capture Traffic easy For later usage
II. Collect DNS Request DNSServer easy Identify which lookups are performed
II. Configure DNS DNSServer easy Controllable DNS to block/whitelist for each qube

Current Setup

Let’s assume a full compromise of a working qube. Traffic is forwarded to a network vm, which tunnels everything.

Both qubes are restricted via qvm-firewall as can be seen in the figure.

Now let’s modify and implement the loggers.

Based on my personal Threat model a new Proxy VM is created, which is chained between the VPN qube and the untrusted qube and provides a DNS server and TCP logger via packetbeat.

I: Collect Network (Meta)data

The collection of metadata can be applied to all qubes and trust levels. This includes collection of source and destination, amount and size of the communication, protocol and port as well as the timestamp information.

For TCP traffic packetbeat from elastic is used.

Create the Logger AppVM

# dom0 - create sys-log appvm
qvm-create --template "fedora-32" --label "yellow" \
	--property vcpus=1 \
	--property maxmem=2048 \
	--property memory=1024 \
	--property provides_network=True \
	--property netvm=sys-vpn \
	sys-log 

# dom0 - change network interface of untrusted
qvm-prefx -s untrusted netvm sys-log

# dom0 - firewall 
qvm-firewall sys-log reset
qvm-firewall sys-log del --rule-no 0 # delete accept rule if not available
qvm-firewall sys-log add accept specialtarget=dns
qvm-firewall sys-log add drop 10.0.0.0/8
qvm-firewall sys-log add drop 172.16.0.0/12
qvm-firewall sys-log add drop 192.168.0.0/16
qvm-firewall sys-log add drop 169.254.0.0/16
qvm-firewall sys-log add accept

Configuration of Packetbeat

Most of the packetbeat configuration is default. The main purpose of packetbeat for this scenario is meta information. Full packet capture is done via a different tool. Therefore, period is set to -1s and several fields are dropped to reduce the volume.

The most important parts of the packetbeat.yml can be found here

For automatic logging on startup it is possible to create .desktop files placed in the $HOME/.config/autostart/ directory. The following configuration might be used

# mkdir -p ~/.config/autostart
# copied from /usr/share/applications/xterm.desktop
[Desktop Entry]
Name=Logger
GenericName=Start Logger
Comment=Starting Logging Services on startup
Exec=sh -c "sudo $HOME/packet-beat -c $HOME/packet-beat.yml" 
Terminal=false
Type=Application
Encoding=UTF-8
Icon=xterm-color
Categories=System;TerminalEmulator;
Keywords=shell;prompt;command;commandline;cmd;
X-Desktop-File-Install-Version=0.24

Configuration for full package capture

Several options are available for full package capture:

  • https://github.com/arkime/arkime
  • packetbeat with the packetbeat -e -dump trace.pcap option
  • Simple capture via tcpdump -i <interface> -w fulldump.pcap
  • Simple capture with gopacket or a modified version

II. Collect and Configure DNSdata

Based on my personal threat model the DNS server is also installed on the same machine. Since golang is my personal choice blockly will be used as a DNS server. But there are plenty of articles how to setup pi-hole in qubes if this fits you more:

Before blockly can be used, some firewall adjustments needed to be mad, which should be appended to the /rw/config/qubes-firewall-user-script script of the sys-log qube:

# Content of /rw/config/qubes-firewall-user-script

# Local DNS 
## Accept requests to port 5353 
iptables -N DNS-SINK
iptables -A DNS-SINK -p udp -m udp --dport 5353 -m conntrack --ctstate NEW -j ACCEPT
iptables -A DNS-SINK -p tcp -m tcp --dport 5353 -m conntrack --ctstate NEW -j ACCEPT
iptables -I INPUT -j DNS-SINK
iptables -I FORWARD -d 169.254.169.254/32 -j DROP

# Redirect Magic DNS Ips to DNS server to port 5353
iptables -F PR-QBS
iptables -A PR-QBS -t nat -d 10.139.1.1/32 -p udp --dport 53 -j DNAT --to <ip-of-sys-log>:5353
iptables -A PR-QBS -t nat -d 10.139.1.1/32 -p tcp --dport 53 -j DNAT --to <ip-of-sys-log>:5353
iptables -A PR-QBS -t nat -d 10.139.1.2/32 -p udp --dport 53 -j DNAT --to <ip-of-sys-log>:5353
iptables -A PR-QBS -t nat -d 10.139.1.2/32 -p tcp --dport 53 -j DNAT --to <ip-of-sys-log>:5353

Configuration of the logger

Blockly (and pi-hole) can be configured to use the qubes names. For blockly the following command can be used to create the clients field in the configuration:

# dom0
qvm-ls --fields NAME,IP --raw-data | tr -s ' ' ':' | grep -v ':-' \
	| sed 's|\(.*\):\(.*\)|         \1: [\2]|g' \
	| qvm-run --pass-io sys-log 'cat - > $HOME/client_list' 

Afterwards it is possible to specify the white/blocklist for each qube or prefix of qubes.

These can also be created later - after visualization and searching through the typical domains.

As documented in the iptables changes blockly can be started on port 5353 to prevent executing it with root privileges.

For automatic logging on startup it is possible to create .desktop files placed in the $HOME/.config/autostart/ directory. The following configuration might be used

# mkdir -p ~/.config/autostart
# copied from /usr/share/applications/xterm.desktop
[Desktop Entry]
Name=DNS
GenericName=Start DNS
Comment=Starting DNS Services on startup
Exec=sh -c "sudo $HOME/blockly -c $HOME/blockly.yml" 
Terminal=false
Type=Application
Encoding=UTF-8
Icon=xterm-color
Categories=System;TerminalEmulator;
Keywords=shell;prompt;command;commandline;cmd;
X-Desktop-File-Install-Version=0.24

Test everything

Create a DVM, which is chained to sys-log and issue a DNS request. You should see a TSV file from blockly.

And it also seems that the HTTP request is also logged via packetbeat. Great now we have the data

Summary

The first milestone is done and it’s now possible to collect traffic metadata and DNS. Furthermore, individual DNS settings can be changed and white/ blocklist can be applied to each individual qube.

The collected data is the foundation for basic and sophisticated analysis, which will be described in the follow-up article.

So far we modified our setup with sys-log running packetbeat and a DNS server.