问答
发起
提问
文章
攻防
活动
Toggle navigation
首页
(current)
问答
商城
实战攻防技术
漏洞分析与复现
NEW
活动
摸鱼办
搜索
登录
注册
打造一款适合自己的扫描工具
安全工具
手把手带你打造一款适合自己的扫描工具
0x01 简言 ======= 作为一名安全从业人员,在平时的工作中,少不了进行一系列漏洞的挖掘验证以及修复。那么除了很多业务逻辑漏洞需要人为的识别和测试以外,一些常规类的漏洞挖掘是可以依据自动化扫描工具去实现的。当然有很多非常成熟且强大功能的安全扫描工具。但本篇文章主要以python编写一款轻便型的扫描脚本工具。 代码地址:<https://github.com/get0shell/AScan.git> 0x02 目标 ======= 1)轻量级且便携性高,python脚本支持随时执行 2)满足子域名猜解、目录爆破、漏洞扫描以及弱口令爆破等功能 3)字典支持根据不同需求进行增减调整优化 4)漏洞检测规则依托json文件,可依据poc复现进行编写 0x03 开发实战 ========= 该主动扫描器主要包括子域名扫描、目录扫描、漏洞扫描以及弱口令扫描等四大模块。 3.1 子域名扫描模块 ----------- 子域名扫描,即对主域名的二级域名存活进行请求判断。具体实现逻辑如下: ```java 1)打印需要输入主域名格式,并进行接受输入的域名内容 2)将接收到的主域名传入具体扫描的方法中 3)从子域名字典中便利二级域名的关键词,并和主域名进行拼接 4)对拼接完成的域名进行get请求,状态码为200则存在并进行打印输出 5)利用多线程进行子域名的扫描(线程数量默认为5) ``` 具体代码如下: ```java # @Author : alan # @File : subScan.py import requests import threading def run(e,s): header = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:99.0) Gecko/20100101 Firefox/99.0", } s.acquire() with open('./plug/sub.txt', 'rt', encoding='utf-8') as f: m = f.readlines() for i in m: url = 'http://' + str(i.strip('\n')) + '.' + str(e) try: response = requests.get(url, headers=header) if response.status_code == 200: print('[-]存在域名:' + str(i.strip('\n')) + '.' + str(e)) else: pass except requests.exceptions.ConnectionError: requests.status_codes = 'xxx' def subScan(): print('======================================================') print('域名格式:xxx.com') print('======================================================') domain = input('请输入域名:').strip() mutex = threading.Lock() for i in range(5): t = threading.Thread(target=run,args=(domain,mutex)) t.start() ``` 3.2 目录扫描模块 ---------- 目录扫描,即对应用系统的url目录存活进行请求判断。目录扫描支持多域名目录扫描和单域名目录扫描,因此代码逻辑进行分开分析,具体如下: ```java 1、单域名目录扫描 1)打印需要输出扫描模式参数规格,以及域名提交格式 2)接收到扫描模式为1时调用单个域名扫描方法 3)提示输入需要扫描的url,并获取传入的url 4)从目录字典中遍历目录关键词,并和传入的url进行拼接 5)将拼接完成的url进行get请求,状态码为200则存在并进行打印输出 2、多域名目录扫描 1)打印需要输出扫描模式参数规格,以及域名提交格式 2)接收到扫描模式为2时调用多个域名扫描方法 3)提示输入需要扫描的url目录,并获取传入的目录文件 4)便利目录文件中的url,且从目录字典中遍历目录关键词,并和便利出的url进行拼接 5)将拼接完成的url进行get请求,状态码为200则存在并进行打印输出 ``` 具体代码如下: ```python # @Author : alan # @File : dirScan.py import requests def scan(): headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:99.0) Gecko/20100101 Firefox/99.0" } url = input('请输入url:').strip() with open('./plug/dir.txt', 'rt', encoding='utf-8') as f: m = f.readlines() for i in m: Url = url + i response = requests.get(Url, headers=headers) if response.status_code == 200: print('[+]存在目录:' + i) else: pass def scan1(): headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:99.0) Gecko/20100101 Firefox/99.0" } pwd = input('请输入文件路径:').strip() with open(pwd, 'rt', encoding='utf-8') as f: m = f.readlines() for i in m: with open('./plug/dir.txt', 'rt', encoding='utf-8') as f: j = f.readlines() for h in j: Url = str(i.strip('\n')) + str(h) response = requests.get(Url, headers=headers) if response.status_code == 200: print('[+]存在目录:' + Url) else: pass def dirScan(): print('======================================================') print('参数规格:') print('1、单个域名扫描') print('2、多域名文件扫描') print('域名格式:http://www.xxx.com') print('======================================================') t = input('请输入扫描模式:').strip() if t == '1': scan() elif t == '2': scan1() else: print('参数错误!') ``` 3.3 漏洞扫描模块 ---------- 漏洞扫描,即对应用系统中存在的漏洞进行请求判断。该模块中扫描逻辑比较简单,主要是从poc文件中获取请求payload进行请求,然后通过响应体中关键内容进行判断是否漏洞存在。这块可以根据自己测试扫描的重点进行对应poc文件的编写,程序以json文件为固定文件格式。具体poc的json文件格式如下: ```python { "name": "druid 监控页未授权访问", "payload": "/druid/index.html", "res": "(\\S)Druid Stat Index(\\S){2}title(\\S)" } ``` 具体代码逻辑如下: ```python 1)打印需要输入url格式,并接收输入的url内容 2)将接收到的url传入具体扫描的方法中 3)从poc目录下便利出所有的poc文件,并对该文件中的内容进行读取 4)将读取到的payload和url进行拼接, 5)对拼接完成的url进行get请求,利用正在匹配响应内容中是否存在poc文件中的特征内容 6)如果匹配成功则打印存在该漏洞,以及存在的url+payload 7)利用多线程实现漏洞的扫描 ``` 具体代码如下: ```python # @Author : alan # @File : vulScan.py import json import os import threading import requests import re def run(u, i): header = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:99.0) Gecko/20100101 Firefox/99.0", } i.acquire() pathDir = os.listdir('./plug/vul/') for allDir in pathDir: p = os.path.join('./plug/vul/' + allDir) try: with open(p, 'rt', encoding='utf-8') as f: json_data = json.load(f) url = u + json_data['payload'] response = requests.get(url, headers=header) i = re.search(json_data['res'], response.text) if i: print('[+] 存在漏洞:' + json_data['name']) print('[+]'+url) except Exception: print('请求异常,检查url是否正确') def vulScan(): print('url格式:http://www.xxx.com/ OR http://www.xxx.com/?id=') domain = input('请输入域名:').strip() mutex = threading.Lock() for i in range(2): t = threading.Thread(target=run, args=(domain, mutex)) t.start() ``` 3.4 弱口令扫描模块 ----------- 弱口令扫描,即对系统不同服务的账户密码进行猜解判断。该模块包括SSH弱口令、FTP弱口令、以及MYSQL弱口令等三大模块。 ### 3.4.1 SSH弱口令扫描模块 SSH弱口令扫描模块主要是针对ssh服务的账户和密码进行猜解,这边主要调用paramiko库进行实现,因此需要提前安装该库。具体代码逻辑如下: ```python 1)读取用户名和密码字典文件中的用户名和字典 2)提示输入ip以及端口,并获取输入的内容 3)将输入的ip和端口传入对应的连接方法 4)利用paramiko.SSHClient()进行连接测试 5)连接成功则打印对应用户名和密码 ``` 具体代码如下: ```python import paramiko import threading def sshScan(t, i, o, u, p): try: t.acquire() client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) client.connect(hostname=i, port=o, username=str(u), password=str(p), timeout=10) print('[+]SSH连接成功,用户:%s,密码:%s' % (u, p)) client.close() except: t.release() def ssh(): with open('./plug/passdict/username.txt', 'r')as f: user = f.readlines() with open('./plug/passdict/password.txt', 'r')as f: passw = f.readlines() ip = input("请输入IP:").strip() port = input("请输入端口:").strip() s = threading.Semaphore(10) for i in user: username = i.strip() for j in passw: password = j.strip() t = threading.Thread(target=sshScan, args=(s, ip, port, username, password)) t.start() ``` ### 3.4.2 FTP弱口令扫描模块 FTP弱口令扫描模块主要针对ftp服务的用户名和密码进行猜解,主要利用ftplib库进行连接测试,这块需要设计有账户密码登录以及无用户密码登录,具体代码逻辑如下: ```python 1、无用户密码登录 1)提示输入ip以及端口,并获取输入的内容 2)将输入的ip和端口传入对应的连接方法 3)利用ftplib.FTP()进行连接测试 4)连接成功则打印成功信息 ``` 具体代码如下: ```python import ftplib def ftp_anyScan(t, i, o): try: t.acquire() ftp = ftplib.FTP() ftp.connect(i, o, 2) ftp.login() ftp.quit() print('[+]FTP连接成功,无用户名密码') except: t.release() def ftp_any(): ip = input("请输入IP:").strip() port = input("请输入端口:").strip() s = threading.Semaphore(10) t = threading.Thread(target=ftp_anyScan, args=(s, ip, port)) t.start() ``` ```python 1、用户密码登录 1)读取用户名和密码字典文件中的用户名和字典 2)提示输入ip以及端口,并获取输入的内容 3)将输入的ip和端口传入对应的连接方法 4)利用ftplib.FTP()进行连接测试 5)连接成功则打印对应用户名和密码 ``` 具体代码如下: ```python import ftplib def ftpScan(t, i, o, u, p): try: t.acquire() ftp = ftplib.FTP() ftp.connect(i, o, 2) ftp.login(u, p) ftp.quit() print('[+]FTP连接成功,用户:%s,密码:%s' % (u, p)) except: t.release() def ftp(): with open('./plug/passdict/username.txt', 'r')as f: user = f.readlines() with open('./plug/passdict/password.txt', 'r')as f: passw = f.readlines() ip = input("请输入IP:").strip() port = input("请输入端口:").strip() s = threading.Semaphore(10) for i in user: username = i.strip() for j in passw: password = j.strip() t = threading.Thread(target=ftpScan, args=(s, ip, port, username, password)) t.start() ``` ### 3.4.3 MYSQL弱口令扫描模块 MYSQL弱口令扫描模块主要是针对mysql服务的账户和密码进行猜解,这边主要调用pymysql库进行实现,因此需要提前安装该库。具体代码逻辑如下: ```python 1)读取用户名和密码字典文件中的用户名和字典 2)提示输入ip以及端口,并获取输入的内容 3)将输入的ip和端口传入对应的连接方法 4)利用pymysql.connect()进行连接测试 5)连接成功则打印对应用户名和密码 ``` 具体代码如下: ```python import pymysql def mysqlScan(t, i, u, p): try: t.acquire() db = pymysql.connect(host=i, user=u, password=p) print('[+]MYSQL连接成功,用户:%s,密码:%s' % (u, p)) db.close() except: t.release() def mysql(): with open('./plug/passdict/username.txt', 'r')as f: user = f.readlines() with open('./plug/passdict/password.txt', 'r')as f: passw = f.readlines() ip = input("请输入IP:").strip() s = threading.Semaphore(10) for i in user: username = i.strip() for j in passw: password = j.strip() t = threading.Thread(target=mysqlScan, args=(s, ip, username, password)) t.start() ``` ### 3.4.4弱口令扫描模块整合 在扫描工具调用的过程中,需要依据当前的需求进行不同模块的扫描代码,因此需要一个模块进行模块选择,将支持的功能模块打印输出,并获取用户输入的参数选择调用对应的扫描方法。具体代码如下: ```python def passScan(): print(''' 支持弱口令扫描类型: 1、SSH弱口令扫描 2、FTP弱口令扫描 3、SMB弱口令扫描 4、MYSQL弱口令扫描 ''') m = input("请选择扫描的类型:").strip() if m == '1': ssh() elif m == '2': ftp() ftp_any() elif m == '3': smb() elif m == '4': mysql() else: print('请输入正确的参数') ``` 3.5 扫描模块整合 ---------- 通过上述一系列代码的编写,成功完成了子域名扫描、目录扫描、漏洞扫描以及弱口令四大模块的扫描逻辑,但是在程序运行时需要实现统一运行,并依据不同的需求选择不同的扫描模块进行执行。因此再编写一个统一的整合模块,用来统一调用和选择不同扫描功能模块。具体代码如下: ```python # @Author : alan # @File : Ascan.py from scan import subScan,dirScan,vulScan from scan import passScan def Ascan(): print('============================================欢迎使用AScan==============================================') print(''' = == == = == = = = = = = = = = = = = = = == = = = = = = = = = = == = = = = = = = = = = = = = = = = = = = = = == == = = = == ''') print('=====================================================================================================') print(''' 扫描模块: 1、子域名扫描 2、目录扫描 3、漏洞扫描 4、弱口令扫描 请选择对应的序号进行扫描 ''') t = input('请输入对应扫描模式序号:').strip() if t == '1': subScan.subScan() elif t == '2': dirScan.dirScan() elif t == '3': vulScan.vulScan() elif t == '4': passScan.passScan() else: print('参数错误!') if __name__ == '__main__': Ascan() ``` 0x04 结语 ======= 那么通过以上代码的编写,成功完成了一个基础的主动漏洞扫描工具。这样的好处就是扩展性高,小巧便携,可以根据自己的不同需求随时进行调整,同时还可以实现自动化的测试。当然主动扫描工具相对被动扫描工具来说还是有很大的弊端,有些漏洞可能因为没有参数之类的无法识别到。因此在后面也会再进行被动扫描器的编写以及利用web界面进行展示功能的优化。
发表于 2022-07-18 09:41:22
阅读 ( 9147 )
分类:
安全工具
7 推荐
收藏
0 条评论
请先
登录
后评论
阿蓝
7 篇文章
×
发送私信
请先
登录
后发送私信
×
举报此文章
垃圾广告信息:
广告、推广、测试等内容
违规内容:
色情、暴力、血腥、敏感信息等内容
不友善内容:
人身攻击、挑衅辱骂、恶意行为
其他原因:
请补充说明
举报原因:
×
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!