- 脚本通过正则和文件读写操作,统计linux安全日志文件中记录的登录失败的ip,登录失败次数,试图登录使用过的用户名和登录操作的时间,并生成了excel表格
安全日志
- 分析脚本利用了/var/log/secure文件,它一般用来记录安全相关的信息,记录最多的是哪些用户登录服务器的相关日志
Dec 27 14:04:51 139 sshd[30956]: Disconnecting: Too many authentication failures [preauth]
Dec 27 14:04:53 139 sshd[30968]: Invalid user user from 193.201.224.12 port 26133
Dec 27 14:04:53 139 sshd[30968]: input_userauth_request: invalid user user [preauth]
Dec 27 14:05:01 139 sshd[30968]: Disconnecting: Change of username or service not allowed: (user,ssh-connection) -> (User,ssh-connection) [preauth]
Dec 27 14:05:03 139 sshd[30996]: Invalid user User from 193.201.224.12 port 43273
Jan 17 12:27:36 139 sshd[12812]: pam_unix(sshd:session): session closed for user root
# 表示root用户关闭了会话(也就是关闭了终端)
Jan 17 12:28:59 139 sshd[14064]: Accepted publickey for root from 14.23.168.10 port 36637 ssh2
# 表示接受来自14.23.168.10的root用户的公钥登录
Jan 17 12:28:59 139 sshd[14064]: pam_unix(sshd:session): session opened for user root by (uid=0)
# 表示给root用户打开一个终端
Jan 17 14:41:10 Mir2_Center sshd[9913]: Received disconnect from 183.60.122.237: 11: disconnected by user
# 表示已经连着的终端主动断开连接,并关闭终端
Jan 17 14:39:48 139 sshd[31261]: Invalid user redis from 45.115.45.3 port 33274
# 表示对端使用无效的用户redis来连接
Jan 17 14:39:48 139 sshd[31261]: input_userauth_request: invalid user redis [preauth]
# 本机对redis用户进行认证,认证失败,发送错误信号给对端
Jan 17 14:39:48 139 sshd[31261]: Received disconnect from 45.115.45.3 port 33274:11: Bye Bye [preauth]
# 对端接收到错误信号主动断开连接
Jan 17 14:39:48 139 sshd[31261]: Disconnected from 45.115.45.3 port 33274 [preauth]
# 连接关闭
xlwt库
import xlwt
# 1.创建 Workbook
wb = xlwt.Workbook()
# 2.创建 worksheet
ws = wb.add_sheet('test_sheet')
# 3.写入第一行内容 ws.write(a, b, c) a:行,b:列,c:内容
ws.write(0, 0, '球队')
ws.write(0, 1, '号码')
ws.write(0, 2, '姓名')
ws.write(0, 3, '位置')
# 保存文件
wb.save('./myExcel.xls')
pandas库
- 这里只用来pandas库的统计功能,temp是数组,按以下操作处理后可以实现数组元素排序,并统计出现次数,次数与元素内容用*间隔
result=pd.value_counts(temp)
result.to_csv('ip.txt', sep='*')
#得到
x.x.x.x*671 x.x.x.x出现671次
z.z.z.z*633 z.z.z.z出现633次
数组去重
num = [1,2,1,4,5]
print(list(set(num)))
#得到
[1, 2, 4, 5]
脚本
- 只需将linux的/var/log/secure文件cv一份命名为original放在脚本同目录下,即可在脚本目录下得到result.xlsx.小白练手,写的很丑🥺
import re
import pandas as pd
import time
import os
import numpy as np
import xlrd
import xlwt
def find1(pattern,input_string):
pattern = pattern
input_string=input_string
match = re.search(pattern, input_string, re.DOTALL)
if match:
return match.groups()
else:
return None
def find(pattern,input_string):
pattern = pattern
input_string=input_string
match = re.search(pattern, input_string, re.DOTALL)
if match:
return match.group(1)
else:
return None
def findall(pattern,input_string):
pattern = pattern
matches = re.findall(pattern, input_string,re.MULTILINE)
return matches
def is_line_without_english(line):
# 使用正则表达式匹配字母
pattern = r'[a-zA-Z]'
match = re.search(pattern, line)
# 如果没有匹配到字母,则表示该行没有英文
if match:
return False
else:
return True
def has_substring(string, substring):
if string.find(substring) != -1:
return True
else:
return False
def get_first_word(string):
words = string.split(" ")
if len(words) > 0:
return words[0]
else:
return ""
if(os.path.exists('result.xls')):
print("存在同名文件占用,请手动删除同目录下的result.xls后重启程序")
time.sleep(10000)
print("程序在5秒后将会启动,请确保original(分析文件)与程序在同一目录下")
time.sleep(5)
print("正在统计访问ip")
original = open("original")
original_txt = original.read()
temp=findall(r'rhost=([\d.]+)',original_txt)
original.close()
result=pd.value_counts(temp)
result.to_csv('ip.txt', sep='*')
original = open("original")
original_txt = original.read()
temp=findall(r'Failed password for invalid user (.*?) port',original_txt)
original.close()
user=pd.value_counts(temp)
user.to_csv('user.txt', sep='\t')
print("正在统计访问用户")
ip = open("ip.txt")
ip_txt = ip.readlines()
user = open("user.txt")
user_txt = user.readlines()
u=1
i=1
with open('result.txt', 'w') as f:
for iline in ip_txt:
#print(iline)
if(i==1):
i=i+1
continue
i=i+1
#print(uline)
iip=find1(r'(?<![\.\d])(([1-9]?\d|1\d\d|2[0-4]\d|25[0-5])\.){3}([1-9]?\d|1\d\d|2[0-4]\d|25[0-5])(?![\.\d])',iline)
#print(uline)
upan=0
for uline in user_txt:
if(u==1):
u=u+1
continue
u=u+1
uip=find1(r'(?<![\.\d])(([1-9]?\d|1\d\d|2[0-4]\d|25[0-5])\.){3}([1-9]?\d|1\d\d|2[0-4]\d|25[0-5])(?![\.\d])',uline)
if(uip==iip):
if(has_substring(iline,get_first_word(uline.replace("\n",'')).replace("\n",''))==False):
if(upan==0):
iline=iline.replace("\n",'')+"*"+get_first_word(uline.replace("\n",'')).replace("\n",'')+"\n"
upan=upan+1
else:
iline=iline.replace("\n",'')+","+get_first_word(uline.replace("\n",'')).replace("\n",'')+"\n"
upan=upan+1
if(upan==0):
iline=iline.replace("\n",'')+" *"+"\n"
print(iline)
f.write(iline)
f.close()
print("正在统计访问时间")
original = open("original")
original_txt = original.readlines()
with open('time.txt', 'w') as f:
for line in original_txt:
if(has_substring(line,"Failed password")):
ip_temp=find(r'from (.*?) port ',line)
time_temp=re.search(r"^(\S+)\s(\d+)\s(\d+):(\d+):(\d+)", line, re.DOTALL).group(1)+" "+re.search(r"^(\S+)\s(\d+)\s(\d+):(\d+):(\d+)", line, re.DOTALL).group(2)+" "+re.search(r"^(\S+)\s(\d+)\s(\d+):(\d+):(\d+)", line, re.DOTALL).group(3)+":"+re.search(r"^(\S+)\s(\d+)\s(\d+):(\d+):(\d+)", line, re.DOTALL).group(4)+":"+re.search(r"^(\S+)\s(\d+)\s(\d+):(\d+):(\d+)", line, re.DOTALL).group(5)
#print(time_temp)
f.write(ip_temp+"@"+time_temp+"\n")
f.close()
print("正在汇总")
result = open("result.txt")
result_txt = result.readlines()
time1 = open("time.txt")
time_txt = time1.readlines()
with open('result.txt', 'w') as f:
f.write("警告:请勿以记事本打开文本,否则可能出现格式混乱等情况!\n")
for rline in result_txt:
rip=find1(r'(?<![\.\d])(([1-9]?\d|1\d\d|2[0-4]\d|25[0-5])\.){3}([1-9]?\d|1\d\d|2[0-4]\d|25[0-5])(?![\.\d])',rline)
tpan=0
for tline in time_txt:
tip=find1(r'(?<![\.\d])(([1-9]?\d|1\d\d|2[0-4]\d|25[0-5])\.){3}([1-9]?\d|1\d\d|2[0-4]\d|25[0-5])(?![\.\d])',tline)
if(rip==tip):
time_temp=re.search(r"@(\S+)\s(\d+)\s(\d+):(\d+):(\d+)", tline, re.DOTALL).group(1)+" "+re.search(r"@(\S+)\s(\d+)\s(\d+):(\d+):(\d+)", tline, re.DOTALL).group(2)+" "+re.search(r"@(\S+)\s(\d+)\s(\d+):(\d+):(\d+)", tline, re.DOTALL).group(3)+":"+re.search(r"@(\S+)\s(\d+)\s(\d+):(\d+):(\d+)", tline, re.DOTALL).group(4)+":"+re.search(r"@(\S+)\s(\d+)\s(\d+):(\d+):(\d+)", tline, re.DOTALL).group(5)
if(has_substring(rline,time_temp)==False):
#print(time_temp)
if(tpan==0):
rline=rline.replace("\n",'')+"*"+time_temp+"\n"
tpan=tpan+1
else:
rline=rline.replace("\n",'')+","+time_temp+"\n"
f.write(rline)
f.close()
print("正在生成excel")
wb = xlwt.Workbook(encoding = 'utf-8') #新建一个excel文件
ws1 = wb.add_sheet('first') #添加一个新表,名字为first
result=open("result.txt")
result_txt=result.readlines()
hang=0
for line in result_txt:
array = line.split('*')
lie=0
for i in range(len(array)):
if(hang==0):
ws1.write(0,0,"访问IP")
ws1.write(0,1,"登录次数")
ws1.write(0,2,"登录用户")
ws1.write(0,3,"登录时间")
continue
ws1.write(hang, lie ,array[i])
lie=lie+1
hang=hang+1
#ws1.write(0,0,"访问IP")
#ws1.write(0,1,"登录次数")
#ws1.write(0,2,"登录用户")
#ws1.write(0,3,"登录时间")
wb.save("result.xls")
try:
os.remove('time.txt')
os.remove('result.txt')
os.remove('user.txt')
os.remove('ip.txt')
except:
print("临时文件:ip.txt,user.txt,time.txt或result.txt无法删除,请手动删除")
print("完成!结果见本目录下result.xlsx")
time.sleep(10000)