CS 161 Notes Lec 21-22

Overview

Lecture 21: DNSSEC
  1. DNS over TLS
    1. Issues
  2. DNSSEC
    1. High-level design

    2. Design details

    3. Implementation details

    4. Key-signing keys and zone-signing keys

    5. NSEC: Signing non-existent domains

    6. In practice

Lecture 22: Denial of Service and Firewalls
  1. Denial of service
    1. Availability

    2. Application-level DoS

    3. Network-level DoS

    4. SYN flooding

  2. Firewalls
    1. Packet filters

    2. Proxy firewalls

DNS over TLS

In lecture 20, DNS was introduced. But since it’s based on UDP, we have no security against MITM and on-path attackers, also, off-path attackers can perform spoofing attacks. So, can we just migrate DNS from UDP to TLS, so that security can be provided?

Note that for DNS, we want to have integrity, but it’s unnecessary to give it confidentiality, since the information in those messages are after all addresses that can be known by anyone.

So, we can try to send all DNS messages on TLS, to gain an end-to-end security.

Issues
  1. Firstly, we know that DNS requests are so frequent that they must be efficient. While TLS has all those complicated handshakes going on for each single connection, which is definitely too much for DNS.

  2. Secondly, TLS is end-to-end secure, so what about the malicious DNS name servers that send poisoned records?

  3. Thirdly, on the other end of this TLS communication, what if the recursive resolver got attacked? The cached records got modified and no one can verify them.

  4. Lastly, what if the recursive resolver itself is malicious, that will be a MITM!

Here we introduce a pair of concepts, channel security and object security.

  • Channel security: Securing the communication channel between two end hosts.

  • Object security: Securing a piece of data (in transit or in storage).

So, TLS over DNS provides channel security, but what we want is object security.

DNSSEC

DNSSEC stands for DNS Security Extensions, it’s an extension of the DNS protocol that ensures integrity on the results.

High-level design

While in most of the previous lectures, protocols will be present in an abstracted version, filtering out some details that might be too complicated or not that important, this time, however, CS 161 instructors decided to present DNSSEC in its whole picture, with all the necessary details :) .

So we’ll begin to design such a secure & efficient protocol step by step.

First of all, we need to know that DNSSEC must be backwards-compatible, meaning that machines using DNSSEC should still be able to recognize the older DNS messages. That’s because not all DNS name servers are gonna support DNSSEC.

Now let’s consider some questions that might provide some guidelines.

  1. What kind of cryptographic primitive should we use to ensure integrity on the records?
    • We should use a scheme that provides integrity: either MACs (symmetric-key) or digital signatures (public-key).

    • Digital signatures are the best solution here: We want everyone to be able to verify integrity (not just the people with the symmetric key).

  2. How do we ensure the returned record is correct and has not been tampered?
    • Signatures!

    • The name server should sign the record with their private key. We should verify the record with their public key.

  3. What does the name server need to send in order to ensure integrity on a record?
    • The record.

    • A signature over the record, signed with the private key.

    • The public key.

  4. How do we makes sure a name server isn’t malicious?
    • Use certificates.

    • What DNSSEC uses is actually PKI(public-key infrastructure) that delegates trust using real-world business relationships.

    • PKI is based on a single trust anchor(the root name server), then let each server certificate its children, so the trust will be passed down hierarchically.

  5. How does a name server delegate trust to a child name server?
    • Just like in a certificate chain, the parent must sign the child’s public key.

At this point, our DNSSEC design will be something like this,

Design details

Let’s now dive into some details of our design.

  1. Sign records
    • Digital signatures provide integrity.
      • Only the name server with the private key can generate signatures.

      • Everybody can verify signatures with the public key.

    • Digital signatures defeat network attackers.
      • An off-path, on-path, or MITM attacker can no longer tamper with records.

      • The recursive resolver can no longer tamper with records(just like how bitcoin transform records are protected).

    • Signatures can be cached with the records for object security
      • Any time we fetch a record from the cache, we can verify its integrity.
  2. Public-Key Infrastructure (PKI)
    • Name servers are arranged in a hierarchy, as in ordinary DNS.

    • Parents can delegate trust to children.
      • The parent signs the child’s public key to delegate trust to the child.

      • If you trust the parent name server, then now you trust the child name server.

    • Trust anchor: We implicitly trust the root name server.
      • The root name server’s public key is hard-coded into resolvers.

      • The private key of root name server is what we believe to be absolutely secure, in fact, many authorities in the field gathered together to generate such keys, according to the instructor of CS 161.

    • PKI defeats malicious name servers.
      • A malicious name server (assuming they don’t have access to the private key, only the signatures) won’t have a valid chain of trust back to the root.

Now, here’s a series of graphs showing how a DNSSEC query might go under our design.

Firstly, a query is sent to root name server,

After receiving a signed response containing public key of the .edu name server, a query will be sent to .edu name server.

Again, we received a response telling us to ask someone else, with the new public key, we sent a query to berkeley.edu name server,

Finally, we got our answer, which can be stored into the cache.

Implementation details

As I’ve mentioned, the instructor decided to show all DNSSEC details in this course, so we’ll now consider implementation details of this protocol.

First thing to know is that flags field in DNS packet is fixed to be 8 bits, using 1/0 we can indicate whether a flag is set or not. Since we have to make DNSSEC backwards-compatible, the length of flags can not be extended.

To solve that, we use encode extra flags in a record called the OPT pseudosection. This record will be sent in additional section, with the type OPT. Such solution is brought in protocol EDNS0 (Extension Mechanisms for DNS).

Now let’s consider resource record sets.

  • Recall that a DNS record has a name, a type, and a value.

  • A group of DNS records with the same name and type form a resource record set (RRSET).

  • RRSETs will be useful for simplifying signatures.

    • Instead of signing every record separately, we can sign an entire RRSET at once.

By our design, the server will include things like public key, signatures in DNS responses, so where should these information be stored in a DNS packet?

  • Again, they’ll be stored as RRs.

  • Thus we have to introduce new types of RRs for them:

    1. RRSIG (resource record signature): encode signatures on records.
      • RRSIG type records encode a signature on records.
        • One RRSIG record (with one signature) can sign an entire RRSET.
      • RRSIG type records contain some additional metadata
        • Type: What type of DNS record we’re signing.

        • Algorithm: What algorithm we’re using to create the signature.

        • Label: Number of segments in the DNS name.

        • Original TTL: The TTL for the records in the RRSET.

        • Signature expiration time (in Unix time: seconds since January 1, 1970).

        • Signature inception time: When the signature was created (in Unix time).

        • Key tag: What key was used (roughly, a checksum on key bits).

        • The name of the signer.

    2. DNSKEY: encode public keys.
      • DNSKEY type records encode the name server’s own public keys.

      • DNSKEY type records contain some additional metadata too

        • 16 bits of flags.

        • Protocol identifier (currently not in use, so always set to 3).

        • Algorithm identifier.

    3. DS (delegated signer): encode the child’s public key (used to delegate trust).
      • DS type records encode the hash of the child’s public keys together with the parent’s name.
        • Used to delegate trust.
      • DS type records contain some additional metadata too
        • The key tag.

        • The algorithm identifier.

        • The hash function used.

With this more detailed implementation, the DNS query process we showed above will turn to this:

Key-signing keys and zone-signing keys

In the slides, this part is about “what to do if a child has to change its private key?”, the mechanism to settle this issue is so complicated that the instructor made this part optional during the lecture.

Personally, I don’t want to spend time learning this part since it contains terrifying graphs like the one below,

So I won’t include this part in this blog :)

NSEC: Signing non-existent domains

Here’s an interesting issue to think about, how should the DNSSEC response look like if it turns out that the domain has no matching IP address?

Why should this be an issue? How does DNS protocol deal with this?

  • In DNS, such non-existent domains will simply get a response saying the domain doesn’t exist.

  • So, why can’t we use the same method in DNSSEC? Because it will bring us to a question, whether to sign this “doesn’t exist” message or not ;) ?
    • If we don’t sign, this message will no longer have integrity, an attacker can pretend to be a DNS name server and tell users that google.com doesn’t exist.

    • If we do sign, the problem is that generating signature takes a lot of time. Since there’re infinitely many non-existent domains, an attacker can make numerous queries of such domain to cause a huge computational burden of the DNS name server.

  • By the way, we call such responses NXDOMAIN responses.

The solution for that is to use NSEC, which stands for NextSECure.

  • Sign a record stating that no record of a given type exists. At the same time, provide two adjacent domains alphabetically, so that you know that no domain in the middle exists.

  • Example: If I query for nonexistent.google.com, I can receive a signed NSEC response saying “No domains exist between maps.google.com and one.google.com.”

  • Since the existing domains are finite(and not likely to be too many), we can be sure that such NXDOMAIN response won’t be that frequent.

Here’s a domain name prefix graph illustrating the idea,

Note that when we want to indicate no domain exists “before” maps, we can say “No domains exist between web.google.com and maps.google.com.”

An issue about NSEC is that such practice give attackers a way to enumerate subdomains of a website.

  • The attacker can start by querying a.google.com, and keep on querying according to the NXDOMAIN responses, to know all the “boundaries”, thus all the subdomains of google.com.

  • If you don’t want others to know some secret subdomains, such attack will be an issue.

NSEC3 tried to solve domain enumeration by hashing all existing subdomains, and order by hash results,

  • Example: If I query for nonexistent.google.com, which hashes to d48678…, I receive a signed NSEC3 saying “There exist no domains which hash to values between c612f3… and d810de…”

This method is much better than NSEC. However, since the length of subdomains are not likely to be too long, it’s still possible for the attackers to brute-force the subdomains.

Denial of service

Availability

Before talking about DoS, the first concept to introduce is the availability.

Availability means making a service(such as google search engine gives user a search result) on the network available for legitimate users.

Denial of Service(DoS) is an attack that disrupts availability of a service, making it unavailable for legitimate users.

DoS attacks are mainly about the following strategies:

  • Exploiting program flaws
    • Software vulnerabilities can cause a service to go offline.

    • Example: Exploit a buffer overflow to execute a shutdown command to the system.

    • Example: Exploit a SQL injection vulnerability to delete the database.

  • Resource exhaustion
    • Everything on the network has limited resources.

    • The attacker consumes all the limited resources so legitimate users can’t use them.

  • Bottlenecks
    • Different parts of the system might have different resource limits.

    • The attacker only needs to exhaust the bottleneck: the part of the system with the least resources.

By the target, DoS attacks can be categorized into:

  • Application-level DoS: Target the high-level application running on the host.

  • Network-level DoS: Target network protocols to affect the host’s Internet.

Application-level DoS

What is an application-level DoS?

  • Target the resources that the application uses.

  • Exploit features of the application itself.

  • Some attacks rely on asymmetry: A small amount of input from the attack results in a large amount of consumed resources!

The goal is to consume the resources of the server. Here’re some examples:

The attacks on the graph above are:

  1. Exhausting filesystem space.

  2. Exhausting RAM.

  3. Exhausting processing threads.

  4. Exhausting disk I/O operations.

For those applications that let user choose input data, and perform algorithm on it,

  • The attackers can use something called algorithmic complexity attack, which supplies input that trigger worst-case complexity of algorithms and data structures used by the server.

  • The defense, on the other hand, should be the server choosing algorithms & data structures with better worst-case complexity.

What are defenses for application-level DoS?

  • Identification: Step 0 of any defense
    • You must be able to distinguish requests from different users before you can do anything else!

    • Requires some method to identify/authenticate users.

    • Authenticating users might be expensive and itself vulnerable to DoS.

  • Isolation: Ensure that one user’s actions do not affect another user’s experience.

  • Quotas: Ensure that users can only access a certain proportion resources.
    • Example: Only trusted users can execute expensive requests.

    • Example: Limit each user to 4 GB of RAM and 2 CPU cores.

  • Proof-of-work: Force users to spend some resources to issue a request.
    • Idea: Make a DoS attack more expensive for the attacker, who now needs to spend resources.

    • Example: Add a CAPTCHA, which the attacker will now have to solve (or pay for solving services).

  • Overprovisioning: Allocate a huge amount of resources, so it’s more difficult for attackers to consume all of them ;) .
    • Can cost the server a lot of money!

    • Depends on your threat model, if doing so worth it, then it’s a straightforward method as defense.

    • Often the most effective defense (“security is economics”).

    • Content delivery network (CDN): A service that allocates a huge amount of resources for you.

      • Example of a CDN: Cloudflare.

      • Cloudflare runs your service for you with a huge amount of resources.

Network-level DoS

As the name indicates, network-level DoS attacks focus on affecting victim’s Internet access.

  • The attacker can try to overwhelm the victim’s bandwidth(amount of data it can upload/download in a given time).
    • Example: The server can only upload/download 10 MB/s. The attacker sends the server 20 MB/s.
  • The attacker can try to overwhelm the victim’s packet processing capacity.
    • Example: The server can process 10 packets/second. The attacker sends the server 20 packets/second.
  • A famous attack related is DDoS(Distributed Denial-of-Service) attack.
    • To use multiple systems to overwhelm the target system.

    • Controlling many systems gives the attacker a huge amount of bandwidth.

    • Sending packets from many sources makes it hard for packet filters to distinguish DDoS traffic from normal traffic.

    • Something involved in this attack is called botnet.

      • Botnet is a collection of compromised computers controlled by one attacker, when attacking, the attacker can tell all the computers on the botnet to flood a given target.

  • Another famous one involved is amplified DoS.
    • To use an amplifier to overwhelm the target more effectively.

    • This one is interesting, instead of controlling a bunch of devices to perform DDoS for you, you take advantage of some legitimate devices that you don’t need to control, but you make them respond your short request with times of longer responses.

    • DNS name server is just a perfect example!
      • The attacker spoofs a query containing a question of domain name, but pretend himself/herself to have IP address of the victim.

      • If you recall, in lecture 20, I showed how a DNS response may look like. It basically contains a lot of records, while the query that triggers such response can be pretty short.

      • As the attacker somehow modifies the UDP header of DNS request, claiming it to be sent by the victim, the responses of the DNS name server will be sent to the victim!

      • So with a short payload of queries, the attacker can make the legitimate server amplify the payload to perform DoS attack! And the attacker doesn’t need to worry about DNS name server bandwidth since they’re definitely stable :)

    • Amplified DoS doesn’t even reveal attacker’s identity to the victim! But it can’t be performed on TCP, since TCP requires handshake. So DNS that based on UDP is a good option for amplified DoS.

Defenses for network-level DoS:

  • Packet filter: Discard any packets that are part of the DoS attack.
    • Discard packets where the source IP is the attacker’s IP address.

    • Find some pattern in the content of the DoS packets to distinguish DoS packets from legitimate packets.

    • The packet filter must be before the bottleneck.

  • But packet filter can be subverted:
    • Spoof DoS packets so that packets look like they’re coming from many IP addresses.
      • Packet filters can’t use IP addresses to filter packets anymore!

      • Hard to defend against.

      • Rely on anti-spoofing mechanisms on the network.

    • Distributed DoS actually send packets from many IP addresses.
      • Packet filters need to be much more sophisticated to defend against DDoS attacks.
  • Overprovisioning: Purchase enough networking bandwidth and equipment to make it harder for attackers to overwhelm the network.
    • Again, depends on your threat model!
SYN flooding

SYN flooding is a type of DoS attack that exploits many TCP connections.

The main idea of SYN flooding:

  • Remember the first step in TCP handshake? It’s a SYN packet sent by the client who want’s to establish a TCP connection

  • When the server receives this SYN packet, it has to allocate some memory and store the relevant data.
    • Relevant data includes the sequence number x, ACK numbers, buffered data, etc.
  • So what if the attacker sends a lot of SYN packets to a server, but doesn’t reply after receiving SYN-ACK packet?

  • A DoS aiming on server’s memory is thus performed.

How do we defend against SYN flooding?

  • Sure, we can use overprovisioning, but it’s still gonna be a lot of cost for the server.

  • Is filtering out attacker’s SYN packets possible? Not exactly, you couldn’t tell whether that will be legitimate before handshake is done. Also, the attacker can pretend to be any IP, so the server can’t block them.

  • The solution is quite clever, it’s called SYN cookies.

    • Remember how cookies are used in browser to store client information for requests to server? SYN cookies use the same idea.

    • Instead of storing the relevant information for this TCP connection request in the server, the server will just send this piece of data(we call it state) back to the client! And let the client send it back in future handshake steps! So no state needs to be stored in the server!

    • But an issue to consider is that how to add this state in SYN-ACK packet? Since we can’t change the TCP handshake message format, the state has to be stored at some field that already exists.

    • While, just use the sequence number! The server will first encode the state in the sequence number and send it to the client.

  • (SYN cookies continued)
    • Now, without manually telling the client to do so, according to TCP, the client will automatically send the ** + 1** back in ACK if it does want to establish this TCP connection, and that's when the server really stores this state(before which it will minus one and decrypt the ).

Based on SYN cookies, we can generalize such idea to all the similar attacks.

  • Instead of storing states for an uncertain request, the server encode the state and send it back to client and make the client to store it instead.

  • The key here is to trick the client to automatically send this encoded state back to server later.

  • Also note that encoding states should not take too much time, otherwise this process itself will turn from a DoS aiming on memory to another DoS aiming on computational power(or time).

Firewalls

The motivation of using a firewall is to protect a set of systems against external attacks.

Instead of protecting machines individually, why not secure the entire network :)

It’s straightforward to provide such a protection, all you need is to assign a single point of access, which connects a network with the Internet. Since the access point is used to protect the network, we just call it firewall.

Surely some policies need to be followed by a firewall:

  • Outbound policy: Defines what traffic is allowed to exit the network.
    • Simply allow all outbound traffic! Since we trust the devices inside the network.
  • Inbound policy: Defines what traffic is allowed to enter the network.
    • Allow inbound traffic in response of an outbound connection.

    • Allow inbound traffic to certain, trusted services (e.g. SSH).

    • Deny all other inbound traffic.

How should we handle traffic that isn’t explicitly allowed or denied?

  • Default-allow policy: Allow all traffic, but deny those on a specified deny-list.
    • As problems arise, add them to the deny-list.
  • Default-deny policy: Deny all traffic, but allow those on a specified allow-list.
    • As needs arise (or users complain), add them to the allow-list.
  • Default-deny is generally accepted to be the best default policy (“consider fail-safe defaults”).
Packet filters

Basically, the firewall’s job is to filter out certain packets from the outside network, so we provide it with two options towards the packets from outside.

  1. Allow the packet to pass through the firewall, forwarding it onwards.

  2. Deny the packet from passing through the firewall, dropping it.

A decision to make here is whether to implement this packet filter in a stateful way. Remember in SYN flooding we saw how servers should tend not to store too much information from clients, so it might be tempting to implement the packet filter in a stateless way, meaning no information about previous packets shall be stored.

Issues about stateless packet filters:

  • Remember our rule stated that outbound packet can go through if it’s a response to an inbound packet? If we don’t store anything, how can we verify that?

So, we’ll use stateful packet filters.

  • The filter keeps track of inbound/outbound connections.

  • Rules define what connections are allowed or denied. Ultimately, packets are still either forwarded or dropped.

  • Example rules:
    • allow tcp connection 4.5.5.4:* -> 3.1.1.2:80
      • Allow connections from 4.5.5.4 to 3.1.1.2 with destination port 80
    • allow tcp connection *:*/int -> *:80/ext
      • Allow outbound connections with destination port 80
    • allow tcp connection *:*/int -> *:*/ext
      • Allow all outbound connections
    • allow tcp connection *:*/ext -> 1.2.2.3:80

    • Allow inbound connections to 1.2.2.3 with destination port 80
  • Stateful packet filters can also track the state of well-known applications.
    • Example: Decoding and tracking HTTP requests/responses.

    • Example: Tracking the files sent in an FTP (File Transfer Protocol) connection.

So, how might packet filters got subverted?

  • Consider a simple, example: say, we want the firewall to deny all inbound packets containing the string “root”.

  • It sounds easy, since the packet filter just need to read all the packets sent from outside and drop those containing “root”.

  • However, since the firewall doesn’t really store the packets(it would be too much for it to store), it can’t tell if a “root” string is sent by split TCP packets.

  • As the diagram shown above, the attacker can send the “root” string in different TCP packets, in which way the firewall won’t be able to filter them out.

  • Here’s another way of attacking.

    • Recall that each IP packet has a TTL(time-to-live) field, which shows how long the packet can travel(by counting routers it has passed through).

    • The attacker can easily find how many hops away a given server is, by sending ping packets with increasing TTLs until the server responds.

    • Then the attacker can send packets that contain trash, but use the TTL to make sure those trash will be seen by the firewall, and get dropped before reaching the target server. See the diagram below,

  • In this way, it’s even harder for firewall to defend!
Proxy firewalls

The issues mentioned above can be settled by something called proxy firewalls.

  • Instead of forwarding packets, form two TCP connections: One with the source, and one with the destination.

  • Basically, just turn the firewall to a man-in-the-middle! So it can actually verify the inbound packets no matter what protocol they use!

A relevant topic here is VPN, which stands for Virtual Private Network.

  • VPN is a set of protocols that allows direct access to an internal network via an external connection.

  • VPN creates an encrypted tunnel to allow internal network traffic to be sent securely over the Internet.

  • The encrypted tunnel is an emulated Ethernet cable that allows you to connect “inside” the network.

  • The firewall allows VPN traffic, which allows arbitrary traffic to be tunneled inside ;)

Written on May 10, 2023
-->