菜单
本页目录

介绍

SiteVulScan是一款用于扫描目标站点漏洞的脚本,支持批量输入目标,将结果输出到Excel中,输出字段:序号、协议、host、端口、URL、影响产品、漏洞名称、漏洞编号、风险等级、漏洞类型、检测时间、参考链接、修复建议。 。

脚本参数

usage: SiteVulScan.py [-h] [-u URL] [-f FILE] [-t THREAD]

options:
  -h, --help            show this help message and exit
  -u URL, --url URL     单个URL检测
  -f FILE, --file FILE  指定url文件(一行一个)
  -t THREAD, --thread THREAD
                        并发数(int: 5)

输出日志

[ CMS ] https://api.birdy02.com:8443 【Laravel,Apache-Shiro,Access-Control,Docker_Daemon,Python】
[ Vul ] Check Laravel Debug 信息泄露
[ Vul ] Check Laravel配置信息泄露
[ CMS ] https://api.birdy02.com 【OpenResty】
[ Vul ] Check Laravel Debug Enabled
[ Vul ] Check Larvel Debug Method Enabled
[ Vul ] Check UniSharp Laravel File Manager 2.0.0 - Arbitrary File Read
[ Vul ] Check Laravel Horizon Dashboard - Unauthenticated
[ Vul ] Check Laravel Ignition - Cross-Site Scripting
[ Vul ] Check Laravel log file publicly accessible
[ Vul ] Check Laravel Telescope Disclosure

[ 检测报告 ] output\SiteVulScan_1733568438\result.xlsx

代码源码

# -*- coding: utf-8 -*-
from secScript import analyze_url, poc_info, exploit, Function, Docx, log, Fore, outPath, program_exit
import openpyxl, argparse, os.path, time
from urllib.parse import urlparse
import concurrent.futures

result = []
model = 'SiteVulScan'
pocs = dict()


# poc漏洞检测
def check_vul(cms: str, _url: str) -> list | None:
    global pocs, result
    for v in pocs[cms]:
        v_res = exploit(v, _url)
        if v_res is None: return
        log("Vul", "{} {}".format(
            Fore.RED + "【Vul Exists】" if v_res["isVul"] else Fore.YELLOW + "Check",
            Fore.RESET + v_res["vName"]
        ), False)
        result.append([v_res, _url]) if v_res["isVul"] else None
    return result


# 主要检测方法
def run(_url: str) -> list:
    _res = []
    global pocs
    if len(pocs) < 1: pocs = poc_info("list")
    res = analyze_url(_url, True)
    if res is None:
        log(Fore.RED + "Request Error", Fore.RED + _url)
        return _res
    cms = ",".join(res.get("CMS")) if res.get("CMS") else ''
    log("CMS", "{} {}".format(Fore.YELLOW + _url, Fore.RESET + f"【{cms}】"))
    if not pocs: return _res
    for i in [i for i in res.get('CMS') if i in pocs] if res.get('CMS') else []:
        _r = check_vul(i, _url)
        _res.extend(_r) if _r is not None else None
    return _res


# 输出Excel表格
def outExcel(path: str) -> str:
    path = os.path.join(outPath, "{}_{}".format(model, path))
    if not os.path.exists(path): os.makedirs(path)
    workbook = openpyxl.Workbook()
    worksheet = workbook.active
    worksheet.append([
        "序号", "协议", "host", "端口", "URL",
        "影响产品", "漏洞名称", "漏洞编号", "风险等级", "漏洞类型", "检测时间", "参考链接", "修复建议"
    ])

    for num, i in enumerate(result):
        if i is None or len(i) == 0: continue
        v = i[0]
        uri = urlparse(i[-1])
        Docx.write_docx(v, i[-1], path)
        worksheet.append([
            str(num + 1), uri.scheme, uri.hostname, uri.port, i[-1],
            v.get("product"), v.get("vName"), ",".join(v.get("vId")),
            v.get("level"), v.get("vType"), v.get("timer"), v.get("link"),
            "\n".join(v.get("fix"))
        ])
    file = os.path.join(path, "result.xlsx")
    workbook.save(file)
    log("检测报告", file)
    return file


if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('-u', '--url', help='单个URL检测')
    parser.add_argument('-f', '--file', help='指定url文件(一行一个)')
    parser.add_argument('-t', '--thread', help='并发数(int: 5)', default=5, type=int)
    args = parser.parse_args()
    if args.thread < 1: args.thread = 1
    if args.url:
        run(args.url)
    elif args.file:
        try:
            with concurrent.futures.ProcessPoolExecutor(max_workers=args.thread) as executor:
                futures = [executor.submit(run, i) for i in Function.fileGetUrl(args.file)]
                result = []
                [result.extend(i.result()) for i in futures]
        except KeyboardInterrupt:
            program_exit()
        else:
            print("")
    else:
        parser.print_help()
    if len(result) > 0: outExcel(str(int(time.time())))