# Network security and firewalls ## CS 3710 === ## Network security --- ## Auditing and blocking traffic <div class="r-stack"> <div class="fragment fade-out" data-fragment-index=1> One of the easiest ways we can mitigate vulnerabilities is to ensure that the outside world can't access hosts and services that they don't need to. </div> <div class="fragment" data-fragment-index=1> Without access to the reporter, the RCE still exists but is much more difficult to exploit. </div> </div> <div class="r-stack image-background"> <div class="fragment fade-out" data-fragment-index=0> <figure> <img src="../../img/networking/firewall_rce_example_1.drawio.webp"style="max-height: 30vh;"> <figcaption> </figcaption> </figure> </div> <div class="fragment fade-in-then-out" data-fragment-index=0> <figure> <img src="../../img/networking/firewall_rce_example_2.drawio.webp"style="max-height: 30vh;"> <figcaption> </figcaption> </figure> </div> <div class="fragment" data-fragment-index=1> <figure> <img src="../../img/networking/firewall_rce_example_3.drawio.webp"style="max-height: 30vh;"> <figcaption> </figcaption> </figure> </div> </div> --- ## Auditing and blocking traffic At a network level, we want to do two things: <div class="fragment semi-fade-out" data-fragment-index=0> _**Restrict**_ communication between hosts, as well as communication from hosts to the outside world. This makes it more difficult to exploit vulnerable services and perform reconnaissance. </div> <div class="fragment" data-fragment-index=0> _**Log and audit**_ traffic to try and detect anomalous behavior. If a host *does* get compromised, you're much more likely to notice it. </div> notes: - Re: detecting anomalous behavior -- ref. Greg's talk where he talked about hosts in the DMZ accessing a login server --- ## Auditing and blocking traffic In the real world, we often *segment* networks to help define restrictions between hosts and what kinds of logging we should do. <figure> <img src="../../img/web/dmz_example.svg"class="image-background"style="max-height: 40vh;"> <figcaption> </figcaption> </figure> === ## Firewalls --- ## Firewalls <div class="container"> <div class="col"> A _**firewall**_ is a system that restricts what kind of traffic can enter or exit a network or host. Firewalls can be deployed on-host, on a router, on a dedicated machine, etc. </div> <div class="col"> <figure> <img src="../../img/networking/wall_of_fire.webp"style="max-height: 40vh;"> <figcaption> </figcaption> </figure> </div> </div> --- ## Blocking ingress traffic You typically want to block ingress traffic to services that external entities don't strictly need to access. *Example:* block all SSH (port 22) and RDP (port 3389) to people outside of your internal network. <figure> <img src="../../img/networking/ingress_firewall.webp"style="max-height: 40vh;"> <figcaption> </figcaption> </figure> --- ## Blocking egress traffic In addition, you probably also want to block (or at least log) traffic leaving hosts. *Example:* block all from the webserver to ports 22 and 3389 of hosts on the internal network. <figure> <img src="../../img/networking/egress_firewall.webp"style="max-height: 40vh;"> <figcaption> </figcaption> </figure> --- ## Why block egress traffic? <div class="fragment semi-fade-out" data-fragment-index=0> The kinds of traffic that leave a machine can tell you a little about what that machine is doing under the hood. </div> <div class="fragment" data-fragment-index=0> If an attacker has gained access to a machine, any C2 traffic and attempts to pivot will be blocked and reflected in the logs. </div> <figure> <img src="../../img/malware/wekby_dns_exfil.webp"style="max-height: 25vh;"> <figcaption> *Source: Unit 42 / Palo Alto Networks* </figcaption> </figure> --- ## Linux firewalls: netfilter From netfilter.org: > The netfilter project enables packet filtering, network address [and port] > translation (NA[P]T), packet logging, userspace packet queueing and other > packet mangling. <figure> <img src="../../img/networking/netfilter-logo.png"> <figcaption> *Source: the [netfilter project](https://netfilter.org/)* </figcaption> </figure> --- ## iptables Traditionally, the canonical way of setting up a Linux firewall was via `iptables`. ```bash # Allow all SSH traffic from 10.0.0.0/8 iptables -A INPUT -p tcp --dport 22 -s 10.0.0.0/8 -j ACCEPT # Insert rules at the start of the input/output chains allowing all traffic # on loopback iptables -I INPUT 0 -i lo -j ACCEPT iptables -I OUTPUT 0 -o lo -j ACCEPT # Add a logging rule to the end of the chain iptables -A INPUT -j LOG --log-prefix "my logging rule" ``` --- ## nftables nftables has since overtaken iptables, and has become the recommended way of setting up firewalls since kernel version 3.13: ```bash # Allow all SSH traffic from 10.0.0.0/8 nft add rule filter input tcp dport 22 saddr 10.0.0.0/8 accept # Insert rules at the start of the input/output chains allowing all traffic # on loopback nft insert rule filter input position 0 iif lo accept nft insert rule filter output position 0 oif lo accept # Add a logging rule to the end of the chain nft add rule filter input log prefix "my logging rule" ``` notes: Kernel version 3.13 was released in 2014 --- ## nftables netfilter provides various hooks into the Linux networking stack that allow you to perform various operations on packets. The `nf_tables` kernel module allows you to implement firewall rules from userspace: ```text $ sudo lsmod | grep ^nf_tables nf_tables 253952 105 nft_compat,nft_counter,nft_chain_nat $ sudo modinfo nf_tables | head -n5 filename: /lib/modules/5.10.0-18-amd64/kernel/net/netfilter/nf_tables.ko alias: nfnetlink-subsys-10 author: Patrick McHardy <kaber@trash.net> license: GPL depends: nfnetlink,libcrc32c ``` *Also notable:* firewalld, ufw notes: - firewalld: - https://firewalld.org/ - ufw - "Uncomplicated Firewall": https://en.wikipedia.org/wiki/Uncomplicated_Firewall --- ## Tables vs chains <div class="fragment semi-fade-out" data-fragment-index=0> _**Tables:**_ top-level containers within an `nftables` ruleset. Each table typically contains one or more chains *(as well as some other types of objects that we won't cover here.)* </div> <div class="fragment" data-fragment-index=0> _**Chains:**_ a list of rules that affect whether a packet is accepted or rejected. A chain can also include various logging statements and counters, references to other chains, etc. </div> --- ## `nftables`: general commands <div class="fragment semi-fade-out" data-fragment-index=0> List all tables and their rules: ```bash nft list ruleset ``` </div> <div class="fragment fade-in-then-semi-out" data-fragment-index=0> Delete all tables and chains: ```bash nft flush ruleset ``` </div> <div class="fragment" data-fragment-index=1> Read firewall rules from a file: ```bash nft -f firewall.nft ``` </div> notes: References: - Nftables wiki: https://wiki.nftables.org/wiki-nftables/index.php/Main_Page - Arch Linux wiki: https://wiki.archlinux.org/title/nftables - Gentoo wiki: https://wiki.gentoo.org/wiki/Nftables/Examples --- ## Components of a chain <figure> <img src="../../img/networking/chain_components.png"style="max-height: 40vh;"> <figcaption> </figcaption> </figure> --- ## `nftables` configuration The following firewall configuration adds a table, `my_table`, with a single chain that drops all input traffic. <pre> <code class="text" data-trim data-line-numbers="1-11|3-4|6|7|8|9" data-fragment-index="0"> #!/usr/sbin/nft -f table inet my_table delete table inet my_table table inet my_table { chain my_chain { type filter hook input priority filter policy drop } } </code> </pre> --- ## `nftables` configuration The following table has dropping all input and output traffic: <pre> <code class="text" data-trim data-line-numbers="1-16|8,13" data-fragment-index="0"> #!/usr/sbin/nft -f table inet my_table delete table inet my_table table inet my_table { chain input_chain { type filter hook input priority filter policy drop } chain output_chain { type filter hook output priority filter policy drop } } </code> </pre> --- ## `nftables` configuration You can add many different types of rules to a chain: <pre> <code class="text" data-trim data-line-numbers="1-20|5-7|9-11|13-14|2-3,16-19" data-fragment-index="0"> chain my_input_chain { # Default policy is to drop packets that don't match a rule type filter hook input priority filter; policy drop; # Allow all inbound traffic on the loopback interface `lo`, which allows your # computer to talk with itself via the 127.0.0.0/8 address range iif lo accept # Allow the ICMP protocol (used by ping); maintain a counter of the number of # ICMP packets that are matched by this rule ip protocol icmp counter accept # Allow all packets from IP addresses in the 10.0.0.0/8 address range ip saddr 10.0.0.0/8 accept # All packets that don't match one of the previous rules get dropped by the # default policy at this point. We have a counter that shows the number of # dropped packets counter comment "Number of dropped inbound packets: " } </code> </pre> --- ## `nftables` configuration <pre> <code class="text" data-trim data-line-numbers="1-20|12-15|1-7,17-19" data-fragment-index="0"> counter dns_counter { comment "Number of DNS packets: " } counter http_counter { comment "Number of HTTP packets: " } chain my_output_chain { type filter hook output priority filter; policy drop; # Allow all outbound traffic on the loopback interface and to hosts on the # 10.0.0.0/8 subnet oif lo accept ip daddr 10.0.0.0/8 accept udp dport 53 counter name dns_counter accept tcp dport 53 counter name dns_counter tcp dport {80, 443} counter name http_counter accept } </code> </pre> --- ## `nftables` configuration It's also possible to set a chain's policy to default to accept: <pre> <code class="text" data-trim data-line-numbers="1-20|2|4-5|7-10|13-20" data-fragment-index="0"> chain audit { type filter hook input priority security; policy accept; # Drop traffic to port 9001 that doesn't come from localhost ip saddr != 127.0.0.1 tcp dport 9001 drop # Log traffic from hosts not in the 127.0.0.0/8, 10.0.0.0/8, or 192.168.0.0/16 # subnets, as well as all inbound SSH traffic ip saddr != {127.0.0.0/8, 10.0.0.0/8, 192.168.0.0/16} goto audit_logging tcp dport 22 goto audit_logging } chain audit_logging { # Emit a log message to the system log with the matched packet # You can view this log by running `journalctl -xe` counter log prefix "Logged input packet: " flags all # After reaching the end of this chain, the default policy from the parent # chain gets applied, so the packet is accepted } </code> </pre> === ## Midterm results --- ## Midterm results _**Median:**_ 14 points _**Average:**_ $\approx$ 12.7 points <figure> <img src="../../img/misc/midterm_grades.png"style="max-height: 40vh;"> <figcaption> </figcaption> </figure> --- ## Midterm _Common issues:_ <div class="fragment semi-fade-out" data-fragment-index=0> - Trying to use a CSRF-type payload for the XSS problem; all you needed to do was <pre> <code class="html" data-trim> <script> document.getElementById("followButton").click(); </script> </code> </pre> </div> <div class="fragment fade-in-then-semi-out" data-fragment-index=0> - Using `sqlmap` for the SQL injection problem </div> <div class="fragment fade-in-then-semi-out" data-fragment-index=1> - Using a `POST` request instead of a `GET` request for the CSRF problem, and using some _extremely unique_ techniques to perform CSRF </div> --- ## Midterm I'd like to hear your feedback about the exam! - What did you think? - Did you like the format? - Was it too long / too short? - What can be improved for the final? === ## Other network security techniques --- ## Traffic analysis: Wireshark Wireshark is a traffic analysis tool for dissecting packet captures ("pcaps") and analyzing the packets sent over a network interface. <figure> <img src="../../img/networking/wireshark.svg"class="image-background"style="max-height: 30vh; padding: 20px;"> <figcaption> </figcaption> </figure> --- ## Wireshark *Example:* `curl http://neverssl.com` <figure> <img src="../../img/networking/wireshark_example_http.webp"style="max-height: 50vh;"> <figcaption> </figcaption> </figure> --- ## Wireshark *Example:* `dig example.org` <figure> <img src="../../img/networking/wireshark_example_dns.webp"style="max-height: 50vh;"> <figcaption> </figcaption> </figure> --- ## NIDS: Zeek/Bro, Snort, Suricata An _**network intrusion detection system (NIDS)**_ is software that watches network activity and attempts to detect anomalous and/or potentially malicious behavior. <div class="container" style="align-items: center;"> <div class="col"> <figure> <img src="../../img/networking/snort3.webp"style="max-height: 30vh;"> <figcaption> </figcaption> </figure> </div> <div class="col image-background"> <figure> <img src="../../img/networking/zeek.png"style="max-height: 30vh;"> <figcaption> </figcaption> </figure> </div> <div class="col"> <figure> <img src="../../img/networking/suricata.png"style="max-height: 30vh;"> <figcaption> </figcaption> </figure> </div> </div> --- ## Suricata examples Default Suricata configuration file: `/etc/suricata/suricata.yaml` Follow Suricata alerts: ```text sudo tail -f /var/log/suricata/eve.json | jq -c 'select(.event_type=="alert")' ``` Reload Suricata rules (while the Suricata daemon is active): ```text sudo suricatasc -c reload-rules ``` --- ## Suricata examples <div class="fragment semi-fade-out" data-fragment-index=0> Generate an alert when outbound HTTP traffic is detected: ```snort alert http any any -> any any ( \ msg: "SURICATA detected outbound HTTP"; \ flow: to_server; \ sid: 1001; \ rev: 1; \ ) ``` </div> <div class="fragment" data-fragment-index=0> Generate an alert for DNS traffic requesting `example.org`: ```snort alert dns any any -> any any ( \ msg: "SURICATA detected DNS"; \ sid: 1002; \ rev: 1; \ dns_query; \ content: "example.org"; \ nocase; \ ) ``` </div> notes: `sid` = signature ID, used to filter for certain types of alerts `rev` = revision (version of the signature) To follow a specific SID: - tail ... | jq -c 'select(.event_type=="alert" and .alert.signature_id==1001)' Reload rules: `sudo suricatasc -c reload-rules` Suricata rules reference: https://suricata.readthedocs.io/en/suricata-6.0.0/rules/index.html - Suricata config file: `/etc/suricata/suricata.yaml` - Suricata rules files: `/etc/suricata/rules/suricata.rules` - Can also modify the rules files read by default in the `rule-files` option --- ## Suricata examples Detect outbound HTTP requests containing JPEG files: ```snort alert http any any -> any any ( \ msg: "FILEMAGIC detected JPG"; \ flow: established,to_server; \ filemagic: "JPEG image data"; \ sid: 1003; \ rev: 1; \ ) ``` notes: Can test with ``` curl -XPOST --data-binary @/path/to/file.jpg $URL ```