看我如何用20行代码做日志分析

不管是渗透测试、应急响应还是运维,日志分析都万分重要。而linux下日志分析最好的工具那就是linux自带的各种命令了。本文将从一个小例子来介绍”如何用linux命令做日志分析”。

0x00 源码


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#!/bin/bash
if ls ./*.result &> /dev/null
then
rm *.result
fi
touch log.result
for i in www-*.log
do
echo $i ...
awk '$9 == 200 {print $7}' $i|grep -i '^/admin/upload/.*\.html$'|sort|uniq -c|sed 's/^ *//g' > $i.result
cat $i.result >> log.result
echo $i.result finished
done
echo final.log.result ...
sort -k2 log.result | uniq -f1 --all-repeated=separate |./log.awk |sort -rn > final.log.result
echo final.log.result finished
log.awk
#!/usr/bin/awk -f
BEGIN{
RS=""}
  {
sum=0
for(i=1;i<=NF;i++){
if((i%2)!=0){
sum += $i}
  }
print sum,$2
  }

0x01 Apache日志

以apache日志为例,下面是三条普通的apache日志记录。

1
2
3
58.40.124.211 - - [25/Jul/2017:08:53:12 +0800] "GET /vulApps_plat/pentest/e31010629c1cb5aa4252c3832f77ed77/index.html HTTP/1.1" 200 4649 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:54.0) Gecko/20100101 Firefox/54.0"
58.40.124.211 - - [25/Jul/2017:08:53:12 +0800] "GET /vulApps_plat/pentest/e31010629c1cb5aa4252c3832f77ed77/js/jquery-2.2.4.min.js HTTP/1.1" 200 85578 "http://121.43.182.76/vulApps_plat/pentest/e31010629c1cb5aa4252c3832f77ed77/index.html" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:54.0) Gecko/20100101 Firefox/54.0"
58.40.124.211 - - [25/Jul/2017:08:53:13 +0800] "GET /vulApps_plat/pentest/e31010629c1cb5aa4252c3832f77ed77/favicon.ico HTTP/1.1" 200 1517 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:54.0) Gecko/20100101 Firefox/54.0"

58.40.124.211表示访问者IP,25/Jul/2017:08:53:12 +0800表示时间,GET表示请求方法,vulApps_plat/pentest/e31010629c1cb5aa4252c3832f77ed77/index.html表示访问的地址,HTTP/1.1表示使用HTTP协议的1.1版本,200表示响应状态码,Mozilla/5.0 (Windows NT 6.1; WOW64; rv:54.0) Gecko/20100101 Firefox/54.0表示访问者user-agent

我们分析一般关注的主要就是:

  • IP地址
  • 访问的地址
  • 状态码

本次就只演示获取某个地址的访问量并排序,即:访问量 地址这种效果。

0x02 思路

Apache日志文件格式形如201707029.log,根据文件格式设计总体思路如下:

  • 处理每天的日志,统计每日文章访问量
  • 生成每月访问结果,统计月度访问量
  • 生成每年访问结果,统计年度访问量

0x03 命令解析

0x03.1 awk

awk '$9 == 200 {print $7}' $i

awk默认是以空格作为分隔符,$9表示匹配是200的响应,打印出第七个字段

0x03.2 grep

grep -i '^/admin/upload/.*\.html$'

根据awk匹配的结果,匹配访问的地址是/admin/upload/.*\.html的记录。i表示不区分大小写,^$是正则表达式的开头结尾。

0x03.3 sort

sort -k2 log.result

由于合成的记录是无序的,所以要将相同的归类。但是第一字段是访问次数,所以使用k2参数根据网址排序。
sort -rn > final.log.result

对awk脚本的处理结果进行排序,sort默认使用第一个字段,参数r表示逆序,从大往小排;参数n表示以数值形式排序

0x03.4 uniq

uniq -c

使用uniq过滤重复的记录,-c表示添加该记录出现的次数。
uniq -f1 --all-repeated=separate

参数f1表示忽略第一个字段(访问次数),只考虑后面的字段(网址)。参数all-repeated=separate,表示过滤掉所有只出现一次的记录,保留所有重复的记录,并且每一组之间用一个空行分隔

0x03.5 sed

sed 's/^ *//g' > $i.result

由于uniq过滤后每条记录前面都是有空格的,所以要先删除掉。sed命令是一个处理行文本的编辑器,'s/^ *//g'是一个正则表达式(^和*之间有一个空格)表示每行记录的空格替换为空(即删除)并将排序结果重定向到文件。

0x03.6 >和>>

>表示重定向,即输出覆盖,>>也是重定向,但是是表示追加

0x03.7 log.awk

首先,默认情况下,awk将”\n”作为记录的分隔符,设置RS=””表示改为将空行作为分隔符其次,NF是一个awk的内置变量,表示当前行的字段总数。由于输入文件之中,每一行都包含两个字段,第一个是访问数,第二个是网址,所以这里做一个条件判断,只要是奇数字段就累加,偶数字段则一律跳过。最后,每个记录输出一个累加值和网址,它们之间用空格分割。

参考文章:
http://www.cnblogs.com/51linux/archive/2012/05/23/2515299.html
http://blog.csdn.net/long2746004900/article/details/53367353
http://www.cnblogs.com/wangqiguo/p/5863266.html
http://blog.csdn.net/github_33736971/article/details/54286736
http://blog.csdn.net/wenxuechaozhe/article/details/52564394
http://www.cnblogs.com/dong008259/archive/2011/12/07/2279897.html

大爷,赏个铜板呗!