Add Rule for unexpected udp traffic (#320)

* Add Rule for unexpected udp traffic

New rule Unexpected UDP Traffic checks for udp traffic not on a list of
expected ports. Currently blocked on
https://github.com/draios/falco/issues/308.

* Add sendto/recvfrom in inbound/outbound macros

Expand the inbound/outbound macros to handle sendfrom/recvto events, so
they can work on unconnected udp sockets. In order to avoid a flood of
events, they also depend on fd.name_changed to only consider
sendto/recvfrom when the connection tuple changes.

Also make the check for protocol a positive check for udp instead of not tcp,
to avoid a warning about event type filters potentially appearing before
a negative condition. This makes filtering rules by event type easier.

This depends on https://github.com/draios/sysdig/pull/1052.

* Add additional restrictions for inbound/outbound

 - only look for fd.name_changed on unconnected sockets.
 - skip connections where both ips are 0.0.0.0 or localhost network.
 - only look for successful or non-blocking actions that are in progress

* Add a combined inbound/outbound macro

Add a combined inbound/outbound macro so you don't have to do all the
other net/result related tests more than once.

* Fix evt generator for new in/outbound restrictions

The new rules skip localhost, so instead connect a udp socket to a
non-local port. That still triggers the inbound/outbound macros.

* Address FPs in regression tests

In some cases, an app may make a udp connection to an address with a
port of 0, or to an address with an application's port, before making a
tcp connection that actually sends/receives traffic. Allow these
connects.

Also, check both the server and client port and only consider the
traffic unexpected if neither port is in range.
This commit is contained in:
Mark Stemm
2018-04-18 10:07:22 -07:00
committed by GitHub
parent ac190ca457
commit b6b490e26e
2 changed files with 71 additions and 13 deletions

View File

@@ -296,23 +296,21 @@ void system_user_interactive() {
}
void network_activity() {
printf("Opening a listening socket on port 8192...\n");
printf("Connecting a udp socket to 10.2.3.4:8192...\n");
int rc;
int sock = socket(PF_INET, SOCK_DGRAM, 0);
struct sockaddr_in localhost;
localhost.sin_family = AF_INET;
localhost.sin_port = htons(8192);
inet_aton("127.0.0.1", &(localhost.sin_addr));
inet_aton("10.2.3.4", &(localhost.sin_addr));
if((rc = bind(sock, (struct sockaddr *) &localhost, sizeof(localhost))) != 0)
if((rc = connect(sock, (struct sockaddr *) &localhost, sizeof(localhost))) != 0)
{
fprintf(stderr, "Could not bind listening socket to localhost: %s\n", strerror(errno));
return;
}
listen(sock, 1);
close(sock);
}

View File

@@ -244,12 +244,33 @@
# Network
- macro: inbound
condition: ((evt.type=listen and evt.dir=>) or (evt.type=accept and evt.dir=<))
condition: >
(((evt.type in (accept,listen) and evt.dir=<) or
(evt.type in (recvfrom,recvmsg) and evt.dir=< and
fd.l4proto != tcp and fd.connected=false and fd.name_changed=true)) and
(fd.typechar = 4 or fd.typechar = 6) and
(fd.ip != "0.0.0.0" and fd.net != "127.0.0.0/8") and
(evt.rawres >= 0 or evt.res = EINPROGRESS))
# Currently sendto is an ignored syscall, otherwise this could also
# check for (evt.type=sendto and evt.dir=>)
- macro: outbound
condition: evt.type=connect and evt.dir=< and (fd.typechar=4 or fd.typechar=6)
condition: >
(((evt.type = connect and evt.dir=<) or
(evt.type in (sendto,sendmsg) and evt.dir=< and
fd.l4proto != tcp and fd.connected=false and fd.name_changed=true)) and
(fd.typechar = 4 or fd.typechar = 6) and
(fd.ip != "0.0.0.0" and fd.net != "127.0.0.0/8") and
(evt.rawres >= 0 or evt.res = EINPROGRESS))
# Very similar to inbound/outbound, but combines the tests together
# for efficiency.
- macro: inbound_outbound
condition: >
(((evt.type in (accept,listen,connect) and evt.dir=<) or
(evt.type in (recvfrom,recvmsg,sendto,sendmsg) and evt.dir=< and
fd.l4proto != tcp and fd.connected=false and fd.name_changed=true)) and
(fd.typechar = 4 or fd.typechar = 6) and
(fd.ip != "0.0.0.0" and fd.net != "127.0.0.0/8") and
(evt.rawres >= 0 or evt.res = EINPROGRESS))
- macro: ssh_port
condition: fd.sport=22
@@ -269,7 +290,7 @@
- rule: Disallowed SSH Connection
desc: Detect any new ssh connection to a host other than those in an allowed group of hosts
condition: (outbound or inbound) and ssh_port and not allowed_ssh_hosts
condition: (inbound_outbound) and ssh_port and not allowed_ssh_hosts
output: Disallowed SSH Connection (command=%proc.cmdline connection=%fd.name user=%user.name)
priority: NOTICE
tags: [network]
@@ -1305,7 +1326,7 @@
desc: any network activity performed by system binaries that are not expected to send or receive any network traffic
condition: >
(fd.sockfamily = ip and system_procs)
and (inbound or outbound)
and (inbound_outbound)
and not proc.name in (systemd, hostid)
and not login_doing_dns_lookup
output: >
@@ -1314,6 +1335,45 @@
priority: NOTICE
tags: [network]
- list: openvpn_udp_ports
items: [1194, 1197, 1198, 8080, 9201]
- list: l2tp_udp_ports
items: [500, 1701, 4500, 10000]
- list: statsd_ports
items: [8125]
- list: mysql_ports
items: [3306]
- list: ntp_ports
items: [123]
# 0 is included in the list because some apps connect to an address
# only to test connectivity.
#
# mysql_ports is included becuase some versions of the mysql client
# will attempt a connect using udp + port 3306 before connecting via
# tcp + port 3306.
#
# 80 is included for the same reason as mysql_ports--some apps do a
# connect using udp before doing a real connect using tcp.
- list: expected_udp_ports
items: [0, 53, 80, openvpn_udp_ports, l2tp_udp_ports, statsd_ports, mysql_ports, ntp_ports]
- macro: expected_udp_traffic
condition: fd.port in (expected_udp_ports)
- rule: Unexpected UDP Traffic
desc: UDP traffic not on port 53 (DNS) or other commonly used ports
condition: (inbound_outbound) and fd.l4proto=udp and not expected_udp_traffic
output: >
Unexpected UDP Traffic Seen
(user=%user.name command=%proc.cmdline connection=%fd.name proto=%fd.l4proto)
priority: NOTICE
tags: [network]
# With the current restriction on system calls handled by falco
# (e.g. excluding read/write/sendto/recvfrom/etc, this rule won't
# trigger).
@@ -1464,7 +1524,7 @@
- rule: Unexpected K8s NodePort Connection
desc: Detect attempts to use K8s NodePorts from a container
condition: (outbound or inbound) and fd.sport >= 30000 and fd.sport <= 32767 and container and not nodeport_containers
condition: (inbound_outbound) and fd.sport >= 30000 and fd.sport <= 32767 and container and not nodeport_containers
output: Unexpected K8s NodePort Connection (command=%proc.cmdline connection=%fd.name)
priority: NOTICE
tags: [network, k8s, container]