# Nikto工具类
import re
from tools.ToolBase import ToolBase

class NiktoTool(ToolBase):
    def validate_instruction(self, instruction):
        '''
        检查指令,过滤规则----暂时屏蔽一些高性能参数
        1.-ssl 强制启用 SSL/TLS 连接扫描,若目标服务器未优化加密处理,可能导致资源消耗过大‌
        :param instruction:
        :return:
        '''
        timeout = 60*30 #30分钟
        # 使用正则表达式匹配 -ssl 参数及其相邻的空格
        cleaned_command = re.sub(r'\s+-ssl\b|\b-ssl\b', '', instruction, flags=re.IGNORECASE)
        # 处理可能残留的多余空格
        command = re.sub(r'\s+', ' ', cleaned_command).strip()
        command = command.replace("-p80","-p 80")
        #添加输出文件
        if "-output" not in instruction:
            instruction += " -output nikto_out.txt"
        return command,timeout


    def analyze_result(self, result,instruction,stderr,stdout):
        # 检查结果
        if stderr:
            result = stderr
        # else:
        #     result = self.parse_nikto_full_info(result)
        return result

    def parse_nikto_full_info(self,nikto_output: str) -> dict:
        """
        从 Nikto 扫描结果中提取尽可能多的漏洞信息和对后续渗透测试有用的信息。

        解析思路:
          1. 通过正则表达式提取以“+”开头的行(Nikto 输出通常以“+”开头)。
          2. 针对常见漏洞格式(如 OSVDB-xxxx)进行匹配。
          3. 针对可能包含“vulnerability”、“warning”、“potential”等关键字的行进行提取。
          4. 针对配置或其他信息(如 "Allowed HTTP Methods", "Cookie", "Directory indexing" 等)也进行匹配。
          5. 对于未知格式,尽量保留原始提示,以供后续人工分析。

        返回的字典包含以下键:
          - vulnerabilities: 漏洞相关信息(如 OSVDB 编号、潜在漏洞提示等)
          - configuration_issues: 与服务器配置、HTTP 方法、Cookie、安全策略等相关的提示
          - misc_info: 其他可能对渗透测试有帮助的信息
          - error: 如解析过程中发生异常,则记录异常信息
        """
        result = {
            "vulnerabilities": [],
            "configuration_issues": [],
            "misc_info": []
        }

        try:
            # 获取所有以 + 开头的行
            plus_lines = re.findall(r'^\+\s*(.+)$', nikto_output, re.MULTILINE)

            # 定义一些常见关键词,出现这些关键词的行我们认为是漏洞或安全问题
            vuln_keywords = [
                "OSVDB", "vulnerab", "potential", "insecure", "misconfig", "expos",
                "Directory indexing", "Outdated", "Deprecated", "SSL", "Cookie", "error"
            ]
            config_keywords = [
                "Allowed HTTP Methods", "Server:", "Banner", "HTTP Options", "Headers", "trace", "PUT", "DELETE"
            ]

            for line in plus_lines:
                # 先将行统一为小写做匹配,但保留原始行内容
                low_line = line.lower()

                # 判断是否属于漏洞信息
                if re.search(r'osvdb-\d+', line):
                    result["vulnerabilities"].append(line.strip())
                elif any(kw.lower() in low_line for kw in vuln_keywords):
                    result["vulnerabilities"].append(line.strip())
                # 判断是否属于配置问题(例如HTTP方法、Cookie安全、服务器banner异常等)
                elif any(kw.lower() in low_line for kw in config_keywords):
                    result["configuration_issues"].append(line.strip())
                else:
                    # 其他信息,可能对后续渗透测试有启示
                    result["misc_info"].append(line.strip())
        except Exception as e:
            result["error"] = f"解析过程中出现异常: {str(e)}"

        return result