在值守的同事们进行溯源的时候,一般会一个个的把攻击IP,放沙箱或者一些威胁情报去查询,看看有没有域名、备案人身份信息、历史解析域名,来进一步溯源。但是如果一天的攻击流量很多,攻击IP也很多,那么就需要一个个的去搜,就很麻烦。于是写了个溯源脚本,来批量反查ip是否有绑定的域名,如果有,是否可以查到域名对应备案人的信息。对于一些没有什么线索和信息的IP,需要判断他是否开放了一些端口,进一步判断他是否是跳板机、肉鸡、红队攻击机或者是否可以进行反制。
首先收集攻击IP 从安全设备中导出告警 复制攻击IP,直接放进ips.txt中(脚本会自动去重,自动过滤内网IP)
提取出所有IP之后尝试多IP进行批量溯源,而通常可以溯源或反制的IP可能具有以下几个特征:
-
IP有对应的域名,可查询域名对应的备案人信息
-
IP开放了高危服务端口:(站在攻击者的角度可能开放以下服务及默认端口)SSH(22)、Redis(6379)、NPS(9999)、Viper(60000)、CobaltStrike(50050)、daybreak(1337)、Frp(7001)
-
该IP对应payload中存在圈名、安全团队名、其VPS的IP(此IP可放入提取到的IP数组中)
那么要对此IP进行溯源,就通常需要经历这几个固定的过程:
-
IP反查域名,包括历史解析域名
使用securitytrails.com(需要配置KEY)的接口进行批量的IP反查域名
-
域名反查备案人/公司信息
如果IP存在域名则使用爱站的接口对域名进行反查备案人信息。
-
域名反查是否存在博客
手动谷歌语法:site:xxx.hacker.com
-
对IP进行指定端口的扫描
使用python 的nmap库对这些端口进行探测
最终脚本代码如下
#Author: Ting
#说明:脚本可以使用微步的API,但是高级API好像是付费的,只有在网上自己找,最后选择使用爱站和国外的一个站(注册需要科学上网)
import re
import requests
import ipaddress
import nmap
def remove_duplicate_ips(ip_list):
seen = set()
unique_ips = []
for ip in ip_list:
if ip not in seen:
seen.add(ip)
unique_ips.append(ip)
return unique_ips
def extract_ips_from_file(file_path):
ip_pattern = r'b(?:d{1,3}.){3}d{1,3}b'
ips_found = []
with open(file_path, 'r', encoding='utf-8') as file:
for line in file:
ips = re.findall(ip_pattern, line)
ips_found.extend(ips)
return remove_duplicate_ips(ips_found)
def filter_public_ips(ip_list):
public_ips = []
for ip in ip_list:
try:
ip_obj = ipaddress.ip_address(ip)
if not ip_obj.is_private:
public_ips.append(ip)
except ValueError:
continue
return public_ips
def scan_ips(ip_list, ports):
nm = nmap.PortScanner()
for ip in ip_list:
nm.scan(ip, arguments='-sn')
if nm._scan_result["scan"] == {}:
continue
if nm._scan_result["scan"][ip]["status"]["state"] == "up":
print(f"{ip} 存活")
nm.scan(ip, arguments=f'-p {",".join(map(str, ports))}') # 扫描指定端口
for port in ports:
if nm[ip]['tcp'][port]['state'] == 'open':
print(f"{ip} 端口:{port} 开放")
else:
continue
else:
continue
def domain_serch(domain):
url = f'https://whois.aizhan.com/{domain}/'
headers = {
'Host': 'whois.aizhan.com',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 Edg/126.0.0.0',
'Connection': 'keep-alive'
}
response = requests.get(url=url, headers=headers)
re_data = response.text
registrant_pattern = r'<b>Registrant: </b>(.*?)<br/>'
email_pattern = r'<b>Registrant Contact Email: </b>(.*?)<br/>'
registrant = re.search(registrant_pattern, re_data)
email = re.search(email_pattern, re_data)
registrant_value = registrant.group(1) if registrant else "未差到"
email_value = email.group(1) if email else "未差到"
print(f"n域名持有人/机构名称:{registrant_value}n域名持有人/机构邮箱:{email_value}")
if __name__ == "__main__":
domains = []
ips = filter_public_ips(extract_ips_from_file("ips.txt"))
for ip in ips:
url = f"https://api.securitytrails.com/v1/ips/nearby/{ip}"
headers = {
'Host': 'api.securitytrails.com',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 Edg/126.0.0.0',
'APIKEY': '需要配置KEY',
'Connection': 'keep-alive'
}
response = requests.get(url,headers)
for i in response.json()["blocks"]:
if ip in i["ip"]:
print(ip + "已知开放的端口有:", end="")
for b in i["ports"]:
print(b,end=" ")
print( "n历史域名有:")
for b in i["hostnames"]:
print(b,end=" ")
domains.extend(b)
domain_serch(b)
break
print("开始扫描端口:22, 6379, 9999, 60000, 50050, 1337, 7001。可以自行添加")
ports = [22, 6379, 9999, 60000, 50050, 1337, 7001]
scan_ips(ips, ports)
脚本使用方式与效果如下
将所有攻击IP放到ips.txt中
原文始发于微信公众号(Ting丶的安全笔记):蓝队技战法-自动溯源小脚本
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论