如何编写检测页面篡改脚本

wen 实用脚本 30

本文目录导读:

如何编写检测页面篡改脚本

  1. 前端页面完整性检测
  2. 服务器端检测脚本
  3. 使用方法
  4. 安全建议

前端页面完整性检测

的哈希校验

(function() {
    // 存储原始内容的哈希值
    const PAGE_HASHES = {
        'index.html': 'abc123...',  // 部署时计算的实际hash
        'about.html': 'def456...',
        // 其他页面...
    };
    // 计算当前页面内容哈希
    async function calculateHash(content) {
        const encoder = new TextEncoder();
        const data = encoder.encode(content);
        const hashBuffer = await crypto.subtle.digest('SHA-256', data);
        const hashArray = Array.from(new Uint8Array(hashBuffer));
        return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
    }
    // 检测页面是否被篡改
    async function detectTampering() {
        const bodyContent = document.body.innerHTML;
        const currentHash = await calculateHash(bodyContent);
        const pageName = window.location.pathname.split('/').pop() || 'index.html';
        if (PAGE_HASHES[pageName] && currentHash !== PAGE_HASHES[pageName]) {
            console.warn('警告:页面内容已被篡改!');
            // 执行告警操作
            alertTampering();
        }
    }
    function alertTampering() {
        // 清除可疑内容
        document.body.innerHTML = '<h1>页面已被篡改,请联系管理员</h1>';
        // 发送告警到服务器
        fetch('/api/alert/tampering', {
            method: 'POST',
            body: JSON.stringify({
                page: window.location.href,
                time: new Date().toISOString()
            })
        });
    }
    // 在页面加载完成后执行检测
    window.addEventListener('load', detectTampering);
    // 定期检测(可选)
    setInterval(detectTampering, 5000);
})();

DOM节点监控

// 使用MutationObserver监控DOM变化
const tamperDetector = {
    observer: null,
    config: {
        childList: true,
        subtree: true,
        attributes: true,
        characterData: true,
        attributeFilter: ['src', 'href', 'onclick', 'onerror']
    },
    // 白名单中的合法修改
    whiteList: [
        'analytics-script',  // 允许的分析脚本
        'user-generated-content'  // 用户生成内容区域
    ],
    init: function() {
        this.observer = new MutationObserver((mutations) => {
            mutations.forEach((mutation) => {
                this.checkMutation(mutation);
            });
        });
        this.observer.observe(document.body, this.config);
    },
    checkMutation: function(mutation) {
        // 检查被修改的元素是否在白名单
        const target = mutation.target;
        const targetId = target.id;
        if (!this.whiteList.includes(targetId)) {
            this.handleTampering(mutation);
        }
    },
    handleTampering: function(mutation) {
        console.warn('检测到可疑的页面修改:', mutation);
        // 尝试恢复原始内容
        if (mutation.type === 'attributes') {
            if (mutation.attributeName === 'src') {
                // 恢复原始src
                const originalSrc = mutation.target.getAttribute('data-original-src');
                if (originalSrc) {
                    mutation.target.src = originalSrc;
                }
            }
        }
        // 记录篡改日志
        this.logTampering(mutation);
    },
    logTampering: function(mutation) {
        const logData = {
            type: mutation.type,
            target: mutation.target.outerHTML.substring(0, 100),
            time: new Date().toISOString(),
            url: window.location.href
        };
        // 发送到日志服务器
        navigator.sendBeacon('/api/log/tampering', JSON.stringify(logData));
    }
};
// 启动监控
if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', () => tamperDetector.init());
} else {
    tamperDetector.init();
}

服务器端检测脚本

Python版本

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
网站页面篡改检测脚本
"""
import hashlib
import json
import logging
import requests
from pathlib import Path
from datetime import datetime
class PageTamperDetector:
    def __init__(self, config_file='page_hashes.json'):
        self.config_file = config_file
        self.logger = self.setup_logger()
        self.known_hashes = self.load_hashes()
    def setup_logger(self):
        """配置日志"""
        logging.basicConfig(
            level=logging.INFO,
            format='%(asctime)s - %(levelname)s - %(message)s',
            handlers=[
                logging.FileHandler('tamper_detection.log'),
                logging.StreamHandler()
            ]
        )
        return logging.getLogger(__name__)
    def calculate_file_hash(self, file_path):
        """计算文件哈希值"""
        sha256_hash = hashlib.sha256()
        with open(file_path, "rb") as f:
            for byte_block in iter(lambda: f.read(4096), b""):
                sha256_hash.update(byte_block)
        return sha256_hash.hexdigest()
    def load_hashes(self):
        """加载已知的哈希值"""
        try:
            with open(self.config_file, 'r') as f:
                return json.load(f)
        except FileNotFoundError:
            return {}
    def save_hashes(self):
        """保存哈希值到配置文件"""
        with open(self.config_file, 'w') as f:
            json.dump(self.known_hashes, f, indent=2)
    def initialize_hashes(self, web_root='/var/www/html'):
        """初始化所有页面的哈希值"""
        web_root = Path(web_root)
        for file_path in web_root.rglob('*.html'):
            if file_path.is_file():
                rel_path = str(file_path.relative_to(web_root))
                hash_value = self.calculate_file_hash(str(file_path))
                self.known_hashes[rel_path] = hash_value
        self.save_hashes()
        self.logger.info(f"已初始化 {len(self.known_hashes)} 个文件的哈希值")
    def detect_changes(self, web_root='/var/www/html'):
        """检测文件是否被篡改"""
        web_root = Path(web_root)
        tampered_files = []
        new_files = []
        missing_files = []
        # 检查已知文件
        for rel_path in list(self.known_hashes.keys()):
            file_path = web_root / rel_path
            if file_path.exists():
                current_hash = self.calculate_file_hash(str(file_path))
                if current_hash != self.known_hashes[rel_path]:
                    tampered_files.append(rel_path)
                    self.logger.warning(f"文件被篡改: {rel_path}")
            else:
                missing_files.append(rel_path)
                self.logger.warning(f"文件缺失: {rel_path}")
        # 检查新文件
        for file_path in web_root.rglob('*.html'):
            if file_path.is_file():
                rel_path = str(file_path.relative_to(web_root))
                if rel_path not in self.known_hashes:
                    new_files.append(rel_path)
                    self.logger.warning(f"发现新文件: {rel_path}")
        return tampered_files, new_files, missing_files
    def send_alert(self, tampered_files):
        """发送告警通知"""
        if not tampered_files:
            return
        alert_data = {
            'timestamp': datetime.now().isoformat(),
            'server': 'main-web-server',
            'tampered_files': tampered_files,
            'severity': 'high'
        }
        # 可以发送邮件、短信或集成其他告警系统
        # 这里作为示例,发送到告警API
        try:
            response = requests.post(
                'https://alert-system.example.com/api/alert',
                json=alert_data,
                timeout=5
            )
            if response.status_code == 200:
                self.logger.info("告警发送成功")
            else:
                self.logger.error(f"告警发送失败: {response.status_code}")
        except Exception as e:
            self.logger.error(f"告警发送异常: {str(e)}")
def main():
    """主函数"""
    detector = PageTamperDetector()
    # 首次运行需要初始化
    # detector.initialize_hashes()
    # 检测页面篡改
    tampered, new_files, missing = detector.detect_changes()
    # 如果有篡改,发送告警
    if tampered:
        detector.send_alert(tampered)
    # 输出结果
    print(f"检测完成:")
    print(f"- 被篡改文件: {len(tampered)}")
    print(f"- 新文件: {len(new_files)}")
    print(f"- 缺失文件: {len(missing)}")
    if tampered:
        print("\n被篡改文件:")
        for f in tampered:
            print(f"  - {f}")
if __name__ == "__main__":
    main()

Shell脚本版本

#!/bin/bash
# 页面篡改检测脚本
# 使用方法: ./tamper_detection.sh
# 配置
WEB_ROOT="/var/www/html"
HASH_FILE="/var/log/page_hashes.txt"
ALERT_EMAIL="admin@example.com"
# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# 初始化哈希值数据库
initialize_hashes() {
    echo "初始化页面哈希值..."
    find "$WEB_ROOT" -name "*.html" -type f | while read file; do
        hash=$(sha256sum "$file" | cut -d' ' -f1)
        relative_path="${file#$WEB_ROOT/}"
        echo "$relative_path:$hash" >> "$HASH_FILE"
    done
    echo "哈希值初始化完成"
}
# 检测文件篡改
detect_tampering() {
    local tampered=0
    local new_files=0
    local missing_files=0
    echo "开始检测页面篡改..."
    echo "检测时间: $(date)"
    echo "================================"
    # 检查已知文件
    while IFS=':' read -r file_path known_hash; do
        full_path="$WEB_ROOT/$file_path"
        if [ -f "$full_path" ]; then
            current_hash=$(sha256sum "$full_path" | cut -d' ' -f1)
            if [ "$current_hash" != "$known_hash" ]; then
                echo -e "${RED}[篡改]${NC} $file_path"
                echo "  原哈希: $known_hash"
                echo "  新哈希: $current_hash"
                tampered=$((tampered + 1))
            fi
        else
            echo -e "${YELLOW}[缺失]${NC} $file_path"
            missing_files=$((missing_files + 1))
        fi
    done < "$HASH_FILE"
    # 检查新文件
    find "$WEB_ROOT" -name "*.html" -type f | while read file; do
        relative_path="${file#$WEB_ROOT/}"
        if ! grep -q "^$relative_path:" "$HASH_FILE" 2>/dev/null; then
            echo -e "${YELLOW}[新文件]${NC} $relative_path"
            new_files=$((new_files + 1))
        fi
    done
    # 输出统计信息
    echo "================================"
    echo -e "检测统计:"
    echo -e "${RED}被篡改: $tampered${NC}"
    echo -e "${YELLOW}新文件: $new_files${NC}"
    echo -e "${YELLOW}缺失文件: $missing_files${NC}"
    return $tampered
}
# 发送告警
send_alert() {
    local tampered=$1
    local subject="[告警] 网站页面被篡改 - $(date +%Y-%m-%d)"
    local body="检测到 $tampered 个页面被篡改,请立即检查!
时间: $(date)
服务器: $(hostname)
站点目录: $WEB_ROOT"
    # 发送邮件告警
    echo "$body" | mail -s "$subject" "$ALERT_EMAIL"
    # 也可以发送到其他告警平台
    # curl -X POST https://alert-api.example.com/alert \
    #   -H "Content-Type: application/json" \
    #   -d "{\"message\": \"$subject\", \"detail\": \"$body\"}"
}
# 自动恢复被篡改的文件(如果存在备份)
restore_files() {
    local backup_dir="/var/backup/web"
    if [ -d "$backup_dir" ]; then
        echo "尝试从备份恢复被篡改文件..."
        while IFS=':' read -r file_path known_hash; do
            full_path="$WEB_ROOT/$file_path"
            backup_file="$backup_dir/$file_path"
            if [ -f "$backup_file" ]; then
                current_hash=$(sha256sum "$full_path" | cut -d' ' -f1)
                if [ "$current_hash" != "$known_hash" ]; then
                    cp "$backup_file" "$full_path"
                    echo -e "${GREEN}[已恢复]${NC} $file_path"
                fi
            fi
        done < "$HASH_FILE"
    fi
}
# 主流程
main() {
    # 检查是否需要初始化
    if [ ! -f "$HASH_FILE" ]; then
        echo "未找到哈希值文件,正在初始化..."
        initialize_hashes
        echo "初始化完成,请再次运行脚本进行检测"
        exit 0
    fi
    # 执行检测
    detect_tampering
    tampered_count=$?
    # 如果有篡改,执行相应操作
    if [ $tampered_count -gt 0 ]; then
        echo "检测到页面篡改,正在处理..."
        # 发送告警
        send_alert $tampered_count
        # 自动恢复(可选)
        # restore_files
        echo "告警已发送"
        exit 1
    else
        echo "所有页面完整,未发现篡改"
        exit 0
    fi
}
# 运行主函数
main

使用方法

前端脚本:

  1. 在页面部署时计算并记录哈希值
  2. 在页面加载时执行检测
  3. 配置告警和恢复机制

服务器端脚本:

  1. 首次运行:初始化哈希值数据库

    python tamper_detector.py
    # 或者
    ./tamper_detection.sh  (首次运行会自动初始化)
  2. 定时检测:设置cron任务

    # 每30分钟检测一次
    */30 * * * * /path/to/tamper_detection.sh
    # 或者使用Python版本
    */30 * * * * python3 /path/to/tamper_detector.py

安全建议

  1. 哈希值离线存储:不要将哈希值放在可被访问的页面中
  2. 多层级检测:结合前端和后端检测
  3. 实时监控:使用文件监控系统(如inotify)
  4. 备份恢复:保持完整备份以便快速恢复
  5. 告警机制:配置多种告警方式(邮件、短信、即时通讯)
  6. 日志审计:记录所有检测和变更日志

这些脚本可以根据您的具体需求进行调整和扩展。

抱歉,评论功能暂时关闭!