diff --git a/extensions/libxt_lscan.c b/extensions/libxt_lscan.c index c3a4aec..6145d39 100644 --- a/extensions/libxt_lscan.c +++ b/extensions/libxt_lscan.c @@ -24,6 +24,7 @@ static const struct option lscan_mt_opts[] = { {.name = "synscan", .has_arg = false, .val = 's'}, {.name = "cnscan", .has_arg = false, .val = 'c'}, {.name = "grscan", .has_arg = false, .val = 'g'}, + {.name = "mirai", .has_arg = false, .val = 'm'}, {NULL}, }; @@ -35,7 +36,8 @@ static void lscan_mt_help(void) " --stealth Match TCP Stealth packets\n" " --synscan Match TCP SYN 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, @@ -50,6 +52,9 @@ static int lscan_mt_parse(int c, char **argv, int invert, case 'g': info->match_fl4 |= LSCAN_FL4_GR; return true; + case 'm': + info->match_fl1 |= LSCAN_FL1_MIRAI; + return true; case 's': info->match_fl2 |= LSCAN_FL2_SYN; return true; @@ -76,6 +81,8 @@ static void lscan_mt_save(const void *ip, const struct xt_entry_match *match) printf(" --cnscan "); if (info->match_fl4 & LSCAN_FL4_GR) printf(" --grscan "); + if (info->match_fl1 & LSCAN_FL1_MIRAI) + printf(" --mirai "); } static void lscan_mt_print(const void *ip, diff --git a/extensions/libxt_lscan.man b/extensions/libxt_lscan.man index 88dd9f7..97e1d7f 100644 --- a/extensions/libxt_lscan.man +++ b/extensions/libxt_lscan.man @@ -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 ports where a protocol runs that is guaranteed to do a bidirectional exchange 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 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, diff --git a/extensions/xt_lscan.c b/extensions/xt_lscan.c index de1ca46..1bb9be6 100644 --- a/extensions/xt_lscan.c +++ b/extensions/xt_lscan.c @@ -175,6 +175,7 @@ lscan_mt(const struct sk_buff *skb, struct xt_action_param *par) { const struct xt_lscan_mtinfo *info = par->matchinfo; enum ip_conntrack_info ctstate; + const struct iphdr *iph = ip_hdr(skb); const struct tcphdr *tcph; struct nf_conn *ctdata; struct tcphdr tcph_buf; @@ -182,6 +183,9 @@ lscan_mt(const struct sk_buff *skb, struct xt_action_param *par) tcph = skb_header_pointer(skb, par->thoff, sizeof(tcph_buf), &tcph_buf); if (tcph == NULL) 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 */ ctdata = nf_ct_get(skb, &ctstate); @@ -221,7 +225,7 @@ static int lscan_mt_check(const struct xt_mtchk_param *par) { const struct xt_lscan_mtinfo *info = par->matchinfo; - if ((info->match_fl1 & ~LSCAN_FL1_STEALTH) || + if ((info->match_fl1 & ~(LSCAN_FL1_STEALTH | LSCAN_FL1_MIRAI)) || (info->match_fl2 & ~LSCAN_FL2_SYN) || (info->match_fl3 & ~LSCAN_FL3_CN) || (info->match_fl4 & ~LSCAN_FL4_GR)) { diff --git a/extensions/xt_lscan.h b/extensions/xt_lscan.h index 9f4822f..80ab85c 100644 --- a/extensions/xt_lscan.h +++ b/extensions/xt_lscan.h @@ -3,6 +3,7 @@ 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,