• 安全工具分析系列-Londly01


    前言

    原创作者:Super403,文章分析主要用于研究教学
    本期研究:【Londly01-safety-tool】工具源码
    简介:自动化资产探测及漏扫脚本
    工具来源:https://github.com/startagain2016/Londly01-safety-tool
    截图展示:【如下图所示】

    工具介绍

    根据作者的工具简介,“自动化进行资产探测及漏洞扫描|红蓝对抗 | 快速打点 | 适用黑客进行赏金活动、SRC活动、大规模攻击使用 | 护网”可以理解这是一个调用市面上常用的渗透工具,进行自动流程化的脚本工具。首先看一下作者调用的工具,masscan,Fscan,httpx,Finger,observer,xray,nuclei,都是一些常见的渗透工具。脚本工具的核心是调用这些工具,采用人工常规渗透方式,及信息收集+资产测绘+漏洞扫描,将其连贯起来做成自动化流程。

    工作流程

    工具分析

    __
    |    cdn.py             # 去除节点ip
    |    const.py           # cdn配置文件
    |    londly.py			# 主程序
    |    README.md          # 说明
    |_   requirements.txt   # 需要下载安装的pip的模块
    

    londly.py

    首先我们从头开始刨析这个脚本工具源码,这里发现主程序londly.py调用os,time,argparse,shutil等模块。

    #coding:utf-8
    import os           #可以用于操作系统交互,执行命令
    import time         #可以用于调用时间相关事件,如演示等等
    import argparse     #用于编写用户友好的命令行接口,可以定义程序命令行参数
    import shutil       #提供了更高级的文件和文件夹操作,如复制、删除、移动文件和文件夹等
    

    图形化展示字符设计,定义函数biaoti,里面包含一个变量splash1,展示输出。

    def biaoti():
        splash1 = """
    
    
     __                                __  __           
    |  \                              |  \|  \          
    | $$      ______   _______    ____| $$| $$ __    __ 
    | $$     /      \ |       \  /      $$| $$|  \  |  \
    | $$    |  $$$$$$\| $$$$$$$\|  $$$$$$$| $$| $$  | $$
    | $$    | $$  | $$| $$  | $$| $$  | $$| $$| $$  | $$
    | $$____| $$__/ $$| $$  | $$| $$__| $$| $$| $$__/ $$
    | $$     \$$    $$| $$  | $$ \$$    $$| $$ \$$    $$
     \$$$$$$$$\$$$$$$  \$$   \$$  \$$$$$$$ \$$ _\$$$$$$$
                                              |  \__| $$
                                               \$$    $$
                                                \$$$$$$ 
    
                                                                     
        """
        print(splash1)
    

    下面主要涉及到argparse模块的知识,看不懂的可以去百度了解,不过多讲述。
    下面代码,定义一个函数args函数,设置解析命令行参数,我看这段代码主要是调用masscan端口扫描工具,执行masscan命令的自定义参数,设置三个参数分别是 -i 从文件中读取要扫描的目标列表,-p 扫描端口,-rate扫描速率。最后将解析命令行参数保存至变量args。

    **description='Masscan2Httpx2Nuclei' ** 设置提示描述,会在界面展示。
    add_argument 用于向ArgumentParser对象,添加命令行参数。
    **required=True ** 是设置命令参数为必选项。
    help='' 是设置帮助信息,提示作用。
    **args = parser.parse_args() **用于解析命令行参数

    def args():
        parser = argparse.ArgumentParser(description='Masscan2Httpx2Nuclei')
        #help换行
        parser.add_argument('-i', '--input', help='参考masscan -iL', required=True)
        parser.add_argument('-p', '--port',help='参考masscan -p', required=True)
        parser.add_argument('-rate','--rate', help='参考masscan速率rate', required=True)
        args = parser.parse_args()
        return args
    

    这段代码定义一个更新模块update函数,设置提示变量展示,可以看到在当前目录下使用os模块执行系统命令来更新nuclei工具和xray工具,更新完成后输出提示。

    def update():
        splash00 = """
            +----------------------------------+
            | 正在更新nuclei&xray       
            +----------------------------------+
        """
        print(splash00)
        os.system('./nuclei -update')
        os.system('./xray_linux_amd64 upgrade')
        splash03 = """
            +----------------------------------+
            | 检查完毕,解放双手!!
            +----------------------------------+
        """
        print(splash03)
    

    设置check_args函数,读取上面所说的args变量存储命令解析参数命令,这里做了三个逻辑判断.

    第一 检查 -i ,input 参数指定的IP文件是否存在,不存在退出程序.
    第二 检查 -p,port 的端口参数是否存在,不存在退出程序.
    第三 检查-rate 的扫描速率参数是否存在,不存在退出程序.

    如果所有逻辑判断正常, 函数会返回原始的 args 对象

    def check_args(args):
        if not os.path.exists(args.input):
            print('ip文件不存在')
            exit()
        if not args.port:
            print('请输入端口参数')
            exit()
        if not args.rate:
            print('请输入扫描速率(例:-rate 2000)')
            exit()
        return args
    

    这段代码的流程是调用check_args函数做个逻辑判断,验证参数无误后,设置三个变量,分别对于命令行中的三个参数,使用os模块执行系统命令,运行masscan,将结果保存到当前目录下的masscan.txt。

    def masscan2httpx2nuclei(args):
        args = check_args(args)
        input_file = args.input
        port = args.port
        rate = args.rate
        os.system('masscan -iL ' + input_file + ' -p' + port + ' -oL masscan.txt --rate ' + rate)
    

    这段代码更好理解了,使用python3命令调用cdn.py ,具体我们看下面的cdn.py代码分析,最后会处理好IP

    def cdn():
        os.system('python3 cdn.py list.txt')
    

    接下来我们分析masscan2httpx2nuclei_main函数:看函数名我们就知道,这个是工具处理函数,首先循环检查masscan.txt是否存在,不存在延时1秒继续检查,然后继续检查,当masscan.txt的大小为0,说明没有扫描到任何开放的端口,因此打印提示信息并退出程序 ,如果不为空则打开masscan.txt 文件并逐行读取。跳过以 # 开头的行(通常是注释或标题)。对于以 open 开头的行(表示扫描到的开放端口),提取端口号和相应的IP地址,并写入到 masscanconvert.txt 文件中 ,如果这个txt存在, 使用 httpx扫描masscanconvert.txt的结果,保存httpxresult.txt中,然后删除文件。

    def masscan2httpx2nuclei_main():
        while True:
            if os.path.exists("masscan.txt"):
                break
            else:
                time.sleep(1)
        if os.path.getsize("masscan.txt") == 0:
            splash3 = """
                +----------------------------------+
                | 无端口开放,程序已退出!          
                +----------------------------------+
            """
            print(splash3)
            exit()
        else :
            splash4 = """
                +----------------------------------------+
                | Masscan扫描结果解析并调用httpx   
                +----------------------------------------+
            """
            print(splash4)
            masscanfile = open("masscan.txt", "r")
            masscanfile.seek(0)
            for line in masscanfile:
                if line.startswith("#"):
                    continue
                if line.startswith("open"):
                    line = line.split(" ")
                    with open("masscanconvert.txt", "a") as f:
                        f.write(line[3]+":"+line[2]+"\n")
                        f.close()
            masscanfile.close()
        if os.path.exists("masscan.txt"):
            os.system('./httpx -l masscanconvert.txt -nc -o httpxresult.txt')
            os.remove("masscan.txt")
            splash2 = """
                +----------------------------------+
                | Httpx is done !                  
                +----------------------------------+
            """
            print(splash2)
        else:
            splash5 = """
                +----------------------------------+
                | 未发现解析后的masscan端口结果    
                +----------------------------------+
            """
            print(splash5)
            exit()
    

    使用observer工具处理masscanconvert.txt的IP端口结果,另存至observer.txt

    def observer():
        os.system('./observer -f masscanconvert.txt -c observer.txt')
    

    使用Finger 指纹识别工具扫描,并处理其输出,将输出文件移动到当前工作目录

    def Finger():
        path=os.getcwd()
        os.system('python3 Finger/Finger.py -f ' + path + r"/masscanconvert.txt")
        files = path + r"/Finger/output/"
        b = os.listdir(files)
        new = path
        for f in b:
            shutil.move(files + f, new)
    

    使用fscan工具扫描ip.txt 保存

    def fscan():
        os.system('./fscan64 -hf ip.txt -o fscan.txt')
    

    nu函数,是检查httpxresult.txt文件存在,然后调用nuclei,xray扫描漏洞并输出,其中nuclei扫描中高危,并输出,如果没有http协议,也就是httpxresult是空文件,发出提示,然后查看nuclei扫描结果是否存在,存在输出提示,不存在输出未发现漏洞提示,然后检查xray扫描结果是否存在,存在输出结果提示,不存在输出未发现提示。

    def nu():
        if os.path.exists("httpxresult.txt"):
            os.system('./nuclei -l httpxresult.txt -s medium,high,critical -o nucleiresult.txt')
            os.system('./xray_linux_amd64 webscan -url-file httpxresult.txt --html-output xray.html')
            os.remove("httpxresult.txt")
            os.remove("masscanconvert.txt")
        else:
            print("扫描结果未发现http协议")
            exit()
        if os.path.exists("nucleiresult.txt"):
            splash6 = """
                +----------------------------------+
                | 扫描完成,请查看nucleiresult.txt 
                +----------------------------------+
            """
            print(splash6)
        else:
            splash7 = """
                +----------------------------------+
                | nuclei未发现中高危漏洞                
                +----------------------------------+
            """
            print(splash7)
        if os.path.exists("xray.html"):
            splash8 = """
                +----------------------------------+
                | 扫描完成,请查看xray.html        
                +----------------------------------+
            """
            print(splash8)
        else:
            splash9 = """
                +----------------------------------+
                | xray未发现漏洞                    
                +----------------------------------+
            """
            print(splash9)
        exit()
    

    接下来是main主程序,梳理一下工作流程
    首先调用logo函数,检查更新,然后使用cdn模块梳理cdn节点,使用masscan2httpx2nuclei函数调用masscan扫描ip端口,httpx函数解析端口站点,调用observer和Finger和fscan扫描端口站点,ip,最后调用nuclei和xray扫描漏洞并输出

    def main(): 
        biaoti()   # logo函数
        update()   # 检查更新
        cdn()      # 使用cdn函数
        masscan2httpx2nuclei(args()) # masscan函数扫描指定的文件
        masscan2httpx2nuclei_main()  # httpx处理解析
        observer()
        Finger()
        fscan()
        nu()
    
    
    if __name__ == '__main__':
        main()
        exit()
    

    cdn.py

    关于cdn.py 简单描述一些自己的看法,通读了代码后,发现逻辑不清晰,这倒可以理解,但是我不理解为什么会有涉及到域名方面的相关的code,而且在调试cdn.py 代码发现真的不好用,cdn.py 有很大几率是作者调用他人的脚本工具,不像是作者独自开发的,为什么说这个逻辑不清晰是有理由的,代码主体顺序还得靠猜,可读性较差。下面是全文代码,可以看一下。

    # -*- coding: utf-8 -*-
    import dns.resolver
    import requests
    import ipaddress
    import geoip2.database
    import socket
    import sys
    import re
    from concurrent.futures import ThreadPoolExecutor,wait, ALL_COMPLETED
    from const import all_CNAME,cdns,ASNS
    
    def matched(obj,list):
    	#print(obj)
    	for i in list:
    		if i in obj:
    			return True
    	return False
    
    
    def getCNAMES(domain):
    	cnames = []
    	cname = getCNAME(domain)
    	if cname is not None:
    		cnames.append(cname)
    	while(cname != None):
    		cname = getCNAME(cname)
    		if cname is not None:
    			cnames.append(cname)
    	return cnames
    
    def getCNAME(domain):
    	try:
    		answer = dns.resolver.resolve(domain,'CNAME')
    	except:
    		return None
    	cname = [_.to_text() for _ in answer][0]
    	return cname
    
    
    def checkIP(ip):
    	try:
    		for cdn in cdns:
    			if ipaddress.ip_address(ip) in ipaddress.ip_network(cdn):
    				return True
    		return False
    	except:
    		return False
    
    def getIP(domain):
    	try:
    		addr = socket.getaddrinfo(domain,None)
    	except:
    		return None
    	return str(addr[0][4][0])
    
    
    def checkASN(ip):
    	try:
    		with geoip2.database.Reader('GeoLite2-ASN.mmdb') as reader:
    			response = reader.asn(ip)
    			for i in ASNS:
    				if response.autonomous_system_number == int(i):
    					return True
    	except:
    		return False
    	return False
    
    
    
    def wFile(file,str):
    	try:
    		f = open(file,'a')
    		f.write(str)
    		f.write('\n')
    	finally:
    		f.close()
    
    def check(data):
    	if not re.search(r'\d+\.\d+\.\d+\.\d+', data):
    		ip = getIP(data)
    	else:
    		ip = data
    	if ip is None:
    		return
    
    	cdnip = checkIP(ip)
    
    	if cdnip == True:
    		print(data+": CDN")
    		wFile('cdn.txt',data)
    		return
    
    	cdnasn = checkASN(ip)
    	if cdnasn == True:
    		print(data+": CDN")
    		wFile('cdn.txt',data)
    		return
    
    	if not re.search(r'\d+\.\d+\.\d+\.\d+', data):
    		cnames = getCNAMES(data)
    		match = False
    		for i in cnames:
    			match = matched(i,all_CNAME)
    			if match == True:
    				break
    		if match == True:
    			print(data+": CDN")
    			wFile('cdn.txt',data)
    			return
    	print(data+": notCDN")
    	wFile('ip.txt',data)
    	#wFile('../ip.txt',ip)
    	return
    
    
    
    if __name__ == '__main__':
    	if len(sys.argv) != 2:
    		print("error command -h for help")
    		exit()
    	if sys.argv[1] == '-h':
    		print("")
    		print("checkCDN.py list.txt")
    		print("")
    		exit()
    	dataList = []
    	try:
    		f = open(sys.argv[1])
    		for text in f.readlines():
    			data = text.strip('\n')
    			dataList.append(data)
    	finally:
    		f.close()
    	with ThreadPoolExecutor(max_workers=100) as pool:
    		all_task = [pool.submit(check,data) for data in dataList]
    		wait(all_task, return_when=ALL_COMPLETED)
    

    简单梳理一下逻辑,下面代码是作者调用的cdn.py的代码

    # -*- coding: utf-8 -*-
    import dns.resolver    # Dns 查询模块
    import requests        
    import ipaddress       # IP处理模块
    import geoip2.database # MaxMind的GeoIP2库的一部分,用于基于IP地址进行地理位置查询
    import socket          
    import sys
    import re              # 正则模块
    from concurrent.futures import ThreadPoolExecutor,wait, ALL_COMPLETED  # 并发
    from const import all_CNAME,cdns,ASNS  # 从const.py 中调用 all_CNAME,cdns,ASNS
    

    首先这部分是做个逻辑判断,调用argv函数判断,-h输出 工具使用然后退出程序

    if __name__ == '__main__':
    	if len(sys.argv) != 2:
    		print("error command -h for help")
    		exit()
    	if sys.argv[1] == '-h':
    		print("")
    		print("checkCDN.py list.txt")
    		print("")
    		exit()
    

    初始化一个空列表dataList,用于存储从文件中读取的数据。尝试打开文件读取文件内容,并且去除末尾换行符之后将数据保存至datalist中,接下来是使用并发线程100来处理主函数设置的任务

    	dataList = []
    	try:
    		f = open(sys.argv[1])
    		for text in f.readlines():
    			data = text.strip('\n')
    			dataList.append(data)
    	finally:
    		f.close()
    	with ThreadPoolExecutor(max_workers=100) as pool:
    		all_task = [pool.submit(check,data) for data in dataList]
    		wait(all_task, return_when=ALL_COMPLETED)
    

    matched函数:是检查判断文件的一个处理逻辑。
    getCNAME 函数:接收domain文件参数,并尝试获取该域名的 CNAME 记录。
    getCNAMES函数:是获取给定域名的所有 CNAME 记录。与之前的 getCNAME 函数不同,getCNAMES 函数会递归地查询每个 CNAME 记录。
    checkIP函数:检查给定的IP地址是否属于const.py里面自定义的cdns列表。尝试将ip和cdns中的每个CDN网络进行比较,如果ip位于cdns网络中,则返回True,否则返回False。
    getIP函数:尝试获取给定域名domain的IP地址。使用socket.getaddrinfo函数来解析域名IP,将解析的IP地址的字符串形式。如果解析失败,则函数返回None。
    checkASN函数:检查IP地址是否属于const.py中预定义的自治系统号ASNS列表。使用geoip2库来查询IP地址的ASN,然后比较查询到的ASN是否与ASNS列表中ASN是否匹配。如果匹配,则继续,如果查询失败或没有匹配项退出。
    wFile函数:将字符串追加指定文件中,用于处理文件操作,当文件不存在则创建一个,写入字符串,并后续添加字符,做个异常处理,无论写入操作是否成功,都会关闭文件

    def matched(obj,list):
    	#print(obj)
    	for i in list:
    		if i in obj:
    			return True
    	return False
    
    
    def getCNAMES(domain):
    	cnames = []
    	cname = getCNAME(domain)
    	if cname is not None:
    		cnames.append(cname)
    	while(cname != None):
    		cname = getCNAME(cname)
    		if cname is not None:
    			cnames.append(cname)
    	return cnames
    
    def getCNAME(domain):
    	try:
    		answer = dns.resolver.resolve(domain,'CNAME')
    	except:
    		return None
    	cname = [_.to_text() for _ in answer][0]
    	return cname
    
    
    def checkIP(ip):
    	try:
    		for cdn in cdns:
    			if ipaddress.ip_address(ip) in ipaddress.ip_network(cdn):
    				return True
    		return False
    	except:
    		return False
    
    def getIP(domain):
    	try:
    		addr = socket.getaddrinfo(domain,None)
    	except:
    		return None
    	return str(addr[0][4][0])
    
    
    def checkASN(ip):
    	try:
    		with geoip2.database.Reader('GeoLite2-ASN.mmdb') as reader:
    			response = reader.asn(ip)
    			for i in ASNS:
    				if response.autonomous_system_number == int(i):
    					return True
    	except:
    		return False
    	return False
    
    
    def wFile(file,str):
    	try:
    		f = open(file,'a')
    		f.write(str)
    		f.write('\n')
    	finally:
    		f.close()
    
    

    check函数:是主函数,首先使用正则处理接收的数据,它接收一个字符串(可能是域名或IP地址)作为输入,然后调用checkIP函数处理IP检查这个字符串是否属于CDN。如果属于CDN,它将打印出这个字符串,并将其写入cdn.txt文件,然后将输出页面print(data+": notCDN") 展示的data变量保存的IP保存至ip.txt

    def check(data):
    	if not re.search(r'\d+\.\d+\.\d+\.\d+', data):
    		ip = getIP(data)
    	else:
    		ip = data
    	if ip is None:
    		return
    
    	cdnip = checkIP(ip)
    
    	if cdnip == True:
    		print(data+": CDN")
    		wFile('cdn.txt',data)
    		return
    
    	cdnasn = checkASN(ip)
    	if cdnasn == True:
    		print(data+": CDN")
    		wFile('cdn.txt',data)
    		return
    
    	if not re.search(r'\d+\.\d+\.\d+\.\d+', data):
    		cnames = getCNAMES(data)
    		match = False
    		for i in cnames:
    			match = matched(i,all_CNAME)
    			if match == True:
    				break
    		if match == True:
    			print(data+": CDN")
    			wFile('cdn.txt',data)
    			return
    	print(data+": notCDN")
    	wFile('ip.txt',data)
    	#wFile('../ip.txt',ip)
    	return
    

    1711970971766.png这里有个问题:它不会判断domain,私下尝试将子域名放入ip列表,然后会将子域名和ip放入ip.txt,实验尝试masscan扫描ip.txt ,会发生报错导致程序运行失败

    const.py

    我们来分析const.py文件什么意思。
    all_CNAME 列表 定义CDN节点域名

    all_CNAME = [
    	"cdn-cdn.net", "fwdns.net", "bitgravity.com", "21okglb.cn", "kxcdn", "fastwebcdn.com", "cachefly.net", "simplecdn.net", "tbcache.com", "footprint.net", "cloudflare.net", "51cdn.com", "google.", "bluehatnetwork.com", "hadns.net", "incapdns", "skyparkcdn", "akamai", "hwcdn", "cdn77.org", "aicdn.com", "akamaitechnologies.com", "fastly", "fpbns", "cdn77.net", "zenedge.net", "akadns.net", "customcdn.com", "fastly.net", "lswcdn", "googleusercontent.com", "mncdn.com", "21speedcdn.com", "hiberniacdn.com", "mirror-image.net", "anankecdn.com.br", "cncssr.chinacache.net", "hichina.net", "insnw.net", "jiashule.com", "llnwd", "cdn.dnsv1.com", "bitgravity", "mwcloudcdn.com", "amazonaws.com", "systemcdn.net", "wscdns.com", "cdnvideo", "ccgslb", "fpbns.net", "dnsv1", "360wzb.com", "inscname.net", "ytcdn.net", "21vokglb.cn", "aliyuncs.com", "cdntip", "netdna-ssl.com", "att-dsa.net", "tcdn.qq.com", "netdna", "ccgslb.com.cn", "netdna.com", "l.doubleclick.net", "chinaidns.net", "turbobytes-cdn.com", "instacontent.net", "speedcdns", "clients.turbobytes.net", "akamai-staging.net", "fastcdn.cn", "wscloudcdn", "gslb.taobao.com", "hichina.com", "fastcache.com", "cachecn.com", "verygslb.com", "cdnzz.net", "fwcdn.com", "kunlunca.com", "cdn.cloudflare.net", "customcdn.cn", "vo.llnwd.net", "swiftserve.com", "lldns.net", "afxcdn.net", "ourwebpic.com", "edgekey", "ucloud.cn", "cdn20.com", "swiftcdn1.com", "cdn77", "azioncdn.net", "akamaized.net", "cdnvideo.ru", "incapdns.net", "tlgslb.com", "kunlun.com", "cloudflare.com", "anankecdn", "cdnudns.com", "footprint", "txnetworks.cn", "akamai.com", "cdnsun.net", "wpc.", "qiniudns.com", "okglb.com", "cloudflare", "ngenix", "cloudfront", "belugacdn.com", "edgecast", "cdnsun.net.", "alicdn.com", "cdn.telefonica.com", "lxdns.com", "internapcdn.net", "ewcache.com", "llnwd.net", "c3cdn.net", "chinacache.net", "21vianet.com.cn", "qingcdn.com", "yunjiasu-cdn", "cdn.ngenix.net", "skyparkcdn.net", "ccgslb.com", "adn.", "presscdn", "panthercdn.com", "edgecastcdn.net", "ay1.b.yahoo.com", "alicloudsec.com", "cachefly", "kunlunar.com", "bdydns.com", "cloudfront.net", "acadn.com", "cap-mii.net", "gslb.tbcache.com", "awsdns", "cdn.bitgravity.com", "cdnify.io", "kxcdn.com", "00cdn.com", "cdnetworks.net", "fastweb.com", "googlesyndication.", "akamaitech.net", "presscdn.com", "cdnetworks", "cdntip.com", "cdnify", "hacdn.net", "azureedge.net", "alicloudlayer.com", "internapcdn", "speedcdns.com", "cdnsun", "cdngc.net", "gccdn.net", "fastlylb.net", "cdnnetworks.com", "mwcloudcdn", "21cvcdn.com", "ccgslb.net", "azioncdn", "wac.", "unicache.com", "vo.msecnd.net", "stackpathdns.com", "lswcdn.net", "dnspao.com", "akamai.net", "azureedge", "aodianyun.com", "dnion.com", "wscloudcdn.com", "ourwebcdn.net", "netdna-cdn.com", "chinacache", "c3cache.net", "aliyun-inc.com", "sprycdn.com", "hwcdn.net", "yimg.", "telefonica", "aqb.so", "alikunlun.com", "chinanetcenter.com", "cloudcdn.net", "xgslb.net", "gccdn.cn", "globalcdn.cn", "lxcdn.com", "rncdn1.com", "youtube.", "txcdn.cn", "edgesuite.net", "okcdn.com", "akamaiedge.net"
    ]
    

    cdns列表 定义节点IP的区间

    cdns = [
    	'223.99.255.0/24', '71.152.0.0/17', '219.153.73.0/24', '125.39.46.0/24', '190.93.240.0/20', '14.0.113.0/24', '14.0.47.0/24', '113.20.148.0/22', '103.75.201.0/24', '1.32.239.0/24', '101.79.239.0/24', '52.46.0.0/18', '125.88.189.0/24', '150.138.248.0/24', '180.153.235.0/24', '205.251.252.0/23', '103.1.65.0/24', '115.127.227.0/24', '14.0.42.0/24', '109.199.58.0/24', '116.211.155.0/24', '112.253.3.0/24', '14.0.58.0/24', '223.112.227.0/24', '113.20.150.0/23', '61.182.141.0/24', '34.216.51.0/25', '124.95.188.0/24', '42.51.25.0/24', '183.136.133.0/24', '52.220.191.0/26', '119.84.93.0/24', '182.118.38.0/24', '13.59.250.0/26', '54.178.75.0/24', '119.84.92.0/24', '183.131.62.0/24', '111.32.136.0/24', '13.124.199.0/24', '111.47.227.0/24', '104.37.177.0/24', '14.0.50.0/24', '183.230.70.0/24', '114.111.59.0/24', '220.181.135.0/24', '112.140.32.0/19', '101.79.230.0/24', '14.0.115.0/24', '103.28.248.0/22', '117.34.72.0/24', '109.199.57.0/24', '101.79.149.0/24', '116.128.128.0/24', '115.231.186.0/24', '103.22.200.0/22', '61.155.165.0/24', '113.20.148.0/23', '185.254.242.0/24', '59.36.120.0/24', '70.132.0.0/18', '116.31.126.0/24', '119.147.134.0/24', '115.127.246.0/24', '52.47.139.0/24', '118.107.175.0/24', '52.78.247.128/26', '110.93.176.0/20', '54.240.128.0/18', '46.51.216.0/21', '119.31.251.0/24', '125.39.18.0/24', '108.175.33.0/24', '1.31.128.0/24', '61.151.163.0/24', '103.95.132.0/24', '58.215.118.0/24', '54.233.255.128/26', '120.52.113.0/24', '118.107.174.0/24', '1.32.242.0/24', '221.195.34.0/24', '101.79.228.0/24', '205.251.249.0/24', '113.200.91.0/24', '101.79.146.0/24', '221.238.22.0/24', '134.19.183.0/24', '110.93.160.0/20', '180.97.158.0/24', '115.127.251.0/24', '119.167.147.0/24', '115.127.238.0/24', '115.127.240.0/22', '14.0.48.0/24', '115.127.240.0/24', '113.7.183.0/24', '112.140.128.0/20', '115.127.255.0/24', '114.31.36.0/22', '101.79.232.0/24', '218.98.44.0/24', '106.119.182.0/24', '101.79.167.0/24', '125.39.5.0/24', '58.49.105.0/24', '124.202.164.0/24', '111.177.6.0/24', '61.133.127.0/24', '185.11.124.0/22', '150.138.150.0/24', '115.127.248.0/24', '103.74.80.0/22', '101.79.166.0/24', '101.71.55.0/24', '198.41.128.0/17', '117.21.219.0/24', '103.231.170.0/24', '221.204.202.0/24', '101.79.224.0/24', '112.25.16.0/24', '111.177.3.0/24', '204.246.168.0/22', '103.40.7.0/24', '134.226.0.0/16', '52.15.127.128/26', '122.190.2.0/24', '101.203.192.0/18', '1.32.238.0/24', '101.79.144.0/24', '176.34.28.0/24', '119.84.15.0/24', '18.216.170.128/25', '222.88.94.0/24', '101.79.150.0/24', '114.111.48.0/21', '124.95.168.0/24', '114.111.48.0/20', '110.93.176.0/21', '223.111.127.0/24', '117.23.61.0/24', '140.207.120.0/24', '157.255.26.0/24', '221.204.14.0/24', '183.222.96.0/24', '104.37.180.0/24', '42.236.93.0/24', '111.63.51.0/24', '114.31.32.0/20', '118.180.50.0/24', '222.240.184.0/24', '205.251.192.0/19', '101.79.225.0/24', '115.127.228.0/24', '113.20.148.0/24', '61.213.176.0/24', '112.65.75.0/24', '111.13.147.0/24', '113.20.145.0/24', '103.253.132.0/24', '52.222.128.0/17', '183.203.7.0/24', '27.221.27.0/24', '103.79.134.0/24', '123.150.187.0/24', '103.15.194.0/24', '162.158.0.0/15', '61.163.30.0/24', '182.140.227.0/24', '112.25.60.0/24', '117.148.161.0/24', '61.182.136.0/24', '114.31.56.0/22', '64.252.128.0/18', '183.61.185.0/24', '115.127.250.0/24', '150.138.138.0/24', '13.210.67.128/26', '211.162.64.0/24', '61.174.9.0/24', '14.0.112.0/24', '52.52.191.128/26', '27.221.124.0/24', '103.4.203.0/24', '103.14.10.0/24', '34.232.163.208/29', '114.31.48.0/20', '59.51.81.0/24', '183.60.235.0/24', '101.227.206.0/24', '125.39.174.0/24', '119.167.246.0/24', '118.107.160.0/21', '223.166.151.0/24', '110.93.160.0/19', '204.246.172.0/23', '119.31.253.0/24', '143.204.0.0/16', '14.0.60.0/24', '123.151.76.0/24', '116.193.80.0/24', '120.241.102.0/24', '180.96.20.0/24', '216.137.32.0/19', '223.94.95.0/24', '103.4.201.0/24', '14.0.56.0/24', '115.127.234.0/24', '113.20.144.0/23', '103.248.104.0/24', '122.143.15.0/24', '101.79.229.0/24', '101.79.163.0/24', '104.37.112.0/22', '115.127.253.0/24', '141.101.64.0/18', '113.20.144.0/22', '101.79.155.0/24', '117.148.160.0/24', '124.193.166.0/24', '109.94.168.0/24', '203.90.247.0/24', '101.79.208.0/21', '182.118.12.0/24', '114.31.58.0/23', '202.162.109.0/24', '101.79.164.0/24', '58.216.2.0/24', '222.216.190.0/24', '101.79.165.0/24', '111.6.191.0/24', '1.255.100.0/24', '52.84.0.0/15', '112.65.74.0/24', '183.250.179.0/24', '101.79.236.0/24', '119.31.252.0/24', '113.20.150.0/24', '60.12.166.0/24', '101.79.234.0/24', '113.17.174.0/24', '101.79.237.0/24', '61.54.46.0/24', '118.212.233.0/24', '183.110.242.0/24', '150.138.149.0/24', '117.34.13.0/24', '115.127.245.0/24', '14.0.102.0/24', '14.0.109.0/24', '61.130.28.0/24', '113.20.151.0/24', '219.159.84.0/24', '114.111.62.0/24', '172.64.0.0/13', '61.155.222.0/24', '120.52.29.0/24', '115.127.231.0/24', '14.0.49.0/24', '113.202.0.0/16', '103.248.104.0/22', '205.251.250.0/23', '103.216.136.0/22', '118.107.160.0/20', '109.87.0.0/21', '54.239.128.0/18', '115.127.224.0/19', '111.202.98.0/24', '109.94.169.0/24', '59.38.112.0/24', '204.246.176.0/20', '123.133.84.0/24', '103.4.200.0/24', '111.161.109.0/24', '112.84.34.0/24', '103.82.129.0/24', '183.3.254.0/24', '112.137.184.0/21', '122.227.237.0/24', '36.42.75.0/24', '13.35.0.0/16', '101.226.4.0/24', '116.140.35.0/24', '58.250.143.0/24', '13.54.63.128/26', '205.251.254.0/24', '173.245.48.0/20', '183.61.177.0/24', '113.20.144.0/24', '104.37.183.0/24', '35.158.136.0/24', '116.211.121.0/24', '42.236.94.0/24', '117.34.91.0/24', '123.6.13.0/24', '13.224.0.0/14', '113.20.146.0/24', '58.58.81.0/24', '52.124.128.0/17', '122.228.198.0/24', '197.234.240.0/22', '99.86.0.0/16', '144.220.0.0/16', '119.188.97.0/24', '36.27.212.0/24', '104.37.178.0/24', '114.31.52.0/22', '218.65.212.0/24', '1.255.41.0/24', '14.0.45.0/24', '1.32.243.0/24', '220.170.185.0/24', '122.190.3.0/24', '103.79.133.0/24', '220.181.55.0/24', '125.39.191.0/24', '115.127.226.0/24', '125.39.32.0/24', '61.120.154.0/24', '103.4.202.0/24', '103.79.134.0/23', '115.127.224.0/24', '113.20.147.0/24', '61.156.149.0/24', '210.209.122.0/24', '115.127.249.0/24', '104.37.179.0/24', '120.52.18.0/24', '54.192.0.0/16', '14.0.55.0/24', '61.160.224.0/24', '113.207.101.0/24', '101.79.157.0/24', '110.93.128.0/20', '58.251.121.0/24', '61.240.149.0/24', '130.176.0.0/16', '113.107.238.0/24', '112.65.73.0/24', '103.75.200.0/23', '199.83.128.0/21', '123.129.220.0/24', '54.230.0.0/16', '114.111.60.0/24', '199.27.128.0/21', '14.0.118.0/24', '101.79.158.0/24', '119.31.248.0/21', '54.182.0.0/16', '113.31.27.0/24', '14.17.69.0/24', '101.79.145.0/24', '113.20.144.0/21', '180.163.22.0/24', '104.37.176.0/21', '117.25.156.0/24', '115.127.252.0/24', '115.127.244.0/23', '14.0.46.0/24', '113.207.102.0/24', '52.199.127.192/26', '13.113.203.0/24', '64.252.64.0/18', '1.32.240.0/24', '123.129.232.0/24', '1.32.241.0/24', '180.163.189.0/24', '157.255.25.0/24', '1.32.244.0/24', '103.248.106.0/24', '121.48.95.0/24', '54.239.192.0/19', '113.20.146.0/23', '61.136.173.0/24', '35.162.63.192/26', '117.34.14.0/24', '183.232.29.0/24', '42.81.93.0/24', '122.228.238.0/24', '183.61.190.0/24', '125.39.239.0/24', '115.127.230.0/24', '103.140.200.0/23', '202.102.85.0/24', '14.0.32.0/21', '14.0.57.0/24', '112.25.90.0/24', '58.211.137.0/24', '210.22.63.0/24', '34.226.14.0/24', '13.32.0.0/15', '101.79.156.0/24', '103.89.176.0/24', '14.0.116.0/24', '106.42.25.0/24', '101.79.233.0/24', '101.79.231.0/24', '103.75.200.0/24', '119.188.9.0/24', '183.232.51.0/24', '149.126.72.0/21', '103.21.244.0/22', '115.127.233.0/24', '27.221.20.0/24', '198.143.32.0/19', '103.248.107.0/24', '101.79.227.0/24', '115.127.242.0/24', '119.31.250.0/24', '103.82.130.0/24', '99.84.0.0/16', '222.73.144.0/24', '103.79.132.0/22', '101.79.208.0/20', '104.37.182.0/24', '101.79.152.0/24', '36.99.18.0/24', '101.71.56.0/24', '36.250.5.0/24', '61.158.240.0/24', '119.188.14.0/24', '13.249.0.0/16', '183.214.156.0/24', '60.221.236.0/24', '58.30.212.0/24', '115.127.254.0/24', '188.114.96.0/20', '115.127.241.0/24', '103.4.200.0/22', '115.127.239.0/24', '115.127.243.0/24', '111.32.135.0/24', '120.221.29.0/24', '115.127.232.0/24', '14.0.43.0/24', '14.0.59.0/24', '183.61.236.0/24', '34.223.12.224/27', '103.24.120.0/24', '52.57.254.0/24', '113.207.100.0/24', '222.186.19.0/24', '113.20.149.0/24', '150.138.151.0/24', '115.231.110.0/24', '52.56.127.0/25', '104.37.176.0/24', '163.177.8.0/24', '163.53.89.0/24', '52.82.128.0/19', '114.111.63.0/24', '108.162.192.0/18', '14.136.130.0/24', '115.127.229.0/24', '14.17.71.0/24', '52.212.248.0/26', '180.163.188.0/24', '61.182.137.0/24', '119.161.224.0/21', '14.0.41.0/24', '202.162.108.0/24', '106.122.248.0/24', '52.66.194.128/26', '115.127.237.0/24', '220.170.186.0/24', '14.0.32.0/19', '14.0.114.0/24', '112.90.216.0/24', '115.127.236.0/24', '116.193.84.0/24', '113.207.76.0/24', '101.79.235.0/24', '101.79.224.0/20', '61.155.149.0/24', '101.79.148.0/24', '180.163.224.0/24', '204.246.174.0/23', '183.60.136.0/24', '101.227.207.0/24', '103.248.105.0/24', '119.188.35.0/24', '42.236.7.0/24', '116.193.88.0/21', '116.193.83.0/24', '120.199.69.0/24', '122.226.182.0/24', '58.20.204.0/24', '110.93.128.0/21', '115.231.187.0/24', '69.28.58.0/24', '114.31.32.0/19', '112.25.91.0/24', '59.52.28.0/24', '117.27.149.0/24', '61.147.92.0/24', '14.0.117.0/24', '14.0.40.0/24', '119.97.151.0/24', '103.199.228.0/22', '122.70.134.0/24', '115.127.244.0/24', '223.112.198.0/24', '115.127.225.0/24', '104.16.0.0/12', '121.12.98.0/24', '103.31.4.0/22', '204.246.164.0/22', '223.94.66.0/24', '35.167.191.128/26', '116.31.127.0/24', '101.79.226.0/24', '34.195.252.0/24', '115.127.247.0/24', '61.240.144.0/24', '108.175.32.0/20', '120.197.85.0/24', '183.232.53.0/24', '111.161.66.0/24', '117.34.28.0/24', '45.64.64.0/22', '14.0.44.0/24', '109.86.0.0/15', '182.23.211.0/24', '58.211.2.0/24', '119.36.164.0/24', '116.55.250.0/24', '101.227.163.0/24', '13.228.69.0/24', '131.0.72.0/22', '120.221.136.0/24', '119.188.132.0/24', '115.127.235.0/24', '42.236.6.0/24', '125.88.190.0/24', '61.54.47.0/24', '103.27.12.0/22', '116.193.80.0/21', '101.79.159.0/24', '123.155.158.0/24', '111.47.226.0/24', '192.230.64.0/18', '107.154.0.0/16', '45.223.0.0/16', '45.60.0.0/16'
    ]
    

    ASNS 列表 定义

    ASNS = [
        '10576', '10762', '11748', '131099', '132601', '133496', '134409', '135295', '136764', '137187', '13777', '13890',
        '14103', '14520', '17132', '199251', '200013', '200325', '200856', '201263', '202294', '203075', '203139', '204248',
        '204286', '204545', '206227', '206734', '206848', '206986', '207158', '208559', '209403', '21030', '21257', '23327',
        '23393', '23637', '23794', '24997', '26492', '268843', '28709', '29264', '30282', '30637', '328126', '36408',
        '38107', '397192', '40366', '43303', '44907', '46071', '46177', '47542', '49287', '49689', '51286', '55082',
        '55254', '56636', '57363', '58127', '59730', '59776', '60068', '60626', '60922', '61107', '61159', '62026', '62229',
        '63062', '64232', '8868', '9053', '55770', '49846', '49249', '48163', '45700', '43639', '39836', '393560', '393234',
        '36183', '35994', '35993', '35204', '34850', '34164', '33905', '32787', '31377', '31110', '31109', '31108', '31107',
        '30675', '24319', '23903', '23455', '23454', '22207', '21399', '21357', '21342', '20940', '20189', '18717', '18680',
        '17334', '16702', '16625', '12222', '209101', '201585', '135429', '395747', '394536', '209242', '203898', '202623',
        '14789', '133877', '13335', '132892', '21859', '6185', '47823', '30148'
    ]
    

    总结

    该项目开发逻辑较为简单,代码写的较为粗糙,思路还行,适合新手参考。

  • 相关阅读:
    Docker专题(五)之 端口映射与容器互联
    [linux学习笔记]02 gcc安装与使用
    哪款蓝牙耳机性价比高?1000元左右高性价比蓝牙耳机推荐
    解决Node服务启动失败的问题
    PHP引用符&的用法介绍
    MySQL开篇:简单的库操作,表操作,数据类型
    践行绿色发展理念,产业园区绿色转型发展之五大路径
    SpringCloud Alibaba Sentinel实现熔断与限流
    深入理解Java虚拟机(第3版)学习笔记——虚拟机字节码执行引擎(超详细)
    计算机毕业设计Java教工公寓管理(源码+系统+mysql数据库+lw文档)
  • 原文地址:https://www.cnblogs.com/Yichensec/p/18134684/GJ_001