根据以往经验,windows服务器遭受的最常见的攻击行为包括:以外网应用服务器为跳板,扫描端口、上传木马、创建账号、登录等。公司目前应用服务器用windows的已经很少了,但最近搞了生产环境网络隔离,所有访问生产服务器的操作必须通过windows跳板机,因此这些跳板机的安全就显得更加重要了。
主要思路:将这些跳板机的登录操作通过syslog集中到某台日志服务器,定期扫描日志,判断嫌疑操作并报警。
nxlog
nxlog包含免费版本和企业版,nxlog客户端可以将windows event日志输出到远程服务器(syslog服务器或者nxlog服务端)。
nxlog客户端免费版基本满足我们要的功能(企业版客户端包括一些日志处理的复杂功能,如rewreite模块等),nxlog服务端(即nxlog manager)也只有企业版才支持,我们直接用开源的syslog-ng作为服务器即可。
下载:
https://nxlog.co/products/nxlog-community-edition/download
安装:直接next即可,参考:
https://nxlog.co/documentation/nxlog-user-guide#install_windows_interactive
配置文件:C:\Program Files (x86)\nxlog\conf\nxlog.conf
## This is a sample configuration file. See the nxlog reference manual about the
## configuration options. It should be installed locally and is also available
## online at http://nxlog.org/docs/
## Please set the ROOT to the folder your nxlog was installed into,
## otherwise it will not start.
#define ROOT C:\Program Files\nxlog
define ROOT C:\Program Files (x86)\nxlog
Moduledir %ROOT%\modules
CacheDir %ROOT%\data
Pidfile %ROOT%\data\nxlog.pid
SpoolDir %ROOT%\data
LogFile %ROOT%\data\nxlog.log
<Extension _json>
Module xm_json
</Extension>
<Extension _syslog>
Module xm_syslog
</Extension>
<Extension _charconv>
Module xm_charconv
AutodetectCharsets utf-8, euc-jp, utf-16, utf-32, iso8859-2
</Extension>
<Input in>
Module im_mseventlog
<Exec>
if $EventID not in (528, 529, 624) drop();
convert_fields("auto", "utf-8");
$SyslogFacility="local2";
$SyslogSeverity="info";
$Message = to_json();
to_syslog_bsd();
</Exec>
</Input>
<Output out>
Module om_tcp
Host <<syslog server ip>>
Port 10000
</Output>
<Route 1>
Path in => out
</Route>
说明:Module:
im_mseventlog:适用于Windows XP, Windows 2000, and Windows 2003
im_msvistalog:适用于Windows 2008/Vista and later
Event:只分析以下三种类别日志
528:成功登陆
529:登陆失败
624:创建用户
syslog-ng
源码下载:
wget http://www.balabit.com/downloads/files?path=/libol/0.3/libol-0.3.18.tar.gz
wget http://www.balabit.com/downloads/files?path=/syslog-ng/open-source-edition/3.3.7/source/eventlog_0.2.12.tar.gz
wget http://www.balabit.com/downloads/files?path=/syslog-ng/open-source-edition/3.3.7/source/syslog-ng_3.3.7.tar.gz
syslog-ng官方文档:
https://www.balabit.com/sites/default/files/documents/syslog-ng-ose-latest-guides/en/syslog-ng-ose-guide-admin/html-single/index.html#concepts-flow-control
安装
yum install pcre pcre-devel glib2-devel json-c json-c-devel
cd eventlog-0.2.12
./configure --prefix=/usr/local/eventlog
make && make install
cd libol-0.3.18
./configure --prefix=/usr/local/libol
make && make install
export PKG_CONFIG_PATH=/usr/local/eventlog/lib/pkgconfig/
cd syslog-ng-3.7.2
./configure --prefix=/usr/local/syslog-ng --with-libol=/usr/local/libol/ --disable-python
make && make install
配置
/usr/local/syslog-ng/etc/syslog-ng.conf
@version: 3.7
@include "scl.conf"
options {
keep-hostname(no);
chain-hostnames(no);
use-dns(no);
flush-lines(0);
time-reap(1);
log-msg-size(4096);
create-dirs(yes);
stats-freq(3600);
owner (root);
group(root);
perm(0600);
dir-perm(0700);
};
source s_local {
system();
internal();
};
source s_app {
tcp(
ip(0.0.0.0)
port(10000)
max-connections(500)
log_iw_size(50000)
flags(validate-utf8)
);
};
filter f_level {
facility(local2) and (level(error) or level(info) or level(debug));
};
parser p_cut {
csv-parser(
columns("MSG.MON", "MSG.DAY", "MSG.TIME","MSG.EVENTTYPE","MSG.CONTENT")
flags(escape-double-char,strip-whitespace,greedy)
delimiters(" ")
quote-pairs('[]')
);
};
parser p_json {
json-parser (
prefix(".json.")
);
};
parser p_kv {
kv-parser (
prefix(".kv.")
template("${.json.Message}")
);
};
rewrite r_subst {
subst(" ","",value(".json.Category") flags(global));
subst("\t用户名:","Mycol1:",value(".json.Message") flags(global));
subst("\t源网络地址:","Mycol2:",value(".json.Message") flags(global));
subst("\t新的帐户名:","Mycol1:",value(".json.Message") flags(global));
subst("\t调用方用户名:","Mycol2:",value(".json.Message") flags(global));
subst("\r\n",",",value(".json.Message") flags(global));
subst(":","=",value(".json.Message") flags(global));
subst("\t","",value(".json.Message") flags(global));
subst(" ","",value(".json.Message") flags(global));
subst(",",", ",value(".json.Message") flags(global));
};
destination d_local {
file("/var/log/messages");
};
destination d_appfile {
file(
"/log/winevent/${.json.Hostname}.log"
template("${.json.EventTime} ${.json.Hostname} ${.json.EventID} ${.json.Category} ${.kv.Mycol1} ${.kv.Mycol2}\n")
log-fifo-size(500000)
);
};
log {
source(s_local);
destination(d_local);
};
log {
source(s_app);
filter(f_level);
parser(p_cut);
parser(p_json);
rewrite(r_subst);
parser(p_kv);
destination(d_appfile);
flags(flow-control);
};
会在syslog server的目录/log/winevent/下生成以hostname.log明明的文件,内容如:
2017-12-26 19:34:24 WIN-68-1 528 登录/注销 administrator 10.40.1.2
2017-12-26 19:34:27 WIN-68-1 528 登录/注销 administrator 10.40.1.2
2017-12-26 19:55:18 WIN-68-1 529 登录/注销 administrator 10.40.1.2
2017-12-26 19:55:24 WIN-68-1 528 登录/注销 administrator 10.40.1.2
2017-12-26 19:56:06 WIN-68-1 624 帐户管理 user1 administrator
说明:
528、529文件格式
时间戳 windows主机名 eventid even操作类型 登录用户名 登录来源IP
624文件格式
时间戳 windows主机名 eventid even操作类型 创建的用户名 创建用户时登录用的用户名
监控报警
monitor.sh
#!/bin/bash
tmpFile=/log/tmpfile
mailFile=/log/mailfile
smsFile=/log/smsfile
> ${mailFile}
> ${smsFile}
for logFile in /log/winevent/*.log
do
indexFile=${logFile/.log/.index}
if [ ! -f ${indexFile} ]; then
echo 0 > ${indexFile}
fi
lastLineNum=`cat ${indexFile}`
nowLineNum=`cat $logFile | wc -l`
if [ ${lastLineNum} -lt ${nowLineNum} ]; then
echo $nowLineNum > ${indexFile}
# check client ip
sed -n ''`expr ${lastLineNum} + 1`','${nowLineNum}'p' ${logFile} | grep " 528 " | grep " 10." > $tmpFile
if [ `wc -l < ${tmpFile}` -gt 0 ]; then
echo "${logFile}, line:`expr $lastLineNum + 1`-$nowLineNum, `wc -l < $tmpFile` suspicion logon" >> $mailFile
echo "${logFile}, line:`expr $lastLineNum + 1`-$nowLineNum, `wc -l < $tmpFile` suspicion logon" >> $smsFile
cat ${tmpFile} >> $mailFile
echo >> $mailFile
fi
# check failed login
sed -n ''`expr ${lastLineNum} + 1`','${nowLineNum}'p' ${logFile} | grep " 529 " > $tmpFile
if [ `wc -l < ${tmpFile}` -gt 0 ]; then
echo "${logFile}, line:`expr $lastLineNum + 1`-$nowLineNum, `wc -l < $tmpFile` failed logon" >> $mailFile
cat ${tmpFile} >> $mailFile
echo >> $mailFile
fi
# check create user
sed -n ''`expr ${lastLineNum} + 1`','${nowLineNum}'p' ${logFile} | grep " 624 " > $tmpFile
if [ `wc -l < ${tmpFile}` -gt 0 ]; then
echo "${logFile}, line:`expr $lastLineNum + 1`-$nowLineNum, `wc -l < $tmpFile` create user" >> $mailFile
echo "${logFile}, line:`expr $lastLineNum + 1`-$nowLineNum, `wc -l < $tmpFile` create user" >> $smsFile
cat "${tmpFile}" >> $mailFile
echo "" >> $mailFile
fi
fi
done
# send mail
if [ `wc -l < ${mailFile}` -gt 0 ]; then
to=邮箱接收人
subject="windows event log warning"
body=`cat $mailFile`
/usr/local/bin/sendEmail -f 发送人的邮箱地址 -t "$to" -s smtp.exmail.qq.com -u "$subject" -o message-content-type=text -o message-charset=utf8 -xu 用户名 -xp 密码
-m "$body" > /dev/null 2>&1
fi
# send sms
if [ ` wc -l < ${smsFile}` -gt 0 ]; then
to=短信接收人
subject="windows event log: `wc -l < $smsFile` warnings"
/usr/local/bin/curl -d "phoneNumber=${to}" -d "msg=${subject}" 公司的短信接口 > /dev/null 2>&1
fi