| 注册
请输入搜索内容

热门搜索

Java Linux MySQL PHP JavaScript Hibernate jQuery Nginx
msoc0751
7年前发布

我的日志分析之道:简单的Web日志分析脚本

   <h2><strong>前言</strong></h2>    <p>长话短说,事情的起因是这样的,由于工作原因需要分析网站日志,服务器是windows,iis日志,在网上找了找,github找了找,居然没找到,看来只有自己动手丰衣足食。</p>    <h3>那么分析方法我大致可分为三种:</h3>    <p><strong>1. 基于时间:</strong> 将请求url按时间段分类,那么我们根据每个时间段的url数量及攻击数量就可以大致判断出哪个时间段有apt类型攻击,哪个时间段是扫描器行为;</p>    <p><strong>2. 基于攻击ip:</strong> 正常的攻击肯定会有请求被记录(当然你要是有0day当我没说,正常的探测总会有吧=。=!),然后每个ip去分析;</p>    <p><strong>3. 基于访问请求的状态码</strong> ,也大致可以判断出行为。</p>    <p>规则可以基于开源waf规则,分析扫描器写正则也可以,开源waf地址是</p>    <p><a href="/misc/goto?guid=4959737075351950366" rel="nofollow,noindex">https://github.com/loveshell/ngx_lua_waf/tree/master/wafconf</a> 。</p>    <p>扫描器正则 <a href="/misc/goto?guid=4959737075442198216" rel="nofollow,noindex">https://github.com/smarttang/w3a_SOCD</a> 的database里面有详细地址</p>    <p><a href="/misc/goto?guid=4959737075527688164" rel="nofollow,noindex">https://github.com/smarttang/w3a_SOC/tree/master/db_sql</a> 。</p>    <p>Sql语句里面有想把它做的功能全一些,但是学python学习时间也不是很长,写出来的代码也没有pythonic,会慢慢写的。目前分三个模块,一个日志归类模块命名为url.py,攻击分析模块attac.py, ip地理位置查询模块ipfind.py,还有一个主函数。</p>    <h3><strong>日志归类模块</strong> <strong>url.py</strong></h3>    <pre>  <code class="language-python"><strong>import </strong>re  <strong>import </strong>os  <strong>import </strong>sys  <strong>from </strong>datetime <strong>import </strong>datetime      dt = datetime.now()    date = str(dt.date())        loglist = []   <em># </em>iplist = []    <em># ip</em><em>统计 </em>urllist = []   <em># url</em><em>统计列表 </em>needlist = []   <em># </em><em>需要统计的 </em>errorlist = []   <em># </em><em>格式错误的列表 </em>ipdict,urldict = {},{}        rizhi = str(input(<strong>'</strong><strong>请输入要分析的日志文件名'</strong>))    <strong>def </strong>find_log():        print(<strong>'>>>>>>></strong><strong>开始解析日志'</strong>)        <strong>with </strong>open(rizhi,<strong>'r'</strong>,encoding=<strong>'UTF-8'</strong>,errors=<strong>'ignore'</strong>) <strong>as </strong>f:            <em>#loglist = f.readlines() </em><strong>for </strong>i <strong>in </strong>f.readlines():   <em># </em><strong>if </strong>i[0] != <strong>'#'</strong>:                    b = re.split(<strong>' '</strong>,i)                    iplist.append(b[10])                    urllist.append(b[6])                    <strong>try</strong>:                        needlist.append([b[10],b[1],b[5],b[6],b[15]])                    <strong>except</strong>:                        errorlist.append(i)        print(<strong>'>>>>>>></strong><strong>日志解析完毕'</strong>)    <strong>def </strong>count(iplist,urllist):    <em>#</em><em>统计ip url访问量函数 </em>print(<strong>'>>>>>>></strong><strong>开始分析url与ip访问量'</strong>)        <strong>global </strong>ipdict,urldict        <strong>for </strong>i <strong>in </strong>set(iplist):            ipdict[i] = iplist.count(i)        <strong>for </strong>i <strong>in </strong>set(urllist):            urldict[i] = urllist.count(i)          ipdict = sorted(ipdict.items(),key=<strong>lambda </strong>d: d[1], reverse=<strong>True</strong>)            urldict = sorted(urldict.items(),key=<strong>lambda </strong>d: d[1], reverse=<strong>True</strong>)        print(type(urldict))        iplist = list(ipdict)        urllist = list(urldict)        ipdict,urldict = {},{}        print(<strong>'>>>>>url</strong><strong>与ip分析完毕.......'</strong>)          <strong>return </strong>[iplist,urllist]    <strong>def </strong>save_count():        print(<strong>'>>>>>>></strong><strong>正在保存分析结果'</strong>)        ipname = <strong>'ip-'</strong>+date+<strong>'.txt' </strong>urlname = <strong>'url-'</strong>+date+<strong>'.txt' </strong><strong>with </strong>open(ipname,<strong>'w'</strong>) <strong>as </strong>f:            <strong>for </strong>i <strong>in </strong>iplist:                f.write(str(list(i))+<strong>'</strong><strong>\n</strong><strong>'</strong>)        <strong>with </strong>open(urlname,<strong>'w'</strong>) <strong>as </strong>f:            <strong>for </strong>i <strong>in </strong>urllist:                f.write(str(list(i))+<strong>'</strong><strong>\n</strong><strong>'</strong>)        print(<strong>'>>>>>>></strong><strong>分析结果保存完毕'</strong>)    find_log()    [iplist,urllist] = count(iplist,urllist)    save_count()</code></pre>    <p>iis日志和apache日志觉得都差不多,就是切割时候改一下就行了。</p>    <p><img src="https://simg.open-open.com/show/5f116eea05d16cf37b69cead531d2d5c.jpg"></p>    <p>Iis日志大概是这样的,用pythonreadlines然后切割出来就好了。</p>    <p>这个url.py我加了个功能把ip访问量及url访问量排序输出出来所以有点慢,=.=没办法野路子哪里会什么算法。将地址,时间,ip,状态码都扔进一个列表里就行了。</p>    <h3><strong>攻击分析模块attack.py</strong></h3>    <pre>  <code class="language-python"><strong>import </strong>os  <strong>import </strong>sys  <strong>import </strong>url      sqllist,xsslist,senlist = [],[],[]    otherurl,xssip,sqlip,senip = [],[],[],[]    feifa = []   <strong>def </strong>find_attack(needlist):        print(<strong>'>>>>>>></strong><strong>开始检测攻击'</strong>)        sql = <strong>r'product.php|preg_\w+|execute|echo|print|print_r|var_dump|(fp)open|^eval$|file_get_contents|include|require|require_once|shell_exec|phpinfo|system|passthru|\(?:define|base64_decode\(|group\s+by.+\(|%20or%20|%20and%20|sleep|delay|nvarchar|exec|union|^select$|version|insert|information_schema|chr\(|concat|%bf|sleep\((\s*)(\d*)(\s*)\)|current|having|database' </strong>xss = <strong>r'alert|^script$|<|>|%3E|%3c|>|\u003c|\u003e|&#x' </strong>sen = <strong>r'\.{2,}|%2e{2,}|%252e{2,}|%uff0e{2,}0x2e{2,}|\./|\{FILE\}|%00+|json|\.shtml|\.pl|\.sh|\.do|\.action|zabbix|phpinfo|/var/|/opt/|/local/|/etc|/apache/|\.log|invest\b|\.xml|apple-touch-icon-152x152|\.zip|\.rar|\.asp\b|\.php|\.bak|\.tar\.gz|\bphpmyadmin\b|admin|\.exe|\.7z|\.zip|\battachments\b|\bupimg\b|uploadfiles|templets|template|data\b|forumdata|includes|cache|jmxinvokerservlet|vhost|bbs|host|wwwroot|\bsite\b|root|hytop|flashfxp|bak|old|mdb|sql|backup|^java$|class' </strong><strong>for </strong>i <strong>in </strong>needlist:            <strong>if </strong>i[2] == <strong>'POST' </strong><strong>or </strong>i[2] == <strong>'HEAD' </strong><strong>or </strong>i[2] == <strong>'GET'</strong>:                response = re.findall(sql,i[3],re.I)                <strong>if </strong>response == []:                    responsexss = re.findall(xss,i[3],re.I)                    <strong>if </strong>responsexss == []:                        responsesen = re.findall(sen,i[3],re.I)                        <strong>if </strong>responsesen == []:                            otherurl.append(i)                        <strong>else</strong>:                            senlist.append(i)                            senip.append(i[0])                            print(responsesen)                            print(<strong>'</strong><strong>检测出敏感目录扫描'</strong>)                            print(i)                    <strong>else</strong>:                        xsslist.append(i)                        xssip.append(i[0])                        print(responsexss)                        print(<strong>'</strong><strong>检测出xss攻击'</strong>)                        print(i)                <strong>else</strong>:                    sqllist.append(i)                    sqlip.append(i[0])                    print(responsexss)                    print(<strong>'</strong><strong>检测出sql攻击'</strong>)                    print(i)            <strong>else</strong>:                feifa.append(i[0])        print(<strong>'</strong><strong>非法请求:'</strong>+str(len(feifa))+<strong>'</strong><strong>次'</strong>+str(len(list(set(feifa))))+<strong>'</strong><strong>个ip'</strong>)        print(<strong>'>>>>>>></strong><strong>攻击检测完毕'</strong>)        <strong>return </strong>[xssip,sqlip,senip,sqllist,xsslist,senlist,otherurl]    这个就简单多了,基于正则分析的正则不是很完善,还有好多是根据自己公司情况来定,大牛轻喷,检索完毕返回ip及url。</code></pre>    <h3>IP 地理位置查询模块 ipfind.py</h3>    <p>Ipfind.py是查找ip地理位置的</p>    <pre>  <code class="language-python"><strong>import </strong>re  <strong>import </strong>urllib.request    <strong>def </strong>url_open(ip):        url = <strong>'http://www.ip138.com/ips138.asp?ip='</strong>+ip        response = urllib.request.urlopen(url)        html = response.read().decode(<strong>'gb2312'</strong>)        <strong>return </strong>html      <strong>def </strong>find_ip(html):        a = <strong>r'</strong><strong>本站数据.{20,}</li>' </strong>p = re.compile(a,re.I)        response = re.findall(p,html)        <strong>for </strong>i <strong>in </strong>response:            b = i        response = re.split(<strong>r'</li><li>'</strong>,b)        ipaddrs = str(response[0][5:])+<strong>','</strong>+str(response[1][6:])+<strong>','</strong>+str(response[2][6:-5])        <strong>return </strong>ipaddrs      <strong>def </strong>find_ipaddrs(ip):                html = url_open(ip)        ipaddrs = find_ip(html)          print(ip+<strong>' : '</strong>+ipaddrs)        这个简单我是直接像爬虫那样写的,用ip138的网址(接口没有找到,百度注册了好几次都不成功,有api的可以用api)。</code></pre>    <h2>主函数</h2>    <h3>主函数main.py</h3>    <pre>  <code class="language-python"><strong>import </strong>re  <strong>import </strong>os  <strong>import </strong>sys  <strong>from </strong>datetime <strong>import </strong>datetime  <strong>import </strong>url  <strong>import </strong>attack  <strong>import </strong>ipfind          needlist = url.needlist    sqllist,xsslist,senlist = [],[],[]    otherurl,iplist = [],[]      [xssip,sqlip,senip,sqllist,xsslist,senlist,otherurl]=attack.find_attack(needlist)    xssip = list(set(xssip))    sqlip = list(set(sqlip))    senip = list(set(senip))    print(<strong>'>>>>>>></strong><strong>检测出xss攻击'</strong>+str(len(xsslist))+<strong>'</strong><strong>次'</strong>+<strong>'</strong><strong>共计'</strong>+str(len(xssip))+<strong>'</strong><strong>个ip'</strong>)  print(xssip)  print(<strong>'>>>>>>></strong><strong>检测出sql攻击'</strong>+str(len(sqllist))+<strong>'</strong><strong>次'</strong>+<strong>'</strong><strong>共计'</strong>+str(len(sqlip))+<strong>'</strong><strong>个ip'</strong>)  print(sqlip)  print(<strong>'>>>>>>></strong><strong>检测出敏感目录扫描'</strong>+str(len(senlist))+<strong>'</strong><strong>次'</strong>+<strong>'</strong><strong>共计'</strong>+str(len(senip))+<strong>'</strong><strong>个ip'</strong>)  print(senip)    iplist = list(set(xssip+sqlip+senip))  print(len(iplist))    print(<strong>'</strong><strong>开始分析ip地理位置'</strong>)  <strong>for </strong>i <strong>in </strong>iplist:        ipfind.find_ipaddrs(str(i))</code></pre>    <p>要分析什么就把需要分析的和main.py放在一个目录下就行了</p>    <h2><strong>总结</strong></h2>    <p>脚本大概说了一遍,说说不足及怎么分析吧。</p>    <p>现实不足:看了差不多有3个月日志了吧,先说一个最严重的问题,post请求data看不见,本身日志就看不到data,何况等到https普及了日志什么样也不知道,要是有能力最好做成和waf联动那样的。还有就是未知威胁从waf来看基于正则,基于关键词有很多都是能绕过的,但是有攻击行为没删日志的话,肯定是会留下攻击痕迹的,这样可以从检测出来的ip来看具体攻击的url,而未知威胁则不同了,就好比一个0day,攻击waf没用了,日志分析看不出来了,那么只能依靠应急响应以及服务器的报警了。</p>    <p>还有好多攻击类型没有加入到里面,后期打算把判断攻击类型写成函数,拿if,else判断,类型少还可以,类型多了感觉很容易乱,还有user-agent的收集与判断(虽然大多数扫描器都能改user-agent)。</p>    <p>具体分析:我都是用脚本跑一遍,然后按ip来看会比较方便些,而这里缺少机器识别,我单独写了一个简易的机器识别的东西,其实要实现很简单,把全部日志按时间,url,ip扔进一个列表里统计一下相同时间相同ip的就可以了。我写的是识别短信轰炸的,后期还会渐渐的完善,如果有能力就把它结合django来弄成图形化,毕竟脚本始终是脚本,终究听着不好听。</p>    <p><strong>效果如下</strong></p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/ae0b8f909b5dfe0a74806e1f6f0cf819.jpg"></p>    <p> </p>    <p>来自:http://www.freebuf.com/sectool/126698.html</p>    <p> </p>    
 本文由用户 msoc0751 自行上传分享,仅供网友学习交流。所有权归原作者,若您的权利被侵害,请联系管理员。
 转载本站原创文章,请注明出处,并保留原始链接、图片水印。
 本站是一个以用户分享为主的开源技术平台,欢迎各类分享!
 本文地址:https://www.open-open.com/lib/view/open1487060138437.html
日志分析 数据库 Python开发