打造一款日志分析工具

news2024/9/21 20:36:47

一、简介

作为一名安全从业者,网络安全事件的应急响应工作是必不可少的,那么在应急支撑时,针对大量的日志数据便需要借助自动化工具实现快速的归类检测,并提取出所需的关键日志数据。本篇文章主要通过利用python语言编写一款web日志的分析工具。

代码地址:https://github.com/get0shell/ALogFry

工具运行效果:

python3 ALogFry.py

1661159540_630348748af727c6ad0ed.png!small

二、设计模式

该web日志分析工具的整个流程包括以下环节:

1661159586_630348a253ac835c1d7bd.png!small?1661159586940

检测文件: 用来检测是否有日志文件,以及输出文件是否存在

数据提取: 用来提取日志数据中的IP、时间以及uri等关键数据

数据处理: 基于规则提取攻击日志,并对攻击日志中关键数据做合并统计

数据输出: 输出数据处理后的数据,并存储于输出文件

三、开发实战

3.1 检测文件

该模块功能主要作用为日志分析前的文件检测,该工具相关涉及两个文件夹,分别为logs和log。

log目录下主要存储检测输出的数据结果,工具运行后先会检测log目录是否存在,

1)如果存在则检测目录下是否存在文件,如果存在文件则为上一次检测生成的结果文件,进行删除

2)如果不存在该目录,则新建一个log目录

if os.path.exists('./log'):
    pathDir = os.listdir('./log/')
    for allDir in pathDir:
        p = os.path.join('./log/' + allDir)
        os.remove(p)
else:
    os.mkdir('./log')

logs目录必须存在,用来存放需要分析的日志文件,工具运行后会检测该目录下的文件,如果无文件则会提示

lpathDir = os.listdir('./logs')
if len(lpathDir) < 1:
    print("logs目录下无日志文件!!!")
else:
    pass

3.2 数据提取

检测文件完成后会对logs目录下的日志文件进行遍历提取,提取出每行日志后,利用split()方法对字符串进行分割,分割后以列表的形式进行存在,因为本次工具主要针对web日志中get请求的日志进行分析,以此IP为列表第0个成员,时间为列表第3和第4个成员组成,请求方法为第5个成员,而url为第6个成员。当然,如果日志中接入了post的数据体,可以针对所在的列表位数进行获取,本次工具中不再赘述。

1661159608_630348b8a0e79c4b7a7db.png!small?1661159609132

具体代码如下:

for lallDir in lpathDir:
        h = os.path.join('./logs/' + lallDir)
        with open(h, 'rt', encoding='utf-8') as f:
            for i in f:
                # 对字符串进行分割,分割之后以列表形式存在
                n = i.split()
                ip = n[0]
                time = n[3] + n[4]
                method = n[5]
                uri = n[6]

3.3 数据处理

针对提取出的日志数据需要进行恶意攻击日志的检测,那么开始之前,需要提前准备好检测工具所具有的功能对应的规则语句。本次工具编写主要针对xss攻击、命令执行、SQL注入、敏感文件以及webshell连接进行检测,因此首先准备对应的正则匹配规则。具体详细规则根据需要可以细化。

xss = "script<alert|script.*alert|img.*src=|document.domain"
comm = "whoami|ifconfig|ipconfig|wget.*http|dir|curl.*ifs|wget.*ifs|uname|think.*invokefunction|echo|net%20user|net user|phpinfo"
sqlinj = "select.*count|select.*limit|select.*regexp|select.*master|group%20by|group by|union.*select|select.*xp_cmdshell|select.*from"
file = "web.xml|database.properties|config.xml|web_config.xml|known_hosts|htpasswd|DS_Store|boot.ini|win.ini|my.ini|etc/passwd|etc/shadow|httpd.conf|.sql|.svn|.bak"
webshell = "shell.jsp|ant.jsp|server.jsp|i.jsp|shell.php|ant.php|server.php|i.php|shell.asp|ant.asp|server.asp|i.asp"

同时再申明几个int类型变量,初始值为0,用来统计不同类型的攻击数量

x = c = s = e = w = 0

上述完成之后开始对攻击语句进行检测,利用正则re.search()方法实现,这块需要注意使用re.I,可以忽略大小写,将匹配到的日志继续存放在log下对应的txt文档中,同时每检测出一次x变量+1次

# XSS攻击检测
if re.search(xss, uri, re.I):
    with open('./log/xss.txt', 'at', encoding='utf-8') as f:
        f.writelines(i)
    x += 1

检测完成之后,如果申明的统计变量x大于0,则证明存在该攻击日志,则需要对该类攻击下的攻击IP进行处理

1)申明一个空列表,用来存放攻击IP

2)查询该类攻击日志的文档,提取其中的攻击IP并添加到列表

3)对攻击IP列表进行去重处理

if x > 0:
                ip_list = []
                print('存在xss攻击:' + str(x) + '次')
                with open('./log/xss.txt', 'rt', encoding='utf-8') as f:
                    for i in f:
                        n = i.split()
                        ip = n[0]
                        ip_list.append(ip)

                ip_new = list(set(ip_list))

3.4 数据输出

通过数据处理操作后,则对结果进行输出,那么上面数据处理代码中可以看到对于存在该类型攻击以及攻击次数会进行打印输入,同时对于统计去重后的攻击IP也会进行输出。完成之后将该类型攻击日志进行遍历打印输出,方便直接查看。

print("攻击ip:")
    for i in range(len(ip_new)):
        print(ip_new[i])
    with open('./log/xss.txt', 'rt', encoding='utf-8') as f:
        print("详细攻击日志:")
        for i in f:
            # 利用splitlines()去除换行符
            print(i.splitlines())

除了打印出输出的数据以外,每种攻击类型的详细日志数据也可以直接在txt文档中查看。

3.5 工具实现

通过上述四个模块的编写,基于python实现的web日志分析工具便完成了,当然以上整体实现只是通过xss攻击检测进行演示,其他类型攻击检测效果同理。具体代码如下:

# @Author : alan
# @File : ALogFry.py

import re
import os

xss = "script<alert|script%3Ealert|img src=|img%20src=|document.domain"
comm = "whoami|ifconfig|ipconfig|wget.*http|dir|curl.*ifs|wget.*ifs|uname|think.*invokefunction|echo|net%20user|net user|phpinfo"
sqlinj = "select.*count|select.*limit|select.*regexp|select.*master|group%20by|group by|union.*select|select.*xp_cmdshell|select.*from"
file = "web.xml|database.properties|config.xml|web_config.xml|known_hosts|htpasswd|DS_Store|boot.ini|win.ini|my.ini|etc/passwd|etc/shadow|httpd.conf|.sql|.svn|.bak"
webshell = "shell.jsp|ant.jsp|server.jsp|i.jsp|shell.php|ant.php|server.php|i.php|shell.asp|ant.asp|server.asp|i.asp"
x = c = s = e = w = 0
if os.path.exists('./log'):
    pathDir = os.listdir('./log/')
    for allDir in pathDir:
        p = os.path.join('./log/' + allDir)
        os.remove(p)
else:
    os.mkdir('./log')
    pathDir = os.listdir('./log/')
    for allDir in pathDir:
        p = os.path.join('./log/' + allDir)
        os.remove(p)
lpathDir = os.listdir('./logs')
if len(lpathDir) < 1:
    print("logs目录下无日志文件!!!")
else:
    for lallDir in lpathDir:
        h = os.path.join('./logs/' + lallDir)
        with open(h, 'rt', encoding='utf-8') as f:
            for i in f:
                # 对字符串进行分割,分割之后以列表形式存在
                n = i.split()
                ip = n[0]
                time = n[3] + n[4]
                method = n[5]
                uri = n[6]
                # XSS攻击检测
                if re.search(xss, uri, re.I):
                    with open('./log/xss.txt', 'at', encoding='utf-8') as f:
                        f.writelines(i)
                    x += 1
                # 命令执行攻击检测
                if re.search(comm, uri, re.I):
                    with open('./log/comm.txt', 'at', encoding='utf-8') as f:
                        f.writelines(i)
                    c += 1
                # sql注入攻击检测
                if re.search(sqlinj, uri, re.I):
                    with open('./log/sqlinj.txt', 'at', encoding='utf-8') as f:
                        f.writelines(i)
                    s += 1
                # 敏感文件攻击检测
                if re.search(file, uri, re.I):
                    with open('./log/file.txt', 'at', encoding='utf-8') as f:
                        f.writelines(i)
                    e += 1
                # webshell连接攻击检测
                if re.search(webshell, uri, re.I):
                    with open('./log/webs.txt', 'at', encoding='utf-8') as f:
                        f.writelines(i)
                    w += 1
            if x > 0:
                ip_list = []
                print('存在xss攻击:' + str(x) + '次')
                with open('./log/xss.txt', 'rt', encoding='utf-8') as f:
                    for i in f:
                        n = i.split()
                        ip = n[0]
                        ip_list.append(ip)

                # print(ip_list)
                ip_new = list(set(ip_list))
                print("攻击ip:")
                for i in range(len(ip_new)):
                    print(ip_new[i])
                with open('./log/xss.txt', 'rt', encoding='utf-8') as f:
                    print("详细攻击日志:")
                    for i in f:
                        # 利用splitlines()去除换行符
                        print(i.splitlines())
                # os.remove(r'../plug/logs/log/xss.txt')
            if c > 0:
                ip_list = []
                print('存在命令执行攻击:' + str(c) + '次')
                with open('./log/comm.txt', 'rt', encoding='utf-8') as f:
                    for i in f:
                        n = i.split()
                        ip = n[0]
                        ip_list.append(ip)

                # print(ip_list)
                ip_new = list(set(ip_list))
                print("攻击ip:")
                for i in range(len(ip_new)):
                    print(ip_new[i])
                with open('./log/comm.txt', 'rt', encoding='utf-8') as f:
                    print("详细攻击日志:")
                    for i in f:
                        print(i.splitlines())
            if s > 0:
                ip_list = []
                print('存在sql注入攻击:' + str(s) + '次')
                with open('./log/sqlinj.txt', 'rt', encoding='utf-8') as f:
                    for i in f:
                        n = i.split()
                        ip = n[0]
                        ip_list.append(ip)

                ip_new = list(set(ip_list))
                print("攻击ip:")
                for i in range(len(ip_new)):
                    print(ip_new[i])
                with open('./log/sqlinj.txt', 'rt', encoding='utf-8') as f:
                    print("详细攻击日志:")
                    for i in f:
                        print(i.splitlines())
            if e > 0:
                ip_list = []
                print('存在敏感文件攻击:' + str(e) + '次')
                with open('./log/file.txt', 'rt', encoding='utf-8') as f:
                    for i in f:
                        n = i.split()
                        ip = n[0]
                        ip_list.append(ip)

                ip_new = list(set(ip_list))
                print("攻击ip:")
                for i in range(len(ip_new)):
                    print(ip_new[i])
                with open('./log/file.txt', 'rt', encoding='utf-8') as f:
                    print("详细攻击日志:")
                    for i in f:
                        print(i.splitlines())
                if w > 0:
                    ip_list = []
                    print('存在webshell连接攻击:' + str(w) + '次')
                    with open('./log/webs.txt', 'rt', encoding='utf-8') as f:
                        for i in f:
                            n = i.split()
                            ip = n[0]
                            ip_list.append(ip)

                    ip_new = list(set(ip_list))
                    print("攻击ip:")
                    for i in range(len(ip_new)):
                        print(ip_new[i])
                    with open('./log/webs.txt', 'rt', encoding='utf-8') as f:
                        print("详细攻击日志:")
                        for i in f:
                            print(i.splitlines())

四、结语

以上便是一个基于python实现的web日志分析工具的逻辑和代码,当然代码还是可以优化的,本次编写为了方便使用全都写到一个py脚本中了。具体检测规则可以根据个人需要进行新增和优化完善,也希望能够在应急分析中有作用,后续代码会慢慢优化更新。

‘rt’, encoding=‘utf-8’) as f:
print(“详细攻击日志:”)
for i in f:
print(i.splitlines())

最后

对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。

同时每个成长路线对应的板块都有配套的视频提供:


当然除了有配套的视频,同时也为大家整理了各种文档和书籍资料&工具,并且已经帮大家分好类了。

因篇幅有限,仅展示部分资料,有需要的小伙伴,可以【扫下方二维码】免费领取:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/359545.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

自带超多工具,好用又免费,这3款手机浏览器你用过了吗

手机浏览器是我们手机中必备的一款软件APP&#xff0c;一款好用的浏览器&#xff0c;可以帮助我们提高工作效率&#xff0c;节省时间。对于懒癌患者来说&#xff0c;手机上安装各种各种的app很麻烦&#xff0c;下面给大家介绍自带超多的工具&#xff0c;好用且免费的浏览器&…

SpringCloud网关Zuul和GateWay区别

getway和zuul没有进行参数调优的时候&#xff0c;getway的性能会远高于zuul。 分析&#xff0c;在空负载的时候&#xff0c;SpringCloud Gateway比zuul 1 性能高50%左右&#xff0c;在模拟处理50ms业务后&#xff0c;&#xff0c;SpringCloud Gateway比zuul 1 性能高9倍左右。 …

嵌入式Qt 开发一个视频播放器

上篇文章&#xff1a;嵌入式 Qt开发一个音乐播放器&#xff0c;使用Qt制作了一个音乐播放器&#xff0c;并在OK3568开发板上进行了运行测试&#xff0c;实际测试效果还不错。 本篇继续来实现一个Qt视频播放器软件&#xff0c;可以实现视频列表的显示与选择播放等&#xff0c;先…

【干货】如何用低代码帮助企业实施OKR?

近年来受疫情的影响&#xff0c;许多企业都开始使用 OKR来进行目标管理。OKR是一套让企业持续保持活力的有效管理工具&#xff0c;能够帮助企业实现目标、激励员工、增加团队凝聚力、减少组织内耗&#xff0c;从而进一步实现创新。但是在实际布局中&#xff0c;很多企业在使用 …

基础面试题 :大端、小端及转换方式

理解网络中大端和小端往往是一道基础面试题 &#xff0c;这里作为记录和整理&#xff0c;希望能帮到大家 目录 前言 一、字节序 二、什么小端顺序 三、什么大端顺序 四、处理器体系所属网络字节顺序 五、大小端转换 1、大端整形转换为小端 2、小端转换为小端 3、…

知乎x-zse-96 参数补环境

本文精工学习参考 目标链接 aHR0cHM6Ly93d3cuemhpaHUuY29tL3NlYXJjaD90eXBlPWNvbnRlbnQmcT1weXRob24接口分析 参数x-zse-93&#xff1a;相当于版本号 参数x-zse-96&#xff1a;看起来需要破解 参数x-zst-81&#xff1a;请求发现可以置空 综上所述x-zse-96才需要逆向。 参数…

中间件安全—Apache常见漏洞

中间件安全—Apache常见漏洞1.Apache常见漏洞1.1.Apache介绍1.2.Apache HTTPD 换行解析漏洞&#xff08;CVE-2017-15715&#xff09;1.2.1.漏洞介绍1.2.2.漏洞环境1.2.2.1.运行漏洞环境1.2.2.2.访问漏洞环境1.2.3.漏洞复现1.2.3.1.拦截1.2.3.2.添加换行1.2.3.3.访问文件1.3.Apa…

[机器学习]卷积神经网络DLC

一、基本结构 CNN的大概模式可以总结为&#xff1a;卷积层池化层全连接层激活函数 而一些比较大型的网络如VGG一般将CNN作为构成单元进行堆叠&#xff0c;而内部卷积核和池化也可以堆叠多个。各个部分的功能如下&#xff1a; 卷积&#xff1a;特征提取 池化&#xff1a;降维和防…

硬件设备 之一 详解 JTAG、SWD 接口、软 / 硬件断点、OpenOCD、J-link

JTAG 和 SWD 在嵌入式开发中可以说是随处可见&#xff0c;他们通常被用来配合 J-Link 、ULINK、ST-LINK 等仿真器在线调试嵌入式程序。此外&#xff0c;还有飞思卡尔芯片中的 Background debug mode&#xff08;BDM&#xff09; 接口&#xff0c;Atmel 芯片中的 debugWIRE &…

文本生成图像应用指南【Stable Diffusion】

Stable Diffusion 是一种文本到图像的潜在扩散模型&#xff0c;由来自 CompVis、Stability AI 和 LAION 的研究人员和工程师创建。 它使用来自 LAION-5B 数据库子集的 512x512 图像进行训练。 稳定扩散&#xff0c;生成人脸&#xff0c;也可以在自己的机器上运行&#xff0c;如…

车载技术开发—{Android CarFrameWork}

Android Automotive平台 Android Automotive是通过Android的通用框架&#xff0c;语言和API来实现的一个全栈&#xff0c;开源&#xff0c;高度可定制的平台。 Android Automotive与整个Android生态系统的关系 Android Automotive是Android的一部分。 Android Automotive不是…

pbootcms被黑木马问题(3)

昨天经过同事告知发现了很早之间做的几个企业官方都中木马了,然后看了一下木马情况,跟之间的两次都有所不同,这里记录一下新的木马的清理过程,有遇到的朋友可以借鉴一下。&#xff08;之前有做过一些防止批量扫站的措施&#xff0c;因为嫌麻烦就没有给这些网站上进行修改&#…

【Spark分布式内存计算框架——Spark SQL】13. 自定义UDF函数

第七章 自定义UDF函数 无论Hive还是SparkSQL分析处理数据时&#xff0c;往往需要使用函数&#xff0c;SparkSQL模块本身自带很多实现公共功能的函数&#xff0c;在org.apache.spark.sql.functions中。SparkSQL与Hive一样支持定义函数&#xff1a;UDF和UDAF&#xff0c;尤其是U…

黑格尔的实践观探究

&#xff08;江苏大学马克思主义学院 212000&#xff09;一、引言人的独特性在于实践活动&#xff0c;以及由实践活动带来的人类社会的不断进化与发展。人类的实践史体现了人的全部本质。但是&#xff0c;人类从理论的高度反思自己的实践活动&#xff0c;尤其是在哲学的层面上进…

【基础算法】之 冒泡排序优化

冒泡排序思想基本思想: 冒泡排序&#xff0c;类似于水中冒泡&#xff0c;较大的数沉下去&#xff0c;较小的数慢慢冒起来&#xff08;假设从小到大&#xff09;&#xff0c;即为较大的数慢慢往后排&#xff0c;较小的数慢慢往前排。直观表达&#xff0c;每一趟遍历&#xff0c;…

大数据框架之Hadoop:MapReduce(三)MapReduce框架原理——shuffle机制

3.3.1Shuffle机制 Map方法之后&#xff0c;Reduce方法之前的数据处理过程称之为Shuffle。 3.3.2Partition分区 1、问题引出 要求将统计结果按照条件输出到不同文件中&#xff08;分区&#xff09;。比如&#xff1a;将统计结果按照手机归属地不同省份输出到不同文件中&#…

2023春季露营投影怎么选?轻薄投影极米Z6X Pro值得推荐

近年来&#xff0c;露营经济在多重因素的共同助推下快速发展&#xff0c;精致露营的攻略开始占据小红书、微博、朋友圈等各类社交平台&#xff0c;吸引着更多用户种草并加入到露营大军中&#xff0c;而露营经济的强势“破圈”给家用智能投影带来了更多的发展契机。凭借着小巧的…

探访上汽通用武汉奥特能超级工厂

上汽通用汽车在电动化和智能网联化新技术领域投入了700亿大洋&#xff0c;武汉奥特能超级工厂就是其中一个重点项目。这个工厂已经投产&#xff0c;将成为上汽通用汽车的新能源生产基地&#xff0c;加速奥特能平台车型的推出。 最近别克推出了Electra E5&#xff0c;它是别克第…

新品BCM6755A1KFEBG/MT7921LE/MT7921AU WiFi芯片

博通在WiFi市场具有相当的实力。在WiFi6上有下面这几个解决方案&#xff1a;型号&#xff1a;BCM6755 BCM6755A1KFEBG类型&#xff1a;四核1.5GHz CPU封装&#xff1a;BGA批次&#xff1a;新BCM6755和BCM6750还是A7架构&#xff0c;更多的用在中低端型号上。BCM6755和BCM6750 C…

Spark 广播变量累加器

广播变量 场景描述&#xff1a;一份数据存在Driver中&#xff0c;但是每个Executor都需要一份。 常规模式下&#xff0c;Driver会给每个分区都发送一份数据。如果在Executor中存在多个分区的情况&#xff0c;那么一个Executor会获得多份数据。 Executor是进程&#xff0c;task…