hfish告警脚本
由于原告警是excel文件不方便阅读,故写了个比较直观的脚本,并且当时环境是部署在gcp上的,故联动gcp接口调用防火墙黑名单 需要调用到基础接口脚本里的数据库读写和google.cloud库
from requests.packages import urllib3
import time,re,json,logging
from google.cloud import compute _v1
from google. oauth2 import service_account
from BasicInterfaces import executeMysqlData
from datetime import datetime,timedelta
def listFirewallRule(credentials,projectId):
client = compute _v1.FirewallsClient(credentials= credentials)
firewallRuleList = client.list(project=projectId)
query = "blocklist"
dataJson = {}
ipList = []
for firewallName in firewallRuleList:
if query in firewallName.name:
dataJson[firewallName.name] = len(firewallName.source_ranges)
ipList. extend(firewallName.source_ranges)
return dataJson,ipList
def addSourceIPToFirewallRule(credentials,projectId, firewallRuleName,ipaddressForAdd):
client = compute_v1.FirewallsClient(credentials=credentials)
firewall = client.get(project=projectId, firewall=firewallRuleName)
firewall.source_ranges.append(ipaddressForAdd)
try:
operation = client.update(project=projectId, firewall=firewallRuleName,firewall_resource=firewall)
operation.result()
except Exception as e:
return str(e).split()[-1]
def removeSourceIPToFirewallRule(credentials,projectId, firewallRuleName,ipaddressForAdd):
client = compute _v1.FirewallsClient(credentials= credentials)
firewall = client.get(project=projectId, firewall=firewallRuleName)
firewall.source_ranges.remove(ipaddressForAdd)
operation = client.update(project=projectId, firewall=firewallRuleName, firewall_resource= firewall)
operation.result()
def newFirewallPolicy(credentials,projectId, firewallRuleName):
client = compute_v1.FirewallsClient(credentials= credentials)
firewall = {
"denied": [{"I_p_protocol": "all"}],
"direction": "INGRESS",
"name": firewallRuleName,
"network": "global/networks/ default",
"priority": 999,
"source_ranges": ["224.1.1.132/32"]
}
try:
client.insert(project=projectId, firewall_resource = firewall)
return True
except Exception as e:
return (str(e).split()[-2] + " " + str(e).split()[-1])
def isPublicIpv4(ip):
pattern = r'^(?:(?:(?:[1-9]?\d|1\d\d|2[θ-4]\d|25[θ-5])\.){3}(?:[1-9]?\d|1\d\d|2[θ-4]\d|25[θ-5]))$'
private_pattern = r'^(?:(?:10|127)\.\d{1,3}\.\d{1,3}\.\d{1,3}|(?:172\.(?:1[6-9]|2\d|3[01]))\.\d{1,3}\.\d{1,3}|192\.168\.\d{1,3}\
return re.match(pattern, ip) is not None and re.match(private_pattern,ip) is None
def makeMaiLContext(data):
table _ html = """
<table style="border-collapse: collapse;">
<tr bgcolor="aqua">
<th style=" border: 1px solid black; padding: 8px;">扫描类型</th>
<th style=" border: 1px solid black; padding: 8px;">来源IP</th>
<th style=" border: 1px solid black; padding: 8px;">来源MAC</th>
<th style=" border: 1px solid black; padding: 8px;">来源区域</th>
<th style=" border: 1px solid black; padding: 8px;">目标IP</th>
<th style=" border: 1px solid black; padding: 8px;">目标端口</th>
<th style=" border: 1px solid black; padding: 8px;">扫描次数</th>
<th style=" border: 1px solid black; padding: 8px;">开始时间</th>
<th style=" border: 1px solid black; padding: 8px;">持续时间</th>
<th style=" border: 1px solid black; padding: 8px;">攻击详情</th>
</tr>
"""
ports = ",".join(filter(None, data[3].split(",")))
table _ html += f"""
<tr>
<td style=" border: 1px solid black; padding: 8px;">{data[6]}</td>
<td style=" border: 1px solid black; padding: 8px;">{data[θ]}</td>
<td style=" border: 1px solid black; padding: 8px;">{data[8]}</td>
<td style=" border: 1px solid black; padding: 8px;">{data[1]}</td>
<td style=" border: 1px solid black; padding: 8px;">{data[2]}</td>
<td style=" border: 1px solid black; padding: 8px;">{ports}</td>
<td style=" border: 1px solid black; padding: 8px;">{data[4]}</td>
<td style=" border: 1px solid black; padding: 8px;">{data[7]}</td>
<td style=" border: 1px solid black; padding: 8px;">{data[5].total_seconds()}</td>
<td style=" border: 1px solid black; padding: 8px;">{data[9]}</td>
</tr>
"""
table_html += "</table>"
return (table_html)
def beijing(sec, what):
beijing_time = datetime.now()+ timedelta(hours=8)
return beijing_time.timetuple()
"""蜜罐收集黑名单"""
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(message)s')
logger = logging.getLogger()
logging.Formatter.converter = beijingprojectCSTId = "xxxx"
# Google Cloud项目ID
credentialsCST = service_account.Credentials.from_service_account_file('dddd.json')projectIdList = [{'projectId':projectCSTId,' credentials':credentialsCST}]
#遍历 project列表
while 1:
logger.info('开始新一轮扫描')
for projectInfo in projectIdList:
firewallInfo,sourceRange = listFirewallRule(project Info['credentials'],projectInfo['projectId'])[θ],listFirewallRule(projectInfo['credentials'],projectInfo['projectId'])[1]
for firewallName in firewallInfo:
if firewallInfo[firewallName] < 5000:
break
queryScanData = "SELECT source_ip,source_ip_country,dest_ip,GROUP_CONCAT(DISTINCT dest_port),count(*) AS ipCount,TIMEDIFF(MAX(update_time),MIN(create_time)),GROUP_CONCAT(DISTINCT scan_type),create_time,source_mac,detail FROM scanners WHERE ifAlreadysent=0 GROUP BY source_ip"
scanpata = executeMysqivata(1,' read', queryscanData)
logger.info ("开始扫描数据库,看是否有新的ip")
if len(scanData) == 0:
logger.info ('本次扫描没有发现新的ip')
else:
for j in scanData:
logger.info (j[0])
if isPublicIpv4(j[0]) == True:
###这边判断是否是自己的ip
if j[0] != 'x.x.x.x':
dataQuery = f"""select * from sync_ip_info where ip={"'" + j[0] + "'"}"""
queryDupIp = executeMysqlData(1,'read',dataQuery)
if len(queryDupIp) == 0:
resultAddIP = addSourceIPToFirewallRule(projectInfo['credentials'],projectInfo['projectId'],firewallName,j[0])
if resultAddIP == '5001.':
logger.info (f'防火墙规则已满,尝试创建新的规则')
for i in range (1,1000):
firewallRuleName = "blocklist" + str(i)
resultAddPolicy = newFirewallPolicy(credentialsCST,projectCSTId,firewallRuleName)
if resultAddPolicy == 'already exists':
logger.info(f'防火墙{firewallRuleName}已经存在,尝试下一个。。。')
i += 1
else:logger.info (f'防火墙{firewallRuleName}创建成功!')
addSourceIPToFirewallRule(projectInfo['credentials'],projectInfo['projectId'],firewallName,j[0])
break
else:
logger.info('防火墙规则写入成功')
dataInsert = f"""insert into sync_ip_info(ip, sync) VALUES ({"'"+ j[0] + "'"},'honeypotserver')"""
executeMysqlData(1,'write',dataInsert)
logger.info("数据写入成功")
else:
logger.info(f'该ip{j[0]}已经写入数据库!')
else:logger.info (f'ip{j[0]}是公司IP,请注意检查!')
time.sleep(60)