日志分析难点
- 日志分析难点
- POST数据不记录导致分析结果不准确
- 思考
- 从不完整的信息中,分析得到一个肯定的答案,从逻辑上就不可行
- 但是我们可以折中实现,尽量向肯定的答案靠近,即使得到一个90%肯定的答案,那也合乎我们想要的结果
- 虽然POST数据不被记录,但是这些“不完整信息”依然能给我们我们提供线索
- 如通过响应大小、响应时间、前后请求关联、POST地址词义分析、状态码等等依然能为我们的分析提供依据
- 如某个请求在日志中的出现次数占访问总数30%以上,且响应大小平均值为2kb,突然某一天这个请求的响应值为10kb,且发起请求的IP曾被攻击特征匹配出过,那么可以80%的怀疑此请求可能存在异常
- 如攻击者使用了联合注入查询了大量数据到页面
- 当然这里只是举例,实际情况可能存在误报
- 如通过响应大小、响应时间、前后请求关联、POST地址词义分析、状态码等等依然能为我们的分析提供依据
- 虽然POST数据不被记录,但是这些“不完整信息”依然能给我们我们提供线索
- 思考
- 状态码很多时候不可信
- 状态码虽然表示了响应状态,但是存在多种不可信情况,如服务器配置自定义状态码
- 举例
- 对于那些自行设置响应状态的,明明404却302的,明明500却要200的
- 客户服务器配置网站应用所有页面状态码皆为200,用页面内容来决定响应
- 服务器配置了302跳转,用302到一个内容为“不存在页面”
- 举例
- 思路
- 对于不同的攻击行为,我们应该定义不同的响应规则
- 如果攻击规则命中的为网站备份文件,那么应该判断请求大小必须超过1k-5k
- 如攻击者发起/wwwroot.rar这种攻击请求,按照常理如果状态码为200,那么本来应该被定性为成功的攻击行为
- 但是因为状态码不可信,我们可以转而通过响应大小来判断
- 因为按照常规逻辑,备份文件一般都不止只有几kb大小
- 但是因为状态码不可信,我们可以转而通过响应大小来判断
- 如攻击者发起Bool注入请求则应该通过判断多个注入攻击请求的规律
- Bool注入通常页面是一大一小一大一小这种规律
- 如攻击者发起联合注入攻击,则页面响应大小会异常于多部分正常页面响应大小
- 如果攻击者发起延时注入请求,则页面响应时间则会和延时注入payload中的响应相近
- 但是这需要分析攻击payload并提取其中的延时秒数来和日志中的响应时间进行比较误差值
- 对于不同的攻击行为,我们应该定义不同的响应规则
- 状态码虽然表示了响应状态,但是存在多种不可信情况,如服务器配置自定义状态码
- 攻击者使用多个代理IP导致无法构成整个攻击路径
- 攻击者可能使用多个代理IP,用代理隐藏了真实IP
- 淘宝上,一万代理IP才不到10块钱
- 更不用说代理IP还可以采集免费的
- 淘宝上,一万代理IP才不到10块钱
- 假设同一攻击者发起的每个请求都来自不同的IP,此时即使攻击规则命中了攻击者所有请求,也无法还原攻击者的攻击路径
- 如果一个攻击者使用了大量不同的IP进行攻击,那么使用上面的方法可能就无法进行攻击行为溯源了
- 思路
- 虽然攻击者使用了多个IP,但是假设攻击者不足够心细,此时你可以通过攻击时间段、请求频率、客户端信息(Ua)、攻击手法、攻击工具(请求主体和请求来源和客户端信息中可能暴露工具特征
- 如sqlmap注入时留下的referer
- 虽然攻击者使用了多个IP,但是假设攻击者不足够心细,此时你可以通过攻击时间段、请求频率、客户端信息(Ua)、攻击手法、攻击工具(请求主体和请求来源和客户端信息中可能暴露工具特征
- 攻击者可能使用多个代理IP,用代理隐藏了真实IP
- 无恶意webshell访问记录
- 常规分析中,我们通过找到后门文件,从而利用这一线索得知攻击者IP继而得知攻击者所有请求,但是如果我们并没有找到webshell,又该用什么作为分析的入口线索呢?
- 思路
- 利用尽可能全面的攻击规则对日志进行匹配,通过IP分组聚合,提取发起过攻击请求的所有IP,再通过得到的IP反查所有请求,再配合其他方法检测提取出的所有请求中的可疑请求
- 编码避开关键字匹配
- 攻击者使用了各种编码,16进制、Base64等等编码,使得日志中找不到恶意行为关键字
- 再加上攻击者使用了代理IP使我们漏掉了分析中攻击者发起的比较重要的攻击请求
- 关于编码、加密问题,某人也曾尝试过
- 但是实际最后发现除了URL编码以外,其他的编码是无法随意使用的
- 因为一个被加密或编码后的请求,服务器是无法正确接收和处理的
- 除非应用本身请求就是加密或编码的
- 且一般加密或编码出现在日志里通常都是配合其他函数实现的
- 如
Char()
、toHexString()
、Ascii()
- 如
- 因为一个被加密或编码后的请求,服务器是无法正确接收和处理的
- 但是实际最后发现除了URL编码以外,其他的编码是无法随意使用的
- 攻击者使用了各种编码,16进制、Base64等等编码,使得日志中找不到恶意行为关键字
- APT分时段攻击
- 攻击者分不同时间段进行攻击,导致时间上无法对应出整个攻击行为
- 举例
- 如果同一攻击者的攻击行为分别来源不同的时间,比如攻击者花一周时间进行“踩点”,然后他就停止了行为
- 过了一周后再继续利用所得信息进行攻击行为,此时因为行为链被断开了一周,我们可能无法很明显的通过时间维度来定位攻击者的攻击路径
- 思路
- 给攻击力路径定义模型,就拿在前面讲到的常规日志分析举例,那么攻击路径模型可定义为:访问主页>探测注入>利用注入>扫描后台>进入后台>上传webshell>通过webshell执行恶意操作
- 其中每一个都可以理解一种行为,而每种行为都有相应的特征或者规则
- 比如主页链接一般在日志中占比较大,且通常路径为index.html、index.php、index.aspx,那么符合这两个规则则视为访问主页
- 而在探测注入行为中,一般会出现探测的payload
- 如时间注入会匹配以下规则
.*(BENCHMARK\\(.*\\)).* .*(WAITFOR.*DELAY).* .*(SLEEP\\(.*\\).* .*(THENDBMS_PIPE.RECEIVE_MESSAGE).*
- Bool注入
.*and.*(>|=|<).* .*or.*(>|=|<).* .*xor.*(>|=|<).*
- 联合注入
.*(order.*by).* .*(union.*select).* .*(union.*all.*select).* .*(union.*select.*from).*
- 显错注入
.*('|"|\\)).* .*(extractvalue\\(.*\\)).* .*(floor\\(.*\\)).* .*(updatexml\\(.*\\)).*
- 如时间注入会匹配以下规则
- 利用注入则会体现出更完整,带有目的性的攻击请求,我们以同理制定规则即可,如查询当前数据库名、查询版本信息、查询数据库表名、列名则会出现
database
、version
、table_name
、column_name
(不同数据库存在不同差异,这里仅举例) - 扫描后台则会产生大量的404请求,且请求较为频繁,请求特征通常为
/admin
、/guanli
、/login.php
、/administrator
- 日志数据噪声
- 攻击者可能会使用扫描器进行大量的扫描
- 此时日志中存在大量扫描行为
- 此类行为同样会被恶意行为关键字匹配出
- 但是此类请求我们无法得知是否成功扫描到漏洞
- 可能也无法得知这些请求是扫描器发出的
- 扫描器可使用代理IP、可进行分时策略、可伪造客户端特征、可伪造请求来源或伪造成爬虫
- 海量恶意请求中很难得出哪些请求攻击成功了
- 思路
- 一种是给每种攻击方法定义成功的特征
- 如延时注入可通过判断日志中的响应时间
- 联合注入可通过与正常请求比较响应大小
- Bool注入可通过页面响应大小的规律
- 当然实际情况中,这种做法得到的结果可能是存在误报的
- 第二种办法就是通过二次请求,通过重放攻击者的请求,定义攻击payload可能会返回的结果,通过重放攻击请求获取响应之后进行判断
- 注意:其实这里已经类似扫描器,只是攻击请求来自于日志,这种方法可能对服务器造成二次伤害,一般情况下不可取,且已经脱离日志分析的范畴
- 一种是给每种攻击方法定义成功的特征
- 攻击者可能会使用扫描器进行大量的扫描
- POST数据不记录导致分析结果不准确