
virustotal是一个免费的服务,用于分析可疑文件和url,以快速检测病毒、蠕虫、特洛伊木马和其他类型的恶意软件。其api允许开发者将virustotal的功能集成到自己的应用程序中,实现自动化安全分析。使用virustotal api扫描url通常涉及两个主要步骤:首先提交待扫描的url,然后使用返回的分析id查询扫描结果。
向VirusTotal提交URL进行扫描是通过发送POST请求完成的。API会返回一个包含分析ID的响应,该ID用于后续查询扫描结果。以下是一个提交URL的Python代码示例:
import requests
import json
def submit_url_for_scan(api_key, scan_url):
"""
向VirusTotal提交URL进行扫描。
"""
submission_url = "https://www.virustotal.com/api/v3/urls"
payload = {"url": scan_url}
headers = {
"accept": "application/json",
"x-apikey": api_key,
}
try:
response = requests.post(submission_url, data=payload, headers=headers)
response.raise_for_status() # 检查HTTP错误
response_data = response.json()
# 提取完整的分析ID
full_analysis_id = response_data.get('data', {}).get('id', '')
if full_analysis_id:
print(f"URL提交成功,完整分析ID: {full_analysis_id}")
return full_analysis_id
else:
print(f"错误:未能从提交响应中获取分析ID。响应: {json.dumps(response_data, indent=2)}")
return None
except requests.exceptions.RequestException as e:
print(f"提交URL时发生请求错误: {e}")
return None
except json.JSONDecodeError:
print(f"提交URL时解析JSON响应失败。响应内容: {response.text}")
return None
# 示例调用 (请替换为您的实际API Key)
# api_key = "YOUR_VIRUSTOTAL_API_KEY"
# url_to_scan = "https://www.youtube.com/"
# analysis_id = submit_url_for_scan(api_key, url_to_scan)
# print(f"获取到的分析ID: {analysis_id}")在上述代码中,full_analysis_id将获取到一个形如u-HASH-TIMESTAMP的字符串,例如u-dbae2d0204aa489e234eb2f903a0127b17c712386428cab12b86c5f68aa75867-1701503514。这个完整的ID是提交操作的标识符。
在获取到full_analysis_id后,下一步是使用该ID查询扫描结果。然而,直接将此完整ID用于查询API可能会遇到"Wrong URL id"的错误,如下所示:
{
"error": {
"message": "Wrong URL id: u-dbae2d0204aa489e234eb2f903a0127b17c712386428cab12b86c5f68aa75867-1701503514",
"code": "BadRequestError"
}
}这个错误表明,尽管我们获得了有效的分析ID,但用于查询的ID格式不符合VirusTotal API的预期。根据VirusTotal的API设计,在查询URL分析结果时,它期望的ID是URL哈希值本身,而不是包含前缀(如u-)和时间戳的完整分析ID。
立即学习“Python免费学习笔记(深入)”;
解决“Wrong URL id”错误的关键在于从full_analysis_id中提取出正确的查询ID。通常,VirusTotal返回的URL分析ID格式为type-actual_id-timestamp,其中type是资源类型(如u代表URL),actual_id是实际的哈希值或标识符,timestamp是时间戳。对于URL,我们需要提取的是中间的actual_id部分。
我们可以通过字符串分割的方法来实现这一点:
# 假设 full_analysis_id = "u-dbae2d0204aa489e234eb2f903a0127b17c712386428cab12b86c5f68aa75867-1701503514"
parts = full_analysis_id.split('-')
if len(parts) > 1:
retrieval_id = parts[1] # 获取中间的哈希部分
else:
# 处理格式异常情况
retrieval_id = full_analysis_id # 如果格式不符,尝试使用原始ID,但可能仍会失败
print(f"用于查询的ID: {retrieval_id}")将提交URL和正确提取ID的逻辑整合起来,我们可以构建一个完整的URL扫描和结果查询函数:
import requests
import json
import time
def scan_and_retrieve_url_report(api_key, scan_url):
"""
使用VirusTotal API扫描URL并获取其分析报告。
"""
# --- 步骤1: 提交URL进行扫描 ---
submission_url = "https://www.virustotal.com/api/v3/urls"
payload = {"url": scan_url}
headers = {
"accept": "application/json",
"x-apikey": api_key,
}
print(f"正在提交URL: {scan_url} 进行扫描...")
try:
response = requests.post(submission_url, data=payload, headers=headers)
response.raise_for_status()
submission_data = response.json()
full_analysis_id = submission_data.get('data', {}).get('id', '')
if not full_analysis_id:
print(f"错误:未能从URL提交响应中获取完整分析ID。响应: {json.dumps(submission_data, indent=2)}")
return None
print(f"URL提交成功。完整分析ID: {full_analysis_id}")
# --- 步骤2: 提取用于查询的ID ---
parts = full_analysis_id.split('-')
if len(parts) >= 2: # 确保至少有两部分,我们取第二部分
retrieval_id = parts[1]
else:
print(f"错误:分析ID格式异常,无法提取查询ID: {full_analysis_id}")
return None
print(f"提取的查询ID: {retrieval_id}")
# --- 步骤3: 查询分析结果 ---
# VirusTotal可能需要一些时间来处理扫描,这里可以添加一个简单的重试机制
max_retries = 5
for attempt in range(max_retries):
retrieval_url = f"https://www.virustotal.com/api/v3/urls/{retrieval_id}"
print(f"尝试查询分析报告 (尝试 {attempt + 1}/{max_retries})...")
report_response = requests.get(retrieval_url, headers=headers)
if report_response.status_code == 200:
report_data = report_response.json()
print("成功获取URL分析报告:")
# 可以根据需要进一步解析报告内容
# 例如,打印总体检测结果
stats = report_data.get('data', {}).get('attributes', {}).get('last_analysis_stats', {})
print(f" 恶意检测数: {stats.get('malicious', 0)}")
print(f" 可疑检测数: {stats.get('suspicious', 0)}")
print(f" 无害检测数: {stats.get('harmless', 0)}")
print(f" 未检测数: {stats.get('undetected', 0)}")
return report_data
elif report_response.status_code == 404: # Not Found,可能还在处理中
print(f"报告尚未准备好或ID无效。响应: {report_response.text}")
if attempt < max_retries - 1:
time.sleep(10) # 等待10秒后重试
else:
print("达到最大重试次数,未能获取报告。")
return None
else:
print(f"查询报告时发生HTTP错误: {report_response.status_code} - {report_response.text}")
return None
except requests.exceptions.RequestException as e:
print(f"API请求发生错误: {e}")
return None
except json.JSONDecodeError:
print(f"解析API响应失败。响应内容: {response.text}")
return None
except Exception as e:
print(f"发生未知错误: {e}")
return None
# --- 实际调用示例 ---
# 请务必替换为您的VirusTotal API Key
VIRUSTOTAL_API_KEY = "YOUR_VIRUSTOTAL_API_KEY"
TEST_URL = "https://www.youtube.com/" # 示例安全URL
# TEST_URL = "http://testphp.vulnweb.com/t.php?test=test" # 示例可能被标记的URL
if VIRUSTOTAL_API_KEY == "YOUR_VIRUSTOTAL_API_KEY":
print("请将 'YOUR_VIRUSTOTAL_API_KEY' 替换为您的实际VirusTotal API Key。")
else:
report = scan_and_retrieve_url_report(VIRUSTOTAL_API_KEY, TEST_URL)
# if report:
# print("\n完整报告数据 (部分展示):")
# print(json.dumps(report, indent=2)[:500] + "...") # 打印报告前500字符通过本教程,您应该已经掌握了如何使用Python与VirusTotal API进行URL扫描的完整流程,并特别解决了在查询分析结果时遇到的“Wrong URL id”错误。正确的ID提取是成功获取报告的关键。结合健壮的错误处理和对API限制的考量,您可以高效地利用VirusTotal API增强您的网络安全分析能力。
以上就是使用Python和VirusTotal API进行URL扫描及结果解析指南的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号