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长度是否符合溢出的长度,然后检测某些溢出针对的系统的返回地址作为特征,还有就是溢出包本身特点