Compare commits

...

14 Commits
v2.13 ... v2.15

Author SHA1 Message Date
Jan Engelhardt
47f5391a37 Xtables-addons 2.15 2021-02-05 19:02:49 +01:00
Jan Engelhardt
16a64492ae xt_lscan: add --mirai option 2021-02-05 19:00:13 +01:00
Jan Engelhardt
cdcf874366 xt_lscan: extend info struct to support more flags (without size change) 2021-01-20 03:09:52 +01:00
Jan Engelhardt
1b4b4347c5 geoip: apply consistent style to xt_geoip_build 2018-02-12 13:58:18 +01:00
Philip Prindeville
2f37af43c5 geoip: selective endianness catalog generation 2018-02-12 13:56:48 +01:00
Jan Engelhardt
56e5970c64 xt_pknock: don't split function heads 2018-01-05 01:36:12 +01:00
Marcelo Henrique Cerri
2b76b68c65 build: support for Linux 4.15
Signed-off-by: Marcelo Henrique Cerri <marcelo.cerri@canonical.com>
2018-01-05 01:35:12 +01:00
Seth Forshee
d2eeac4c32 build: (additional) support for Linux 4.14
Signed-off-by: Seth Forshee <seth.forshee@canonical.com>
2018-01-05 01:35:07 +01:00
Jan Engelhardt
0e9037b000 Xtables-addons 2.14 2017-11-22 18:29:25 +01:00
Jan Engelhardt
0a6091b64a DNETMAP: remove NF_CT_ASSERT use
The hooks are already checked by the xtables core (due to struct
xt_target::hooks).
2017-11-22 18:27:36 +01:00
Jan Engelhardt
b565a85fb6 DNETMAP: fix write past end of buffer 2017-11-22 18:24:10 +01:00
Jan Engelhardt
89c80f5981 DELUDE: fix PVSStudio reports
V560 A part of conditional expression is always true: !oth->rst.
2017-07-23 19:59:36 +02:00
Jan Engelhardt
8579fd2b3b ipp2p: fix PVSStudio reports
V666 Consider inspecting fourth argument of the function 'HX_memmem'.
It is possible that the value does not correspond with the length of
a string which was passed with the third argument.
2017-07-23 19:56:42 +02:00
Jan Engelhardt
0a836e9677 pknock: fix PVSStudio static analyzer reports
V595 The 'peer' pointer was utilized before it was verified against
nullptr.
2017-07-23 19:55:06 +02:00
13 changed files with 143 additions and 60 deletions

View File

@@ -1,4 +1,4 @@
AC_INIT([xtables-addons], [2.13]) AC_INIT([xtables-addons], [2.15])
AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_HEADERS([config.h]) AC_CONFIG_HEADERS([config.h])
AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_MACRO_DIR([m4])

View File

@@ -1,6 +1,17 @@
HEAD v2.15 (2021-02-05)
==== ==================
Enhancements:
- support for Linux up to 4.15
- xt_lscan: add --mirai option
v2.14 (2017-11-22)
==================
Enhancements:
- support for Linux up to 4.14
Fixes:
- xt_DNETMAP: fix some reports from PVSStudio (a static checker)
v2.13 (2017-06-29) v2.13 (2017-06-29)

View File

@@ -93,4 +93,8 @@ static inline struct net *par_net(const struct xt_action_param *par)
#endif #endif
} }
#ifndef NF_CT_ASSERT
# define NF_CT_ASSERT(x) WARN_ON(!(x))
#endif
#endif /* _XTABLES_COMPAT_H */ #endif /* _XTABLES_COMPAT_H */

View File

@@ -24,6 +24,7 @@ static const struct option lscan_mt_opts[] = {
{.name = "synscan", .has_arg = false, .val = 's'}, {.name = "synscan", .has_arg = false, .val = 's'},
{.name = "cnscan", .has_arg = false, .val = 'c'}, {.name = "cnscan", .has_arg = false, .val = 'c'},
{.name = "grscan", .has_arg = false, .val = 'g'}, {.name = "grscan", .has_arg = false, .val = 'g'},
{.name = "mirai", .has_arg = false, .val = 'm'},
{NULL}, {NULL},
}; };
@@ -35,7 +36,8 @@ static void lscan_mt_help(void)
" --stealth Match TCP Stealth packets\n" " --stealth Match TCP Stealth packets\n"
" --synscan Match TCP SYN scans\n" " --synscan Match TCP SYN scans\n"
" --cnscan Match TCP Connect scans\n" " --cnscan Match TCP Connect scans\n"
" --grscan Match Banner Grabbing scans\n"); " --grscan Match Banner Grabbing scans\n"
" --mirai Match TCP scan with ISN = dest. IP\n");
} }
static int lscan_mt_parse(int c, char **argv, int invert, static int lscan_mt_parse(int c, char **argv, int invert,
@@ -45,16 +47,19 @@ static int lscan_mt_parse(int c, char **argv, int invert,
switch (c) { switch (c) {
case 'c': case 'c':
info->match_cn = true; info->match_fl3 |= LSCAN_FL3_CN;
return true; return true;
case 'g': case 'g':
info->match_gr = true; info->match_fl4 |= LSCAN_FL4_GR;
return true;
case 'm':
info->match_fl1 |= LSCAN_FL1_MIRAI;
return true; return true;
case 's': case 's':
info->match_syn = true; info->match_fl2 |= LSCAN_FL2_SYN;
return true; return true;
case 'x': case 'x':
info->match_stealth = true; info->match_fl1 |= LSCAN_FL1_STEALTH;
return true; return true;
} }
return false; return false;
@@ -68,14 +73,16 @@ static void lscan_mt_save(const void *ip, const struct xt_entry_match *match)
{ {
const struct xt_lscan_mtinfo *info = (const void *)(match->data); const struct xt_lscan_mtinfo *info = (const void *)(match->data);
if (info->match_stealth) if (info->match_fl1 & LSCAN_FL1_STEALTH)
printf(" --stealth "); printf(" --stealth ");
if (info->match_syn) if (info->match_fl2 & LSCAN_FL2_SYN)
printf(" --synscan "); printf(" --synscan ");
if (info->match_cn) if (info->match_fl3 & LSCAN_FL3_CN)
printf(" --cnscan "); printf(" --cnscan ");
if (info->match_gr) if (info->match_fl4 & LSCAN_FL4_GR)
printf(" --grscan "); printf(" --grscan ");
if (info->match_fl1 & LSCAN_FL1_MIRAI)
printf(" --mirai ");
} }
static void lscan_mt_print(const void *ip, static void lscan_mt_print(const void *ip,

View File

@@ -27,6 +27,11 @@ warranted single-direction data flows, usually bulk data transfers such as
FTP DATA connections or IRC DCC. Grab Scan Detection should only be used on FTP DATA connections or IRC DCC. Grab Scan Detection should only be used on
ports where a protocol runs that is guaranteed to do a bidirectional exchange ports where a protocol runs that is guaranteed to do a bidirectional exchange
of bytes. of bytes.
.TP
\fB\-\-mirai\fP
Match if the TCP ISN is equal to the IPv4 destination address; this is used
by the devices in the Mirai botnet as a form of TCP SYN scan, so you will
have to explicitly specify --syn for the rule.
.PP .PP
NOTE: Some clients (Windows XP for example) may do what looks like a SYN scan, NOTE: Some clients (Windows XP for example) may do what looks like a SYN scan,
so be advised to carefully use xt_lscan in conjunction with blocking rules, so be advised to carefully use xt_lscan in conjunction with blocking rules,

View File

@@ -357,11 +357,18 @@ has_logged_during_this_minute(const struct peer *peer)
* *
* @r: rule * @r: rule
*/ */
static void #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
peer_gc(unsigned long r) static void peer_gc(struct timer_list *tl)
#else
static void peer_gc(unsigned long r)
#endif
{ {
unsigned int i; unsigned int i;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
struct xt_pknock_rule *rule = from_timer(rule, tl, timer);
#else
struct xt_pknock_rule *rule = (struct xt_pknock_rule *)r; struct xt_pknock_rule *rule = (struct xt_pknock_rule *)r;
#endif
struct peer *peer; struct peer *peer;
struct list_head *pos, *n; struct list_head *pos, *n;
@@ -469,9 +476,13 @@ add_rule(struct xt_pknock_mtinfo *info)
if (rule->peer_head == NULL) if (rule->peer_head == NULL)
goto out; goto out;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)
timer_setup(&rule->timer, peer_gc, 0);
#else
init_timer(&rule->timer); init_timer(&rule->timer);
rule->timer.function = peer_gc; rule->timer.function = peer_gc;
rule->timer.data = (unsigned long)rule; rule->timer.data = (unsigned long)rule;
#endif
rule->status_proc = proc_create_data(info->rule_name, 0, pde, rule->status_proc = proc_create_data(info->rule_name, 0, pde,
&pknock_proc_ops, rule); &pknock_proc_ops, rule);
@@ -619,9 +630,10 @@ static void add_peer(struct peer *peer, struct xt_pknock_rule *rule)
*/ */
static void remove_peer(struct peer *peer) static void remove_peer(struct peer *peer)
{ {
if (peer == NULL)
return;
list_del(&peer->head); list_del(&peer->head);
if (peer != NULL) kfree(peer);
kfree(peer);
} }
/** /**

View File

@@ -79,7 +79,7 @@ static void delude_send_reset(struct net *net, struct sk_buff *oldskb,
tcph->doff = sizeof(struct tcphdr) / 4; tcph->doff = sizeof(struct tcphdr) / 4;
/* DELUDE essential part */ /* DELUDE essential part */
if (oth->syn && !oth->ack && !oth->rst && !oth->fin) { if (oth->syn && !oth->ack && !oth->fin) {
tcph->syn = true; tcph->syn = true;
tcph->seq = 0; tcph->seq = 0;
tcph->ack = true; tcph->ack = true;

View File

@@ -376,10 +376,6 @@ dnetmap_tg(struct sk_buff *skb, const struct xt_action_param *par)
#else #else
unsigned int hooknum = par->hooknum; unsigned int hooknum = par->hooknum;
#endif #endif
NF_CT_ASSERT(hooknum == NF_INET_POST_ROUTING ||
hooknum == NF_INET_LOCAL_OUT ||
hooknum == NF_INET_PRE_ROUTING);
ct = nf_ct_get(skb, &ctinfo); ct = nf_ct_get(skb, &ctinfo);
jttl = tginfo->flags & XT_DNETMAP_TTL ? tginfo->ttl * HZ : jtimeout; jttl = tginfo->flags & XT_DNETMAP_TTL ? tginfo->ttl * HZ : jtimeout;
@@ -398,7 +394,7 @@ dnetmap_tg(struct sk_buff *skb, const struct xt_action_param *par)
/* if prefix is specified, we check if /* if prefix is specified, we check if
it matches lookedup entry */ it matches lookedup entry */
if (tginfo->flags & XT_DNETMAP_PREFIX) if (tginfo->flags & XT_DNETMAP_PREFIX)
if (memcmp(mr, &e->prefix, sizeof(*mr))) if (memcmp(mr, &e->prefix->prefix, sizeof(*mr)))
goto no_rev_map; goto no_rev_map;
/* don't reset ttl if flag is set */ /* don't reset ttl if flag is set */
if (jttl >= 0 && (! (e->flags & XT_DNETMAP_STATIC) ) ) { if (jttl >= 0 && (! (e->flags & XT_DNETMAP_STATIC) ) ) {

View File

@@ -511,7 +511,7 @@ search_bittorrent(const unsigned char *payload, const unsigned int plen)
* but *must have* one (or more) of strings listed below (true for scrape and announce) * but *must have* one (or more) of strings listed below (true for scrape and announce)
*/ */
if (memcmp(payload, "GET /", 5) == 0) { if (memcmp(payload, "GET /", 5) == 0) {
if (HX_memmem(payload, plen, "info_hash=", 9) != NULL) if (HX_memmem(payload, plen, "info_hash=", 10) != NULL)
return IPP2P_BIT * 100 + 1; return IPP2P_BIT * 100 + 1;
if (HX_memmem(payload, plen, "peer_id=", 8) != NULL) if (HX_memmem(payload, plen, "peer_id=", 8) != NULL)
return IPP2P_BIT * 100 + 2; return IPP2P_BIT * 100 + 2;

View File

@@ -175,6 +175,7 @@ lscan_mt(const struct sk_buff *skb, struct xt_action_param *par)
{ {
const struct xt_lscan_mtinfo *info = par->matchinfo; const struct xt_lscan_mtinfo *info = par->matchinfo;
enum ip_conntrack_info ctstate; enum ip_conntrack_info ctstate;
const struct iphdr *iph = ip_hdr(skb);
const struct tcphdr *tcph; const struct tcphdr *tcph;
struct nf_conn *ctdata; struct nf_conn *ctdata;
struct tcphdr tcph_buf; struct tcphdr tcph_buf;
@@ -182,10 +183,13 @@ lscan_mt(const struct sk_buff *skb, struct xt_action_param *par)
tcph = skb_header_pointer(skb, par->thoff, sizeof(tcph_buf), &tcph_buf); tcph = skb_header_pointer(skb, par->thoff, sizeof(tcph_buf), &tcph_buf);
if (tcph == NULL) if (tcph == NULL)
return false; return false;
if (info->match_fl1 & LSCAN_FL1_MIRAI && iph != NULL &&
iph->version == 4 && iph->daddr == tcph->seq)
return true;
/* Check for invalid packets: -m conntrack --ctstate INVALID */ /* Check for invalid packets: -m conntrack --ctstate INVALID */
if ((ctdata = nf_ct_get(skb, &ctstate)) == NULL) { if ((ctdata = nf_ct_get(skb, &ctstate)) == NULL) {
if (info->match_stealth) if (info->match_fl1 & LSCAN_FL1_STEALTH)
return lscan_mt_stealth(tcph); return lscan_mt_stealth(tcph);
/* /*
* If @ctdata is NULL, we cannot match the other scan * If @ctdata is NULL, we cannot match the other scan
@@ -215,17 +219,19 @@ lscan_mt(const struct sk_buff *skb, struct xt_action_param *par)
skb_nfmark(skb) = (skb_nfmark(skb) & ~packet_mask) ^ mark_seen; skb_nfmark(skb) = (skb_nfmark(skb) & ~packet_mask) ^ mark_seen;
} }
return (info->match_syn && ctdata->mark == mark_synscan) || return (info->match_fl1 & LSCAN_FL1_STEALTH && ctdata->mark == mark_synscan) ||
(info->match_cn && ctdata->mark == mark_cnscan) || (info->match_fl3 & LSCAN_FL3_CN && ctdata->mark == mark_cnscan) ||
(info->match_gr && ctdata->mark == mark_grscan); (info->match_fl4 & LSCAN_FL4_GR && ctdata->mark == mark_grscan);
} }
static int lscan_mt_check(const struct xt_mtchk_param *par) static int lscan_mt_check(const struct xt_mtchk_param *par)
{ {
const struct xt_lscan_mtinfo *info = par->matchinfo; const struct xt_lscan_mtinfo *info = par->matchinfo;
if ((info->match_stealth & ~1) || (info->match_syn & ~1) || if ((info->match_fl1 & ~(LSCAN_FL1_STEALTH | LSCAN_FL1_MIRAI)) ||
(info->match_cn & ~1) || (info->match_gr & ~1)) { (info->match_fl2 & ~LSCAN_FL2_SYN) ||
(info->match_fl3 & ~LSCAN_FL3_CN) ||
(info->match_fl4 & ~LSCAN_FL4_GR)) {
printk(KERN_WARNING PFX "Invalid flags\n"); printk(KERN_WARNING PFX "Invalid flags\n");
return -EINVAL; return -EINVAL;
} }

View File

@@ -1,8 +1,16 @@
#ifndef _LINUX_NETFILTER_XT_LSCAN_H #ifndef _LINUX_NETFILTER_XT_LSCAN_H
#define _LINUX_NETFILTER_XT_LSCAN_H 1 #define _LINUX_NETFILTER_XT_LSCAN_H 1
enum {
LSCAN_FL1_STEALTH = 1 << 0,
LSCAN_FL1_MIRAI = 1 << 1,
LSCAN_FL2_SYN = 1 << 0,
LSCAN_FL3_CN = 1 << 0,
LSCAN_FL4_GR = 1 << 0,
};
struct xt_lscan_mtinfo { struct xt_lscan_mtinfo {
uint8_t match_stealth, match_syn, match_cn, match_gr; uint8_t match_fl1, match_fl2, match_fl3, match_fl4;
}; };
#endif /* _LINUX_NETFILTER_XT_LSCAN_H */ #endif /* _LINUX_NETFILTER_XT_LSCAN_H */

View File

@@ -8,23 +8,45 @@ use IO::Handle;
use Text::CSV_XS; # or trade for Text::CSV use Text::CSV_XS; # or trade for Text::CSV
use strict; use strict;
my $le32 = pack("V", 0x10000000);
my $be32 = pack("N", 0x10000000);
my $u32 = undef;
sub wantBE { return !$u32 || $u32 eq $be32; }
sub wantLE { return !$u32 || $u32 eq $le32; }
my $csv = Text::CSV_XS->new({ my $csv = Text::CSV_XS->new({
allow_whitespace => 1, allow_whitespace => 1,
binary => 1, binary => 1,
eol => $/, eol => $/,
}); # or Text::CSV }); # or Text::CSV
my $target_dir = "."; my $target_dir = ".";
my $native_only = 0;
&Getopt::Long::Configure(qw(bundling)); &Getopt::Long::Configure(qw(bundling));
&GetOptions( &GetOptions(
"D=s" => \$target_dir, "D=s" => \$target_dir,
"n" => \$native_only,
); );
if (!-d $target_dir) { if (!-d $target_dir) {
print STDERR "Target directory $target_dir does not exist.\n"; print STDERR "Target directory $target_dir does not exist.\n";
exit 1; exit 1;
} }
foreach (qw(LE BE)) { my @dbs = qw(LE BE);
if ($native_only) {
$u32 = pack("L", 0x10000000);
if ($u32 eq $le32) {
@dbs = qw(LE);
} elsif ($u32 eq $be32) {
@dbs = qw(BE);
} else {
print STDERRR "Cannot determine endianness.\n";
exit 1;
}
}
foreach (@dbs) {
my $dir = "$target_dir/$_"; my $dir = "$target_dir/$_";
if (!-e $dir && !mkdir($dir)) { if (!-e $dir && !mkdir($dir)) {
print STDERR "Could not mkdir $dir: $!\n"; print STDERR "Could not mkdir $dir: $!\n";
@@ -80,43 +102,55 @@ sub dump_one
scalar(@{$country->{pool_v6}}), scalar(@{$country->{pool_v6}}),
$iso_code, $country->{name}; $iso_code, $country->{name};
$file = "$target_dir/LE/".uc($iso_code).".iv6"; if (wantLE) {
if (!open($fh_le, "> $file")) { $file = "$target_dir/LE/".uc($iso_code).".iv6";
print STDERR "Error opening $file: $!\n"; if (!open($fh_le, "> $file")) {
exit 1; print STDERR "Error opening $file: $!\n";
exit 1;
}
foreach my $range (@{$country->{pool_v6}}) {
print $fh_le &ip6_swap($range->[0]), &ip6_swap($range->[1]);
}
close $fh_le;
} }
$file = "$target_dir/BE/".uc($iso_code).".iv6"; if (wantBE) {
if (!open($fh_be, "> $file")) { $file = "$target_dir/BE/".uc($iso_code).".iv6";
print STDERR "Error opening $file: $!\n"; if (!open($fh_be, "> $file")) {
exit 1; print STDERR "Error opening $file: $!\n";
exit 1;
}
foreach my $range (@{$country->{pool_v6}}) {
print $fh_be $range->[0], $range->[1];
}
close $fh_be;
} }
foreach my $range (@{$country->{pool_v6}}) {
print $fh_be $range->[0], $range->[1];
print $fh_le &ip6_swap($range->[0]), &ip6_swap($range->[1]);
}
close $fh_le;
close $fh_be;
printf "%5u IPv4 ranges for %s %s\n", printf "%5u IPv4 ranges for %s %s\n",
scalar(@{$country->{pool_v4}}), scalar(@{$country->{pool_v4}}),
$iso_code, $country->{name}; $iso_code, $country->{name};
$file = "$target_dir/LE/".uc($iso_code).".iv4"; if (wantLE) {
if (!open($fh_le, "> $file")) { $file = "$target_dir/LE/".uc($iso_code).".iv4";
print STDERR "Error opening $file: $!\n"; if (!open($fh_le, "> $file")) {
exit 1; print STDERR "Error opening $file: $!\n";
exit 1;
}
foreach my $range (@{$country->{pool_v4}}) {
print $fh_le pack("VV", $range->[0], $range->[1]);
}
close $fh_le;
} }
$file = "$target_dir/BE/".uc($iso_code).".iv4"; if (wantBE) {
if (!open($fh_be, "> $file")) { $file = "$target_dir/BE/".uc($iso_code).".iv4";
print STDERR "Error opening $file: $!\n"; if (!open($fh_be, "> $file")) {
exit 1; print STDERR "Error opening $file: $!\n";
exit 1;
}
foreach my $range (@{$country->{pool_v4}}) {
print $fh_be pack("NN", $range->[0], $range->[1]);
}
close $fh_be;
} }
foreach my $range (@{$country->{pool_v4}}) {
print $fh_le pack("VV", $range->[0], $range->[1]);
print $fh_be pack("NN", $range->[0], $range->[1]);
}
close $fh_le;
close $fh_be;
} }
sub ip6_pack sub ip6_pack

View File

@@ -1,4 +1,4 @@
.TH xtables-addons 8 "" "" "v2.13 (2017-06-27)" .TH xtables-addons 8 "" "" "v2.15 (2021-02-05)"
.SH Name .SH Name
Xtables-addons \(em additional extensions for iptables, ip6tables, etc. Xtables-addons \(em additional extensions for iptables, ip6tables, etc.
.SH Targets .SH Targets