From 207c24a3d30031f37d485556d54ac16188ce9960 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=97=E5=AE=B8=C2=B7=E8=B0=A2=E5=B0=94=E6=AF=94?= <88515720+ChinaRan0@users.noreply.github.com> Date: Tue, 4 Feb 2025 17:49:47 +0800 Subject: [PATCH] Add files via upload --- DeepSeekSelfTool.py | 32 +++-- config.py | 4 +- ollamaMain.py | 334 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 356 insertions(+), 14 deletions(-) create mode 100644 ollamaMain.py diff --git a/DeepSeekSelfTool.py b/DeepSeekSelfTool.py index bfc2e2b..b219590 100644 --- a/DeepSeekSelfTool.py +++ b/DeepSeekSelfTool.py @@ -364,17 +364,25 @@ class SourceCodeAuditThread(QThread): # API请求 try: - prompt = f"""请对以下代码文件进行安全审计,要求: -1. 识别SQL注入、XSS、文件包含、命令执行等漏洞 -2. 检查不安全的权限设置和敏感信息泄露 -3. 输出格式:【文件名】{os.path.basename(file_path)} - - 漏洞类型: - - 危险等级: - - 位置行号: - - 修复建议: -4.如果不存在漏洞,则不输出 -5.忽略API请求失败,不输出 -文件内容: + prompt = f"""【强制指令】你是一个专业的安全审计AI,请按以下要求分析代码: + +1. 漏洞分析流程: + 1.1 识别潜在风险点(SQL操作、文件操作、用户输入点、文件上传漏洞、CSRF、SSRF、XSS、RCE、OWASP top10等漏洞) + 1.2 验证漏洞可利用性 + 1.3 按CVSS评分标准评估风险等级 + +2. 输出规则: + - 仅输出确认存在的高危/中危漏洞 + - 使用严格格式:[风险等级] 类型 - 位置:行号 - 50字内描述 + - 禁止解释漏洞原理 + - 禁止给出修复建议 + - 每文件最多报告3个最严重问题 + +3. 输出示例(除此外不要有任何输出): + [高危] SQL注入 - {os.path.basename(file_path)}:32 - 未过滤的$_GET参数直接拼接SQL查询 + [中危] XSS - {os.path.basename(file_path)}:15 - 未转义的userInput输出到HTML + +4. 当前代码(仅限分析): {content[:3000]}""" # 限制每个文件内容长度 result = self.api.chat_completion(prompt) @@ -1127,4 +1135,4 @@ if __name__ == '__main__': window = CyberSecurityApp() window.show() - sys.exit(app.exec_()) + sys.exit(app.exec_()) \ No newline at end of file diff --git a/config.py b/config.py index cf29721..cdd9c19 100644 --- a/config.py +++ b/config.py @@ -1,12 +1,12 @@ # API配置 -API_TYPE="deepseek" # 可选值: "deepseek" 或 "ollama" +API_TYPE="ollama" # 可选值: "deepseek" 或 "ollama" # DeepSeek API配置 DEEPSEEK_API_KEY="" # Ollama API配置 OLLAMA_API_URL="http://localhost:11434/api/chat" # Ollama API地址 -OLLAMA_MODEL="deepseek-r1:7b" # Ollama模型名称 +OLLAMA_MODEL="qwen2.5-coder:14b" # Ollama模型名称 # 主题配色方案 THEMES = { diff --git a/ollamaMain.py b/ollamaMain.py new file mode 100644 index 0000000..45ab327 --- /dev/null +++ b/ollamaMain.py @@ -0,0 +1,334 @@ +import os +import re +import json +import requests +from PyQt5 import QtCore, QtGui, QtWidgets +from PyQt5.QtCore import QThread, pyqtSignal +from config import OLLAMA_API_URL, OLLAMA_MODEL # 用户自定义配置 + +class CyberTextEdit(QtWidgets.QTextEdit): + def __init__(self, parent=None): + super().__init__(parent) + self.setStyleSheet(""" + QTextEdit { + background-color: #001a1a; + color: #00ff00; + border: 2px solid #00ffff; + border-radius: 5px; + padding: 10px; + font-family: 'Consolas'; + font-size: 12pt; + } + """) + +class HackerWorker(QThread): + analysis_complete = pyqtSignal(str) + progress_update = pyqtSignal(str) + + def __init__(self, files_content): + super().__init__() + self.files_content = files_content + + def run(self): + full_report = [] + for filepath, content in self.files_content.items(): + self.progress_update.emit(f"🔍 Analyzing {os.path.basename(filepath)}...") + + prompt = f"""【强制指令】你是一个专业的安全审计AI,请按以下要求分析代码: + +1. 漏洞分析流程: + 1.1 识别潜在风险点(SQL操作、文件操作、用户输入点、文件上传漏洞、CSRF、SSRF、XSS、RCE、OWASP top10等漏洞) + 1.2 验证漏洞可利用性 + 1.3 按CVSS评分标准评估风险等级 + +2. 输出规则: + - 仅输出确认存在的高危/中危漏洞 + - 使用严格格式:[风险等级] 类型 - 位置:行号 - 50字内描述 + - 禁止解释漏洞原理 + - 禁止给出修复建议 + - 每文件最多报告3个最严重问题 + +3. 输出示例(除此外不要有任何输出): + [高危] SQL注入 - user_login.php:32 - 未过滤的$_GET参数直接拼接SQL查询 + [中危] XSS - comment.jsp:15 - 未转义的userInput输出到HTML + +4. 当前代码(仅限分析): +{content[:3000]}""" + try: + response = requests.post( + f"{OLLAMA_HOST}/api/generate", + json={ + "model": OLLAMA_MODEL, + "prompt": prompt, + "stream": False + } + ) + result = json.loads(response.text)["response"] + result = re.sub(r'.*?', '', result, flags=re.DOTALL) + full_report.append(f"📄 文件:{filepath}\n{result}\n{'━'*50}") + except Exception as e: + full_report.append(f"❌ 错误:处理文件 {filepath} 时发生错误\n{str(e)}") + + self.analysis_complete.emit("\n".join(full_report)) + +class WebshellWorker(QThread): + detection_complete = pyqtSignal(str) + progress_update = pyqtSignal(str) + + def __init__(self, files_content): + super().__init__() + self.files_content = files_content + + def run(self): + detection_results = [] + for filepath, content in self.files_content.items(): + self.progress_update.emit(f"🕵️ 扫描 {os.path.basename(filepath)}...") + + prompt = f"""【Webshell检测指令】请严格按以下步骤分析代码: + +1. 检测要求: + 请分析以下文件内容是否为WebShell或内存马。要求: + 1. 检查PHP/JSP/ASP等WebShell特征(如加密函数、执行系统命令、文件操作) + 2. 识别内存马特征(如无文件落地、进程注入、异常网络连接) + 3. 分析代码中的可疑功能(如命令执行、文件上传、信息收集) + 4. 检查混淆编码、加密手段等规避技术 + +2. 判断规则: + - 仅当确认恶意性时报告 + - 输出格式:🔴 [高危] Webshell - 文件名:行号 - 检测到[特征1+特征2+...] + +3. 输出示例(严格按照此格式输出,不要有任何的补充,如果未检测到危险,则不输出,除此之外,不要有任何输出): + 🔴 [高危] Webshell - malicious.php:8 - 检测到[system执行+base64解码+错误抑制] + +4. 待分析代码: +{content[:3000]}""" + + try: + response = requests.post( + f"{OLLAMA_HOST}/api/generate", + json={ + "model": OLLAMA_MODEL, + "prompt": prompt, + "stream": False + } + ) + result = json.loads(response.text)["response"] + result = re.sub(r'.*?', '', result, flags=re.DOTALL) + detection_results.append(f"📁 {filepath}\n{result}\n{'━'*50}") + except Exception as e: + detection_results.append(f"❌ 错误:{filepath}\n{str(e)}") + + self.detection_complete.emit("\n".join(detection_results)) + +class CyberScanner(QtWidgets.QMainWindow): + def __init__(self): + super().__init__() + self.setWindowTitle("AI安全审计系统 BY:公众号_知攻善防实验室 ChinaRan404 ") + self.setGeometry(100, 100, 1280, 720) + self.setup_ui() + self.files_content = {} + self.scan_thread = None + + def setup_ui(self): + main_widget = QtWidgets.QWidget() + self.setCentralWidget(main_widget) + layout = QtWidgets.QHBoxLayout(main_widget) + + # 左侧面板 + left_panel = QtWidgets.QFrame() + left_panel.setStyleSheet("background-color: #000d1a; border-right: 2px solid #00ffff;") + left_layout = QtWidgets.QVBoxLayout(left_panel) + + # 目录选择按钮 + self.btn_select = QtWidgets.QPushButton("📁 激活数据源") + self.btn_select.setStyleSheet(""" + QPushButton { + background-color: #002b2b; + color: #00ffff; + border: 2px solid #008080; + padding: 12px; + font-size: 14pt; + font-weight: bold; + border-radius: 5px; + } + QPushButton:hover { + background-color: #004d4d; + border-color: #00ffff; + } + """) + self.btn_select.clicked.connect(self.select_directory) + left_layout.addWidget(self.btn_select) + + # 路径显示 + self.lbl_path = QtWidgets.QLabel("未选择数据源") + self.lbl_path.setStyleSheet("color: #00ff00; font-size: 10pt; padding: 5px;") + left_layout.addWidget(self.lbl_path) + + # 模式选择 + mode_group = QtWidgets.QGroupBox("🔧 检测模式") + mode_group.setStyleSheet(""" + QGroupBox { + color: #00ff00; + border: 1px solid #00ffff; + margin-top: 10px; + font-size: 12pt; + } + """) + mode_layout = QtWidgets.QVBoxLayout() + self.radio_audit = QtWidgets.QRadioButton("代码安全审计") + self.radio_webshell = QtWidgets.QRadioButton("Webshell检测") + self.radio_audit.setChecked(True) + for rb in [self.radio_audit, self.radio_webshell]: + rb.setStyleSheet(""" + QRadioButton { color: #00ff00; padding: 8px; } + QRadioButton::indicator { width: 20px; height: 20px; } + """) + mode_layout.addWidget(rb) + mode_group.setLayout(mode_layout) + left_layout.addWidget(mode_group) + + # 文件树 + self.file_tree = QtWidgets.QTreeView() + self.file_model = QtWidgets.QFileSystemModel() + self.file_model.setRootPath("") + self.file_tree.setModel(self.file_model) + self.file_tree.setStyleSheet(""" + QTreeView { + background-color: #001a1a; + color: #00ff00; + border: 1px solid #008080; + font-family: 'Consolas'; + } + QTreeView::item:hover { background-color: #003333; } + """) + left_layout.addWidget(self.file_tree) + + # 扫描按钮 + self.btn_scan = QtWidgets.QPushButton("🚨 启动扫描协议") + self.btn_scan.setStyleSheet(""" + QPushButton { + background-color: #004d4d; + color: #00ffff; + border: 2px solid #00ffff; + padding: 15px; + font-size: 16pt; + font-weight: bold; + border-radius: 5px; + } + QPushButton:disabled { + background-color: #002b2b; + color: #008080; + border-color: #004d4d; + } + QPushButton:hover { background-color: #006666; } + """) + self.btn_scan.clicked.connect(self.start_scan) + self.btn_scan.setEnabled(False) + left_layout.addWidget(self.btn_scan) + + # 右侧显示区 + self.result_display = CyberTextEdit() + self.result_display.setAcceptRichText(True) + + layout.addWidget(left_panel, 1) + layout.addWidget(self.result_display, 2) + + # 状态栏 + self.status_bar = QtWidgets.QStatusBar() + self.setStatusBar(self.status_bar) + self.status_bar.setStyleSheet(""" + QStatusBar { + background-color: #000d1a; + color: #00ff00; + border-top: 1px solid #00ffff; + font-family: 'Consolas'; + } + """) + + def select_directory(self): + directory = QtWidgets.QFileDialog.getExistingDirectory( + self, + "选择代码矩阵接入点", + "", + QtWidgets.QFileDialog.ShowDirsOnly + ) + if directory: + self.lbl_path.setText(f"📂 数据源:{directory}") + self.file_tree.setRootIndex(self.file_model.index(directory)) + self.btn_scan.setEnabled(True) + self.status_bar.showMessage("✅ 数据源接入成功") + + def start_scan(self): + root_index = self.file_tree.rootIndex() + if not root_index.isValid(): + QtWidgets.QMessageBox.warning(self, "警告", "请先选择代码目录!") + return + + root_path = self.file_model.filePath(root_index) + self.files_content = self.scan_code_files(root_path) + + if self.radio_audit.isChecked(): + worker = HackerWorker(self.files_content) + init_msg = "🚀 启动深度代码分析协议..." + complete_signal = worker.analysis_complete + else: + worker = WebshellWorker(self.files_content) + init_msg = "🕵️ 启动Webshell检测协议..." + complete_signal = worker.detection_complete + + self.scan_thread = worker + self.scan_thread.progress_update.connect(self.update_status) + complete_signal.connect(self.show_results) + self.scan_thread.start() + + self.btn_scan.setEnabled(False) + self.result_display.setText(f"{init_msg}\n" + "▮"*50 + "\n") + + def scan_code_files(self, directory): + allowed_ext = ['.php', '.jsp', '.asp', '.js', '.html', '.py', '.java'] + code_files = {} + + for root, _, files in os.walk(directory): + for file in files: + if os.path.splitext(file)[1].lower() in allowed_ext: + path = os.path.join(root, file) + try: + with open(path, 'r', encoding='utf-8') as f: + code_files[path] = f.read() + except: + code_files[path] = "无法读取文件内容" + return code_files + + def update_status(self, message): + self.status_bar.showMessage(message) + self.result_display.append(f"⚡ {message}") + + def show_results(self, report): + self.btn_scan.setEnabled(True) + + if self.radio_webshell.isChecked(): + self.result_display.append("\n🔍 Webshell检测完成!结果如下:\n") + report = re.sub(r'🔴 \[高危\]', '🔴 [高危]', report) + report = re.sub(r'✅ \[安全\]', '✅ [安全]', report) + else: + self.result_display.append("\n🔥 代码审计完成!发现以下安全漏洞:\n") + report = re.sub(r'\[高危\]', '[高危]', report) + report = re.sub(r'\[中危\]', '[中危]', report) + + self.result_display.append(report) + self.status_bar.showMessage("✅ 扫描完成") + +if __name__ == "__main__": +# 保持源文本的核心内容不变 + + OLLAMA_HOST = OLLAMA_API_URL.split('/api')[0] + + app = QtWidgets.QApplication([]) + app.setStyle('Fusion') + + font = QtGui.QFont("Consolas", 10) + app.setFont(font) + + window = CyberScanner() + window.show() + app.exec_() \ No newline at end of file