Skill: 43622283/security-log-analyzer (version 1.0.0)

# 安全事件日志调查助手 ## 功能说明 基于 LLM 的安全事件日志分析工具，支持简要分析和详细分析两种模式。 ## 安装 ```bash cd /root/.openclaw/skills/security-log-analyzer pip install -r requirements.txt cp .env.example .env # 编辑.env 文件，填写 API Key ``` ## 配置 编辑 `.env` 文件： ```bash SILICONFLOW_API_KEY=sk-your-api-key-here SILICONFLOW_BASE_URL=https://api.siliconflow.cn/v1 SILICONFLOW_MODEL=Qwen/Qwen3-8B API_RATE_LIMIT=2 ``` ## 使用方法 ### 方式 1: 交互模式 ```bash cd /root/.openclaw/skills/security-log-analyzer python src/analyzer.py ``` ### 方式 2: 文件模式 ```bash python src/analyzer.py /path/to/log.txt brief # 简要分析 python src/analyzer.py /path/to/log.txt detailed # 详细分析 ``` ## 分析模式 - **简要分析**：快速提取关键信息（威胁等级、事件类型、建议行动） - **详细分析**：深度分析攻击链、IOC 指标、缓解建议 ## 限流保护 - 默认请求间隔：2 秒 - 429 错误自动重试（等待 10 秒） - 单条日志超过 4000 token 自动截断 ## 示例日志 查看 `examples/sample_logs/` 目录中的示例日志文件。 ## 输出示例 ```markdown ## 事件概览 - 事件类型：SSH 暴力破解 - 威胁等级：中 - 时间范围：2026-04-22 20:00 - 21:30 ## 关键发现 - 来自同一 IP 的 150+ 次失败登录尝试 - 目标账号：root, admin, ubuntu ## IOC 指标 - IP: 192.168.1.100 ## 建议行动 1. 封禁源 IP 2. 启用 fail2ban 3. 配置 SSH 密钥认证 ```

path: DESIGN.md
content: # 安全事件日志调查助手 - 设计文档

## 项目概述

一个基于 LLM 的安全事件日志分析工具，帮助用户快速理解和调查安全日志事件。

## 核心功能

1. **日志分析模式**
   - 简要分析：快速提取关键信息（威胁等级、事件类型、建议行动）
   - 详细分析：深度分析攻击链、IOC 指标、缓解建议

2. **API 配置**
   - 使用 OpenAI 兼容 API
   - 支持 SiliconFlow 平台
   - 通过.env 文件管理密钥和配置

3. **限流保护**
   - 请求间隔控制
   - 批量日志分片处理
   - 错误重试机制

## 技术架构

```
security-log-analyzer/
├── DESIGN.md           # 设计文档
├── SKILL.md           # 技能说明文档
├── .env.example       # 环境变量示例
├── requirements.txt   # Python 依赖
├── src/
│   ├── __init__.py
│   ├── analyzer.py    # 核心分析逻辑
│   ├── llm_client.py  # LLM API 客户端
│   └── prompts.py     # 提示词模板
└── examples/
    └── sample_logs/   # 示例日志文件
```

## API 配置

**SiliconFlow 配置**：
- Base URL: https://api.siliconflow.cn/v1
- Model: Qwen/Qwen3-8B
- API Key: 从.env 文件读取

## 分析模式

### 简要分析（默认）
- 事件类型识别
- 威胁等级评估（低/中/高/严重）
- 关键 IOC 提取
- 3 条以内行动建议

### 详细分析
- 完整事件时间线
- 攻击链分析（MITRE ATT&CK 映射）
- 所有 IOC 指标提取
- 详细缓解和修复建议
- 相关日志关联分析

## 限流策略

1. **请求间隔**：每次 API 调用间隔≥2 秒
2. **批量处理**：超过 10 条日志时分批处理
3. **错误处理**：429 错误时指数退避重试
4. **日志截断**：单条日志超过 4000 token 时自动截断

## 使用流程

1. 用户选择分析模式（简要/详细）
2. 输入或粘贴安全日志
3. 调用 LLM 进行分析
4. 输出结构化分析报告

## 输出格式

```markdown
## 安全事件分析报告

### 事件概览
- 事件类型：[类型]
- 威胁等级：[等级]
- 时间范围：[时间]

### 关键发现
- [发现 1]
- [发现 2]

### IOC 指标
- IP: [...]
- 域名：[...]
- 文件哈希：[...]

### 建议行动
1. [行动 1]
2. [行动 2]
```

## 安全注意事项

1. API Key 仅存储在.env 文件，不提交到版本控制
2. 日志内容不持久化存储
3. 敏感信息自动脱敏处理


path: clawhub.yaml
content: name: security-log-analyzer
displayName: 安全事件日志调查助手
version: 1.0.0
description: 基于 LLM 的安全事件日志分析工具，支持简要分析和详细分析两种模式，可识别威胁等级、提取 IOC 指标、提供修复建议
author: beijinglaoli
license: MIT
tags:
  - security
  - log-analysis
  - threat-hunting
  - incident-response
  - llm

requirements:
  bins:
    - python3
  python:
    packages:
      - openai>=1.0.0
      - python-dotenv>=1.0.0
      - tiktoken>=0.5.0

config:
  env:
    - SILICONFLOW_API_KEY
    - SILICONFLOW_BASE_URL
    - SILICONFLOW_MODEL
    - API_RATE_LIMIT

entryPoint: src/analyzer.py

examples:
  - name: 简要分析 SSH 日志
    command: python src/analyzer.py examples/sample_logs/ssh_bruteforce.log brief
  - name: 详细分析 Web 日志
    command: python src/analyzer.py /path/to/access.log detailed

changelog:
  - version: 1.0.0
    changes:
      - 初始版本发布
      - 支持简要分析和详细分析两种模式
      - 集成 SiliconFlow Qwen/Qwen3-8B 模型
      - 内置限流保护机制
      - 提供示例日志文件


path: requirements.txt
content: openai>=1.0.0
python-dotenv>=1.0.0
tiktoken>=0.5.0


path: src/__init__.py
content: """
安全事件日志调查助手
"""

__version__ = "1.0.0"
__author__ = "beijinglaoli"


path: src/analyzer.py
content: """
安全事件日志分析器 - 主程序
"""

import os
import sys
from dotenv import load_dotenv

# 加载环境变量
load_dotenv()

from llm_client import LLMClient


def truncate_log(log_content: str, max_tokens: int = 4000) -> str:
    """
    截断过长的日志内容
    
    Args:
        log_content: 原始日志
        max_tokens: 最大 token 数（估算：1 token ≈ 4 字符）
        
    Returns:
        截断后的日志
    """
    max_chars = max_tokens * 4
    if len(log_content) <= max_chars:
        return log_content
    
    # 保留开头和结尾
    head_len = max_chars // 2
    tail_len = max_chars // 2
    truncated = log_content[:head_len] + "\n\n... [内容已截断] ...\n\n" + log_content[-tail_len:]
    
    print(f"⚠️  日志过长，已截断至{max_chars}字符（原始：{len(log_content)}字符）")
    return truncated


def analyze_security_log(log_content: str, mode: str = "brief") -> str:
    """
    分析安全日志
    
    Args:
        log_content: 日志内容
        mode: 分析模式 ("brief" 或 "detailed")
        
    Returns:
        分析报告
    """
    # 截断过长的日志
    max_tokens = int(os.getenv("MAX_LOG_TOKENS", "4000"))
    log_content = truncate_log(log_content, max_tokens)
    
    # 创建客户端并分析
    client = LLMClient()
    print(f"🔍 正在{mode}分析日志...")
    
    report = client.analyze_log(log_content, mode)
    
    return report


def interactive_mode():
    """交互式分析模式"""
    print("=" * 60)
    print("🛡️  安全事件日志调查助手")
    print("=" * 60)
    print()
    
    # 选择分析模式
    print("请选择分析模式：")
    print("1. 简要分析（快速提取关键信息）")
    print("2. 详细分析（深度分析报告）")
    print()
    
    choice = input("输入选项 (1/2): ").strip()
    mode = "detailed" if choice == "2" else "brief"
    
    print()
    print("请输入安全日志内容（粘贴后按 Ctrl+D 或输入 END 结束）：")
    print("-" * 60)
    
    # 读取日志内容
    log_lines = []
    for line in sys.stdin:
        if line.strip() == "END":
            break
        log_lines.append(line)
    
    log_content = "".join(log_lines).strip()
    
    if not log_content:
        print("❌ 未输入日志内容")
        return
    
    print()
    print("=" * 60)
    
    # 执行分析
    try:
        report = analyze_security_log(log_content, mode)
        print(report)
        print("=" * 60)
        print("✅ 分析完成")
    except Exception as e:
        print(f"❌ 分析失败：{e}")


def main():
    """主函数"""
    # 检查环境变量
    if not os.getenv("SILICONFLOW_API_KEY"):
        print("❌ 错误：SILICONFLOW_API_KEY 未配置")
        print("请复制.env.example 为.env 并填写 API Key")
        sys.exit(1)
    
    # 检查命令行参数
    if len(sys.argv) > 1:
        # 从文件读取日志
        log_file = sys.argv[1]
        mode = sys.argv[2] if len(sys.argv) > 2 else "brief"
        
        if not os.path.exists(log_file):
            print(f"❌ 文件不存在：{log_file}")
            sys.exit(1)
        
        with open(log_file, "r", encoding="utf-8") as f:
            log_content = f.read()
        
        report = analyze_security_log(log_content, mode)
        print(report)
    else:
        # 交互模式
        interactive_mode()


if __name__ == "__main__":
    main()


path: src/llm_client.py
content: """
LLM API 客户端 - 支持 OpenAI 兼容 API
"""

import os
import time
from typing import Optional
from openai import OpenAI
from dotenv import load_dotenv

# 加载环境变量
load_dotenv()


class LLMClient:
    """SiliconFlow LLM 客户端"""
    
    def __init__(self):
        self.[REDACTED_SECRET]"SILICONFLOW_API_KEY")
        self.base_url = os.getenv("SILICONFLOW_BASE_URL", "https://api.siliconflow.cn/v1")
        self.model = os.getenv("SILICONFLOW_MODEL", "Qwen/Qwen3-8B")
        self.rate_limit = int(os.getenv("API_RATE_LIMIT", "2"))
        
        if not self.api_key:
            raise ValueError("SILICONFLOW_API_KEY 未配置，请检查.env 文件")
        
        self.client = OpenAI(
            [REDACTED_SECRET],
            base_url=self.base_url
        )
        
        self._last_request_time = 0
    
    def _wait_for_rate_limit(self):
        """等待以满足限流要求"""
        elapsed = time.time() - self._last_request_time
        if elapsed < self.rate_limit:
            sleep_time = self.rate_limit - elapsed
            time.sleep(sleep_time)
        self._last_request_time = time.time()
    
    def chat(self, messages: list, max_tokens: int = 2000) -> str:
        """
        发送聊天请求
        
        Args:
            messages: 消息列表，格式为 [{"role": "user", "content": "..."}]
            max_tokens: 最大返回 token 数
            
        Returns:
            LLM 响应文本
        """
        self._wait_for_rate_limit()
        
        try:
            response = self.client.chat.completions.create(
                model=self.model,
                messages=messages,
                max_tokens=max_tokens,
                temperature=0.3,  # 较低温度，保证分析准确性
            )
            return response.choices[0].message.content
        except Exception as e:
            if "429" in str(e) or "rate limit" in str(e).lower():
                # 遇到限流，等待更长时间后重试
                print("⚠️  触发限流，等待 10 秒后重试...")
                time.sleep(10)
                return self.chat(messages, max_tokens)
            raise e
    
    def analyze_log(self, log_content: str, mode: str = "brief") -> str:
        """
        分析安全日志
        
        Args:
            log_content: 日志内容
            mode: 分析模式 ("brief" 或 "detailed")
            
        Returns:
            分析报告
        """
        from prompts import SYSTEM_PROMPT, BRIEF_ANALYSIS_PROMPT, DETAILED_ANALYSIS_PROMPT
        
        # 选择提示词
        if mode == "detailed":
            user_prompt = DETAILED_ANALYSIS_PROMPT.format(log_content=log_content)
            max_tokens = 3000
        else:
            user_prompt = BRIEF_ANALYSIS_PROMPT.format(log_content=log_content)
            max_tokens = 1500
        
        messages = [
            {"role": "system", "content": SYSTEM_PROMPT},
            {"role": "user", "content": user_prompt}
        ]
        
        return self.chat(messages, max_tokens)


# 测试函数
def test_connection():
    """测试 API 连接"""
    client = LLMClient()
    try:
        response = client.chat([{"role": "user", "content": "你好，请用一句话介绍你自己"}])
        print("✅ API 连接成功")
        print(f"响应：{response[:100]}...")
        return True
    except Exception as e:
        print(f"❌ API 连接失败：{e}")
        return False


if __name__ == "__main__":
    test_connection()


path: src/prompts.py
content: """
提示词模板 - 安全事件日志分析
"""

BRIEF_ANALYSIS_PROMPT = """你是一名资深的安全事件响应分析师。请分析以下安全日志，提供简要分析报告。

要求：
1. 识别事件类型（如：暴力破解、SQL 注入、恶意软件、未授权访问等）
2. 评估威胁等级（低/中/高/严重）
3. 提取关键 IOC 指标（IP、域名、文件哈希、用户账号等）
4. 提供最多 3 条行动建议

日志内容：
{log_content}

请按以下格式输出：
## 事件概览
- 事件类型：
- 威胁等级：
- 时间范围：

## 关键发现
- [要点 1]
- [要点 2]

## IOC 指标
- IP:
- 域名:
- 其他:

## 建议行动
1. 
2. 
3. 
"""

DETAILED_ANALYSIS_PROMPT = """你是一名资深的安全事件响应分析师，拥有 10 年以上安全运营经验。请对以下安全日志进行深度分析。

要求：
1. 完整事件时间线重建
2. 攻击链分析（映射到 MITRE ATT&CK 框架）
3. 提取所有 IOC 指标（IP、域名、文件哈希、用户账号、URL、邮箱等）
4. 攻击者 TTPs（战术、技术、程序）分析
5. 影响范围评估
6. 详细的缓解和修复建议
7. 后续监控建议

日志内容：
{log_content}

请按以下格式输出：
## 事件概览
- 事件类型：
- 威胁等级：
- 时间范围：
- 影响系统：

## 事件时间线
| 时间 | 事件 | 严重性 |
|------|------|--------|
| ... | ... | ... |

## 攻击链分析 (MITRE ATT&CK)
- 初始访问：[战术] - [技术 ID]
- 执行：[战术] - [技术 ID]
- 持久化：[战术] - [技术 ID]
- ...

## IOC 指标
### 网络指标
- IP 地址:
- 域名:
- URL:

### 主机指标
- 文件哈希 (MD5/SHA1/SHA256):
- 文件名:
- 注册表键:

### 身份指标
- 用户账号:
- 邮箱地址:

## 攻击者 TTPs 分析
[详细描述攻击者使用的战术、技术和程序]

## 影响范围评估
[评估受影响的系统、数据、业务]

## 缓解和修复建议
### 立即行动（24 小时内）
1. 
2. 
3. 

### 短期修复（1 周内）
1. 
2. 

### 长期改进（1 月内）
1. 
2. 

## 后续监控建议
[建议添加的监控规则和告警]
"""

SYSTEM_PROMPT = """你是一名专业的安全事件响应分析师，擅长日志分析、威胁狩猎和事件调查。
你的分析应该：
- 准确识别安全威胁
- 提供可操作的建议
- 使用清晰的结构化格式
- 避免过度警报，专注于真实威胁
"""


Security scan verdicts — ClawScan: suspicious | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (CRITICAL)