数据库注入:黑客最常用的SEO垃圾攻击手段
当WordPress被成功入侵后,攻击者最常见的操作之一是直接向数据库写入垃圾内容:
– 大量包含赌博、药品、成人关键词的垃圾文章
– 在正常文章的内容末尾追加隐藏垃圾链接
– 在wp_options表中写入恶意重定向设置
– 在评论中批量注入垃圾链接
数据库层面的清理比文件层面更复杂,因为需要精确找到”哪些是正常内容,哪些是注入的垃圾”。
开始之前:务必备份数据库!
# 通过mysqldump备份
mysqldump -u 数据库用户名 -p 数据库名 > backup_$(date +%Y%m%d).sql
# 通过WP-CLI备份
wp db export backup_$(date +%Y%m%d).sql
检查感染范围
查看异常文章数量
-- 查看总文章数(正常情况下应该与你实际发布的文章数匹配)
SELECT post_status, COUNT(*) as count
FROM wp_posts
WHERE post_type = 'post'
GROUP BY post_status;
-- 查看最近发布的文章(按时间排序,看是否有异常批量发布)
SELECT ID, post_title, post_date, post_author
FROM wp_posts
WHERE post_type = 'post'
AND post_status = 'publish'
ORDER BY post_date DESC
LIMIT 50;
搜索特定垃圾关键词
-- 搜索常见垃圾关键词(根据实际情况替换关键词)
SELECT ID, post_title, LEFT(post_content, 100) as excerpt
FROM wp_posts
WHERE post_status = 'publish'
AND (
post_content LIKE '%casino%' OR
post_content LIKE '%viagra%' OR
post_content LIKE '%gambling%' OR
post_content LIKE '%slots%' OR
post_content LIKE '%ポーカー%' OR -- 日文扑克
post_content LIKE '%カジノ%' OR -- 日文赌场
post_content LIKE '%バイアグラ%' -- 日文伟哥
)
LIMIT 100;
搜索隐藏链接(常见注入模式)
-- 搜索含有隐藏链接的文章(style="display:none"或visibility:hidden)
SELECT ID, post_title
FROM wp_posts
WHERE post_content LIKE '%display:none%'
OR post_content LIKE '%visibility:hidden%'
OR post_content LIKE '%font-size:0%';
清理wp_posts表(垃圾文章)
方案1:删除特定关键词的文章
-- 先预览要删除的内容(不执行删除)
SELECT COUNT(*) FROM wp_posts
WHERE post_status = 'publish'
AND (post_title LIKE '%casino%' OR post_content LIKE '%casino%');
-- 确认无误后执行删除
DELETE FROM wp_posts
WHERE post_status = 'publish'
AND (post_title LIKE '%casino%' OR post_content LIKE '%casino%');
-- 删除对应的postmeta(孤立数据)
DELETE pm FROM wp_postmeta pm
LEFT JOIN wp_posts p ON p.ID = pm.post_id
WHERE p.ID IS NULL;
方案2:按时间范围删除(如果攻击时间明确)
-- 删除特定时间段内发布的所有文章(非正常批量发布期间)
-- 请先确认这个时间段内确实没有你自己发布的正常文章!
DELETE FROM wp_posts
WHERE post_type = 'post'
AND post_status = 'publish'
AND post_date BETWEEN '2026-01-15 00:00:00' AND '2026-02-01 23:59:59';
方案3:按用户ID删除(如果攻击者创建了新用户)
-- 先查找可疑用户
SELECT ID, user_login, user_email, user_registered
FROM wp_users
ORDER BY user_registered DESC;
-- 删除特定用户发布的所有文章
DELETE FROM wp_posts
WHERE post_author = 可疑用户ID
AND post_type = 'post';
方案4:通过正则表达式删除日文内容文章
-- 删除标题或内容包含日文字符的文章
DELETE FROM wp_posts
WHERE post_type IN ('post', 'page')
AND post_status = 'publish'
AND (
post_title REGEXP '[ぁ-んァ-ン一-龥]' OR
post_content REGEXP '[ぁ-んァ-ン一-龥]'
);
清理文章内容中的注入链接
如果垃圾内容是注入到你正常文章末尾的,不能直接删除整篇文章,需要精确替换:
-- 查找内容末尾被注入了垃圾链接的文章
SELECT ID, post_title,
RIGHT(post_content, 200) as last_200_chars
FROM wp_posts
WHERE post_content LIKE '%<a href="http://垃圾域名%'
AND post_type = 'post'
AND post_status = 'publish';
-- 使用REPLACE删除特定的垃圾链接(精确匹配)
UPDATE wp_posts
SET post_content = REPLACE(
post_content,
'<a href="http://垃圾域名.com">垃圾链接文字</a>',
''
)
WHERE post_content LIKE '%垃圾域名.com%';
清理wp_options表
黑客有时在wp_options表中写入恶意设置,如修改网站URL、添加恶意重定向等:
-- 查看最近修改的options(检查是否有可疑内容)
SELECT option_name, LEFT(option_value, 200) as value_preview
FROM wp_options
WHERE option_name IN (
'siteurl', 'home', 'blogdescription', 'admin_email',
'blogname', 'permalink_structure'
);
-- 搜索option_value中包含可疑URL的条目
SELECT option_name, option_value
FROM wp_options
WHERE option_value LIKE '%垃圾域名%'
OR option_value LIKE '%base64_decode%';
如果发现siteurl或home被改为其他域名:
UPDATE wp_options SET option_value = 'https://你的正确域名.com' WHERE option_name = 'siteurl';
UPDATE wp_options SET option_value = 'https://你的正确域名.com' WHERE option_name = 'home';
清理wp_comments表(垃圾评论)
-- 统计可疑评论
SELECT COUNT(*), comment_type, comment_approved
FROM wp_comments
GROUP BY comment_type, comment_approved;
-- 删除所有spam评论
DELETE FROM wp_comments WHERE comment_approved = 'spam';
-- 删除包含特定链接的评论
DELETE FROM wp_comments
WHERE comment_content LIKE '%垃圾域名.com%'
OR comment_author_url LIKE '%垃圾域名.com%';
使用WP-CLI批量操作(更安全的方式)
WP-CLI提供了比直接SQL更安全的数据库操作方式:
# 搜索数据库中的特定字符串
wp search-replace '垃圾内容关键词' '' --dry-run # 先预览
wp search-replace '垃圾内容关键词' '' # 确认后执行
# 删除垃圾评论
wp comment delete $(wp comment list --status=spam --format=ids)
# 批量删除特定分类的文章
wp post delete $(wp post list --category=垃圾分类ID --format=ids)
# 更精细的搜索和删除
wp post list --post_type=post --fields=ID,post_title,post_date | grep "关键词"
清理后的验证步骤
-- 验证1:确认垃圾文章已删除
SELECT COUNT(*) FROM wp_posts
WHERE post_content LIKE '%casino%'
AND post_status = 'publish';
-- 期望结果:0
-- 验证2:检查孤立的postmeta(应该为0)
SELECT COUNT(*) FROM wp_postmeta pm
LEFT JOIN wp_posts p ON p.ID = pm.post_id
WHERE p.ID IS NULL;
-- 如果不为0,执行清理:
DELETE pm FROM wp_postmeta pm
LEFT JOIN wp_posts p ON p.ID = pm.post_id
WHERE p.ID IS NULL;
-- 验证3:优化数据库表(清理后的维护工作)
OPTIMIZE TABLE wp_posts, wp_postmeta, wp_options, wp_comments;
预防数据库注入攻击
数据库注入攻击通常通过以下途径实现:
1. SQL注入漏洞:插件未做好输入验证,攻击者通过构造SQL直接操作数据库
2. 文件系统权限:获得PHP执行权限后直接连接数据库操作
3. 泄露的数据库凭据:通过FTP读取了wp-config.php
防护措施:
– 定期更新所有插件(SQL注入漏洞会被修复)
– 为数据库用户设置最小权限(只允许SELECT/INSERT/UPDATE/DELETE,不允许DROP/GRANT)
– 保护wp-config.php(设置600权限)
– 使用独立数据库前缀(非默认的wp_)
如果清理过程中发现感染范围极大,建议进行专业安全修复,确保彻底清洁并找到根本原因。