如何排查sqlserver被篡改

娱乐 2026-10-17 04:02:41 7

数据库被篡改,何排最先暴露问题的被篡往往不是监控告警,而是何排业务端反馈"数据对不上"。某次我遇到一个案例:客户的被篡对账单金额频繁出现几分钱的偏差,开发查了三天代码没找到问题,何排最后发现是被篡有人直接连上SQL Server改了流水表的金额字段,每次只改几毛钱,何排持续了两个月。被篡

这种事一旦发生,何排排查方向比排查速度更重要。被篡下面按逻辑链条展开。何排

先确认:真的被篡被篡改了?

别急着怀疑安全事件。应用bug、何排触发器逻辑错误、被篡复制冲突都可能造成数据异常。何排先做减法——把最近部署的代码回滚到上一个稳定版本,观察数据是否还在变。如果回滚后异常消失,问题在代码层,不用往下查了。

如果回滚后数据仍在变化,继续。

查SQL Server日志,但要查对地方

很多人第一反应是看Error Log,但默认的Error Log根本不记录UPDATE、DELETE这类DML操作。你需要确认几件事:

登录审计是否开启?执行以下语句查看:

SELECT * FROM sys.dm_exec_sessions WHERE is_user_process = 1;

这只能看到当前会话。历史登录记录要靠Login Auditing——在SSMS里右键实例→属性→安全性,确认"登录审核"是否设为"失败和成功"。如果只设了"失败",成功的登录不会留下记录,排查等于瞎了一半。

更关键的是C2审计。SQL Server 2016 SP1以上版本支持SQL Server Audit功能,可以捕获SELECT、UPDATE、DELETE等具体操作。如果事前没配,事后查不到。这是最容易被忽略的一点——很多DBA只配了登录审计,没配语句级审计。

默认跟踪能救命,但有时间窗口

SQL Server默认开启Default Trace,记录对象创建、权限变更、配置修改等事件。查询方式:

SELECT * FROM sys.traces WHERE is_default = 1;

拿到路径后用fn_trace_gettable读取。但默认跟踪文件会滚动覆盖,通常只保留20MB左右。如果篡改发生在几天前,很可能已经被冲掉了。发现异常后第一时间备份当前trace文件,别等。

看系统视图里的蛛丝马迹

几个容易被忽视的视图:

sys.dm_db_index_usage_stats——如果某张表平时只有SELECT,突然出现大量UPDATE计数,而应用层并没有对应的写操作,值得警惕。

sys.sql_modules——检查是否有新增的存储过程或触发器。攻击者常留后门触发器,在特定条件下篡改数据。用以下语句搜索最近修改的模块:

SELECT OBJECT_NAME(object_id), definition FROM sys.sql_modules WHERE OBJECT_NAME(object_id) NOT IN (SELECT name FROM sys.objects WHERE type = 'P');

等等,这个写法有问题。更直接的方式是查sys.objects按modify_date排序:

SELECT name, type_desc, create_date, modify_date FROM sys.objects WHERE modify_date > DATEADD(DAY, -30, GETDATE()) ORDER BY modify_date DESC;

任何你叫不出名字的对象,都是线索。

数据库层面的权限排查

查谁有写权限:

SELECT dp.name, dp.type_desc, o.name AS object_name, p.permission_name FROM sys.database_permissions p JOIN sys.database_principals dp ON p.grantee_principal_id = dp.principal_id LEFT JOIN sys.objects o ON p.major_id = o.object_id WHERE p.permission_name IN ('UPDATE', 'DELETE', 'INSERT', 'CONTROL') AND dp.name NOT IN ('dbo', 'sys', 'INFORMATION_SCHEMA');

重点看两类账号:一是应用连接串里使用的账号,权限是否过大;二是是否存在孤立的SQL登录账号,密码简单或长期未改。

实在查不到,用触发器兜底

如果审计没开、trace被覆盖、日志也翻不出东西,最后的办法是建一个审计触发器,记录后续所有变更。虽然抓不到已经发生的事,但至少能止损:

CREATE TRIGGER tr_Audit_YourTable ON YourTable AFTER UPDATE, DELETE AS BEGIN INSERT INTO AuditLog (TableName, ActionType, ChangedBy, ChangeDate, OldData) SELECT 'YourTable', 'UPDATE', SUSER_SNAME(), GETDATE(), * FROM deleted; END;

注意触发器的性能开销,别在生产高峰加。

一个容易漏掉的入口

很多人只盯着数据库本身,忘了SQL Server所在的操作系统。如果攻击者拿到了Windows登录权限,可以直接附加数据库文件、停掉服务替换mdf文件,或者在SSMS之外用其他工具连进来。检查Windows事件日志中的远程桌面登录记录、检查SQL Server服务账号是否被改过密码、检查是否有计划任务在非工作时间执行脚本。

排查这件事,事后做不如事前做。审计开着、权限收着、日志留着,真出事的时候才有东西可查。否则就只能像我那个客户一样,查了两个月才发现是内鬼用sa账号在改数据。

本文地址:http://www.79wt.cn/news/1598b1699824.html
版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。

友情链接