Re: Passive OS fingerprint xtables match (iptables)

Previous thread: [PATCH 2/3] be2net: The core logic by Sathya Perla on Tuesday, March 10, 2009 - 5:14 am. (1 message)

Next thread: [PATCH 0/5] Retrieving Ethernet PHY wireup from the OF device tree by Grant Likely on Tuesday, March 10, 2009 - 8:21 am. (10 messages)
From: Evgeniy Polyakov
Date: Tuesday, March 10, 2009 - 8:13 am

Hi.

Passive OS fingerprinting netfilter module allows to passively detect
remote OS and perform various netfilter actions based on that knowledge.
This module compares some data (WS, MSS, options and it's order, ttl, df
and others) from packets with SYN bit set with dynamically loaded OS
fingerprints.

Fingerprint matching rules can be downloaded from OpenBSD source tree
and loaded via netlink connector into the kernel via special util found
in archive. It will also listen for events about matching packets.

Archive also contains library file (also attached), which was shipped
with iptables extensions some time ago (at least when ipt_osf existed
in patch-o-matic).

This release implements suggestions found during the code review like
codying style, structure split and tighter packing, bool and %pi4
usage and similar changes.

Fingerprints can be downloaded from
http://www.openbsd.org/cgi-bin/cvsweb/src/etc/pf.os

Example usage:
# modrpobe xt_osf
# ./ucon_osf -f ./pf.os
^C Daemon will listen for incoming match events 
-d switch removes fingerprints
# iptables -I INPUT -j ACCEPT -p tcp -m osf --genre Linux --log 0 --ttl 2 --connector

You will find something like this in the syslog:
ipt_osf: Windows [2000:SP3:Windows XP Pro SP1, 2000 SP3]: 11.22.33.55:4024 -> 11.22.33.44:139

Please consider for inclusion.
Thank you.

Passive OS fingerprint homepage (archives, examples):
http://www.ioremap.net/projects/osf

Signed-off-by: Evgeniy Polyakov <zbr@ioremap.net>

diff --git a/include/linux/connector.h b/include/linux/connector.h
index 34f2789..da6595e 100644
--- a/include/linux/connector.h
+++ b/include/linux/connector.h
@@ -39,6 +39,8 @@
 #define CN_IDX_V86D			0x4
 #define CN_VAL_V86D_UVESAFB		0x1
 #define CN_IDX_BB			0x5	/* BlackBoard, from the TSP GPL sampling framework */
+#define CN_IDX_OSF			0x6	/* Passive OS fingerprint iptables module */
+#define CN_VAL_OSF			0x0
 
 #define CN_NETLINK_USERS		6
 
diff --git a/include/linux/netfilter/xt_osf.h ...
From: Evgeniy Polyakov
Date: Tuesday, March 10, 2009 - 9:01 am

Not the latest version, it misses the following fix from the parallel
tree.

    Fixed TCP header copy to the userspace when given option is enabled.

diff --git a/net/netfilter/xt_osf.c b/net/netfilter/xt_osf.c
index 3114bbd..e619f09 100644
--- a/net/netfilter/xt_osf.c
+++ b/net/netfilter/xt_osf.c
@@ -83,7 +83,7 @@ static void ipt_osf_send_connector(struct ipt_osf_user_finger *f,
 	struct ipt_osf_message *msg = &per_cpu(ipt_osf_mbuf, smp_processor_id());
 	struct ipt_osf_nlmsg *data = &msg->nlmsg;
 	struct iphdr *iph = ip_hdr(skb);
-	struct tcphdr *tcph = tcp_hdr(skb);
+	struct tcphdr *tcp;
 
 	memcpy(&msg->cmsg.id, &cn_osf_id, sizeof(struct cn_msg));
 	msg->cmsg.seq = osf_seq++;
@@ -92,7 +92,9 @@ static void ipt_osf_send_connector(struct ipt_osf_user_finger *f,
 
 	memcpy(&data->f, f, sizeof(struct ipt_osf_user_finger));
 	memcpy(&data->ip, iph, sizeof(struct iphdr));
-	memcpy(&data->tcp, tcph, sizeof(struct tcphdr));
+	tcp = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(struct tcphdr), &data->tcp);
+	if (tcp)
+		memcpy(&data->tcp, tcp, sizeof(struct tcphdr));
 
 	cn_netlink_send(&msg->cmsg, CN_IDX_OSF, GFP_ATOMIC);
 }


-- 
	Evgeniy Polyakov
--

From: Jan Engelhardt
Date: Tuesday, March 10, 2009 - 9:07 am

Since the module's name is xt_osf now, it would make sense to follow

Just a minor thing, could you add "osf" somewhere in the short-text
so that people instantly know the name of the module (without having
to consult the help text), like the other entries. For example


A bit of rewording I suggest.

	This option selects the Passive OS Fingerprinting match module
	that allows to passively match the

should -> can

	Rules and loading software can be downloaded from

Please have the list sorted alphabetically. (This keeps merge conflicts

iph and tcph are only used in memcpy and could be directly substituted:

	memcpy(&data->ip, ip_hdr(skb), ...)


xt_osf does not look at TCP options, is not it?

Note that you cannot directly use tcp_hdr(skb) as the
skb->transport_header has not yet been initialized (it still points
at skb->network_header) because the packet has not yet been seen by
the next handler. This affects PREROUTING, and INPUT chains (and
BROUTING, for ebtables people, but irrelevant here).

The packet may also be fragmented or non-linear.









-Jan
--

From: Evgeniy Polyakov
Date: Wednesday, March 11, 2009 - 2:43 pm

Hi Jan.

Thanks for the review, I will incorporate the changes and respin it soon.

-- 
	Evgeniy Polyakov
--

From: Jan Engelhardt
Date: Tuesday, March 10, 2009 - 9:12 am

You can remove this function, as it does no initialization.

This would allow specifying --ttl 12345.

Use of xtables_strtoui (v1.4.3-rc1+git) for bounds checking,
and use of optarg seem beneficial:

	unsigned int num;

	if (!xtables_strtoui(optarg, NULL, &num, 0, UINT8_MAX))
		exit_error(PARAMETER_PROBLEM, "*shrug*");


Needs .family = NFPROTO_IPV4.
--

From: Jesper Dangaard Brouer
Date: Tuesday, March 10, 2009 - 2:01 pm

In some of my code I call synchronize_net(), is it enough to call 
rcu_barrier()?

What is the difference between:

  synchronize_rcu()
  synchronize_net()
  rcu_barrier()

Hilsen
   Jesper Brouer

--
-------------------------------------------------------------------
MSc. Master of Computer Science
Dept. of Computer Science, University of Copenhagen
Author of http://www.adsl-optimizer.dk
-------------------------------------------------------------------
--

From: Evgeniy Polyakov
Date: Tuesday, March 10, 2009 - 2:54 pm

Hi.


Not required at this place - all users are already unregistered and

It is enough here, rcu_barrier() will wait until all scheduled
call_rcu() are completed, that's what we need. But in some cases we
should only wait for the whole grace period to elapse, then one has to use
synchronize_rcu() and friends. rcu_barrier() will wait for the callbacks
to be executed, while they are executed after grace period has elapsed,
so it implicitly includes synchronize_rcu(), but effectively they are
the same: both functions register rcu callback and wait for the
completion, rcu_barrier() is a bit more enhanced, since it has several

Those are essentially the same - synchronize_net() has additional
might_sleep()  call. Both will wait until grace period elapced - i.e.

It will wait until all scheduled rcu callbacks are executed.

So from the description they look different, but implementation
suggestes that effectively they are the same, except that there are a
bit different invocation types for the barrier.

-- 
	Evgeniy Polyakov
--

From: Patrick McHardy
Date: Monday, March 16, 2009 - 7:40 am

synchronize_net() is just a call to synchronize_rcu(), so their
functionality is equivalent. synchronize_net() is however only
supposed to synchronize with RX packet processing, which is usually
not enough for netfilter. So I prefer synchronize_rcu() for clarity.
--

From: Pablo Neira Ayuso
Date: Wednesday, March 11, 2009 - 2:54 am

I like this feature. We have nfnetlink so I don't see why we should use
the netlink connector instead.

BTW, is there any difference with regards to userspace p0f apart from
having this integrated into iptables?

-- 
"Los honestos son inadaptados sociales" -- Les Luthiers
--

From: Evgeniy Polyakov
Date: Wednesday, March 11, 2009 - 3:00 am

Hi Pablo.


OSF exists about 6 years already, netlink configuration was added in
2005, I do not remember if nfnetlink existed those days (IIRC it did
not, since I reused ULOG netlink first), right now I just cleanup

There should be no major differences, there are some tweaks for the
MTU comparison, maybe something else.

-- 
	Evgeniy Polyakov
--

From: Patrick McHardy
Date: Monday, March 16, 2009 - 7:42 am

We do have nfnetlink today however, so this argument does no longer
apply. I don't mind the order in which things are fixed up of course,
but before merging, it needs to be converted to nfnetlink.
--

Previous thread: [PATCH 2/3] be2net: The core logic by Sathya Perla on Tuesday, March 10, 2009 - 5:14 am. (1 message)

Next thread: [PATCH 0/5] Retrieving Ethernet PHY wireup from the OF device tree by Grant Likely on Tuesday, March 10, 2009 - 8:21 am. (10 messages)