[关闭]
@xuxuzhaozhao 2020-08-14T08:42:20.000000Z 字数 3824 阅读 1467

如何挽救中了勒索病毒的Windows服务器中的数据库数据

服务器


前阵子公司服务器遭了勒索病毒,现把数据库数据挽救经历写下来,干货哦!万一有人用得上呢!万一呢!

一、发生了什么?

“徐程意,徐程意,快看下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,登录后,快速的输入了极其熟悉的一句话:

  1. USE YUMUTANG
  2. SELECT TOP 100 * FROM dbo.View_Orders

望着结果页面返回的100条订单数据,我嘴角轻抬。
“各位不要急,还有救。”

首先把中了病毒服务器上的御木堂的数据库生成脚本并在本地【YUMUTANGTEST】执行一下。

在挽救数据之前,我做了以下两步工作:
第一、尝试在本地的对象页面打开御木堂数据库并读取数据:

  1. SELECT a.* FROM
  2. OPENROWSET('SQLOLEDB', 'xxx.xxx.xxx.195'; 'username'; 'password', YUMUTANG.dbo.Orders)

OK!没问题,出来了数据,心里稍微有底了 。

第二、将读出的数据,插入本地新建的相同结构的空表中。

  1. -- dbo.B_TreeHoleType无自增列
  2. USE YUMUTANGTEST
  3. INSERT INTO dbo.B_TreeHoleType
  4. SELECT a.* FROM
  5. OPENROWSET('SQLOLEDB', 'xxx.xxx.xxx.195'; 'username'; 'password', YUMUTANG.dbo.B_TreeHoleType)

OK!没问题,能插入,挽救了第一张表数据!

NICE!现在就是些重复工作了!

此时,出现新问题了。300多张表,九年的数据量,订单数据少的几十万条多的几百多万条,五个项目,这么亚子一个一个操作还叫什么程序员呢!

“Don't repeat yourself!”。

四、成功挽救数据

正式开始挽救数据:
由于有些表有【自增列】,有些表【无自增列】,在使用上述方法的时候如果有【自增列】,必须列明所有字段并且加入SET IDENTITY_INSERT @Table ON

第一、判断此表是否有自增列

  1. -- 判断此表是否有自增列
  2. CREATE FUNCTION [dbo].[S_GetIdentity]
  3. (
  4. @Table nvarchar(200)
  5. )
  6. RETURNS nvarchar(4000)
  7. AS
  8. BEGIN
  9. declare @sRs nvarchar(4000)
  10. set @sRs= isnull((select name+',' from sys.all_columns
  11. where is_identity=1 and object_id=(select object_id from sys.all_objects where type='u' and name=@Table) for xml path('')
  12. ),'')
  13. if LEN(@sRs)>0
  14. begin
  15. set @sRs=SUBSTRING(@sRs,1,LEN(@sRs)-1)
  16. end
  17. return @sRs
  18. END
  19. GO

第二、如果有自增列,则列举出表的所有字段

  1. CREATE FUNCTION [dbo].[S_GetColumns]
  2. (
  3. @Table nvarchar(200)
  4. )
  5. RETURNS nvarchar(4000)
  6. AS
  7. BEGIN
  8. declare @sRs nvarchar(4000)
  9. set @sRs= (select name+',' from sys.all_columns
  10. where object_id=(select object_id from sys.all_objects where type='u' and name=@Table) for xml path('')
  11. )
  12. set @sRs=SUBSTRING(@sRs,1,LEN(@sRs)-1)
  13. return @sRs
  14. END
  15. GO

第三、生成插入语句,根据是否有自增列会生成两种插入语句

  1. declare @sql nvarchar(4000)
  2. declare @src nvarchar(100)
  3. declare @table nvarchar(200)
  4. declare @cols nvarchar(4000)
  5. --这个指定原数据库的拥有关系,必须在目标数据库的查询分析器中执行
  6. set @src='YUMUTANG.dbo.'
  7. declare Cur112 cursor for
  8. select [name] from [sysobjects] where [type] = 'u' and [name] not in('dtproperties','sysdiagrams') order by [name]
  9. OPEN Cur112
  10. FETCH NEXT FROM Cur112 into @table
  11. WHILE @@FETCH_STATUS = 0
  12. begin
  13. set @sql=''
  14. if(len(dbo.S_GetIdentity(@table))>0)--存在自增列
  15. begin
  16. set @cols=dbo.S_GetColumns(@table)
  17. set @sql=@sql+'set IDENTITY_INSERT '+@table+' on;'
  18. set @sql=@sql+'INSERT INTO '+@table+'('+@cols+') select * from openrowset( ''SQLOLEDB '', ''xxx.xxx.xxx.195''; ''username''; ''password'','+@src+@table+');'
  19. set @sql=@sql+'set IDENTITY_INSERT '+@table+' off;'
  20. end else
  21. begin
  22. set @sql=@sql+'insert into '+@table+' select * from openrowset( ''SQLOLEDB '', ''xxx.xxx.xxx.195''; ''username''; ''password'','+@src+@table+');'
  23. end
  24. print @sql
  25. FETCH NEXT FROM Cur112 into @table
  26. END
  27. CLOSE Cur112
  28. DEALLOCATE Cur112

第四、将结果中的生成的所有INSERT语句拷贝到【YUMUTANGTEST】中,全选->F5执行,接着就是等待。
如果一切顺利(基本会一切顺利,五个项目没有一个出错),数据将全部被找回。

五、反思

经过长达5个多小时从发现到恢复,下午两点过,五个项目的ERP数据全部恢复。剩下的发布程序及拷贝数据库交给了另外一个同事,问题解决也终于松了一口气。

总结一下:
1、Windows服务器的3389端口一定要关闭,换一个奇怪的端口号;
2、经过此事后,我司所有服务器每个月定期更换一次密码;
3、数据库一定得做好异地备份,有空我将如何异地备份SqlServer数据库写出来;
4、遇事不要慌,慌则乱,不要放弃,车到山前必有路。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注