Python调用Graylog APi 分析401错误登录日志
ret_lst处理完成后是一个list,内容如下:
[{'c_ip': '10.10.202.139', 'uname': 'ee'}, {'c_ip': '10.10.202.139', 'uname': 'tt'}, {'c_ip': '192.168.195.131', 'uname': 'ee'}, {'c_ip': '192.168.195.131', 'uname': 'aa'}, {'c_ip': '192.168.195.131', 'uname': 'bb'}, {'c_ip': '10.10.202.139', 'uname': 'liuyana'}, {'c_ip': '192.168.195.131', 'uname': 'bb'}, {'c_ip': '192.168.195.131', 'uname': 'eee'}, {'c_ip': '192.168.195.131', 'uname': 'bb'}, {'c_ip': '192.168.195.131', 'uname': 'cc'}, {'c_ip': '192.168.195.131', 'uname': 'ee'}, {'c_ip': '192.168.195.131', 'uname': 'ee'}, {'c_ip': '10.10.202.139', 'uname': 'tt'}, {'c_ip': '192.168.195.131', 'uname': 'aa'}, {'c_ip': '192.168.195.131', 'uname': 'eee'}, {'c_ip': '192.168.195.131', 'uname': 'aa'}, {'c_ip': '10.10.202.139', 'uname': 'lb'}, {'c_ip': '192.168.195.131', 'uname': 'ee'}, {'c_ip': '10.10.202.139', 'uname': 'lc'}, {'c_ip': '10.10.202.139', 'uname': 'la'}, {'c_ip': '10.10.202.139', 'uname': 'l'}, {'c_ip': '10.10.202.139', 'uname': 'la'}]
pip3 install grapi
import copy from operator import itemgetter #itemgetter用来去dict中的key,省去了使用lambda函数 from itertools import groupby #itertool还包含有其他很多函数,比如将多个list联合起来。。 from grapi.grapi import Grapi token = 'tokenstring' url = 'http://10.1.21.7:9000/api/search/universal/keyword' my_params = { 'filter':'streams:662f338c147dc13b477e9beb', "query": 'cs_status:401 AND (NOT uname:"-")', # Required "fields": 'c_ip,uname', # Required # "from": "<YYYY-MM-DD HH-MM-SS>", # Required # "to": "<YYYY-MM-DD HH-MM-SS>", # Required "keyword":"last 1 hours", "limit": 150 # Optional: Default limit is 150 in Graylog } my_api = Grapi(url, token) response = my_api.send("get", **my_params) if response.status_code == 200: res_lst = [] res_line = {} for line in response.iter_lines(): res_line0 = {} line_s = line.decode('utf8').replace('"','').split(',') res_line0['c_ip'] = line_s[1] res_line0['uname'] = line_s[2] res_lst.append(res_line0) res_lst = res_lst[1:] #第一行为字典名称,删除 print(res_lst) #先按客户端IP进行分组,然后再统计每个IP破解的账户名称 ip_times_attacked = 0 #定义单个IP发生401的最少错误次数,超过该次数才会告警 uname_count_attacked = 0 #定义单个IP上尝试登录失败的最少账号数量,超过该数量才会告警 for key,group_cip in groupby(sorted(res_lst,key=itemgetter('c_ip')),itemgetter('c_ip')): lgroup_cip = list(group_cip) if len(lgroup_cip) > ip_times_attacked: group_uname = groupby(sorted(lgroup_cip,key=itemgetter('uname')),itemgetter('uname')) lsgroup_uname2 = list(copy.deepcopy(group_uname)) print(f'客户端IP:{key} ,尝试登录失败的账户数量为: {len(lsgroup_uname2)}') if len(lsgroup_uname2) > uname_count_attacked: for key1,group_uname1 in group_uname: lguname1 = list(group_uname1) print(f'客户端IP:{key} ,账户 {key1} 尝试登录失败次数为: {len(lguname1)}') else: print(response.status_code,response.reason)