Skip to content

Commit

Permalink
Add Rule for unexpected udp traffic (#320)
Browse files Browse the repository at this point in the history
* 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
#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 draios/sysdig#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.
  • Loading branch information
mstemm authored Apr 18, 2018
1 parent ac190ca commit b6b490e
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 13 deletions.
8 changes: 3 additions & 5 deletions docker/event-generator/event_generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
76 changes: 68 additions & 8 deletions rules/falco_rules.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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]
Expand Down Expand Up @@ -715,7 +736,7 @@
and not proc.pname in (sysdigcloud_binaries, mail_config_binaries, hddtemp.postins, sshkit_script_binaries, locales.postins, deb_binaries, dhcp_binaries)
and not fd.name pmatch (safe_etc_dirs)
and not fd.name in (/etc/container_environment.sh, /etc/container_environment.json, /etc/motd, /etc/motd.svc)
and not exe_running_docker_save
and not exe_running_docker_save
and not ansible_running_python
and not python_running_denyhosts
and not fluentd_writing_conf_files
Expand Down Expand Up @@ -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: >
Expand All @@ -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).
Expand Down Expand Up @@ -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]
Expand Down

0 comments on commit b6b490e

Please sign in to comment.