1.背景
由于某些原因未成功申请到企业邮箱的smtp,pop3的SSL证书协议,导致QQ、163邮箱无法通过SSL通信协议进行互相收发邮件
近日企业内部用户经常反馈收到垃圾邮件、邮件发不出去,尴尬了。
一查服务器日志,发现大量的攻击行为。。。。
2019/12/04-11:42:41 6856 Connect from 185.234.219.81
2019/12/04-11:42:41 6856 remote ehlo = XXXXX.com
2019/12/04-11:42:41 6856 max msg size = 0
2019/12/04-11:42:43 6856 smtp authenticate fail! Username = jackie@XXXXXcom
以上是典型的账户验证操作,大量的账户会话错误,占用端口对服务器资源造成非常大的浪费,影响正常业务的展开。
2.企业邮箱
服务程序升级可以解决这样的漏洞,但需要支付费用,在没有预算的条件下,只有自己动手 了。
经过文件的对比确认,最终确定service.cfg文件可以将攻击ip添加至黑名单。
但是每天去查日志,手工添加,我表示太累了。。人生苦短,我用Python,来吧兄弟,上代码:
半天的时间就调试完成了。上代码:
-----------------------------------------------------
import re
import time
import datetime
count = 0 # 初始的文件指针设置为0
def readlog(logfiles, **kwargs):
final_black_list = [] # 超过一定错误日志数量的问题ip最终转化为黑名单
for per in logfiles:
count = 0
with open(per, mode="r") as fr: ##, encoding="utf-8"
log_list = [] # 每次循环时把列表清空,因为是按1分钟进行统计的
bad_iplist = [] # 有问题的ip地址
connect_ip_list = []
fr.seek(count) # 根据文件指针进行文件内容读取
for line in fr: # 循环拿每一行内容
log_list.append(line.split("\n")[0]) # 取每一行的数据
if line.find("Connect from") > 0:
connect_ip_list.append(line.split("\n")[0])
else:
pass
count = fr.tell() # 读完之后更新文件的指针
for row in range(1, len(log_list), 1): # 循环读取集合中的错误行内容,匹配smtp authenticate fail,返回回话id,
try:
thist_line = str(log_list[row])
get_auth_sessionid = re.findall('[ ]+(.+?)[ ]+smtp authenticate fail', thist_line) # 识别黑客猜smtp密码
get_guessacc_sessionid = re.findall('[ ]+(.+?)[ ]+mailbox not found', thist_line) # 识别黑客猜邮箱账户名称
get_ddos_sessionid = re.findall('[ ]+(.+?)[ ]+This IP frequency too high', thist_line) # 识别DDos攻击
# 应对办法只有添加至防火墙黑名单列表,本程序不做开发
get_command_sessionid = re.findall('[ ]+(.+?)[ ]+unrecognized command', thist_line) # 识别黑客尝试协议注入
get_guesspsw_sessionid = re.findall('[ ]+(.+?)[ ]+password error', thist_line) # 识别猜指定存在账户密码
totalsessionidlist = get_auth_sessionid+get_guessacc_sessionid+get_ddos_sessionid+get_command_sessionid+get_guesspsw_sessionid
totalsessionid = ""
totalsessionid = "".join(totalsessionidlist)
#print(totalsessionid)
if len(totalsessionid) != 0:
Regexstr = r'%s+[ Connect from ]+(.+?)ASA'%(totalsessionid)
allconnect_ip_list = "ASA".join(connect_ip_list)
ip = re.findall(Regexstr, allconnect_ip_list, re.S)
# 2019/11/26-00:03:32 14404 Connect from 78.128.113.123
bad_iplist.append(ip[0])
else:
pass
except IndexError as e:
continue
for eachip in bad_iplist: # 统计当日badip出现次数
if bad_iplist.count(eachip) > 10:
final_black_list.append(eachip)
# print("把ip为%s的加入到黑名单" % eachip)
else:
pass
fr.close() # 最后关闭文件句柄
return list(set(final_black_list))
def write_cfg(bad_iplist, cfgfile):
alllines = []
f = open(cfgfile, mode="r")
alllines = f.readlines()
newtxt = ""
for i in range(0, len(alllines), 1):
newtxt = newtxt + alllines[i]
f.close()
accessip_lines = []
exist_bad_iplist = []
for row in range(0, len(alllines), 1):
thislinestr = ""
thislinestr = alllines[row]
if thislinestr.find("accessip") > 0:
accessip_lines.append(row)
ip = re.findall(r'(?<![\.\d])(?:\d{1,3}\.){3}\d{1,3}(?![\.\d])', str(newtxt), re.S)
exist_bad_iplist = exist_bad_iplist + ip
else:
pass
addlist = set(exist_bad_iplist + bad_iplist)
write_str = "<accessip>" + ";".join(addlist) + "</accessip>"
open(cfgfile, mode='w').write(re.sub(r'<accessip>(.+?)</accessip>', write_str, str(newtxt)))
return "完成一次刷新策略!"
def weekly_clear_config(cfgfile):
f = open(cfgfile, mode="r")
alllines = f.readlines()
newtxt = ""
for i in range(0, len(alllines), 1):
newtxt = newtxt + alllines[i]
f.close()
write_str = "<accessip>255.255.255.255</accessip>"
write_str2 = "<control>1</control>"
open(cfgfile, mode='w').write(re.sub(r'<accessip>(.+?)</accessip>', write_str, str(newtxt)))
open(cfgfile, mode='w').write(re.sub(r'<control>(.+?)</control>', write_str2, str(newtxt)))
if __name__ == '__main__':
logfiles = ["smtp.log","smtpssl.log","pop3.log","pop3ssl.log"]
cfgfile = 'C:\\CProgram Files XXXXXXailserver\\service.cfg'
while True:
today = datetime.date.today()
weekday = today.isoweekday()
nowtime = time.strftime('%H:%M', time.localtime(time.time()))
if weekday ==1 and (nowtime=="08:01" or nowtime=="08:02" or nowtime=="08:03" or nowtime=="08:04"):
#每周指定时间段将规则清空!苦海无边,回头是岸!~~
weekly_clear_config(cfgfile)
else:
final_black_list = readlog(logfiles)
print("今日最新黑名单列表" + str(set(final_black_list)))
status = write_cfg(final_black_list, cfgfile)
time.sleep(10)
continue
-------------------------------------------------------
3.结语
仅100来行代码实现了4个文件的循环读取,识别5种黑客攻击的痕迹,并将尝试次数超过10次的问题IP记录至service.cfg文件中对应位置。至此完成了企业邮箱自动识别攻击行为并将阻止问题ip的访问。为了防止Ip的数量越来越大(互联网的黑客太多了),给一个窗口清空设置,还用户一个改过自新的机会。呵呵~~~
以上代码实战测试过,有相同问题的网友可以评论回复哟。
对了,邮件服务器上没有python,可以直接打包exe运行。
pyinstaller.exe -F C:\Users\Administrator\PycharmProjects\untitled3\AThack-mail\readlog_at_hack.py
........................................
13849 INFO: Building EXE because EXE-00.toc is non existent
13849 INFO: Building EXE from EXE-00.toc
13849 INFO: Appending archive to EXE C:\Users\Administrator\PycharmProjects\untitled3\dist\readlog_at_hack.exe
13875 INFO: Building EXE from EXE-00.toc completed successfully.
至此程序已经生成,我们把程序移动到服务器运行。。下面是执行效果