打造一款日志分析工具
一、简介
作为一名安全从业者,网络安全事件的应急响应工作是必不可少的,那么在应急支撑时,针对大量的日志数据便需要借助自动化工具实现快速的归类检测,并提取出所需的关键日志数据。本篇文章主要通过利用python语言编写一款web日志的分析工具。
代码地址:https://github.com/get0shell/ALogFry
工具运行效果:
python3 ALogFry.py

二、设计模式
该web日志分析工具的整个流程包括以下环节:

检测文件: 用来检测是否有日志文件,以及输出文件是否存在
数据提取: 用来提取日志数据中的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的数据体,可以针对所在的列表位数进行获取,本次工具中不再赘述。

具体代码如下:
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.pyimport re
import osxss = "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 += 1if 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())
最后
对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。

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


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

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

相关文章:
打造一款日志分析工具
一、简介 作为一名安全从业者,网络安全事件的应急响应工作是必不可少的,那么在应急支撑时,针对大量的日志数据便需要借助自动化工具实现快速的归类检测,并提取出所需的关键日志数据。本篇文章主要通过利用python语言编写一款web日…...
网络编程基础知识
套接字类型:1.字节流套接字(stream) 2.数据报接套接字(datagram) 3.原始套接字(raw) 端口:1.周知端口: 0~1023 2.注册端口: 1024~49151 3.动态端口: 49152~65535 OSI七层协议结构应用层表示层会话层...
2023北京老博会(CBIAIE全国老年产业必参盛会)
CBIAIE北京老博会|把握政策导向,迎合市场需求,引导销售渠道建设,搭建国际化的商业平台; 2023第十届中国(北京)国际老年产业博览会(CBIAIE北京老博会) The 2023 tenth China (Beijin…...
【字典转模型 Objective-C语言】
一、点按钮,弹出的这个效果,这实际上是个Label, 这实际上是一个Label,点按钮弹出的这个效果, 设置一个Label的背景色、前景色、透明度、等等, 让它加进来,然后通过动画让它隐藏掉, 这就是,这个效果的实现思路, 咱们这个效果,先稍微往后放一放, 这个并不是重点…...
【LeetCode】剑指 Offer(6)
目录 写在前面: 题目:剑指 Offer 12. 矩阵中的路径 - 力扣(Leetcode) 题目的接口: 解题思路: 代码: 过啦!!! 写在最后: 写在前面ÿ…...
论文投稿指南——中文核心期刊推荐(法律)
【前言】 🚀 想发论文怎么办?手把手教你论文如何投稿!那么,首先要搞懂投稿目标——论文期刊 🎄 在期刊论文的分布中,存在一种普遍现象:即对于某一特定的学科或专业来说,少数期刊所含…...
Qt音视频开发15-动态切换解码内核的设计
一、前言 动态切换解码内核这个需求也是源自客户的真实需求,既然是动态切换,那肯定是运行期间切换,而不是通过改变标志位重新编译程序来切换,最开始做的就是这种方式,这样就是实现起来简单,但是用起来不够…...
concurrent-map 和 sync.Map,我该选择哪个?
官方的map并不是线程安全的,如果我们在多线程中并发对一个map进行读写操作,是会引发panic的。解决方案除了使用锁来对map进行保护外,还有两种方式:一,开源项目 concurrent-map 提供了可以用来做并发安全的map二&#x…...
华为OD机试 - 最少数量线段覆盖| 机试题算法思路 【2023】
最近更新的博客 华为OD机试 - 简易压缩算法(Python) | 机试题算法思路 【2023】 华为OD机试题 - 获取最大软件版本号(JavaScript) 华为OD机试 - 猜字谜(Python) | 机试题+算法思路 【2023】 华为OD机试 - 删除指定目录(Python) | 机试题算法思路 【2023】 华为OD机试 …...
【蓝桥集训】第五天——递推
作者:指针不指南吗 专栏:Acwing 蓝桥集训每日一题 🐾或许会很慢,但是不可以停下来🐾 文章目录1.砖块递推算法是一种简单的算法,通过已知条件,利用特定关系得出中间推论,逐步递推&…...
qnx的网络知识记录
1、网络驱动加载http://www.qnx.com/developers/docs/7.1/index.html#com.qnx.doc.core_networking/topic/drivers_Loading.html使用mount挂载io-pkt模块mount -Tio-pkt /lib/dll/devnp-e1000.sonicinfo 命令可以查看网卡的各种状态,包括phy的状态2、iopktiopkt的介…...
【Vue/基础知识】Vue基础知识(一)
如果觉得我的分享有一定帮助,欢迎关注我的微信公众号 “码农的科研笔记”,了解更多我的算法和代码学习总结记录。或者点击链接扫码关注 【Vue/基础知识】Vue基础知识(一) 1、v-show 和 v-if 指令的共同点和不同点? 共…...
Iceberg实战踩坑指南
第 1 章 介绍 Apache Iceberg 是一种用于大型分析数据集的开放表格,Iceberge 向 Trino 和 Spark 添加了使用高性能格式的表,就像 Sql 表一样。 Iceberg 为了避免出现不变要的一些意外,表结构和组织并不会实际删除,用户也不需要特…...
预告|2月25日 第四届OpenI/O 启智开发者大会昇腾人工智能应用专场邀您共启数字未来!
如今,人工智能早已脱离科幻小说中的虚构想象,成为可触及的现实,并渗透到我们的生活。随着人工智能的发展,我们正在迎来一个全新的时代——数智化时代。数据、信息和知识是这个时代的核心资源,而人工智能则是这些资源的…...
UnRaid虚拟机安装OpenWrt软路由
文章目录0、前言1、Openwrt虚拟机安装1.1、前提,需要先在UnRaid中开启虚拟机:1.2、下载OpenWrt虚拟机镜像并上传至UnRaid共享文件夹1.3、创建OpenWrt虚拟机2、开启并设置OpenWrt虚拟机2.1、修改OpenWrt管理ip2.2、OpenWrt的上网设置0、前言 最近折腾了很…...
开发日记-lombok
开发日记-lombok环境问题解决方案:1 Data注解失效 无法正常生成 get和set方法2 RequiredArgsConstructor(onConstructor _(Lazy)) 符号_无法识别环境 idea2020.1lombok1.18.24jdk1.8 问题 Data注解失效 无法正常生成 get和set方法RequiredArgsConstructor(onCons…...
Web3中文|2023年zk赛道爆发,即将推出的Polygon zkEVM有多重要?
2月15日,以太坊第2层解决方案提供商Polygon终于公布了备受期待的扩展更新,其零知识以太坊虚拟机(zkEVM)主网的测试版定于3月27日发布。 据官方消息报道,自去年10月上线测试网以来,已取得许多重要的里程碑&…...
【自然语言处理】主题建模:Top2Vec(理论篇)
主题建模:Top2Vec(理论篇)Top2Vec 是一种用于 主题建模 和 语义搜索 的算法。它自动检测文本中出现的主题,并生成联合嵌入的主题、文档和词向量。 算法基于的假设:许多语义相似的文档都可以由一个潜在的主题表示。首先…...
【ICLR 2022】重新思考点云中的网络设计和局部几何:一个简单的残差MLP框架
文章目录RETHINKING NETWORK DESIGN AND LOCAL GEOMETRY IN POINT CLOUD: A SIMPLE RESIDUAL MLP FRAMEWORKPointMLP残差点模块几何仿射模块精简版模型:PointMLP-elite实验结果消融实验RETHINKING NETWORK DESIGN AND LOCAL GEOMETRY IN POINT CLOUD: A SIMPLE RESI…...
《MySQL学习》 count(*) 原理
一 . count(*)的实现方式 MyISAM 引擎把一个表的总行数存在了磁盘上,因此执行 count() 的时候会直接返回这个数,效率很高; 而 InnoDB 引擎就麻烦了,它执行 count(*) 的时候,需要把数据一行一行…...
CloudFlare R2的S3兼容性有多香?一个PicGo插件搞定七牛云、阿里云OSS无缝迁移
CloudFlare R2的S3兼容性实战:用PicGo实现多平台图床无缝迁移 当七牛云突然调整存储计费策略时,我服务器上3000多张技术文档配图每月产生了近200元的额外成本。而迁移到阿里云OSS后,又遇到了国内备案的繁琐流程。直到发现CloudFlare R2的S3兼…...
2026届最火的AI辅助写作平台解析与推荐
Ai论文网站排名(开题报告、文献综述、降aigc率、降重综合对比) TOP1. 千笔AI TOP2. aipasspaper TOP3. 清北论文 TOP4. 豆包 TOP5. kimi TOP6. deepseek 一种基于自然语言处理以及深度学习模型的论文一键生成技术,其中,该技…...
DETR训练避坑大全:Windows10+PyCharm环境下的5个常见报错解决方案
DETR实战指南:Windows 10环境下的5大典型问题深度解析与解决方案 在目标检测领域,DETR(Detection Transformer)作为首个完全基于Transformer架构的端到端检测系统,正在改变传统计算机视觉任务的实现方式。不同于Faste…...
MFC界面现代化---自定义标题栏与控件美化实战
1. 为什么需要MFC界面现代化改造 很多老牌企业软件和工业控制系统都基于MFC框架开发,这些系统通常运行了十几年甚至更久。我接手过不少这类项目,最直观的感受就是界面实在太"复古"了——灰底蓝框的窗口、生硬的按钮、像素感明显的图标…...
C++高性能网络库ZLToolKit资源池源码解析:如何用智能指针实现对象复用与自动回收
C高性能网络库ZLToolKit资源池源码解析:智能指针实现对象复用与自动回收 在C高性能服务器开发中,频繁的对象创建与销毁往往是性能瓶颈之一。想象一下这样的场景:一个直播服务器每秒需要处理数万条消息,每条消息都需要临时创建对象…...
用PyTorch从零复现SiamFC:手把手教你搭建自己的单目标跟踪器(附完整代码)
用PyTorch从零复现SiamFC:手把手教你搭建自己的单目标跟踪器(附完整代码) 单目标跟踪是计算机视觉领域的经典问题之一,它的核心任务是在视频序列中持续定位特定目标的位置。想象一下这样的场景:你正在开发一个智能监控…...
实战演练:基于快马平台codex构建可一键部署的智能api接口生成器
今天想和大家分享一个特别实用的开发技巧——如何用AI快速生成可用的API接口代码。这个项目我是在InsCode(快马)平台上完成的,整个过程非常顺畅,尤其是最后的一键部署功能,让我省去了很多配置环境的麻烦。 项目背景与需求 最近在做一个内部…...
5步轻松打造随身游戏库:Playnite便携版终极配置指南
5步轻松打造随身游戏库:Playnite便携版终极配置指南 【免费下载链接】Playnite Video game library manager with support for wide range of 3rd party libraries and game emulation support, providing one unified interface for your games. 项目地址: https…...
【AI智能体】Dify 实战:构建企业级自然语言SQL查询引擎
1. 从个人工具到企业级解决方案的跨越 第一次接触Dify的自然语言转SQL功能时,我被它的便捷性惊艳到了。只需要输入"显示上季度销售额最高的产品",系统就能自动生成正确的SQL语句。但当我尝试在团队中推广使用时,各种问题接踵而至&a…...
4大技术引擎破解魔兽争霸3现代适配难题
4大技术引擎破解魔兽争霸3现代适配难题 【免费下载链接】WarcraftHelper Warcraft III Helper , support 1.20e, 1.24e, 1.26a, 1.27a, 1.27b 项目地址: https://gitcode.com/gh_mirrors/wa/WarcraftHelper 当经典RTS游戏遇上现代硬件环境,总会面临兼容性的严…...
