Skip to main content

Announcing Invariant 2.0

· 5 min read

We’re pleased to announce the release of Invariant 2.0. This is a major update to the Invariant application, delivering on our vision of transforming how network teams validate and monitor networks.

Introducing Instant Rule Evaluation

Starting in Invariant 2.0, users can run instant connectivity checks from the UI using the Quick Trace feature.

Invariant Quick Trace Screenshot

Specify protocols, a destination IP address (or CIDR), and optionally service or port constraints to exhaustively search for any connectivity issues within that range. The UI includes an interactive results viewer to visualize or view raw trace data by outcome, by source packet, or by a specific trace path.

If your team is using Aerleon, you can import your Aerleon network and service definitions into Invariant and use them in Quick Trace. You can even import a global set of definitions and overlay site-specific adjustments (e.g., site-specific CIDRs for GUEST_VLAN).

Share your instant connectivity check results with any authorized user via URL.

Target any network snapshot, including past states of the network or proposed network states.

As always, the vendor-agnostic network model considers ACLs, IPSec, BGP, OSPF, and packet transformations when performing synthetic connectivity checks.

Introducing Network Rules

Invariant 2.0 disentangles the management of network validation rules from snapshot creation. Now, authorized users can directly create, edit, and test network validation rules directly through the web.

Invariant Rule Editor Screenshot

Network Rules delivers on the continuous synthetic network validation story: define your network validation rules once, and Invariant will validate every new snapshot against it. If configured, Invariant can notify your team or connected systems via Slack or email. You will get an immediate compliance verdict spanning your whole suite of connectivity and access control rules.

Slack Notifications

In addition to email notifications, Invariant can now be configured to post in Slack when a new snapshot fails its validation rule suite.

Invariant Slack Alert Example

Democratize Access To Data

Invariant 2.0 adds the Data screen, a powerful surface for inspecting deep details of the synthetic network model across a wide range of network features.

Invariant Data: Route Tables

The data tables can be filtered, downloaded, and shared to authorized users via URL.

Invariant Data: BGP Status

Surfacing this information allows network stakeholders to understand how core protocols are functioning (or are expected to function after proposed changes are rolled out) and troubleshoot issues when they arise. Incident response teams can instantly access deep details like estimated device route tables directly in Invariant.

Secret Mangling By Default

Starting in version 2.0, the Invariant Client will automatically mangle secrets found in network configs.

Ingestion Pipeline

The new invariant sync command, integrated into the Invariant Client, can directly fetch network configs per your fetcher.yaml config file and sync them with Invariant. For more advanced workflows, invariant fetch fetches the configs to local disk, where you can later use invariant run to create a snapshot.

Advanced Connectivity And Vulnerability Scanning Platform

The new invariant eval command, which performs instant rule evaluation against a target network snapshot, is the dark horse of this release. While the primary purpose of this command is to allow you to rapidly iterate on rules using an editor or IDE, it can also be used to deploy advanced connectivity and vulnerability scans against multiple snapshots.

Suppose you wish to investigate your network's exposure to a novel vulnerability. Write a rule that tests whether the relevant service is exposed. Evaluate this rule against the current snapshot for each network using invariant eval and receive an answer in seconds. Want to automate this function? The Invariant REST API exposes the same eval capability.

Suppose you are investigating a connectivity issue and you want to determine when the issue was first introduced. Your existing network rule suite didn't cover this particular flow. While in the UI you can quickly check the connectivity one snapshot at a time, you can apply eval --condense in a loop against all snapshots for the current network, working backward in time until the command output changes from FAIL to PASS.

General Improvements

This release includes a wide range of small improvements to ease the experience of using the system. Some highlights:

  • Network snapshots may be deleted or moved between networks, and networks can be renamed or deleted.
  • New unfiltered reports were introduced for simplified access to rule evaluation results: policy_summary_all, policy_details_all, and policy_logs_all.
  • Syntax errors and other file- or policy-level issues are now surfaced more consistently in the UI and rule evaluation result data files. The UI includes a dedicated visualizer for the errors file, and position and provenance metadata are now attached to all rule evaluation results.
  • The Invariant Client's interactive login feature now stores credentials in your encrypted OS keychain when available. XDG is used as a fallback.
  • De-permissioned sync-only service accounts can now be created via RBAC.

Discovering Network Vulnerabilities with Invariant

· 8 min read

Invariant can be used to rapidly and comprehensively assess your network’s exposure to malicious traffic. This article will demonstrate how to assess an example network’s exposure to the critical linux CUPS vulnerability (CVE-2024-47176).

For background, CVE-2024-47176 is a widely discussed high-severity vulnerability involving malicious UDP traffic reaching vulnerable linux hosts on port 631. Blocking UDP traffic on port 631, especially from untrusted sources like the internet, is part of a recommended remediation strategy for this issue.

This article will show how to use Invariant to perform the following steps:

  • Determine whether traffic originating from the internet can reach any network subnets, and if so, how.
  • Given a known vulnerable machine, determine if there is any exposure to malicious traffic from less-trusted parts of our network.

Internet Exposure

Invariant works by evaluating whether user-defined rules are true or false. We will create a policy which asserts that no traffic originating from the public internet can reach any internal subnet on UDP port 631.

The way we will do that is by using egress-deny rules which apply to all traffic egressing from the public internet to our network. The source-address will be set to ANY, excluding RFC1918 space and our DMZ address space (defined elsewhere). One rule will then refer to traffic with destination-address in RFC1918 space and the other to traffic that can reach the DMZ. The reasoning behind this split is based on our own expectation and knowledge of our network: it seems more likely that the DMZ has some exposure than the private IP space, so the first rule is expected to pass, while the second one we are not totally sure of.

access-policy:
- name: deny-malicious-external-traffic
egress-network:
source-address: ANY
source-address-exclude: RFC1918 DMZ
rules:
- type: egress-deny
destination-address: RFC1918
destination-port: IPP
protocol: udp
- type: egress-deny
destination-address: DMZ
destination-port: IPP
protocol: udp

The egress-deny rules have the destination port and protocol set to IPP (port 631) over UDP. When we run Invariant, it will verify that there is no possibility of a successful IPP connection over UDP between the internet and the two destination subnets.

What makes Invariant especially strong is it will take into consideration not just ACLs but also NAT, BGP, and null routes. So it could be the case that the RFC1918 subnet is protected not by an ACL, but through the absence of viable routes. Moreover, Invariant will give answers very quickly - it can search all possible cases in seconds.

After placing this policy in invariant/policies/cups-check.yaml we will run it in Invariant.

$ invariant run --condensed
snapshot: e929babf-34de-407b-92cc-9cbec4badb04
outcome: All rules passed

No violations were found in this case. We are now confident that no internet traffic can connect to any part of our network on port 631 over UDP.

Internal Exposure

Our network contains a print server. This is a known higher risk target as the vulnerable cupsd service is more likely to be enabled on print servers. We know it cannot be reached from the internet, but what about exposure to untrusted VLANs? Of special concern are the guest wireless network and the external HVAC vendor with access to our network.

The next step is to make a similar rule to look at traffic originating in the GUEST_WIRELESS and HVAC_VLAN subnets. We will set the destination-address to PRINT_SERVER, the IP of the print server.

Invariant is especially useful here because these source VLANs are present in multiple physical locations. We would have had to manually check each distribution switch and the paths each physical location would take. Instead, Invariant will automatically find and consider all possible start locations and all possible paths.

access-policy:
- name: deny-malicious-ipp-traffic
egress-network:
source-address: GUEST_WIRELESS HVAC_VLAN
rules:
- type: egress-deny
comment: Check that CVE-2024-47176 is denied to our print server.
destination-address: PRINT_SERVER
destination-port: IPP
protocol: udp

Looking good, let’s run it in Invariant.

$ invariant run --condensed
snapshot: 1d8df64b-b220-4808-901b-f7de0f21f9b4
outcome: Rule violations found

Invariant found a violation. When an egress-deny rule fails, Invariant will produce one or more virtual traceroutes showing how the target network is exposed. The next step is to access those violations.

First, use the “invariant show” command to get a listing of all files generated during the last “run” command. We want to check the “Access Policy” section.

$ invariant show
(skipped for this article)

╭──────────────────────────────────────┬────────╮
│ Access Policy │ Rows │
├──────────────────────────────────────┼────────┤
│ critical_flows_ok │ 0
│ critical_flows_violations │ 0
│ critical_flows_violations_unenforced │ 0
│ critical_flows_skipped │ 0
│ critical_flows_details │ 0
│ critical_flows_logs │ 0
│ policy_ok │ 2
│ policy_violations │ 1
│ policy_violations_unenforced │ 0
│ policy_skipped │ 0
│ policy_details │ 7
│ policy_logs │ 3
╰──────────────────────────────────────┴────────╯

Our egress-deny rule counts as a “policy” rule. The virtual traceroutes will be found in the policy_details file. This policy_details file is fairly large but we can jump right to the ‘traces’ section. We can see four different virtual trace routes in that section showing how offending packets might traverse the network and reach the print server.

The first traceroute shows how a packet could originate on dist-1 and pass through core-2, asa, and dc-1 to reach the print server. The packet would traverse two ACLs, vlan10 and internal-to-external, which we might want to consider as potential policy enforcement points.

$ invariant show policy_details --json
"traces": [
{
"disposition": "DELIVERED_TO_SUBNET",
"hops": [
{
"node": "dist-1",
"steps": [
{
"action": "RECEIVED",
"detail": {...}
},
{
"action": "PERMITTED",
"detail": {
"filter": "vlan10",
"filterType": "INGRESS_FILTER",
"flow": {
"dscp": 0,
"dstIp": "172.16.50.20",
"dstPort": 631,
"ecn": 0,
"fragmentOffset": 0,
"icmpCode": null,
"icmpVar": null,
"ingressInterface": "Vlan10",
"ingressNode": "dist-1",
"ingressVrf": null,
"ipProtocol": "UDP",
"packetLength": 512,
"srcIp": "192.168.10.252",
"srcPort": 49152,
"tcpFlagsAck": 0,
"tcpFlagsCwr": 0,
"tcpFlagsEce": 0,
"tcpFlagsFin": 0,
"tcpFlagsPsh": 0,
"tcpFlagsRst": 0,
"tcpFlagsSyn": 0,
"tcpFlagsUrg": 0
},
}
},
{
"action": "FORWARDED",
"detail": {...}
},
{
"action": "TRANSMITTED",
"detail": {...}
}
]
},
{
"node": "core-2",
"steps": [
{
"action": "RECEIVED",
"detail": {...}
},
{
"action": "FORWARDED",
"detail": {...}
},
{
"action": "TRANSMITTED",
"detail": {...}
}
]
},
{
"node": "asa",
"steps": [
{
"action": "RECEIVED",
"detail": {...}
},
{
"action": "PERMITTED",
"detail": {
"arpIp": null,
"filter": "internal-to-external",
"filterType": "POST_TRANSFORMATION_INGRESS_FILTER",
"flow": {
"dscp": 0,
"dstIp": "172.16.50.20",
"dstPort": 631,
"ecn": 0,
"fragmentOffset": 0,
"icmpCode": null,
"icmpVar": null,
"ingressInterface": "Vlan10",
"ingressNode": "dist-1",
"ingressVrf": null,
"ipProtocol": "UDP",
"packetLength": 512,
"srcIp": "192.168.10.252",
"srcPort": 49152,
"tcpFlagsAck": 0,
"tcpFlagsCwr": 0,
"tcpFlagsEce": 0,
"tcpFlagsFin": 0,
"tcpFlagsPsh": 0,
"tcpFlagsRst": 0,
"tcpFlagsSyn": 0,
"tcpFlagsUrg": 0
},
"inputInterface": "INSIDE0",
}
},
{
"action": "FORWARDED",
"detail": {...}
},
{
"action": "PERMITTED",
"detail": {
"arpIp": null,
"filter": "~COMBINED_OUTGOING_ACL~SERVER0~",
"filterType": "PRE_TRANSFORMATION_EGRESS_FILTER",
"flow": {
"dscp": 0,
"dstIp": "172.16.50.20",
"dstPort": 631,
"ecn": 0,
"fragmentOffset": 0,
"icmpCode": null,
"icmpVar": null,
"ingressInterface": "Vlan10",
"ingressNode": "dist-1",
"ingressVrf": null,
"ipProtocol": "UDP",
"packetLength": 512,
"srcIp": "192.168.10.252",
"srcPort": 49152,
"tcpFlagsAck": 0,
"tcpFlagsCwr": 0,
"tcpFlagsEce": 0,
"tcpFlagsFin": 0,
"tcpFlagsPsh": 0,
"tcpFlagsRst": 0,
"tcpFlagsSyn": 0,
"tcpFlagsUrg": 0
},
"inputInterface": "INSIDE0",
}
},
{
"action": "SETUP_SESSION",
"detail": {...}
},
{
"action": "TRANSMITTED",
"detail": {...}
}
]
},
{
"node": "dc-1",
"steps": [
{
"action": "RECEIVED",
"detail": {...}
},
{
"action": "FORWARDED",
"detail": {...}
},
{
"action": "TRANSMITTED",
"detail": {...}
},
{
"action": "DELIVERED_TO_SUBNET",
"detail": {...}
}
]
}
]
},

],

Conclusion

In today's rapidly evolving cybersecurity landscape, new vulnerabilities are discovered daily, leaving organizations constantly racing to protect their networks. One of the latest threats, CVE-2024-47176, has raised significant concern due to its potential impact on critical network systems. Understanding how this vulnerability affects their infrastructure is paramount for network engineers and security teams, but this is often easier said than done.

CVE-2024-47176 is part of a series of vulnerabilities released in September related to CUPS (Common UNIX Printing System), an application included in Linux and Mac operating systems. Exploiting these vulnerabilities could allow an attacker to execute arbitrary code on your server. The potential consequences of such an attack are severe—an attacker could gain a critical foothold into your network, potentially leading to ransomware and other severe security breaches. Invariant can help you identify if you are vulnerable, address the vulnerability, and ensure it never occurs again.

Validating whether a company's network is affected by this vulnerability would be complex. It would require checking each network configuration to determine the routability of a malicious packet and the ACLs permitting traffic. However, with Invariant, you can assess the situation definitively, providing a reliable and efficient solution to this complex problem. You can do this by focusing on where the malicious traffic originates and validating traffic towards vulnerable subnets.

With a single rule and a few minutes, we exhaustively tested our entire network and found that we were vulnerable, saving us time on troubleshooting and evaluating every configuration. The information provided gives us a couple of ACLs that would be good candidates to filter the traffic on. Leaving this rule in place would ensure that we never accidentally reintroduce this vulnerability to our network again.

Vulnerabilities arise daily, and manually checking your network for each is time-consuming. Furthermore, preventing any regression to an unsafe state can be challenging. With Invariant, both of these tasks become simple. You can easily create rules to validate your security posture, reducing the time spent on tedious tasks.

Try It Yourself

You can create a free, limited Invariant account which you can use to try out this scenario or invent your own.