自动化安全脚本学习

1.目录扫描器

目标:使用python编写一个自动化目录扫描工具,实现简单信息收集,判断目标网站是否存在常见路径。

复制代码
import requests  #用于发HTTP请求
from concurrent.futures import ThreadPoolExecutor #实现多线程扫描

# 扫描目标
target = 'http://vulnweb.com'

# 常见目录字典
wordlist = ['admin', 'login', 'uploads', 'phpinfo', 'config', 'dashboard', 'include', 'images', 'assets']

#扫描函数
def scan(path):
    url = f"{target.rstrip('/')}/{path}"  # rstrip:用于删除末尾指定符号
    try:
        r = requests.get(url, timeout=3) #发起get请求
        if r.status_code in [200, 403]:  #若返回码是200,403则输出
            print(f"[+] Found: {url} (Status: {r.status_code})")
    except requests.RequestException:
        pass

# 线程池并发扫描(用map方法将wordlist中每一项传给scan函数并执行)
with ThreadPoolExecutor(max_workers=10) as executor:
    executor.map(scan, wordlist)

执行:

扩展:

1)把结果写入文件,而不是直接输出

复制代码
with open('result.txt', 'a') as f:
    f.write(f"{url} (Status: {r.status_code})\n")

2)从文件读取字典,而不是自己一个一个写

复制代码
with open('dict.txt') as f:
    wordlist = [line.strip() for line in f]

结果:

2.XSS自动化测试器

目标:写一个脚本自动检测GET参数是否存在XSS注入点

复制代码
import requests
import sys
from urllib.parse import urlparse, parse_qs, urlencode, urlunparse

# 用一个简单的 payload 测试是否反射
payload = "<script>alert(1)</script>"

def scan_xss(url):
    parsed = urlparse(url)  # 分解 URL 成分
    query = parse_qs(parsed.query)  # 获取参数字典 {"q": ["123"], "name": ["abc"]}

    # 替换每个参数为 payload
    new_query = {}
    for param in query: 
        new_query[param] = payload

    # 构造新的 URL
    encoded_query = urlencode(new_query, doseq=True)
    new_url = urlunparse((parsed.scheme, parsed.netloc, parsed.path, '', encoded_query, ''))

    print(f"[*] Testing: {new_url}")

    try:
        r = requests.get(new_url, timeout=5)
        if payload in r.text:
            print(f"[+] Possible XSS found! Payload reflected in response.")
        else:
            print("[-] No reflection detected.")
    except requests.RequestException as e:
        print(f"[!] Request failed: {e}")

if __name__ == "__main__":
    if len(sys.argv) != 2:
        print(f"Usage: python3 {sys.argv[0]} <url>")
        sys.exit(1)

    target_url = sys.argv[1]
    scan_xss(target_url)

requests:用于向目标网站发HTTP请求

sys:用于获取命令行参数

urllib.parse:用来拆解和重建URL,特别是带参数的GET请求地址

payload:最简单的例子,可能还需要绕过

优化:

1.解析命令行参数(argparse)

复制代码
import argparse

def parse_args():
    parser = argparse.ArgumentParser(description="XSS 注入检测器")
    parser.add_argument("-u", "--url", required=True, help="目标 URL(带参数,payload 用 test 占位)")
    parser.add_argument("-p", "--payloads", help="指定 payload 字典文件")
    parser.add_argument("-v", "--verbose", action="store_true", help="显示详细信息(每次测试 URL)")
    parser.add_argument("-o", "--output", help="将检测结果保存到文件")
    return parser.parse_args()

解释:创建命令行解析器,添加参数规则,-u是必须的,用户必须传入目标URL,-p是可选的,用于指定自定义payload文件,-o是可选的,用于指定保存结果的文件路径,parser.parse_args():把命令行参数解析为对象,代码中通过 args.url 这样访问。

2.加载payload列表

复制代码
def load_payloads(payload_file=None):
    if payload_file:
        with open(payload_file, "r") as f:
            return [line.strip() for line in f if line.strip()]
    else:
        return [
            "<script>alert(1)</script>",
            "'\"><script>alert(1)</script>",
            "<img src=x onerror=alert(1)>",
        ]

解释:如果用户传了-p,我们从给定的文件中读取每一行,作为一个payload,否则就用内置的三个payload,strip()用于去除换行和空格,确保干净的数据

3.主程序逻辑

复制代码
import requests

if __name__ == "__main__":
    args = parse_args()
    target_url = args.url
    payloads = load_payloads(args.payloads)

    for payload in payloads:
        test_url = target_url.replace("test", payload)
        if args.verbose:
            print(f"[*] Testing: {test_url}")
        try:
            response = requests.get(test_url, timeout=5)
        except Exception as e:
            print(f"[!] 请求失败: {e}")
            continue

        if payload in response.text:
            print(f"[+] Possible XSS found! Payload reflected in response: {payload}")
            if args.output:
                with open(args.output, "a") as f:
                    f.write(f"{test_url}\n")

解释:

  • args = parse_args():调用刚才定义的函数,获取命令行参数。

  • payloads = load_payloads(...):加载 payload 字典。

  • 遍历每个 payload,替换 URL 中的 test 为 payload。

  • 发起请求(requests.get())并捕获异常。

  • 检查响应中是否回显了 payload,如果是,就打印结果并可选保存。

4.支持自动识别参数并插入payload

目标:程序自动识别所有参数,然后挨个哪这些参数值替换为paylaod,生成多个新URL进行测试

复制代码
import requests
import sys
from urllib.parse import urlparse, parse_qs, urlencode, urlunparse
import argparse

# 默认 XSS payload 列表
DEFAULT_PAYLOADS = [
    "<script>alert(1)</script>",
    "'\"><script>alert(1)</script>",
    "<img src=x onerror=alert(1)>"
]

# ========== 解析参数 ========== #
def parse_args():
    parser = argparse.ArgumentParser(description="XSS 注入检测器")
    parser.add_argument("-u", "--url", required=True, help="目标 URL(带参数)")
    parser.add_argument("-p", "--payloads", help="自定义 payload 字典文件")
    parser.add_argument("--param", help="只测试指定参数(可选)")
    parser.add_argument("-v", "--verbose", action="store_true", help="显示详细信息")
    parser.add_argument("-o", "--output", help="保存结果到文件")
    return parser.parse_args()

# ========== 加载 Payload 文件 ========== #
def load_payloads(filepath):
    if not os.path.exists(filepath):
        print(f"[!] 文件不存在: {filepath}")
        return []
    with open(filepath, "r", encoding="utf-8") as f:
        return [line.strip() for line in f if line.strip()]
        

# ========== 生成注入 URL ========== #
def generate_payload_urls(url, payloads, target_param=None):
    parsed = urlparse(url)
    params = parse_qs(parsed.query)
    
    if not params:
    	print("[!] 未检测到任何参数。")
        return []
    
    result = []
    
    if target_param:
    	if target_param not in params:
            print(f"[!] 参数 {target_param} 不存在。")
            return []

        for payload in payloads:
            new_params = params.copy()
            new_params[target_param] = [payload]
            new_query = urlencode(new_params, doseq=True)
            new_url = urlunparse(parsed._replace(query=new_query))
            result.append((new_url, payload, target_param))
    
     else:
        for param in params:
            for payload in payloads:
                new_params = params.copy()
                new_params[param] = [payload]
                new_query = urlencode(new_params, doseq=True)
                new_url = urlunparse(parsed._replace(query=new_query))
                result.append((new_url, payload, param))

    return result
    
# ========== 执行测试并输出结果 ========== #
def test_payload_urls(payload_urls, verbose=False):
    detected = []

    for url, payload, param in payload_urls:
        if verbose:
            print(f"[*] 正在测试参数 '{param}':{url}")
        else:
            print(f"[*] Testing: {param}")

        try:
            resp = requests.get(url, timeout=6)
            if payload in resp.text:
                print(f"[+] [参数:{param}] 可能存在 XSS 注入:{url}")
                detected.append((url, param, payload))
            elif verbose:
                print(f"[-] [参数:{param}] 未发现反射。")
        except Exception as e:
            print(f"[!] 请求失败:{e}")

    return detected
    

# ========== 保存结果到文件 ========== #
def save_results(output_file, results):
    with open(output_file, "w", encoding="utf-8") as f:
        for url, param, payload in results:
            f.write(f"[XSS] param={param} | payload={payload} | url={url}\n")
    print(f"[+] 结果已保存至:{output_file}")


# ========== 主函数 ========== #
if __name__ == "__main__":
    args = parse_args()

    # 加载 payloads
    if args.payloads:
        payloads = load_payloads(args.payloads)
        if not payloads:
            print("[!] 自定义 payload 加载失败,使用默认 payload。")
            payloads = DEFAULT_PAYLOADS
    else:
        payloads = DEFAULT_PAYLOADS

    # 生成注入 URL
    injected_urls = generate_payload_urls(args.url, payloads, args.param)
    if not injected_urls:
        return

    # 检测
    results = test_payload_urls(injected_urls, verbose=args.verbose)

    # 输出结果
    if args.output and results:
        save_results(args.output, results)
参数 类型 是否必填 说明
-u / --url 字符串 必须 目标带参数的 URL
-p / --payloads 字符串(文件路径) 可选 自定义 payload 文件
--param 字符串 可选 只测试某一个参数(而不是全部)
-v / --verbose 布尔值 可选 是否显示详细信息
-o / --output 字符串(文件路径) 可选 将结果写入文件

示例:

1)自动遍历所有参数

复制代码
python3 xss_scan.py -u "https://example.com/page?search=test"

2)指定测试参数q

复制代码
python3 xss_scan.py -u "https://example.com/page?q=test&lang=en" --param q

3)使用自定义payload文件

复制代码
python3 xss_scan.py -u "https://example.com/page?q=test" -p my_payloads.txt

4)保存检测结果到文件

复制代码
python3 xss_scan.py -u "https://example.com/page?q=test" -o results.txt

5)详细模式查看全部过程

复制代码
python3 xss_scan.py -u "https://example.com/page?q=test" -v

5.添加POST请求

1)修改扩展命令行参数,添加POST和data

复制代码
parser.add_argument("-m", "--method", choices=["GET", "POST"], default="GET", help="请求方法,默认GET")
parser.add_argument("-d", "--data", help="POST请求的数据,格式:param1=val1&param2=val2")

2)修改生成带payload的请求函数,支持GET和POST两种模式

复制代码
from urllib.parse import urlparse, parse_qs, urlencode, urlunparse

def generate_payload_requests(url, payloads, method="GET", data=None, target_param=None):
    """
    根据请求类型生成带 payload 的请求列表。

    返回格式:
      - GET 请求:(url, None, payload, param)
      - POST 请求:(url, post_data, payload, param)
    """

    results = []

    if method.upper() == "GET":
        parsed = urlparse(url)
        params = parse_qs(parsed.query)

        if not params:
            print("[!] 未检测到任何 GET 参数。")
            return []

        if target_param:
            if target_param not in params:
                print(f"[!] 参数 {target_param} 不存在于 GET 参数中。")
                return []
            for payload in payloads:
                new_params = params.copy()
                new_params[target_param] = [payload]
                new_query = urlencode(new_params, doseq=True)
                new_url = urlunparse(parsed._replace(query=new_query))
                results.append((new_url, None, payload, target_param))
        else:
            for param in params:
                for payload in payloads:
                    new_params = params.copy()
                    new_params[param] = [payload]
                    new_query = urlencode(new_params, doseq=True)
                    new_url = urlunparse(parsed._replace(query=new_query))
                    results.append((new_url, None, payload, param))

    elif method.upper() == "POST":
        if not data:
            print("[!] POST 请求必须提供 data 参数。")
            return []

        post_params = parse_qs(data)

        if not post_params:
            print("[!] 未检测到任何 POST 参数。")
            return []

        if target_param:
            if target_param not in post_params:
                print(f"[!] 参数 {target_param} 不存在于 POST 参数中。")
                return []
            for payload in payloads:
                new_post_params = post_params.copy()
                new_post_params[target_param] = [payload]
                new_post_data = urlencode(new_post_params, doseq=True)
                results.append((url, new_post_data, payload, target_param))
        else:
            for param in post_params:
                for payload in payloads:
                    new_post_params = post_params.copy()
                    new_post_params[param] = [payload]
                    new_post_data = urlencode(new_post_params, doseq=True)
                    results.append((url, new_post_data, payload, param))
    else:
        print(f"[!] 不支持的请求方法: {method}")
        return []

    return results

3)修改请求发送和检测函数

复制代码
import requests

def test_payload_requests(requests_list, verbose=False):
    detected = []
    for method, url, post_data, payload, param in requests_list:
        try:
            if method == "GET":
                response = requests.get(url, timeout=10)
            else:  # POST
                headers = {"Content-Type": "application/x-www-form-urlencoded"}
                response = requests.post(url, data=post_data, headers=headers, timeout=10)

            if payload in response.text:
                detected.append( (method, url, post_data, payload, param) )
                if verbose:
                    print(f"[+] 发现可能的XSS,参数: {param},Payload: {payload},请求方式: {method}")

            elif verbose:
                print(f"[-] 无XSS,参数: {param},Payload: {payload},请求方式: {method}")

        except Exception as e:
            print(f"[!] 请求异常: {e}")

    return detected

4)修改main

复制代码
requests_list = generate_payloads_for_request(
        url=args.url,
        payloads=payloads,
        method=args.method,
        data=args.data,
        target_param=args.param
    )

示例:

复制代码
# GET 模式全参数扫描
python xss_scan.py -u "https://example.com/search?q=test&cat=1" -m GET

# GET 模式只扫描 q 参数
python xss_scan.py -u "https://example.com/search?q=test&cat=1" -m GET --param q

# POST 模式全参数扫描
python xss_scan.py -u "https://example.com/submit" -m POST -d "username=alice&comment=hello"

# POST 模式只扫描 comment 参数
python xss_scan.py -u "https://example.com/submit" -m POST -d "username=alice&comment=hello" --param comment
相关推荐
SelectDB20 小时前
Litefuse 开源并推出单进程轻量模式,25 秒就能跑起来的 Agent 可观测与评估平台
运维·后端·自动化运维
XIAOHEZIcode2 天前
Linux系统鼠标偏移常见原因以及修复方案
linux·运维·游戏
用户0328472220703 天前
如何搭建本地yum源(上)
运维
大树886 天前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠6 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
通信小呆呆6 天前
当算法有了“五感”:多模态数据融合如何向人体感官协同学习?
人工智能·学习·算法·机器学习·机器人
霸道流氓气质6 天前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务
H__Rick6 天前
自动对焦学习-3
人工智能·学习·计算机视觉
Daisy Lee6 天前
量化学习-第1章-什么是量化金融
学习·金融·datawhale
Inhand陈工6 天前
基于台达PLC与映翰通IG502的智慧水产养殖精准投喂与远程运维解决方案
运维·人工智能·物联网·阿里云·信息与通信