本文目录导读:

前端页面完整性检测
的哈希校验
(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
使用方法
前端脚本:
- 在页面部署时计算并记录哈希值
- 在页面加载时执行检测
- 配置告警和恢复机制
服务器端脚本:
-
首次运行:初始化哈希值数据库
python tamper_detector.py # 或者 ./tamper_detection.sh (首次运行会自动初始化)
-
定时检测:设置cron任务
# 每30分钟检测一次 */30 * * * * /path/to/tamper_detection.sh # 或者使用Python版本 */30 * * * * python3 /path/to/tamper_detector.py
安全建议
- 哈希值离线存储:不要将哈希值放在可被访问的页面中
- 多层级检测:结合前端和后端检测
- 实时监控:使用文件监控系统(如inotify)
- 备份恢复:保持完整备份以便快速恢复
- 告警机制:配置多种告警方式(邮件、短信、即时通讯)
- 日志审计:记录所有检测和变更日志
这些脚本可以根据您的具体需求进行调整和扩展。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播