falcosecurity / libs

libsinsp, libscap, the kernel module driver, and the eBPF driver sources
https://falcosecurity.github.io/libs/
Apache License 2.0
232 stars 165 forks source link

No fd.net set for UDP event? #2159

Open petterreinholdtsen opened 3 days ago

petterreinholdtsen commented 3 days ago

I am using the rule set from falco-incubating_rules.yaml, and try to filter out some of the irrelevant UDP traffic from the 'Unexpected UDP traffic' rule. When I try to filter on fd.net to avoid reports for traffic to and from localhost, this do not work. This is using the RPM packages for falco version 0.39.1-1.

For reference, the rule I am trying to modify look like this:

- rule: Unexpected UDP Traffic
  desc: > 
    Detecting UDP traffic on ports other than 53 (DNS) or other commonly used ports. Misusing UDP is a known TTP among attackers. 
    Monitoring unusual network activity is highly valuable but often generates significant noise, as is the case with this detection.
  condition: > 
    inbound_outbound 
    and fd.l4proto=udp 
    and not expected_udp_traffic
  output: Unexpected UDP Traffic Seen (connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags %container.info)
  priority: NOTICE
  tags: [maturity_incubating, host, container, network, mitre_exfiltration, TA0011]

I am overriding the expected_udp_traffic. This do not work as expected. I've tried to reduce it to a simple test case, to demonstrate the problem, using this simpler rule to trigger on ping packages not heading for localhost:

- rule: test_ping
  desc: >
    Detect UDP traffic that is not UDP ping to localhost.
    Demonstrating missing fd.net value in UDP event.
  condition: >
    (
      inbound_outbound 
      and fd.l4proto=udp 
      and proc.name=ping
      and evt.dir=<
      and not fd.net in ("127.0.0.0/8", "::1/128")
    )
  output: Unexpected UDP ping Traffic Seen (connection=%fd.name lport=%fd.lport rport=%fd.rport fd_type=%fd.type fd_proto=fd.l4proto evt_type=%evt.type user=%user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.exepath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags %container.info)
  priority: NOTICE
  tags: [maturity_incubating, host, container, network, mitre_exfiltration, TA0011]

When I test with 'ping localhost' with this rule loaded, I get events like this in /var/log/falco.log:

{
  "hostname": "mytesthost",
  "output": "11:01:14.459786448: Notice Unexpected UDP ping Traffic Seen (connection=::1:47763->::1:0 lport=47763 rport=0 fd_type=ipv6 fd_proto=fd.l4proto evt_type=connect user=root user_uid=0 user_loginuid=43502 process=ping proc_exepath=/usr/bin/ping parent=bash command=ping localhost terminal=34817 exe_flags=<NA> container_id=host container_name=host)",
  "output_fields": {
    "container.id": "host",
    "container.name": "host",
    "evt.arg.flags": null,
    "evt.time": 1731492074459786448,
    "evt.type": "connect",
    "fd.lport": 47763,
    "fd.name": "::1:47763->::1:0",
    "fd.rport": 0,
    "fd.type": "ipv6",
    "proc.cmdline": "ping localhost",
    "proc.exepath": "/usr/bin/ping",
    "proc.name": "ping",
    "proc.pname": "bash",
    "proc.tty": 34817,
    "user.loginuid": 43502,
    "user.name": "root",
    "user.uid": 0
  },
  "priority": "Notice",
  "rule": "test_ping",
  "source": "syscall",
  "tags": [
    "TA0011",
    "container",
    "host",
    "maturity_incubating",
    "mitre_exfiltration",
    "network"
  ],
  "time": "2024-11-13T10:01:14.459786448Z"
}
{
  "hostname": "mytesthost",
  "output": "11:01:14.459836313: Notice Unexpected UDP Traffic Seen (connection=::1:45431->::1:1025 lport=45431 rport=1025 fd_type=ipv6 fd_proto=fd.l4proto evt_type=connect user=root user_uid=0 user_loginuid=43502 process=ping proc_exepath=/usr/bin/ping parent=bash command=ping localhost terminal=34817 exe_flags=<NA> container_id=host container_name=host)",
  "output_fields": {
    "container.id": "host",
    "container.name": "host",
    "evt.arg.flags": null,
    "evt.time": 1731492074459836313,
    "evt.type": "connect",
    "fd.lport": 45431,
    "fd.name": "::1:45431->::1:1025",
    "fd.rport": 1025,
    "fd.type": "ipv6",
    "proc.cmdline": "ping localhost",
    "proc.exepath": "/usr/bin/ping",
    "proc.name": "ping",
    "proc.pname": "bash",
    "proc.tty": 34817,
    "user.loginuid": 43502,
    "user.name": "root",
    "user.uid": 0
  },
  "priority": "Notice",
  "rule": "Unexpected UDP Traffic",
  "source": "syscall",
  "tags": [
    "TA0011",
    "container",
    "host",
    "maturity_incubating",
    "mitre_exfiltration",
    "network"
  ],
  "time": "2024-11-13T10:01:14.459836313Z"
}

I expected these events to be ignored, as the fd.net content should match the localhost IPv4 and IPv6 content.

Environment

petterreinholdtsen commented 2 days ago

With a closer look at the logs, I now suspect that fd.net work for IPv4, but not for IPv6.

petterreinholdtsen commented 1 day ago

Perhaps it is related to https://github.com/draios/sysdig/pull/1091and https://github.com/falcosecurity/falco/pull/343 ? The unit test in the latter only test for IPv4, perhaps it could be extended to test IPv6 too? The patch in sysdig only mention IPv4, but I guess the case is equally valid for IPv6.

petterreinholdtsen commented 1 day ago

I suspect something like this might be a step in the right direction. Unfortunately I do not know how to make the IPv6 .scap file, so I am unable to complete the test.

diff --git a/test/falco_tests.yaml b/test/falco_tests.yaml
index f8dedc0..378462d 100644
--- a/test/falco_tests.yaml
+++ b/test/falco_tests.yaml
@@ -1066,12 +1066,19 @@ trace_files: !mux
     trace_file: trace_files/cat_write.scap
     stdout_contains: "^(.*\"tags\":[ ]*\\[\\],.*)"

-  in_operator_netmasks:
+  in_operator_ipv4_netmasks:
     detect: True
     detect_level: INFO
     rules_file:
       - rules/detect_connect_using_in.yaml
-    trace_file: trace_files/connect_localhost.scap
+    trace_file: trace_files/connect_ipv4_localhost.scap
+
+  in_operator_ipv6_netmasks:
+    detect: True
+    detect_level: INFO
+    rules_file:
+      - rules/detect_connect_using_in.yaml
+    trace_file: trace_files/connect_ipv6_localhost.scap

   syscalls:
     detect: True
diff --git a/test/rules/detect_connect_using_in.yaml b/test/rules/detect_connect_using_in.yaml
index ad65bdc..30abb87 100644
--- a/test/rules/detect_connect_using_in.yaml
+++ b/test/rules/detect_connect_using_in.yaml
@@ -14,9 +14,15 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
-- rule: Localhost connect
-  desc: Detect any connect to the localhost network, using fd.net and the in operator
+- rule: Localhost IPv4 connect
+  desc: Detect any connect to the IPv4 localhost network, using fd.net and the in operator
   condition: evt.type=connect and fd.net in ("127.0.0.1/24")
-  output: Program connected to localhost network
+  output: Program connected to IPv4 localhost network
+    (user=%user.name user_loginuid=%user.loginuid command=%proc.cmdline connection=%fd.name)
+  priority: INFO
+- rule: Localhost IPv6 connect
+  desc: Detect any connect to the IPv6 localhost network, using fd.net and the in operator
+  condition: evt.type=connect and fd.net in ("::1/128")
+  output: Program connected to IPv6 localhost network
     (user=%user.name user_loginuid=%user.loginuid command=%proc.cmdline connection=%fd.name)
   priority: INFO
diff --git a/test/trace_files/connect_localhost.scap b/test/trace_files/connect_ipv4_localhost.scap
similarity index 100%
rename from test/trace_files/connect_localhost.scap
rename to test/trace_files/connect_ipv4_localhost.scap