Compare commits
7 Commits
5eee69704a
...
ae2ee482ad
Author | SHA1 | Date | |
---|---|---|---|
ae2ee482ad | |||
4835af7ff7 | |||
6041a8f573 | |||
bc852ec52c | |||
d60700e215 | |||
464db87919 | |||
102c631ed9 |
52
.github/workflows/detection.yml
vendored
52
.github/workflows/detection.yml
vendored
@@ -1,52 +0,0 @@
|
||||
name: Vulnerability and Backdoor Detection Workflow
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
branches: [main]
|
||||
|
||||
jobs:
|
||||
# build:
|
||||
# runs-on: ubuntu-latest
|
||||
# steps:
|
||||
# - uses: actions/checkout@v2
|
||||
# - name: Install dependencies
|
||||
# run: pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
|
||||
# - name: Run tests
|
||||
# run: python -m unittest discover -s tests
|
||||
|
||||
security_check:
|
||||
runs-on: ubuntu-latest
|
||||
# needs: build # 确保安全检查在构建后执行
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
repository: "sangge/BackDoorBuster"
|
||||
ref: "feature/match"
|
||||
path: "BackDoorBuster"
|
||||
# - name: Install dependencies
|
||||
# run: pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
|
||||
# - name: Run Backdoor and Vulnerability Detection
|
||||
# uses: sangge/BackDoorBuster@feature/match # 使用BackDoorBuster仓库的根目录下的 action.yml
|
||||
# with:
|
||||
# code_path: "./tests"
|
||||
# requirements_file: "./requirements.txt"
|
||||
# output_format: "txt"
|
||||
# 需要新建一个仓库进行测试
|
||||
# - name: Clone custom Git repository
|
||||
# run: |
|
||||
# git clone -b feature/match https://git.mamahaha.work/sangge/BackDoorBuster
|
||||
# cd BackDoorBuster/detection
|
||||
|
||||
- name: Run Backdoor Detection
|
||||
run: python ${{ github.workspace }}/BackDoorBuster/detection/backdoor_detection.py ${{ github.workspace }}/BackDoorBuster/tests txt
|
||||
|
||||
- name: Run Requirements Detection
|
||||
run: python ${{ github.workspace }}/BackDoorBuster/detection/requirements_detection.py ${{ github.workspace }}/BackDoorBuster/crawler/trans_extracted_data.txt ${{ github.workspace }}/BackDoorBuster/requirements.txt txt
|
||||
|
||||
- name: Upload Result Artifacts
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: detection-results
|
||||
path: ./results/code/
|
18
.github/workflows/python-tests.yml
vendored
Normal file
18
.github/workflows/python-tests.yml
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
name: Python application test
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
branches: [main]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: "ubuntu-latest"
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Install dependencies
|
||||
run: pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
|
||||
- name: Run tests
|
||||
run: python -m unittest discover -s tests
|
@@ -1,12 +1,15 @@
|
||||
# Usage: python backdoor_detection.py <code_path> <output_format>
|
||||
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
from typing import Dict, List, Tuple
|
||||
from reportlab.lib.pagesizes import letter
|
||||
from reportlab.pdfgen import canvas
|
||||
from reportlab.lib.styles import getSampleStyleSheet
|
||||
from reportlab.platypus import Paragraph, Spacer, SimpleDocTemplate
|
||||
from reportlab.lib import colors
|
||||
|
||||
SUPPORTED_EXTENSIONS = {".py", ".js", ".cpp"}
|
||||
OUTPUT_FORMATS = ["html", "md", "txt"]
|
||||
OUTPUT_FORMATS = ["html", "md", "txt", "pdf"]
|
||||
|
||||
|
||||
def read_file_content(file_path: str) -> str:
|
||||
@@ -57,110 +60,181 @@ def find_dangerous_functions(
|
||||
clean_line = remove_comments(line, file_extension)
|
||||
if not clean_line:
|
||||
continue
|
||||
found = False
|
||||
for pattern, risk_level in risk_patterns.items():
|
||||
if re.search(pattern, clean_line):
|
||||
classified_results[risk_level].append((line_number, clean_line))
|
||||
found = True
|
||||
break
|
||||
if not found:
|
||||
classified_results["none"].append((line_number, clean_line))
|
||||
return classified_results
|
||||
|
||||
|
||||
def output_results(
|
||||
results: Dict[str, List[Tuple[int, str]]], output_format: str, file_path: str
|
||||
):
|
||||
# Create the 'results' directory if it does not exist
|
||||
# 这里如果集成测试的话应该设置为./
|
||||
results_dir = "./results/code"
|
||||
if not os.path.exists(results_dir):
|
||||
os.makedirs(results_dir)
|
||||
|
||||
base_name = os.path.basename(file_path)
|
||||
output_file = os.path.join(
|
||||
results_dir, f"{os.path.splitext(base_name)[0]}.{output_format}"
|
||||
)
|
||||
|
||||
if output_format == "html":
|
||||
output_html(results, output_file)
|
||||
elif output_format == "md":
|
||||
output_markdown(results, output_file)
|
||||
elif output_format == "txt":
|
||||
output_text(results, output_file)
|
||||
def generate_text_content(results):
|
||||
text_output = "Security Analysis Report\n"
|
||||
for risk_level, entries in results.items():
|
||||
if entries and risk_level != "none":
|
||||
text_output += f"{risk_level.capitalize()} Risk:\n"
|
||||
for line_num, line in entries:
|
||||
text_output += f" Line {line_num}: {line}\n"
|
||||
return text_output
|
||||
|
||||
|
||||
def output_html(results: Dict[str, List[Tuple[int, str]]], file_name: str):
|
||||
html_output = f"<html><head><title>Analysis of {file_name}</title></head><body>"
|
||||
def output_results(results, output_format, output_file=None):
|
||||
if output_file:
|
||||
file_name, file_extension = os.path.splitext(output_file)
|
||||
if output_format not in OUTPUT_FORMATS:
|
||||
output_format = "txt"
|
||||
output_file = f"{file_name}.txt"
|
||||
results_dir = os.path.dirname(output_file)
|
||||
if not os.path.exists(results_dir):
|
||||
os.makedirs(results_dir)
|
||||
if output_format == "pdf":
|
||||
output_pdf(results, output_file)
|
||||
elif output_format == "html":
|
||||
output_html(results, output_file)
|
||||
elif output_format == "md":
|
||||
output_markdown(results, output_file)
|
||||
else: # Default to txt
|
||||
output_text(results, output_file)
|
||||
else:
|
||||
# If no output file is specified, default to text output to the terminal.
|
||||
txt_output = generate_text_content(results)
|
||||
print(txt_output)
|
||||
|
||||
|
||||
def output_pdf(results: Dict[str, List[Tuple[int, str]]], file_name):
|
||||
doc = SimpleDocTemplate(file_name, pagesize=letter)
|
||||
story = []
|
||||
styles = getSampleStyleSheet()
|
||||
|
||||
# Add the title centered
|
||||
title_style = styles["Title"]
|
||||
title_style.alignment = 1 # Center alignment
|
||||
title = Paragraph("Security Analysis Report", title_style)
|
||||
story.append(title)
|
||||
story.append(Spacer(1, 20)) # Space after title
|
||||
|
||||
# Add risk levels and entries
|
||||
normal_style = styles["BodyText"]
|
||||
for risk_level, entries in results.items():
|
||||
if risk_level != "none":
|
||||
story.append(
|
||||
Paragraph(f"{risk_level.capitalize()} Risk:", styles["Heading2"])
|
||||
)
|
||||
for line_num, line in entries:
|
||||
entry = Paragraph(f"Line {line_num}: {line}", normal_style)
|
||||
story.append(entry)
|
||||
story.append(Spacer(1, 12)) # Space between sections
|
||||
|
||||
doc.build(story)
|
||||
|
||||
|
||||
def output_html(results: Dict[str, List[Tuple[int, str]]], file_name=None):
|
||||
html_output = "<html><head><title>Security Analysis Report</title></head><body>"
|
||||
html_output += "<h1>Security Analysis Report</h1>"
|
||||
for risk_level, entries in results.items():
|
||||
html_output += f"<h2>{risk_level.capitalize()} Risk</h2><ul>"
|
||||
for line_num, line in entries:
|
||||
html_output += f"<li>Line {line_num}: {line}</li>"
|
||||
html_output += "</ul>"
|
||||
if risk_level != "none":
|
||||
html_output += f"<h2>{risk_level.capitalize()} Risk</h2><ul>"
|
||||
for line_num, line in entries:
|
||||
html_output += f"<li>{line_num}: {line}</li>"
|
||||
html_output += "</ul>"
|
||||
html_output += "</body></html>"
|
||||
with open(file_name, "w") as file:
|
||||
file.write(html_output)
|
||||
if file_name:
|
||||
with open(file_name, "w") as file:
|
||||
file.write(html_output)
|
||||
else:
|
||||
return html_output
|
||||
|
||||
|
||||
def output_markdown(results: Dict[str, List[Tuple[int, str]]], file_name: str):
|
||||
md_output = f"# Security Analysis Report for {file_name}\n"
|
||||
def output_markdown(results: Dict[str, List[Tuple[int, str]]], file_name=None):
|
||||
md_output = "# Security Analysis Report\n"
|
||||
for risk_level, entries in results.items():
|
||||
md_output += f"## {risk_level.capitalize()} Risk\n"
|
||||
for line_num, line in entries:
|
||||
md_output += f"- Line {line_num}: {line}\n"
|
||||
with open(file_name, "w") as file:
|
||||
file.write(md_output)
|
||||
if risk_level != "none":
|
||||
md_output += f"## {risk_level.capitalize()} Risk\n"
|
||||
for line_num, line in entries:
|
||||
md_output += f"- {line_num}: {line}\n"
|
||||
if file_name:
|
||||
with open(file_name, "w") as file:
|
||||
file.write(md_output)
|
||||
else:
|
||||
return md_output
|
||||
|
||||
|
||||
def output_text(results: Dict[str, List[Tuple[int, str]]], file_name: str):
|
||||
text_output = f"Security Analysis Report for {file_name}\n"
|
||||
def output_text(results: Dict[str, List[Tuple[int, str]]], file_name=None):
|
||||
text_output = "Security Analysis Report\n"
|
||||
for risk_level, entries in results.items():
|
||||
text_output += f"{risk_level.capitalize()} Risk:\n"
|
||||
for line_num, line in entries:
|
||||
text_output += f" Line {line_num}: {line}\n"
|
||||
with open(file_name, "w") as file:
|
||||
file.write(text_output)
|
||||
if risk_level != "none":
|
||||
text_output += f"{risk_level.capitalize()} Risk:\n"
|
||||
for line_num, line in entries:
|
||||
text_output += f" {line_num}: {line}\n"
|
||||
if file_name:
|
||||
with open(file_name, "w") as file:
|
||||
file.write(text_output)
|
||||
else:
|
||||
return text_output
|
||||
|
||||
|
||||
def process_path(path: str, output_format: str):
|
||||
def process_path(path: str, output_format: str, output_file=None):
|
||||
results = {"high": [], "medium": [], "low": [], "none": []}
|
||||
if os.path.isdir(path):
|
||||
for root, dirs, files in os.walk(path):
|
||||
for file in files:
|
||||
file_extension = os.path.splitext(file)[1]
|
||||
if file_extension in SUPPORTED_EXTENSIONS:
|
||||
file_path = os.path.join(root, file)
|
||||
print(f"Processing {file_path}...")
|
||||
file_results = find_dangerous_functions(
|
||||
read_file_content(file_path), file_extension
|
||||
)
|
||||
output_results(file_results, output_format, file_path)
|
||||
for key in file_results:
|
||||
if key != "none": # Exclude 'none' risk level
|
||||
results[key].extend(
|
||||
[
|
||||
(f"{file_path}: Line {line_num}", line)
|
||||
for line_num, line in file_results[key]
|
||||
]
|
||||
)
|
||||
elif os.path.isfile(path):
|
||||
file_extension = os.path.splitext(path)[1]
|
||||
if file_extension in SUPPORTED_EXTENSIONS:
|
||||
file_results = find_dangerous_functions(
|
||||
read_file_content(path), file_extension
|
||||
)
|
||||
output_results(file_results, output_format, path)
|
||||
for key in file_results:
|
||||
if key != "none": # Exclude 'none' risk level
|
||||
results[key].extend(
|
||||
[
|
||||
(f"{path}: Line {line_num}", line)
|
||||
for line_num, line in file_results[key]
|
||||
]
|
||||
)
|
||||
else:
|
||||
print("Unsupported file type.")
|
||||
return
|
||||
else:
|
||||
print("Invalid path.")
|
||||
sys.exit(1)
|
||||
|
||||
output_results(results, output_format, output_file)
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) < 3:
|
||||
print("Usage: python backdoor_detection.py <path> <output_format>")
|
||||
sys.exit(1)
|
||||
path = sys.argv[1]
|
||||
output_format = sys.argv[2]
|
||||
if output_format not in OUTPUT_FORMATS:
|
||||
print(
|
||||
f"Unsupported output format. Supported formats are: {', '.join(OUTPUT_FORMATS)}"
|
||||
)
|
||||
sys.exit(1)
|
||||
process_path(path, output_format)
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(description="Backdoor detection tool.")
|
||||
parser.add_argument("path", help="Path to the code to analyze")
|
||||
parser.add_argument("-o", "--output", help="Output file path", default=None)
|
||||
args = parser.parse_args()
|
||||
output_format = "txt" # Default output format
|
||||
output_file = None
|
||||
if args.output:
|
||||
_, ext = os.path.splitext(args.output)
|
||||
ext = ext.lower()
|
||||
if ext in [".html", ".md", ".txt", ".pdf"]:
|
||||
output_format = ext.replace(".", "")
|
||||
output_file = args.output
|
||||
else:
|
||||
print(
|
||||
"Your input file format was incorrect, the output has been saved as a TXT file."
|
||||
)
|
||||
output_file = args.output.rsplit(".", 1)[0] + ".txt"
|
||||
process_path(args.path, output_format, output_file)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
@@ -1,10 +1,12 @@
|
||||
# Usage: python requirements_detection.py ../crawler/trans_extracted_data.txt ../requirements.txt <output_format>
|
||||
|
||||
import sys
|
||||
import argparse
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
from packaging import version
|
||||
from packaging.specifiers import SpecifierSet
|
||||
import re
|
||||
from reportlab.lib.pagesizes import letter
|
||||
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer
|
||||
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
|
||||
|
||||
|
||||
def load_vulnerable_packages(filename):
|
||||
@@ -38,6 +40,42 @@ def load_requirements(filename):
|
||||
return requirements
|
||||
|
||||
|
||||
def output_pdf(results, file_name):
|
||||
doc = SimpleDocTemplate(file_name, pagesize=letter)
|
||||
story = []
|
||||
styles = getSampleStyleSheet()
|
||||
|
||||
# Custom styles
|
||||
title_style = styles["Title"]
|
||||
title_style.alignment = 1 # Center alignment
|
||||
|
||||
warning_style = ParagraphStyle(
|
||||
"WarningStyle", parent=styles["BodyText"], fontName="Helvetica-Bold"
|
||||
)
|
||||
normal_style = styles["BodyText"]
|
||||
|
||||
# Add the title
|
||||
title = Paragraph("Vulnerability Report", title_style)
|
||||
story.append(title)
|
||||
story.append(Spacer(1, 20)) # Space after title
|
||||
|
||||
# Iterate through results to add entries
|
||||
for result in results:
|
||||
if "WARNING:" in result:
|
||||
# Add warning text in bold
|
||||
entry = Paragraph(
|
||||
result.replace("WARNING:", "<b>WARNING:</b>"), warning_style
|
||||
)
|
||||
else:
|
||||
# Add normal text
|
||||
entry = Paragraph(result, normal_style)
|
||||
|
||||
story.append(entry)
|
||||
story.append(Spacer(1, 12)) # Space between entries
|
||||
|
||||
doc.build(story)
|
||||
|
||||
|
||||
def output_results(filename, results, format_type):
|
||||
"""根据指定的格式输出结果"""
|
||||
output_dir = os.path.dirname(filename)
|
||||
@@ -55,43 +93,67 @@ def output_results(filename, results, format_type):
|
||||
file.write("# Vulnerability Report\n")
|
||||
for result in results:
|
||||
file.write(f"* {result}\n")
|
||||
else: # default to txt
|
||||
elif format_type == "pdf":
|
||||
output_pdf(results, filename)
|
||||
else: # 默认为txt
|
||||
for result in results:
|
||||
file.write(f"{result}\n")
|
||||
|
||||
|
||||
def check_vulnerabilities(requirements, vulnerabilities, output_format):
|
||||
def check_vulnerabilities(requirements, vulnerabilities, output_file):
|
||||
"""检查依赖项是否存在已知漏洞,并输出结果"""
|
||||
results = []
|
||||
results_warning = [] # 存储有漏洞的依赖
|
||||
results_ok = [] # 存储没有漏洞的依赖
|
||||
|
||||
for req_name, req_version in requirements.items():
|
||||
if req_name in vulnerabilities:
|
||||
spec = vulnerabilities[req_name]
|
||||
if version.parse(req_version) in spec:
|
||||
results.append(f"WARNING: {req_name}=={req_version} is vulnerable!")
|
||||
results_warning.append(
|
||||
f"WARNING: {req_name}=={req_version} is vulnerable!"
|
||||
)
|
||||
else:
|
||||
results.append(f"OK: {req_name}=={req_version} is not affected.")
|
||||
results_ok.append(f"OK: {req_name}=={req_version} is not affected.")
|
||||
else:
|
||||
results.append(f"OK: {req_name} not found in the vulnerability database.")
|
||||
# 集成测试这里应该修改为./
|
||||
output_results(
|
||||
"./results/requirements/results." + output_format, results, output_format
|
||||
)
|
||||
results_ok.append(
|
||||
f"OK: {req_name} not found in the vulnerability database."
|
||||
)
|
||||
|
||||
# 合并结果,先输出所有警告,然后输出所有正常情况
|
||||
results = results_warning + results_ok
|
||||
|
||||
if output_file:
|
||||
filename, ext = os.path.splitext(output_file)
|
||||
output_format = ext[1:] if ext[1:] else "txt"
|
||||
if output_format not in ["txt", "md", "html", "pdf"]:
|
||||
print("Warning: Invalid file format specified. Defaulting to TXT format.")
|
||||
output_format = "txt" # 确保使用默认格式
|
||||
output_file = filename + ".txt"
|
||||
output_results(output_file, results, output_format)
|
||||
else:
|
||||
print("\n".join(results))
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) < 4:
|
||||
print(
|
||||
"Usage: python script.py <vulnerabilities_file> <requirements_file> <output_format>"
|
||||
)
|
||||
sys.exit(1)
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Check project dependencies for vulnerabilities."
|
||||
)
|
||||
parser.add_argument(
|
||||
"vulnerabilities_file", help="Path to the file containing vulnerability data"
|
||||
)
|
||||
parser.add_argument(
|
||||
"requirements_file", help="Path to the requirements file of the project"
|
||||
)
|
||||
parser.add_argument(
|
||||
"-o",
|
||||
"--output",
|
||||
help="Output file path with extension, e.g., './output/report.txt'",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
vulnerabilities_file = sys.argv[1]
|
||||
requirements_file = sys.argv[2]
|
||||
output_format = sys.argv[3]
|
||||
|
||||
vulnerabilities = load_vulnerable_packages(vulnerabilities_file)
|
||||
requirements = load_requirements(requirements_file)
|
||||
check_vulnerabilities(requirements, vulnerabilities, output_format)
|
||||
vulnerabilities = load_vulnerable_packages(args.vulnerabilities_file)
|
||||
requirements = load_requirements(args.requirements_file)
|
||||
check_vulnerabilities(requirements, vulnerabilities, args.output)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
@@ -0,0 +1,81 @@
|
||||
# 项目设计文档 - 后门检测系统
|
||||
|
||||
## 静态代码后门检测
|
||||
|
||||
**功能描述**:
|
||||
这个脚本用于扫描指定路径下的代码文件,检测潜在的危险函数调用,支持 `.py`, `.js`, `.cpp` 文件。
|
||||
|
||||
**主要组件**:
|
||||
|
||||
- `read_file_content(file_path)`: 读取文件内容。
|
||||
- `remove_comments(code, extension)`: 移除代码中的注释。
|
||||
- `find_dangerous_functions(file_content, file_extension)`: 检测并标记危险函数的使用与威胁等级。
|
||||
- `output_results(results, output_format, output_file)`: 输出检测结果到指定格式和路径。
|
||||
|
||||
**输入**:
|
||||
|
||||
- 代码路径(文件或目录)。
|
||||
- 输出文件路径和格式(通过命令行参数指定)。
|
||||
|
||||
**输出**:
|
||||
|
||||
- 安全分析报告,可选格式为 HTML、Markdown、TXT 或 PDF。
|
||||
|
||||
**设计考虑**:
|
||||
|
||||
- 动态识别文件类型并适应不同的注释规则。
|
||||
- 使用正则表达式检测潜在的危险函数调用。
|
||||
- 使用 ReportLab 库生成 PDF,提供丰富的文档布局。
|
||||
|
||||
**使用示例**:
|
||||
|
||||
```bash
|
||||
python backdoor_detection.py ./src -o ./output/report.pdf
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 依赖版本漏洞检测
|
||||
|
||||
**功能描述**:
|
||||
这个脚本用于检测项目依赖中是否存在已知的安全漏洞。它通过读取一个包含漏洞信息的文件和项目的 `requirements.txt`,对比确定哪些依赖项是不安全的。
|
||||
|
||||
**主要组件**:
|
||||
|
||||
- `load_vulnerable_packages(filename)`: 从给定的文件中加载包含漏洞的包信息。
|
||||
- `load_requirements(filename)`: 从项目的 `requirements.txt` 文件中加载依赖信息。
|
||||
- `output_results(filename, results, format_type)`: 根据指定格式输出检测结果。
|
||||
- `check_vulnerabilities(requirements, vulnerabilities, output_file)`: 核心功能,对比依赖与漏洞信息并生成报告。
|
||||
- `output_results(filename, results, format_type)`: 根据用户需求设置扫描结果输出格式。
|
||||
|
||||
**输入**:
|
||||
|
||||
- 依赖漏洞文件路径。
|
||||
- 项目 `requirements.txt` 文件路径。
|
||||
- 输出文件路径和格式(通过命令行参数指定)。
|
||||
|
||||
**输出**:
|
||||
|
||||
- 报告文件,格式可以是 HTML、Markdown、TXT 或 PDF。
|
||||
|
||||
**设计考虑**:
|
||||
|
||||
- 使用 `argparse` 处理命令行输入。
|
||||
- 使用 `packaging` 库来处理和比较版本号。
|
||||
- 使用异常处理来确保文件读写操作的安全性。
|
||||
|
||||
**使用示例**:
|
||||
|
||||
```bash
|
||||
python requirements_detection.py vulnerabilities_data.txt requirements.txt -o ./output/report.md
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 结论
|
||||
|
||||
这两个脚本为后门检测项目提供了两个不同的安全检查角度:一个是外部依赖的安全性,另一个是内部代码潜在的安全漏洞。通过将这两种功能结合,可以提供一个全面的安全审计工具,以保障项目的安全性。
|
||||
|
||||
---
|
||||
|
||||
以上就是针对后门检测系统的项目设计文档。通过这样的设计,项目团队可以更好地了解系统的运作方式和如何使用系统进行安全检测。
|
||||
|
@@ -6,7 +6,7 @@
|
||||
|
||||
工具开发:使用正则表达式和模式匹配来搜索代码中的可疑结构或者片段。
|
||||
|
||||
参考项目: https://github.com/SonarSource/sonarqube
|
||||
参考项目: [https://github.com/SonarSource/sonarqube]
|
||||
|
||||
## 控制流分析
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
实施策略:开发脚本或工具来自动化检查外部库的可信度和更新记录。
|
||||
|
||||
这个网站可以搜索依赖中是否存在漏洞: https://security.snyk.io/package/pip/
|
||||
这个网站可以搜索依赖中是否存在漏洞: [https://security.snyk.io/package/pip/]
|
||||
|
||||
## 异常行为检测
|
||||
|
||||
|
@@ -0,0 +1,51 @@
|
||||
# 技术说明文档 - 后门检测系统
|
||||
|
||||
本文档详细说明了后门检测系统中使用的技术和库,以及这些技术的应用方式和原理。
|
||||
|
||||
## 1. Python 编程语言
|
||||
|
||||
本项目主要使用 Python 编程语言编写。Python 是一种解释型、高级和通用的编程语言。Python 的设计哲学强调代码的可读性和简洁的语法(尤其是使用空格缩进划分代码块,而非使用大括号或关键字)。详细信息可参考:[Python 官网](https://www.python.org/)
|
||||
|
||||
## 2. `packaging` 库
|
||||
|
||||
`packaging` 库提供了版本号解析和比较的功能,非常适合用于处理和比较软件包的版本号。在本项目中,它被用来解析 `requirements.txt` 文件中的依赖版本,并与已知的漏洞版本进行比较,以判断是否存在安全风险。
|
||||
|
||||
- **主要应用**:比较依赖包版本是否在漏洞版本范围内。
|
||||
- **官方文档**:[packaging on PyPI](https://pypi.org/project/packaging/)
|
||||
|
||||
## 3. `reportlab` 库
|
||||
|
||||
`reportlab` 是 Python 中强大的 PDF 生成库,允许快速创建复杂的 PDF 文档。在此项目中,`reportlab` 用于生成具有格式化文本和布局的 PDF 报告。
|
||||
|
||||
- **主要应用**:生成 PDF 格式的报告,包括带有标题、段落和间距的文档结构。
|
||||
- **官方文档**:[ReportLab User Guide](https://www.reportlab.com/docs/reportlab-user-guide.pdf)
|
||||
|
||||
## 4. `argparse` 库
|
||||
|
||||
`argparse` 库是用于解析命令行参数和选项的标准库。它让开发者能够轻松地编写用户友好的命令行接口,程序可以从 `sys.argv` 中提取出所需的命令行参数。本项目中使用 `argparse` 来接收用户指定的文件路径和输出格式。
|
||||
|
||||
- **主要应用**:解析命令行输入,获取用户指定的文件路径和输出选项。
|
||||
- **官方文档**:[argparse — Command-line option and argument parsing](https://docs.python.org/3/library/argparse.html)
|
||||
|
||||
## 5. 正则表达式 (`re` 模块)
|
||||
|
||||
正则表达式在本项目中用于从配置文件中提取出软件包名称和版本范围。`re` 模块提供了对正则表达式的全面支持,允许进行复杂的字符串搜索、匹配及替换。
|
||||
|
||||
- **主要应用**:解析和处理文本数据,特别是在加载漏洞信息和分析代码文件时用于提取特定模式的字符串。
|
||||
- **官方文档**:[re — Regular expression operations](https://docs.python.org/3/library/re.html)
|
||||
|
||||
## 6. 文件处理
|
||||
|
||||
文件的读取和写入是通过 Python 的内置功能进行的,确保了项目能够处理外部数据文件和输出结果到指定的文件中。
|
||||
|
||||
- **主要应用**:读取漏洞数据文件和依赖文件,输出结果报告到文本、Markdown、HTML 或 PDF 文件。
|
||||
|
||||
## 7. 代码和风险分析
|
||||
|
||||
项目中实现了基本的静态代码分析功能,用于识别和报告潜在的安全风险函数调用,如 `system`、`exec` 等。
|
||||
|
||||
- **技术说明**:通过正则表达式匹配高风险函数的调用,评估代码文件的安全性。
|
||||
|
||||
通过这些技术的综合应用,后门检测系统能够为用户提供全面的安全检测功能,
|
||||
|
||||
帮助识别和预防安全风险。这些技术的深入了解和正确应用是确保系统有效运行的关键。
|
||||
|
@@ -0,0 +1,81 @@
|
||||
# 使用说明文档 - 后门检测系统
|
||||
|
||||
本文档提供了后门检测系统的使用方法,包括依赖版本漏洞检测和静态代码后门检测两部分。这将帮助用户正确执行安全检测,并理解输出结果。
|
||||
|
||||
## 安装需求
|
||||
|
||||
在开始使用本系统之前,请确保您的环境中安装了以下依赖:
|
||||
|
||||
- Python 3.6 或更高版本
|
||||
- `packaging` 库:用于版本控制和比较
|
||||
- `reportlab` 库:用于生成 PDF 报告
|
||||
|
||||
您可以通过以下命令安装必要的 Python 库:
|
||||
|
||||
```bash
|
||||
pip install packaging reportlab
|
||||
```
|
||||
|
||||
## 下载和配置
|
||||
|
||||
- 克隆或下载后门检测系统到您的本地环境。
|
||||
- 确保脚本文件 (`requirements_detection.py` 和 `backdoor_detection.py`) 在您的工作目录中。
|
||||
|
||||
## 运行依赖版本漏洞检测脚本
|
||||
|
||||
**命令格式**:
|
||||
|
||||
```bash
|
||||
python requirements_detection.py <vulnerabilities_file> <requirements_file> -o <output_file>
|
||||
```
|
||||
|
||||
**参数说明**:
|
||||
|
||||
- `<vulnerabilities_file>`: 包含漏洞信息的文件路径。
|
||||
- `<requirements_file>`: 项目的 `requirements.txt` 文件路径。
|
||||
- `<output_file>`: 指定输出结果的文件路径和格式,支持的格式有 `.txt`, `.md`, `.html`, `.pdf`。
|
||||
|
||||
**示例**:
|
||||
|
||||
```bash
|
||||
python requirements_detection.py vulnerabilities_data.txt requirements.txt -o output/report.md
|
||||
```
|
||||
|
||||
## 运行静态代码后门检测脚本
|
||||
|
||||
**命令格式**:
|
||||
|
||||
```bash
|
||||
python backdoor_detection.py <code_path> -o <output_file>
|
||||
```
|
||||
|
||||
**参数说明**:
|
||||
|
||||
- `<code_path>`: 代码文件或目录的路径。
|
||||
- `<output_file>`: 指定输出结果的文件路径和格式,支持的格式有 `.txt`, `.md`, `.html`, `.pdf`。
|
||||
|
||||
**示例**:
|
||||
|
||||
```bash
|
||||
python backdoor_detection.py ./src -o output/report.pdf
|
||||
```
|
||||
|
||||
## 结果解读
|
||||
|
||||
- 输出结果将根据指定的格式保存在您指定的文件中。
|
||||
- 结果中会标注出每个文件中发现的高风险和中风险函数调用位置。
|
||||
- 对于依赖检测,结果将标明每个依赖包的安全状态,包括存在安全风险的依赖及其版本。
|
||||
|
||||
## 常见问题处理
|
||||
|
||||
- 确保所有路径都正确无误,避免因路径错误导致文件读取失败。
|
||||
- 如果输出格式指定错误,系统将默认输出为 `.txt` 格式。
|
||||
- 确保安装了所有必要的依赖库,以避免运行时错误。
|
||||
|
||||
## 支持
|
||||
|
||||
如果您在使用过程中遇到任何问题,或需要进一步的技术支持,请联系开发团队或访问我们的Git仓库以获取帮助和最新信息。
|
||||
|
||||
---
|
||||
|
||||
以上是后门检测系统的使用说明文档。请按照这些步骤进行操作,以确保您能有效地使用本系统进行安全检测。
|
||||
|
@@ -1,6 +1,2 @@
|
||||
apache-airflow==2.8.0
|
||||
mlflow==2.5.1
|
||||
torch==2.0.0
|
||||
aiohttp==3.6.2
|
||||
flask==1.1.2
|
||||
numpy==1.18.5
|
||||
reportlab
|
||||
packaging
|
@@ -1 +0,0 @@
|
||||
<html><head><title>Analysis of ../results/code\test_backdoor_detection.html</title></head><body><h1>Security Analysis Report</h1><h2>High Risk</h2><ul><li>Line 9: os.system('rm -rf /')</li><li>Line 10: exec('print("Hello")')</li><li>Line 11: eval('2 + 2')</li><li>Line 15: self.assertIn((2, "os.system('rm -rf /')"), results["high"])</li><li>Line 16: self.assertIn((3, "exec('print(\"Hello\")')"), results["high"])</li><li>Line 17: self.assertIn((4, "eval('2 + 2')"), results["high"])</li><li>Line 44: eval('2 + 2')</li><li>Line 50: (3, "eval('2 + 2')"),</li></ul><h2>Medium Risk</h2><ul><li>Line 21: subprocess.run(['ls', '-l'])</li><li>Line 23: os.popen('ls')</li><li>Line 27: self.assertIn((2, "subprocess.run(['ls', '-l'])"), results["medium"])</li><li>Line 28: self.assertIn((4, "os.popen('ls')"), results["medium"])</li><li>Line 45: subprocess.run(['echo', 'hello'])</li><li>Line 54: (4, "subprocess.run(['echo', 'hello'])"),</li></ul><h2>Low Risk</h2><ul></ul><h2>None Risk</h2><ul><li>Line 1: import unittest</li><li>Line 3: from detection.backdoor_detection import find_dangerous_functions</li><li>Line 6: class TestBackdoorDetection(unittest.TestCase):</li><li>Line 7: def test_high_risk_detection(self):</li><li>Line 8: content = """import os</li><li>Line 12: """</li><li>Line 13: file_extension = ".py"</li><li>Line 14: results = find_dangerous_functions(content, file_extension)</li><li>Line 19: def test_medium_risk_detection(self):</li><li>Line 20: content = """import subprocess</li><li>Line 22: import os</li><li>Line 24: """</li><li>Line 25: file_extension = ".py"</li><li>Line 26: results = find_dangerous_functions(content, file_extension)</li><li>Line 30: def test_no_risk_detection(self):</li><li>Line 31: content = """a = 10</li><li>Line 32: b = a + 5</li><li>Line 33: print('This should not be detected as risky.')</li><li>Line 34: """</li><li>Line 35: file_extension = ".py"</li><li>Line 36: results = find_dangerous_functions(content, file_extension)</li><li>Line 37: self.assertEqual(len(results["high"]), 0)</li><li>Line 38: self.assertEqual(len(results["medium"]), 0)</li><li>Line 39: self.assertEqual(len(results["low"]), 0)</li><li>Line 41: def test_inclusion_of_comments(self):</li><li>Line 42: content = """</li><li>Line 43: print('This is a safe line')</li><li>Line 46: """</li><li>Line 47: file_extension = ".py"</li><li>Line 48: results = find_dangerous_functions(content, file_extension)</li><li>Line 49: self.assertIn(</li><li>Line 51: results["high"],</li><li>Line 52: )</li><li>Line 53: self.assertIn(</li><li>Line 55: results["medium"],</li><li>Line 56: )</li><li>Line 59: if __name__ == "__main__":</li><li>Line 60: unittest.main()</li></ul></body></html>
|
@@ -1,57 +0,0 @@
|
||||
# Security Analysis Report for ../results/code\test_backdoor_detection.md
|
||||
## High Risk
|
||||
- Line 9: os.system('rm -rf /')
|
||||
- Line 10: exec('print("Hello")')
|
||||
- Line 11: eval('2 + 2')
|
||||
- Line 15: self.assertIn((2, "os.system('rm -rf /')"), results["high"])
|
||||
- Line 16: self.assertIn((3, "exec('print(\"Hello\")')"), results["high"])
|
||||
- Line 17: self.assertIn((4, "eval('2 + 2')"), results["high"])
|
||||
- Line 44: eval('2 + 2')
|
||||
- Line 50: (3, "eval('2 + 2')"),
|
||||
## Medium Risk
|
||||
- Line 21: subprocess.run(['ls', '-l'])
|
||||
- Line 23: os.popen('ls')
|
||||
- Line 27: self.assertIn((2, "subprocess.run(['ls', '-l'])"), results["medium"])
|
||||
- Line 28: self.assertIn((4, "os.popen('ls')"), results["medium"])
|
||||
- Line 45: subprocess.run(['echo', 'hello'])
|
||||
- Line 54: (4, "subprocess.run(['echo', 'hello'])"),
|
||||
## Low Risk
|
||||
## None Risk
|
||||
- Line 1: import unittest
|
||||
- Line 3: from detection.backdoor_detection import find_dangerous_functions
|
||||
- Line 6: class TestBackdoorDetection(unittest.TestCase):
|
||||
- Line 7: def test_high_risk_detection(self):
|
||||
- Line 8: content = """import os
|
||||
- Line 12: """
|
||||
- Line 13: file_extension = ".py"
|
||||
- Line 14: results = find_dangerous_functions(content, file_extension)
|
||||
- Line 19: def test_medium_risk_detection(self):
|
||||
- Line 20: content = """import subprocess
|
||||
- Line 22: import os
|
||||
- Line 24: """
|
||||
- Line 25: file_extension = ".py"
|
||||
- Line 26: results = find_dangerous_functions(content, file_extension)
|
||||
- Line 30: def test_no_risk_detection(self):
|
||||
- Line 31: content = """a = 10
|
||||
- Line 32: b = a + 5
|
||||
- Line 33: print('This should not be detected as risky.')
|
||||
- Line 34: """
|
||||
- Line 35: file_extension = ".py"
|
||||
- Line 36: results = find_dangerous_functions(content, file_extension)
|
||||
- Line 37: self.assertEqual(len(results["high"]), 0)
|
||||
- Line 38: self.assertEqual(len(results["medium"]), 0)
|
||||
- Line 39: self.assertEqual(len(results["low"]), 0)
|
||||
- Line 41: def test_inclusion_of_comments(self):
|
||||
- Line 42: content = """
|
||||
- Line 43: print('This is a safe line')
|
||||
- Line 46: """
|
||||
- Line 47: file_extension = ".py"
|
||||
- Line 48: results = find_dangerous_functions(content, file_extension)
|
||||
- Line 49: self.assertIn(
|
||||
- Line 51: results["high"],
|
||||
- Line 52: )
|
||||
- Line 53: self.assertIn(
|
||||
- Line 55: results["medium"],
|
||||
- Line 56: )
|
||||
- Line 59: if __name__ == "__main__":
|
||||
- Line 60: unittest.main()
|
@@ -1,57 +0,0 @@
|
||||
Security Analysis Report for ../results/code\test_backdoor_detection.txt
|
||||
High Risk:
|
||||
Line 9: os.system('rm -rf /')
|
||||
Line 10: exec('print("Hello")')
|
||||
Line 11: eval('2 + 2')
|
||||
Line 15: self.assertIn((2, "os.system('rm -rf /')"), results["high"])
|
||||
Line 16: self.assertIn((3, "exec('print(\"Hello\")')"), results["high"])
|
||||
Line 17: self.assertIn((4, "eval('2 + 2')"), results["high"])
|
||||
Line 44: eval('2 + 2')
|
||||
Line 50: (3, "eval('2 + 2')"),
|
||||
Medium Risk:
|
||||
Line 21: subprocess.run(['ls', '-l'])
|
||||
Line 23: os.popen('ls')
|
||||
Line 27: self.assertIn((2, "subprocess.run(['ls', '-l'])"), results["medium"])
|
||||
Line 28: self.assertIn((4, "os.popen('ls')"), results["medium"])
|
||||
Line 45: subprocess.run(['echo', 'hello'])
|
||||
Line 54: (4, "subprocess.run(['echo', 'hello'])"),
|
||||
Low Risk:
|
||||
None Risk:
|
||||
Line 1: import unittest
|
||||
Line 3: from detection.backdoor_detection import find_dangerous_functions
|
||||
Line 6: class TestBackdoorDetection(unittest.TestCase):
|
||||
Line 7: def test_high_risk_detection(self):
|
||||
Line 8: content = """import os
|
||||
Line 12: """
|
||||
Line 13: file_extension = ".py"
|
||||
Line 14: results = find_dangerous_functions(content, file_extension)
|
||||
Line 19: def test_medium_risk_detection(self):
|
||||
Line 20: content = """import subprocess
|
||||
Line 22: import os
|
||||
Line 24: """
|
||||
Line 25: file_extension = ".py"
|
||||
Line 26: results = find_dangerous_functions(content, file_extension)
|
||||
Line 30: def test_no_risk_detection(self):
|
||||
Line 31: content = """a = 10
|
||||
Line 32: b = a + 5
|
||||
Line 33: print('This should not be detected as risky.')
|
||||
Line 34: """
|
||||
Line 35: file_extension = ".py"
|
||||
Line 36: results = find_dangerous_functions(content, file_extension)
|
||||
Line 37: self.assertEqual(len(results["high"]), 0)
|
||||
Line 38: self.assertEqual(len(results["medium"]), 0)
|
||||
Line 39: self.assertEqual(len(results["low"]), 0)
|
||||
Line 41: def test_inclusion_of_comments(self):
|
||||
Line 42: content = """
|
||||
Line 43: print('This is a safe line')
|
||||
Line 46: """
|
||||
Line 47: file_extension = ".py"
|
||||
Line 48: results = find_dangerous_functions(content, file_extension)
|
||||
Line 49: self.assertIn(
|
||||
Line 51: results["high"],
|
||||
Line 52: )
|
||||
Line 53: self.assertIn(
|
||||
Line 55: results["medium"],
|
||||
Line 56: )
|
||||
Line 59: if __name__ == "__main__":
|
||||
Line 60: unittest.main()
|
@@ -1,9 +0,0 @@
|
||||
<html><head><title>Vulnerability Report</title></head><body>
|
||||
<h1>Vulnerability Report</h1>
|
||||
<p>OK: apache-airflow==2.8.0 is not affected.</p>
|
||||
<p>WARNING: mlflow==2.5.1 is vulnerable!</p>
|
||||
<p>OK: torch==2.0.0 is not affected.</p>
|
||||
<p>WARNING: aiohttp==3.6.2 is vulnerable!</p>
|
||||
<p>OK: flask not found in the vulnerability database.</p>
|
||||
<p>OK: numpy not found in the vulnerability database.</p>
|
||||
</body></html>
|
@@ -1,7 +0,0 @@
|
||||
# Vulnerability Report
|
||||
* OK: apache-airflow==2.8.0 is not affected.
|
||||
* WARNING: mlflow==2.5.1 is vulnerable!
|
||||
* OK: torch==2.0.0 is not affected.
|
||||
* WARNING: aiohttp==3.6.2 is vulnerable!
|
||||
* OK: flask not found in the vulnerability database.
|
||||
* OK: numpy not found in the vulnerability database.
|
@@ -1,6 +0,0 @@
|
||||
OK: apache-airflow==2.8.0 is not affected.
|
||||
WARNING: mlflow==2.5.1 is vulnerable!
|
||||
OK: torch==2.0.0 is not affected.
|
||||
WARNING: aiohttp==3.6.2 is vulnerable!
|
||||
OK: flask not found in the vulnerability database.
|
||||
OK: numpy not found in the vulnerability database.
|
Reference in New Issue
Block a user