网络安全 频道

IPS/IDS特征识别和签名或规则编写

E)      EMAIL相关攻击的签名

1)      SMTP帐号破解

SNORT RULES 2.4中有一条规则

alert tcp $EXTERNAL_NET any -> $SMTP_SERVERS 25 (msg:"SMTP expn root"; flow:to_server,established; content:"expn"; nocase; content:"root"; nocase; pcre:"/^expn\s+root/smi"; reference:arachnids,31; reference:cve,1999-0531; reference:nessus,10249; classtype:attempted-recon; sid:660; rev:10;)

SMTP 协议获取用户名的命令字是expn,这里就是在到目的端口25的TCP的数据报的PAYLOAD里检查是否有expn 和 root,并且还用正则表达式匹配: "/^expn\s+root/smi"

NFR NCODE里检查还是比较合理的:

filter reg_call timeout (sec: 1, once) {

       foreach $i inside (SMTP_PROBE_COMMANDS) {

              $il = split(toupper($i),":");

              $cmd = elem($il);

              $status = elem($il, 1);

             

              if ($status == "FAIL") {

                     if ($cmd == "EXPN") {

                            smtp2:reg_callback(do_failed_expn, "REPLY-CODE",

                                   "EXPN");

                     } else if ($cmd == "RCPT") {

                            smtp2:reg_callback(do_failed_rcpt, "REPLY-CODE",

                                   "RCPT");

                     } else if ($cmd == "VRFY") {

                            smtp2:reg_callback(do_failed_vrfy, "REPLY-CODE",

                                   "VRFY");

                     }

              } else if ($status == "ALL") {

                     if ($cmd == "EXPN") {

                            smtp2:reg_callback(do_expn, "COMMAND",

                                   "EXPN");

                     } else if ($cmd == "RCPT") {

                            smtp2:reg_callback(do_rcpt, "COMMAND",

                                   "RCPT");

                     } else if ($cmd == "VRFY") {

                            smtp2:reg_callback(do_vrfy, "COMMAND",

                                   "VRFY");

                     }

              }

       }

}

func parse_arg {

       $cmdlist = split($1);

       if (($ll = listlen($cmdlist)) > 2)

              return(substr($1, index($1, elem($cmdlist, 1))));

       else if ($ll == 1)

              return("EMPTY ARGUMENT");

       else 

              return(elem($cmdlist, 1));

}

#CVE-1999-0531

func do_rcpt {

       declare $RcptCount inside tcp.connsym;

       $RcptCount = $RcptCount ? $RcptCount + 1 : 1;

       declare $DidAlert inside tcp.connsym;

       if ($RcptCount >= SMTP_PROBE_RCPT_THRESHOLD &&  

              !$DidAlert["RCPT_COUNT"]) {

              $DidAlert["RCPT_COUNT"] = 1;

              notify(cat($RcptCount, RCPT_STATUS, " RCPT commands"),

                     "do_rcpt");

       }

}

func do_failed_rcpt {

       if (!prefix(tcp.blob, "4") && !prefix(tcp.blob, "5")) {

              return;

       }

       declare $RcptCount inside tcp.connsym;

       $RcptCount = $RcptCount ? $RcptCount + 1 : 1;

       declare $DidAlert inside tcp.connsym;

       if ($RcptCount >= SMTP_PROBE_RCPT_THRESHOLD &&

              !$DidAlert["RCPT_COUNT"]) {

              $DidAlert["RCPT_COUNT"] = 1;

              notify(cat($RcptCount, " failed RCPT commands"));

       }

}

func do_expn {

       $arg = parse_arg(tcp.blob);

       notify(cat("Style: EXPN command. Argument: \"", $arg, "\"."));

}

func do_failed_expn {

       if (!prefix(tcp.blob, "4") && !prefix(tcp.blob, "5")) {

              return;

       }

       $arg = parse_arg($1);

       notify(cat("Style: Failed EXPN command. Argument: \"", $arg, "\"."));

}

      

func do_vrfy {

       $arg = parse_arg(tcp.blob);

       notify(cat("Style: VRFY command. Argument: \"", $arg, "\"."));

}

func do_failed_vrfy {

       if (!prefix(tcp.blob, "4") && !prefix(tcp.blob, "5")) {

              return;

       }

       $arg = parse_arg($1);

       notify(cat("Style: Failed VRFY command. Argument: \"", $arg, "\"."));

}

func notify {

       alert (smtpuserprobes_source, probe_alert, $1,

               tcp.connsrc, tcp.conndst, tcp.connhash,

                  "--AlertDetails", "ALERT_ID", "9-42",

              "ALERT_CONFIDENCE", 70,

              "ALERT_SEVERITY", "low", "ALERT_IMPACT",

              "information gathering",

              "ALERT_EVENT_TYPE", "information gathering",

              "ALERT_ASSESSMENT", "unknown",

              "REASON", $1, "SESSION_ID", tcp.connhash, "IP_PROTO_NUM", 6,

              "IP_ADDR_SRC", tcp.connsrc, "IP_ADDR_DST", tcp.conndst,

              "PORT_SRC", tcp.connsport, "PORT_DST", tcp.conndport,

              "CONTEXT", attack:context(probe_alert));

       record packet.sec, tcp.connsrc, tcp.connsport, tcp.conndst,

              tcp.conndport, tcp.connhash, $1 to userprobes_recorder;  

       misc_attacks:rec(system.time, scope(),

              cat("SMTP user probing technique: ",$1),

              tcp.connsrc, tcp.conndst);

}

他的做法是先做SMTP 的DECODE,然后用timeout的内置函数判断EXPN获取用户名的次数,如果次数大于上限,就报警.

2)      SENDMAIL 溢出

SNORT RULES 2.4中有一条规则

alert tcp $EXTERNAL_NET any -> $SMTP_SERVERS 25 (msg:"SMTP sendmail 8.6.9 exploit"; flow:to_server,established; content:"|0A|C|3A|daemon|0A|R"; reference:arachnids,139; reference:bugtraq,2311; reference:cve,1999-0204; classtype:attempted-user; sid:670; rev:7;)

这里主要检测到SMTP SERVER 25端口的流量的PAYLOAD里有没有:"|0A|C|3A|daemon|0A|R",我认为这样的检测方法不是很准,这种检测办法是针对某一类工具来的,真正的检测办法,是要DECODE协议,检测PAYLOAD长度是否符合溢出的长度,然后检测某些溢出针对的系统的返回地址作为特征,还有就是溢出包本身特点

1
相关文章