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¶m2=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