3 ipt_unclean.c | 612 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 3 files changed, 627 insertions(+)
6 diff -Nur --exclude '*.orig' linux.org/net/ipv4/netfilter/Kconfig linux/net/ipv4/netfilter/Kconfig
7 --- linux.org/net/ipv4/netfilter/Kconfig 2006-05-02 23:38:44.000000000 +0200
8 +++ linux/net/ipv4/netfilter/Kconfig 2006-05-04 14:49:54.000000000 +0200
10 Allows altering the ARP packet payload: source and destination
11 hardware and network addresses.
13 +config IP_NF_MATCH_UNCLEAN
14 + tristate 'Unclean match support (DANGEROUS)'
15 + depends on EXPERIMENTAL && IP_NF_IPTABLES
17 + Unclean packet matching matches any strange or invalid packets, by
18 + looking at a series of fields in the IP, TCP, UDP and ICMP headers.
20 + Please note that this kind of matching is considered dangerous and
21 + might harm the future compatibility of your packet filter.
23 + It has happened before, search on the net for ECN blackholes :(
29 diff -Nur --exclude '*.orig' linux.org/net/ipv4/netfilter/Makefile linux/net/ipv4/netfilter/Makefile
30 --- linux.org/net/ipv4/netfilter/Makefile 2006-05-02 23:38:44.000000000 +0200
31 +++ linux/net/ipv4/netfilter/Makefile 2006-05-04 14:49:54.000000000 +0200
33 +obj-$(CONFIG_IP_NF_MATCH_UNCLEAN) += ipt_unclean.o
34 diff -Nur --exclude '*.orig' linux.org/net/ipv4/netfilter/ipt_unclean.c linux/net/ipv4/netfilter/ipt_unclean.c
35 --- linux.org/net/ipv4/netfilter/ipt_unclean.c 1970-01-01 01:00:00.000000000 +0100
36 +++ linux/net/ipv4/netfilter/ipt_unclean.c 2006-05-04 14:49:54.000000000 +0200
38 +/* Kernel module to match suspect packets. */
39 +#include <linux/module.h>
40 +#include <linux/skbuff.h>
41 +#include <linux/ip.h>
42 +#include <linux/udp.h>
43 +#include <linux/tcp.h>
44 +#include <linux/icmp.h>
45 +#include <net/checksum.h>
48 +#include <linux/netfilter_ipv4/ip_tables.h>
50 +#define limpk(format, args...) \
52 + if (net_ratelimit()) \
53 + printk("ipt_unclean: %s" format, \
54 + embedded ? "(embedded packet) " : "" , ## args); \
57 +enum icmp_error_status
66 + size_t min_len, max_len;
67 + enum icmp_error_status err;
68 + u_int8_t min_code, max_code;
72 +check_ip(const struct sk_buff *skb, unsigned int offset);
74 +/* ICMP-specific checks. */
76 +check_icmp(const struct sk_buff *skb,
77 + unsigned int offset,
78 + unsigned int fragoff,
82 + struct icmphdr icmph;
83 + static struct icmp_info info[]
84 + = { [ICMP_ECHOREPLY]
85 + = { 8, 65536, ICMP_NOT_ERROR, 0, 0 },
87 + = { 8 + 28, 65536, ICMP_IS_ERROR, 0, 15 },
88 + [ICMP_SOURCE_QUENCH]
89 + = { 8 + 28, 65536, ICMP_IS_ERROR, 0, 0 },
91 + = { 8 + 28, 65536, ICMP_IS_ERROR, 0, 3 },
93 + = { 8, 65536, ICMP_NOT_ERROR, 0, 0 },
94 + /* Router advertisement. */
96 + = { 8, 8 + 255 * 8, ICMP_NOT_ERROR, 0, 0 },
97 + /* Router solicitation. */
99 + = { 8, 8, ICMP_NOT_ERROR, 0, 0 },
100 + [ICMP_TIME_EXCEEDED]
101 + = { 8 + 28, 65536, ICMP_IS_ERROR, 0, 1 },
102 + [ICMP_PARAMETERPROB]
103 + = { 8 + 28, 65536, ICMP_IS_ERROR, 0, 1 },
105 + = { 20, 20, ICMP_NOT_ERROR, 0, 0 },
106 + [ICMP_TIMESTAMPREPLY]
107 + = { 20, 20, ICMP_NOT_ERROR, 0, 0 },
108 + [ICMP_INFO_REQUEST]
109 + = { 8, 65536, ICMP_NOT_ERROR, 0, 0 },
111 + = { 8, 65536, ICMP_NOT_ERROR, 0, 0 },
113 + = { 12, 12, ICMP_NOT_ERROR, 0, 0 },
114 + [ICMP_ADDRESSREPLY]
115 + = { 12, 12, ICMP_NOT_ERROR, 0, 0 } };
117 + /* Can't do anything if it's a fragment. */
121 + /* CHECK: Must have whole header.. */
122 + if (skb_copy_bits(skb, offset, &icmph, sizeof(icmph)) < 0) {
123 + limpk("ICMP len=%u too short\n", skb->len - offset);
127 + /* If not embedded in an ICMP error already. */
129 + /* CHECK: Truncated ICMP (even if first fragment). */
130 + if (icmph.type < sizeof(info)/sizeof(struct icmp_info)
131 + && info[icmph.type].min_len != 0
132 + && skb->len - offset < info[icmph.type].min_len) {
133 + limpk("ICMP type %u len %u too short\n",
134 + icmph.type, skb->len - offset);
138 + /* CHECK: Check within known error ICMPs. */
139 + if (icmph.type < sizeof(info)/sizeof(struct icmp_info)
140 + && info[icmph.type].err == ICMP_IS_ERROR) {
141 + /* Max IP header size = 60 */
142 + char inner[60 + 8];
143 + struct iphdr *inner_ip = (struct iphdr *)inner;
145 + /* CHECK: Embedded packet must be at least
146 + length of iph + 8 bytes. */
147 + if (skb_copy_bits(skb, offset + sizeof(icmph),
148 + inner, sizeof(struct iphdr)+8) < 0) {
149 + limpk("ICMP error internal way too short\n");
153 + /* iphhdr may actually be longer: still need 8
154 + actual protocol bytes. */
155 + if (offset + sizeof(icmph) + inner_ip->ihl*4 + 8
157 + limpk("ICMP error internal too short\n");
160 + if (!check_ip(skb, offset + sizeof(icmph)))
164 + /* CHECK: Can't embed ICMP unless known non-error. */
165 + if (icmph.type >= sizeof(info)/sizeof(struct icmp_info)
166 + || info[icmph.type].err != ICMP_NOT_ERROR) {
167 + limpk("ICMP type %u not embeddable\n",
173 + /* CHECK: Invalid ICMP codes. */
174 + if (icmph.type < sizeof(info)/sizeof(struct icmp_info)
175 + && (icmph.code < info[icmph.type].min_code
176 + || icmph.code > info[icmph.type].max_code)) {
177 + limpk("ICMP type=%u code=%u\n",
178 + icmph.type, icmph.code);
182 + /* CHECK: Above maximum length. */
183 + if (icmph.type < sizeof(info)/sizeof(struct icmp_info)
184 + && info[icmph.type].max_len != 0
185 + && skb->len - offset > info[icmph.type].max_len) {
186 + limpk("ICMP type=%u too long: %u bytes\n",
187 + icmph.type, skb->len - offset);
191 + switch (icmph.type) {
192 + case ICMP_PARAMETERPROB: {
193 + /* CHECK: Problem param must be within error packet's
195 + u_int32_t arg = ntohl(icmph.un.gateway);
197 + if (icmph.code == 0) {
198 + /* We've already made sure it's long enough. */
200 + skb_copy_bits(skb, offset + sizeof(icmph), &iph,
202 + /* Code 0 means that upper 8 bits is pointer
204 + if ((arg >> 24) >= iph.ihl*4) {
205 + limpk("ICMP PARAMETERPROB ptr = %u\n",
206 + ntohl(icmph.un.gateway) >> 24);
212 + /* CHECK: Rest must be zero. */
214 + limpk("ICMP PARAMETERPROB nonzero arg = %u\n",
221 + case ICMP_TIME_EXCEEDED:
222 + case ICMP_SOURCE_QUENCH:
223 + /* CHECK: Unused must be zero. */
224 + if (icmph.un.gateway != 0) {
225 + limpk("ICMP type=%u unused = %u\n",
226 + icmph.type, ntohl(icmph.un.gateway));
235 +/* UDP-specific checks. */
237 +check_udp(const struct sk_buff *skb,
238 + unsigned int offset,
239 + unsigned int fragoff,
243 + struct udphdr udph;
245 + /* Can't do anything if it's a fragment. */
249 + /* CHECK: Must cover UDP header. */
250 + if (skb_copy_bits(skb, offset, &udph, sizeof(udph)) < 0) {
251 + limpk("UDP len=%u too short\n", skb->len - offset);
255 + /* CHECK: Destination port can't be zero. */
257 + limpk("UDP zero destination port\n");
263 + /* CHECK: UDP length must match. */
264 + if (ntohs(udph.len) != skb->len - offset) {
265 + limpk("UDP len too short %u vs %u\n",
266 + ntohs(udph.len), skb->len - offset);
270 + /* CHECK: UDP length be >= this truncated pkt. */
271 + if (ntohs(udph.len) < skb->len - offset) {
272 + limpk("UDP len too long %u vs %u\n",
273 + ntohs(udph.len), skb->len - offset);
278 + /* CHECK: UDP length must be > this frag's length. */
279 + if (ntohs(udph.len) <= skb->len - offset) {
280 + limpk("UDP fragment len too short %u vs %u\n",
281 + ntohs(udph.len), skb->len - offset);
289 +/* TCP-specific checks. */
291 +check_tcp(const struct sk_buff *skb,
292 + unsigned int offset,
293 + unsigned int fragoff,
297 + struct tcphdr tcph;
298 + unsigned char opt[15 * 4 - sizeof(struct tcphdr)];
300 + int end_of_options = 0;
301 + unsigned int i, optlen;
303 + /* CHECK: Can't have offset=1: used to override TCP syn-checks. */
304 + /* In fact, this is caught below (offset < 516). */
306 + /* Can't do anything if it's a fragment. */
310 + /* CHECK: Smaller than minimal TCP hdr. */
311 + if (skb_copy_bits(skb, offset, &tcph, sizeof(tcph)) < 0) {
315 + limpk("Packet length %u < TCP header.\n",
316 + skb->len - offset);
320 + /* Must have ports available (datalen >= 8), from
321 + check_icmp which set embedded = 1 */
322 + /* CHECK: TCP ports inside ICMP error */
323 + skb_copy_bits(skb, offset, ports, sizeof(ports));
324 + if (!ports[0] || !ports[1]) {
325 + limpk("Zero TCP ports %u/%u.\n",
326 + htons(ports[0]), htons(ports[1]));
332 + /* CHECK: TCP header claims tiny size. */
333 + if (tcph.doff * 4 < sizeof(tcph)) {
334 + limpk("TCP header claims tiny size %u\n", tcph.doff * 4);
338 + /* CHECK: Packet smaller than actual TCP hdr. */
339 + optlen = tcph.doff*4 - sizeof(tcph);
340 + if (skb_copy_bits(skb, offset + sizeof(tcph), opt, optlen) < 0) {
342 + limpk("Packet length %u < actual TCP header.\n",
343 + skb->len - offset);
349 + /* CHECK: TCP ports non-zero */
350 + if (!tcph.source || !tcph.dest) {
351 + limpk("Zero TCP ports %u/%u.\n",
352 + htons(tcph.source), htons(tcph.dest));
356 + tcpflags = tcp_flag_word(&tcph);
358 + /* CHECK: TCP reserved bits zero. */
359 + if (tcpflags & TCP_RESERVED_BITS) {
360 + limpk("TCP reserved bits not zero\n");
364 + tcpflags &= ~(TCP_DATA_OFFSET | TCP_FLAG_CWR | TCP_FLAG_ECE
365 + | __constant_htonl(0x0000FFFF));
367 + /* CHECK: TCP flags. */
368 + if (tcpflags != TCP_FLAG_SYN
369 + && tcpflags != (TCP_FLAG_SYN|TCP_FLAG_ACK)
370 + && tcpflags != TCP_FLAG_RST
371 + && tcpflags != (TCP_FLAG_RST|TCP_FLAG_ACK)
372 + && tcpflags != (TCP_FLAG_RST|TCP_FLAG_ACK|TCP_FLAG_PSH)
373 + && tcpflags != (TCP_FLAG_FIN|TCP_FLAG_ACK)
374 + && tcpflags != TCP_FLAG_ACK
375 + && tcpflags != (TCP_FLAG_ACK|TCP_FLAG_PSH)
376 + && tcpflags != (TCP_FLAG_ACK|TCP_FLAG_URG)
377 + && tcpflags != (TCP_FLAG_ACK|TCP_FLAG_URG|TCP_FLAG_PSH)
378 + && tcpflags != (TCP_FLAG_FIN|TCP_FLAG_ACK|TCP_FLAG_PSH)
379 + && tcpflags != (TCP_FLAG_FIN|TCP_FLAG_ACK|TCP_FLAG_URG)
380 + && tcpflags != (TCP_FLAG_FIN|TCP_FLAG_ACK|TCP_FLAG_URG
382 + limpk("TCP flags bad: 0x%04X\n", ntohl(tcpflags) >> 16);
386 + for (i = 0; i < optlen; ) {
389 + end_of_options = 1;
396 + /* CHECK: options after EOO. */
397 + if (end_of_options) {
398 + limpk("TCP option %u after end\n",
402 + /* CHECK: options at tail. */
403 + else if (i+1 >= optlen) {
404 + limpk("TCP option %u at tail\n",
408 + /* CHECK: zero-length options. */
409 + else if (opt[i+1] == 0) {
410 + limpk("TCP option %u 0 len\n",
414 + /* CHECK: oversize options. */
415 + else if (i + opt[i+1] > optlen) {
416 + limpk("TCP option %u at %u too long\n",
417 + (unsigned int) opt[i], i);
420 + /* Move to next option */
428 +/* Returns 1 if ok */
429 +/* Standard IP checks. */
431 +check_ip(const struct sk_buff *skb, unsigned int offset)
433 + int end_of_options = 0;
434 + unsigned int datalen, optlen;
436 + unsigned int fragoff;
438 + unsigned char opt[15 * 4 - sizeof(struct iphdr)];
439 + int embedded = offset;
441 + /* Should only happen for local outgoing raw-socket packets. */
442 + /* CHECK: length >= ip header. */
443 + if (skb_copy_bits(skb, offset, &iph, sizeof(iph)) < 0) {
444 + limpk("Packet length %u < IP header.\n", skb->len - offset);
447 + if (iph.ihl * 4 < sizeof(iph)) {
448 + limpk("IP len %u < minimum IP header.\n", iph.ihl*4);
452 + optlen = iph.ihl * 4 - sizeof(iph);
453 + if (skb_copy_bits(skb, offset+sizeof(struct iphdr), opt, optlen)<0) {
454 + limpk("Packet length %u < IP header %u.\n",
455 + skb->len - offset, iph.ihl * 4);
459 + fragoff = (ntohs(iph.frag_off) & IP_OFFSET);
460 + datalen = skb->len - (offset + sizeof(struct iphdr) + optlen);
462 + /* CHECK: Embedded fragment. */
463 + if (offset && fragoff) {
464 + limpk("Embedded fragment.\n");
468 + for (i = 0; i < optlen; ) {
471 + end_of_options = 1;
478 + /* CHECK: options after EOO. */
479 + if (end_of_options) {
480 + limpk("IP option %u after end\n",
484 + /* CHECK: options at tail. */
485 + else if (i+1 >= optlen) {
486 + limpk("IP option %u at tail\n",
490 + /* CHECK: zero-length or one-length options. */
491 + else if (opt[i+1] < 2) {
492 + limpk("IP option %u %u len\n",
496 + /* CHECK: oversize options. */
497 + else if (i + opt[i+1] > optlen) {
498 + limpk("IP option %u at %u too long\n",
502 + /* Move to next option */
507 + /* Fragment checks. */
509 + /* CHECK: More fragments, but doesn't fill 8-byte boundary. */
510 + if ((ntohs(iph.frag_off) & IP_MF)
511 + && (ntohs(iph.tot_len) % 8) != 0) {
512 + limpk("Truncated fragment %u long.\n", ntohs(iph.tot_len));
516 + /* CHECK: Oversize fragment a-la Ping of Death. */
517 + if (fragoff * 8 + datalen > 65535) {
518 + limpk("Oversize fragment to %u.\n", fragoff * 8);
522 + /* CHECK: DF set and fragoff or MF set. */
523 + if ((ntohs(iph.frag_off) & IP_DF)
524 + && (fragoff || (ntohs(iph.frag_off) & IP_MF))) {
525 + limpk("DF set and offset=%u, MF=%u.\n",
526 + fragoff, ntohs(iph.frag_off) & IP_MF);
530 + /* CHECK: Zero-sized fragments. */
531 + if ((fragoff || (ntohs(iph.frag_off) & IP_MF))
533 + limpk("Zero size fragment offset=%u\n", fragoff);
537 + /* Note: we can have even middle fragments smaller than this:
538 + consider a large packet passing through a 600MTU then
539 + 576MTU link: this gives a fragment of 24 data bytes. But
540 + everyone packs fragments largest first, hence a fragment
541 + can't START before 576 - MAX_IP_HEADER_LEN. */
543 + /* Used to be min-size 576: I recall Alan Cox saying ax25 goes
544 + down to 128 (576 taken from RFC 791: All hosts must be
545 + prepared to accept datagrams of up to 576 octets). Use 128
547 +#define MIN_LIKELY_MTU 128
548 + /* CHECK: Min size of first frag = 128. */
549 + if ((ntohs(iph.frag_off) & IP_MF)
551 + && ntohs(iph.tot_len) < MIN_LIKELY_MTU) {
552 + limpk("First fragment size %u < %u\n", ntohs(iph.tot_len),
557 + /* CHECK: Min offset of frag = 128 - IP hdr len. */
558 + if (fragoff && fragoff * 8 < MIN_LIKELY_MTU - iph.ihl * 4) {
559 + limpk("Fragment starts at %u < %u\n", fragoff * 8,
560 + MIN_LIKELY_MTU - iph.ihl * 4);
564 + /* CHECK: Protocol specification non-zero. */
565 + if (iph.protocol == 0) {
566 + limpk("Zero protocol\n");
570 + /* FIXME: This is already checked for in "Oversize fragment"
572 + /* CHECK: Do not use what is unused.
573 + * First bit of fragmentation flags should be unused.
574 + * May be used by OS fingerprinting tools.
575 + * 04 Jun 2002, Maciej Soltysiak, solt@dns.toxicfilms.tv
577 + if (ntohs(iph.frag_off)>>15) {
578 + limpk("IP unused bit set\n");
582 + /* Per-protocol checks. */
583 + switch (iph.protocol) {
585 + return check_icmp(skb, offset + iph.ihl*4, fragoff,
586 + (ntohs(iph.frag_off) & IP_MF),
590 + return check_udp(skb, offset + iph.ihl*4, fragoff,
591 + (ntohs(iph.frag_off) & IP_MF),
595 + return check_tcp(skb, offset + iph.ihl*4, fragoff,
596 + (ntohs(iph.frag_off) & IP_MF),
599 + /* Ignorance is bliss. */
605 +match(const struct sk_buff *skb,
606 + const struct net_device *in,
607 + const struct net_device *out,
608 + const void *matchinfo,
610 + unsigned int protoff,
613 + return !check_ip(skb, 0);
616 +/* Called when user tries to insert an entry of this type. */
618 +checkentry(const char *tablename,
621 + unsigned int matchsize,
622 + unsigned int hook_mask)
624 + if (matchsize != IPT_ALIGN(0))
630 +static struct ipt_match unclean_match = {
633 + .checkentry = &checkentry,
637 +static int __init init(void)
639 + return ipt_register_match(&unclean_match);
642 +static void __exit fini(void)
644 + ipt_unregister_match(&unclean_match);
649 +MODULE_LICENSE("GPL");