作者: jeary@安百科技

一、为什么需要对日志进行分析?

随着Web技术不断发展,Web被应用得越来越广泛,所谓有价值的地方就有江湖,网站被恶意黑客攻击的频率和网站的价值一般成正比趋势,即使网站价值相对较小,也会面对“脚本小子”的恶意测试攻击或者躺枪于各种大范围漏洞扫描器,正如安全行业的一句话:“世界上只有两种人,一种是知道自己被黑了的,另外一种是被黑了还不知道的”

此时对网站的日志分析就显得特别重要,作为网站管理运维等人员如不能实时的了解服务器的安全状况,则必定会成为“被黑了还不知道的”那一类人,从而造成损失,当然还有一个场景是已经因为黑客攻击造成经济损失,此时我们也会进行日志分析等各种应急措施尽量挽回损失,简而言之日志分析最直接明显的两个目的,一为网站安全自检查,了解服务器上正在发生的安全事件,二为应急事件中的分析取证。

二、如何进行日志分析?

在说如何进行分析之前,我们先来了解一下Web服务器中产生的日志是什么样子.
我们以Nginx容器为例:

随机抽取一条日志:

61.144.119.65 - - [29/May/2017:22:01:32 +0800] "GET /page/1 HTTP/1.1" 200 6403 "http://www.baidu.com" "Scrapy/1.1.2 (+http://scrapy.org)"

作为Web开发或者运维人员,可能对图中的日志信息比较熟悉,如果对日志不那么熟悉也没关系,我们可以查看Nginx中关于日志格式的配置,查看nginx.conf配置文件:

可以看到日志格式为:

$remote_addr - $remote_user [$time_local] "$request" '$status $body_bytes_sent "$http_referer" '$http_user_agent" "$http_x_forwarded_for"';

翻译过来即为:

远程IP - 远程用户  服务器时间 请求主体 响应状态 响应体大小 请求来源 客户端信息 客户端代理IP

通过以上信息,我们可以得知服务器会记录来自客户端的每一个请求,其中有大量来自正常用户的请求,当然也包括来自恶意攻击者的请求,那么我们如何区分正常请求和恶意攻击请求呢?站在攻击者的角度,攻击者对网站进行渗透时,其中包含大量的扫描请求和执行恶意操作的请求,而这两者在日志中都有各自的特征,如扫描请求会访问大量不存在的地址,在日志中体现则为大量的响应状态码为404,而不同的恶意请求都有各自相应的特征,如当有人对服务器进行SQL注入漏洞探测时:


(图中以"select"为关键字进行过滤)
聪明的你肯定想到了,如果此时加上时间条件,状态码等条件就能查询到最近可能成功的SQL注入攻击了,当然实际情况中,仅仅只依靠状态码来判断攻击是否成功是不可行的,因为很多时候请求的确成功了,但并不能代表攻击也成功了,如请求一个静态页面或者图片,会产生这样一个请求:

/logo.png?attack=test';select/**/1/**/from/**/1

此时请求状态码为200,但是此注入攻击并没有得到执行,实际情况中,还会有更多情况导致产生此类的噪声数据。
抛开这类情况不谈,我们来说说在一般应急响应场景中我们分析日志的常规办法。
在常规应急响应常见中,一般客户会有这几种被黑情况:

1.带宽被占满,导致网站响应速度变慢,用户无法正常访问
2.造成已知经济损失,客户被恶意转账、对账发现金额无端流失
3.网站被篡改或者添加暗链,常见为黑客黑页、博彩链接等
..
对于这些情况,按照经验,我们会先建议对已知被黑的服务器进行断网,然后开始进行日志分析操作。假设我们面对的是一个相对初级的黑客,一般我们直接到服务器检查是否存有明显的webshell即可。检查方式也很简单:
1.搜索最近一周被创建、更新的脚本文件
2.根据网站所用语言,搜索对应webshell文件常见的关键字
找到webshell后门文件后,通过查看日志中谁访问了webshell,然后得出攻击者IP,再通过IP提取出攻击者所有请求进行分析
如果不出意外,可能我们得到类似这样一个日志结果:(为清晰呈现攻击路径,此日志为人工撰造)
eg:

00:01  GET http://localhost/index.php 9.9.9.9  200  [正常请求]
00:02  GET http://localhost/index.php?id=1' 9.9.9.9 500  [疑似攻击]
00:05  GET http://localhost/index.php?id=1' and 1=user() or ''=' 9.9.9.9  500  [确认攻击]
00:07 GET http://localhost/index.php?id=1' and 1=(select top 1 name from userinfo) or ''=' 9.9.9.9 500 [确认攻击]
00:09 GET http://localhost/index.php?id=1' and 1=(select top 1 pass from userinfo) or ''=' 9.9.9.9 500 [确认攻击]
00:10  GET http://localhost/admin/ 9.9.9.9 404 [疑似攻击]
00:12  GET http://localhost/login.php 9.9.9.9 404 [疑似攻击]
00:13  GET http://localhost/admin.php 9.9.9.9 404 [疑似攻击]
00:14  GET http://localhost/manager/ 9.9.9.9  404 [疑似攻击]
00:15  GET http://localhost/admin_login.php 9.9.9.9 404 [疑似攻击]
00:15  GET http://localhost/guanli/ 9.9.9.9 200 [疑似攻击]
00:18  POST http://localhost/guanli/ 9.9.9.9 200 [疑似攻击]
00:20  GET http://localhost/main.php 9.9.9.9 200 [疑似攻击]
00:20  POST http://localhost/upload.php 9.9.9.9 200 [疑似攻击]
00:23  POST http://localhost/webshell.php 9.9.9.9 200 [确认攻击]
00:25  POST http://localhost/webshell.php 9.9.9.9 200 [确认攻击]
00:26  POST http://localhost/webshell.php 9.9.9.9 200 [确认攻击]

首先我们通过找到后门文件“webshell.php”,得知攻击者IP为9.9.9.9,然后提取了此IP所有请求,从这些请求可以清楚看出攻击者从00:01访问网站首页,然后使用了单引号对网站进行SQL注入探测,然后利用报错注入的方式得到了用户名和密码,随后扫描到了管理后台进入了登录进了网站后台上传了webshell文件进行了一些恶意操作。
从以上分析我们可以得出,/index.php这个页面存在SQL注入漏洞,后台地址为/guanli.php,/upload.php可直接上传webshell
那么很容易就能得出补救方法,修复注入漏洞、更改管理员密码、对文件上传进行限制、限制上传目录的执行权限、删除webshell。

三、日志分析中存在的难题

看完上一节可能大家会觉得原来日志分析这么简单,不过熟悉Web安全的人可能会知道,关于日志的安全分析如果真有如此简单那就太轻松了。其实实际情况中的日志分析,需要分析人员有大量的安全经验,即使是刚才上节中简单的日志分析,可能存在各种多变的情况导致提高我们分析溯源的难度。
对于日志的安全分析,可能会有如下几个问题,不知道各位可否想过。
1.日志中POST数据是不记录的,所以攻击者如果找到的漏洞点为POST请求,那么刚刚上面的注入请求就不会在日志中体现
2.状态码虽然表示了响应状态,但是存在多种不可信情况,如服务器配置自定义状态码。
如在我经验中,客户服务器配置网站应用所有页面状态码皆为200,用页面内容来决定响应,或者说服务器配置了302跳转,用302到一个内容为“不存在页面”(你可以尝试用curl访问http://www.baidu.com/test.php看看响应体)
3.攻击者可能使用多个代理IP,假如我是一个恶意攻击者,为了避免日后攻击被溯源、IP被定位,会使用大量的代理IP从而增加分析的难度(淘宝上,一万代理IP才不到10块钱,就不说代理IP可以采集免费的了)
如果一个攻击者使用了大量不同的IP进行攻击,那么使用上面的方法可能就无法进行攻击行为溯源了
4.无恶意webshell访问记录,刚才我们采用的方法是通过“webshell”这个文件名从日志中找到恶意行为,如果分析过程中我们没有找到这么一个恶意webshell访问,又该从何入手寻找攻击者的攻击路径呢?
5.分析过程中我们还使用恶意行为关键字来对日志进行匹配,假设攻击者避开了我们的关键字进行攻击?比如使用了各种编码,16进制、Base64等等编码,再加上攻击者使用了代理IP使我们漏掉了分析中攻击者发起的比较重要的攻击请求
6.APT攻击,攻击者分不同时间段进行攻击,导致时间上无法对应出整个攻击行为
7.日志数据噪声(这词我也不知道用得对不对)上文提到过,攻击者可能会使用扫描器进行大量的扫描,此时日志中存在大量扫描行为,此类行为同样会被恶意行为关键字匹配出,但是此类请求我们无法得知是否成功扫描到漏洞,可能也无法得知这些请求是扫描器发出的,扫描器可使用代理IP、可进行分时策略、可伪造客户端特征、可伪造请求来源或伪造成爬虫。此时我们从匹配出的海量恶意请求中很难得出哪些请求攻击成功了
..

四、日志分析工程化之路 [探索篇]

(上一节留下的坑我们留到最后讨论[因为我也觉得比较头疼],我们现在来讨论一点让人轻松的~)
曾经有运维的人员问我们公司的大神,该如何分析日志?
大神回答了三个字:“用命令”
因为站在安全经验丰富的人角度来看,的确用命令足矣,可是对于安全经验不那么丰富的人来说,可能就不知道从何入手了。但是即使身为一个安全从业人员,我也觉得用命令太过耗时耗力(还有那么多有趣的事情和伟大的事情没做呐,当然还要节约出一点时光来嗨嗨嗨呀,难道每次分析日志我们都用命令一个个给一点点分析?)
于是,聪明的黑客们就想到了,将这些步骤流程写成工具,让工具来帮我们分析日志,当然我也想到了,可是在我造这么一个轮子之前,我习惯性的到各大网站上先翻一翻,看看有没有人实现过,还真让我找到一些,如下:

腾讯安全实验室:
https://security.tencent.com/index.php/opensource/detail/15

北风飘然@金乌网络安全实验室
http://www.freebuf.com/sectool/126698.html

网络ID为piaox的安全从业人员:
http://www.freebuf.com/sectool/110644.html

网络ID:SecSky
http://www.freebuf.com/sectool/8982.html

网络ID:鬼魅羊羔
http://www.freebuf.com/articles/web/96675.html

我以“Web安全日志分析”为关键字,百度&Google了一番,发现并没有找到自己觉得不错的日志分析工具,难道安全行业就没有大牛写个优秀的日志分析工具出来?年轻时的我如此想到,后来我发现并非如此,而是稍微优秀一点的都跑去做产品了,于是我转战搜寻关于日志安全分析产品,通过各种方式也让我找到了几个,如下:

首先是推广做得比较好的:日志易
https://www.rizhiyi.com/

日志易确实像它推广视频里所说的:“国内领先的海量日志搜索分析产品”
前段时间,有客户联系到我们,说他们买了日志易的产品,但是其中对安全的监控比较缺乏,让我们能不能在日志易的基础上添加一些安全规则,建立安全告警,他们要投放到大屏幕,然后来实时监控各个服务器的安全状态。然后我就大概看了一遍日志易的产品,安全方面的分析,基本为0.
但是日志易确实有几个优点
1.日志采集方面相对成熟,已经能针对多种日志格式解析并结构化,还支持用户自定义日志格的辅助解析
2.海量日志存储相对完善,可接收来自各个客户端的日志,Saas服务成熟,能对接各大云主机
3.搜索方面技术优秀,千亿级别数据索引只需60秒
(但是,我要的安全分析啊,其他的再成熟,也始终是个不错的日志分析平台而已,我要的是安全分析、安全分析、安全分析[重要的话说三遍])
补:
(后来我发现,日志易其实有在安全方面进行分析,但是这个如图这个结果,并没有让我觉得眼前一亮,而且其中还有大量的误报)

后来我从朋友那里得知另外一个产品,算是看到一个稍微像那么回事的产品:
安全易
https://www.anquanyi.com/

他们推广做得不那么好,所以在我一开始的搜索中,并没有从搜索引擎找到它,这个产品是可以免费注册并试用的,于是我迫不及待注册了一个账号进去看看,如图:

当我试用过安全易这个产品之后,提取出了他们在关于安全方面所做的统计列表,如下:

1.威胁时序图
2.疑似威胁分析
3.疑似威胁漏报分析
4.威胁访问流量
5.威胁流量占比
6.境外威胁来源国家(地区)统计
7.境内威胁来源城市统计
8.威胁严重度
9.威胁响应分析

点击收藏 | 9 关注 | 5
登录 后跟帖