*本文原创作者:RipZ,本文属FreeBuf原创奖励计划,未经许可禁止转载
每天都会有大量的公网恶意扫描和攻击行为,在企业安全建设中,可以利用大数据来实时分析攻击,通过防火墙联动来自动封禁恶意IP,其优点是配置灵活,且无需串联新设备。在此与大家分享一下大数据分析的应用实践。
如下图所示,蓝色箭头表示数据流向,橙色箭头表示接口调用。splunk收集所有服务器、蜜罐、防火墙的日志,实时分析是否存在恶意攻击,如果判定为攻击行为,则立即调用防火墙接口进行IP封禁,完成防火墙联动。
(数据流向图)
splunk:大数据分析平台,搜索极快,字段创建灵活。
splunk官方网站:[ http://www.freebuf.com/articles/network/112065.html ]
防火墙:需要使用自带API的防火墙,以便进行命令调用。
部署splunk的转发器进行统一日志收集,同时可以配置splunk索引器(日志中心)的端口监听,来收集所有设备的syslog。索引器和转发器的配置安装网上也有教程,这里不再多写。
(splunk整体架构)
splunk自带了一部分日志模板,如tomcat、IIS、windows日志等(如下图),同时也不必担心无法分析其他的日志,我们可以通过正则表达式来灵活地建立自定义字段,从而将同一类型的日志进行精细化处理。
(内置的字段)
在splunk左侧的界面可以针对想要的字段进行搜索,如下图,这些创建字段的教程网上有不少,不再赘述。
(字段查询结果)
下面说一下检测公网扫描的行为,判定扫描的规则是:
1.扫描肯定会产生404或500错误
(sc_status=404 OR sc_status=500)
2.由公网发起的
(c_ip!="10.*.*.*" )
3. URI 中包含了下列关键字(黑名单方式)
(cs_uri_stem="*action redirect*" OR cs_uri_stem="*invoker*" OR cs_uri_stem="*jmx-console*" OR cs_uri_stem="*web-console*" OR cs_uri_stem="*fck*" OR cs_uri_stem="*dede*" OR cs_uri_stem="*Websense*" OR cs_uri_stem="*console*" OR cs_uri_stem="*xss*" OR cs_uri_stem="*script*" OR cs_uri_stem="*select*" OR cs_uri_stem="*where*" OR cs_uri_stem="*union*" OR cs_uri_stem="*common.inc.php*" OR cs_uri_stem="*concat*" OR cs_uri_stem="*appscan*" OR cs_uri_stem="*wvs*" OR cs_uri_stem="*admin*" OR cs_uri_stem="*shell*" OR cs_uri_stem="*etc/passwd*")
4.如果是扫描,日志中同一个源IP 肯定会在短时间(至少持续了30 秒)内有很多的错误事件
transaction c_ip maxspan=3m | whereduration>30
汇总后如下,并且需要设置实时监控:
搜索出的结果如下图所示,已经将每个进行扫描的源IP进行抓取,如下图所示。
(实时监测的公网扫描行为)
利用同样的检测原理,我们可以设置对邮箱的暴力破解(OWA、SMTP等)进行监控(只需要自己模拟一下暴力破解过程,在splunk上搜索相应的登录失败日志即可。)
既然可以抓到实时的扫描源IP,下一步就是要进行邮件通知安全部门。
(添加告警触发后的操作)
由此可以设置邮件告警,通告扫描的源IP。此时已经具备了收到告警后,手动在防火墙封禁的条件。
(扫描告警邮件)
俗话说的好:不用自动化,不是好攻城狮。于是开始了研究防火墙联动的工作,首先即着手如何用splunk导出告警原文并运行脚本。想要导出告警文本,就需要知道splunk告警中的变量,其中总共有8个变量,从0到8(没有7),如下表所示。
变量 | 描述 | 变量 | 描述 |
---|---|---|---|
0 | 脚本名称 | 4 | 报表名称 |
1 | 返回事件的数量 | 5 | 触发原因 |
2 | 搜索项目 | 6 | 浏览报表的浏览器URL |
3 | 具有完全资质的查询字符串 | 8 | 搜索结果储存的文件 |
在这里我们需要用到变量8,其变量内容为_raw(即搜索出来的结果,如下图)
每次告警触发的时候都会有一批raw输出,而告警搜索语句中我们设置了针对同一源IP的扫描进行事件归并,所以每次告警的源IP肯定是一样的。由此我们可以利用正则表达式来筛选出单独的IP,同时要排除10.*.*.*,又由于可能一次告警出现多条攻击记录,正则筛选出IP后,可能是很多行同样的IP,此时摘出来第一个即可。脚本如(addBlack.sh)。
#!/bin/bash ip=`gunzip -c $8 | grep -oE'[0-9]{1,3}/.[0-9]{1,3}/.[0-9]{1,3}/.[0-9]{1,3}'| grep -v -E'^10/.[0-9]{1,3}/.[0-9]{1,3}/.[0-9]{1,3}$'| head -n1` echo "$ip `date`" >>/opt/splunk/bin/scripts/ScanBanIPLog.txt python /opt/splunk/bin/scripts/checkIP.py"$ip"
在调用python脚本时,必须要写全py文件所在路径,否则sh脚本无法自动找到当前的路径。在筛选出IP后,需要先过一遍公司各分支机构的白名单,以防误将公司分支IP封禁。脚本如下(checkIP.py)
#coding:utf-8 import os import sys ip = sys.argv[1]+"/n" flag = "False" f = open("/opt/splunk/bin/scripts/whiteIP.txt") for i in f: if i == ip: flag = "True" f.close() if flag == "False": os.system("python /opt/splunk/bin/scripts/addGroup.py "+ip) else: print "This IP is in the whitelist!"
如果攻击IP不在白名单中,则调用防火墙API封禁IP(具体的API就不共享了,领会精神)。
import urllib2 import urllib import sys ip = sys.argv[1] add_black = "https://10.1.0.1/api/?xxxxxxxx="+ip+"&key=xxxxxx" add_req = urllib2.Request(add_black) urllib2.urlopen(add_req)
至此,三个脚本环环相扣调用完毕,剩下的就是要在splunk配置告警时运行的脚本了。在编辑告警操作中,添加运行脚本”addBlack.sh”(脚本需放置于$SPLUNK_HOME/bin/scripts目录中)
(添加运行脚本)
此后再检测到扫描,splunk会自动发送邮件到安全部门,并调用防火墙API直接封禁攻击IP(世界终于清净了一些)。
在文章开头附了cowrie部署的文章,通过cowrie可以搭建一个SSH蜜罐,同时splunk分析防火墙发来的日志,实时监测对于cowrie蜜罐22端口的连接情况。在正常情况下,蜜罐不会被正常用户访问,何况还是SSH登录的请求,如果短时间内产生了超过2条以上的连接情况,必是恶意请求无疑,此时使用告警脚本调用防火墙API封禁恶意IP即可。
其实web蜜罐很简单,只需一个Apache+静态HTML页面即可。映射到公网之后,配置一个“奇葩的”公司二级域名(如fuck.xx.com)指向到这个公网IP,普通用户肯定不会访问到这个域名。Apache启动后实时监测防火墙发来的日志,一旦发现有对蜜罐80端口的访问记录,立即告警,如果限制的比较严格,可以直接使用告警脚本调用防火墙API封禁访问蜜罐的IP。
至此,简单的WAF已经制作完毕,其实核心的只是几个特征,可以将恶意扫描实时封禁,对于sqlmap也会有一定的防护,但是对于0day来说并没有很好的防护效果,还需根据特征值来手动加入检测规则。
P.S splunk一定要装在linux里。装在windows容易悲剧,不知道什么时候就会卡的欲仙欲死。
*本文原创作者:RipZ,本文属FreeBuf原创奖励计划,未经许可禁止转载