@xuxuzhaozhao
2020-08-14T08:42:20.000000Z
字数 3824
阅读 1467
服务器
前阵子公司服务器遭了勒索病毒,现把数据库数据挽救经历写下来,干货哦!万一有人用得上呢!万一呢!
“徐程意,徐程意,快看下195服务器怎么回事,御木堂的ERP打不开了!”,云总慌慌张张的跑到我的办公桌前。
“不要慌撒,慢慢说?”,我说道。按照以往情况来看,估计是订单审核员在执行批量的订单计算把服务器CPU拖垮了,这种情况一般是数据库在写入大量计算数据的时候,经销商在不停刷新页面导致的。
“跟以前不一样,整个页面打开全是 503 服务不可用。”
“不对,九凤的ERP也打不开了。”,我司另外一个小朋友强作镇静地说。
什么情况!这时,心里有点小慌慌了。没遇到过啊,我们ERP程序再吃计算资源,也不会导致全部都是503啊。
远程登录服务器看下。
这不看不要紧,一看,桌面全是一串乱码的文件,除了一个叫how_to_back_files.html
。我双击打开后:
“wtf,我&……¥#¥(*@¥”,这玩意儿不是存在于各种网络段子上嘛!万万没想到啊!我们也遭啦!
“云总,服务器中勒索病毒了,文件全都没了。”,经过这么多勒索病毒的故事,心里清楚,一旦中了勒索病毒,这个服务器基本也就毁了。
“不是每日备份了的吗,拿来恢复一下,不就好了。”,云总疑惑的看着我。
“备份的文件也被加密了,没了。”
左边商务部,不停的给客户打电话,什么“服务器突发故障”,“西部数码在调整”一堆理由来安抚客户。
面前,云总看着我,“徐程意,还有其他办法没得?”。
“这...,有啊,给勒索者转比特币吧!”,开玩笑,我怎么可能这么说!
“我去Google搜下,看下有办法没。”,此时,心里边五味杂成,也清楚自己面临的这个东西基本没救了。
果不其然,打开后,基本都是这样的:
要不就是这样的:
总结起来就是,没救了!怎么说呢,按本山叔的说法就是,心里拔凉拔凉的!
如果找不回数据,商务部预估的损失金额在150万左右。
人啊,总在绝境的情况下(虽然远远谈不上),脑子突然就会变得特别好使。
各个版本的程序源代码本地还有,只要找回数据库的数据,就可以解救这次危机。
就在此时,一阵灵光闪过我的大脑。突然想到,数据库在运行的时候,数据库文件是无法被删除及修改的。不知道这个勒索病毒有没有把SQL Server的服务停了再加密文件。
我打开服务器,右键底部任务管理器,查看服务。手里按着‘S’直到找到SQL Server(MSSQL SERVER)服务。往后一看,出现了三个好亲切的汉字【已启动】。
”卧槽,有戏!“,心里想着,但是还不敢表现出来。
”小王,御木堂的数据库连接字符串,发给我一下,速度。“
我在本机打开SQL Server Management,登录后,快速的输入了极其熟悉的一句话:
USE YUMUTANG
SELECT TOP 100 * FROM dbo.View_Orders
望着结果页面返回的100条订单数据,我嘴角轻抬。
“各位不要急,还有救。”
首先把中了病毒服务器上的御木堂的数据库生成脚本并在本地【YUMUTANGTEST】执行一下。
在挽救数据之前,我做了以下两步工作:
第一、尝试在本地的对象页面打开御木堂数据库并读取数据:
SELECT a.* FROM
OPENROWSET('SQLOLEDB', 'xxx.xxx.xxx.195'; 'username'; 'password', YUMUTANG.dbo.Orders)
OK!没问题,出来了数据,心里稍微有底了 。
第二、将读出的数据,插入本地新建的相同结构的空表中。
-- dbo.B_TreeHoleType无自增列
USE YUMUTANGTEST
INSERT INTO dbo.B_TreeHoleType
SELECT a.* FROM
OPENROWSET('SQLOLEDB', 'xxx.xxx.xxx.195'; 'username'; 'password', YUMUTANG.dbo.B_TreeHoleType)
OK!没问题,能插入,挽救了第一张表数据!
NICE!现在就是些重复工作了!
此时,出现新问题了。300多张表,九年的数据量,订单数据少的几十万条多的几百多万条,五个项目,这么亚子一个一个操作还叫什么程序员呢!
“Don't repeat yourself!”。
正式开始挽救数据:
由于有些表有【自增列】,有些表【无自增列】,在使用上述方法的时候如果有【自增列】,必须列明所有字段并且加入SET IDENTITY_INSERT @Table ON
。
第一、判断此表是否有自增列
-- 判断此表是否有自增列
CREATE FUNCTION [dbo].[S_GetIdentity]
(
@Table nvarchar(200)
)
RETURNS nvarchar(4000)
AS
BEGIN
declare @sRs nvarchar(4000)
set @sRs= isnull((select name+',' from sys.all_columns
where is_identity=1 and object_id=(select object_id from sys.all_objects where type='u' and name=@Table) for xml path('')
),'')
if LEN(@sRs)>0
begin
set @sRs=SUBSTRING(@sRs,1,LEN(@sRs)-1)
end
return @sRs
END
GO
第二、如果有自增列,则列举出表的所有字段
CREATE FUNCTION [dbo].[S_GetColumns]
(
@Table nvarchar(200)
)
RETURNS nvarchar(4000)
AS
BEGIN
declare @sRs nvarchar(4000)
set @sRs= (select name+',' from sys.all_columns
where object_id=(select object_id from sys.all_objects where type='u' and name=@Table) for xml path('')
)
set @sRs=SUBSTRING(@sRs,1,LEN(@sRs)-1)
return @sRs
END
GO
第三、生成插入语句,根据是否有自增列会生成两种插入语句
declare @sql nvarchar(4000)
declare @src nvarchar(100)
declare @table nvarchar(200)
declare @cols nvarchar(4000)
--这个指定原数据库的拥有关系,必须在目标数据库的查询分析器中执行
set @src='YUMUTANG.dbo.'
declare Cur112 cursor for
select [name] from [sysobjects] where [type] = 'u' and [name] not in('dtproperties','sysdiagrams') order by [name]
OPEN Cur112
FETCH NEXT FROM Cur112 into @table
WHILE @@FETCH_STATUS = 0
begin
set @sql=''
if(len(dbo.S_GetIdentity(@table))>0)--存在自增列
begin
set @cols=dbo.S_GetColumns(@table)
set @sql=@sql+'set IDENTITY_INSERT '+@table+' on;'
set @sql=@sql+'INSERT INTO '+@table+'('+@cols+') select * from openrowset( ''SQLOLEDB '', ''xxx.xxx.xxx.195''; ''username''; ''password'','+@src+@table+');'
set @sql=@sql+'set IDENTITY_INSERT '+@table+' off;'
end else
begin
set @sql=@sql+'insert into '+@table+' select * from openrowset( ''SQLOLEDB '', ''xxx.xxx.xxx.195''; ''username''; ''password'','+@src+@table+');'
end
print @sql
FETCH NEXT FROM Cur112 into @table
END
CLOSE Cur112
DEALLOCATE Cur112
第四、将结果中的生成的所有INSERT语句拷贝到【YUMUTANGTEST】中,全选->F5执行,接着就是等待。
如果一切顺利(基本会一切顺利,五个项目没有一个出错),数据将全部被找回。
经过长达5个多小时从发现到恢复,下午两点过,五个项目的ERP数据全部恢复。剩下的发布程序及拷贝数据库交给了另外一个同事,问题解决也终于松了一口气。
总结一下:
1、Windows服务器的3389端口一定要关闭,换一个奇怪的端口号;
2、经过此事后,我司所有服务器每个月定期更换一次密码;
3、数据库一定得做好异地备份,有空我将如何异地备份SqlServer数据库写出来;
4、遇事不要慌,慌则乱,不要放弃,车到山前必有路。