1、背景介绍
有朋友联系到我,某用户生产环境数据库被加密,问我是否能够恢复?
通过简单的交流确定了被勒索的环境是windows,使用的数据库是oracle,但数据库版本不详、数据量不详。


然后远程了该用户环境,确认损坏情况:



通过分析,得到了如下信息:
1)、数据库是11g的,但不确定具体版本,alert日志被加密,数据库备份被加密
2)、每个文件分6段加密,分别为文件头前32个block,中间4个32 block加密,尾部32个block加密;总共加密192个block,大概就是1.5MB样子;
--确定了环境后开始了恢复的方案;
2、恢复思路
oracle相比其它db不同的是,它是数据集中存储,破坏了小部分的数据,关键块未损坏的情况下是可以将库构造关键块后拉起来,重建数据库恢复业务的。也可以不拉库,利用dul类似工具抽数据进行恢复。但往往生产环境中有很多xml、blob、clob数据,大部分的dul工具售价并不便宜,所以我这里采用传统的自研办法解决;解决思路打开有两种,一种是只有单个system.dbf的,另外一种是有多个system.dbf的,如下:
单个system的恢复思路:
1)利用批处理,删掉或不全末尾的字节到8192,因为黑客是在末尾多写了部分字节,但不是8k,数据库识别必须是8k的块。
2)获取损坏的库数据字典props$基表块,拿到创建控制文件的关键信息:数据库名称、数据库版本信息、数据库字符集。这个要拿到手工创建控制文件使用。
3)得到了数据库版本信息后,手工创建一个相同版本的库,如现在dbname是orcl,我新建的时候还是取orcl。
4)将新创建dbca的orcl下的system文件前xx个块批量dd到被加密的所有dbf文件下,这个时候所有文件的信息都是system表空间的信息。
5)利用批处理,拿好的system.dbf文件50~128区间的块批量清空被加密的所有3号块之后的所有位图快,因为位图标记为可能被使用,会出现一些空间分配的问题,重建bitmap可能会报错。
6)将每个文件前300个块dd出来,然后上传到linux
7)linux 一键安装bbed,一键从rdba读取文件号生成bbed修改参数
8)由于前面dd了之后,数据块信息还是system的,比如rdba地址不对,每个块都有自己的地址,数据文件头、os块头、位图头块的大小、rootdba信息都存在问题,需要进行修改;
9)利用bbed生成修改的命令,将不是文件1的全部清空rootdba,修改每个文件的大小,分别存在0、1、2块上;
10)修改scn信息,可以大于原来生产库,但不能小于,可以通过dbv确认文件的最高scn。实在不清楚,多找几个文件确认,或设置大一点的wrap和base。
11)修改dbnam,将旧库全部改为orcl1;
12) 拷贝修改好的system到windows下,然后dd覆盖恢复,再单system起库,其余文件依次修改,rename位置,recover;
13)重建数据库
多个system的恢复思路:
多个system情况下,因为不确定这些system是对应的什么文件号,是不是system表空间的,所以只有利用dul工具先将关键信息抽取出来,然后shell处理生成bbed修改命令,全部文件统一修改,再拷贝到windows,全部文件的情况下创建控制文件,开库;
3、恢复步骤和截图
1)利用批处理,删掉或不全末尾的字节到8192,因为黑客是在末尾多写了部分字节,但不是8k,数据库识别必须是8k的块。--末尾多了几百kb
可以看到末尾多了多少258 bit,有几个文件例外,多了274bit!!!
需要删除每个文件多余的字节,保障大小和占用空间相等!!!


2)获取损坏的库数据字典props$基表块,拿到创建控制文件的关键信息:数据库名称、数据库版本信息、数据库字符集。这个要拿到手工创建控制文件使用。
11g从801块读取获取



3)得到了数据库版本信息后,手工创建一个相同版本的库,如现在dbname是orcl,我新建的时候还是取orcl。

4)将新创建dbca的orcl下的system文件前xx个块批量dd到被加密的所有dbf文件下,这个时候所有文件的信息都是system表空间的信息。

5)利用批处理,拿好的system.dbf文件50~128区间的块批量清空被加密的所有3号块之后的所有位图快,因为位图标记为可能被使用,会出现一些空间分配的问题,重建bitmap可能会报错。

6)将每个文件前300个块dd出来,然后上传到linux

7)linux 一键安装bbed,一键从rdba读取文件号生成bbed修改参数

8)由于前面dd了之后,数据块信息还是system的,比如rdba地址不对,每个块都有自己的地址,数据文件头、os块头、位图头块的大小、rootdba信息都存在问题,需要进行修改;
--使用自己编写的脚本处理
bbed parfile=bbed.par cmdfile=bbed_clearrootdba.txtbbed parfile=/home/oracle/bbed.par cmdfile=/home/oracle/bbed_rdba.txt


9)利用bbed生成修改的命令,将不是文件1的全部清空rootdba,修改每个文件的大小,分别存在0、1、2块上;
sed -i 's/ORCL/ORCL1/g' 3fix_size.sh[ora11g@ol7 sh]$ sh 3fix_size.shbbed parfile=bbed.par cmdfile=bbed_fixsize.txt
10)修改scn信息,可以大于原来生产库,但不能小于,可以通过dbv确认文件的最高scn。实在不清楚,多找几个文件确认,或设置大一点的wrap和base。
bbed parfile=bbed.par cmdfile=bbed_scn.txtbbed parfile=bbed.par cmdfile=bbed_sumapply.txt
11)修改dbnam,将旧库全部改为orcl1;
bbed parfile=bbed.par cmdfile=bbed_dbname.txt
12) 拷贝修改好的system到windows下,然后dd覆盖恢复,再单system起库,其余文件依次修改,rename位置,recover;
--获取回滚段用于屏蔽echo "p dba 1,225 kdbr"|bbed parfile=bbed.par|grep kdbrseq 0 20 | xargs -I{} echo 'x rncnnnnnnnnnnnnnnn dba 1,225 offset 0 *kdbr[{}]' |bbed parfile=bbed.par|grep "_SYS"|cut -f2 -d:|sed 's/ g'|tr "\n" ","|sed s'/.$//'C:\Users\wang>dd if=E:\hb\SYSTEM01.DBF of=E:\oradata\orcl1\SYSTEM01.DBF count=300 conv=notrunc*._allow_resetlogs_corruption=TRUE*._allow_error_simulation=TRUE*.compatible='11.2.0.4.0'*.control_files='E:\oradata\orcl1\CONTROL01.CTL'*.db_block_size=8192*.db_domain=''*.db_name='orcl1'*.diagnostic_dest='E:\app\wang'*.dispatchers='(PROTOCOL=TCP) (SERVICE=orclXDB)'*.open_cursors=300*.pga_aggregate_target=300M*.processes=1000*.remote_login_passwordfile='EXCLUSIVE'*.sga_target=1g*.undo_management='manual'*.undo_tablespace='SYSTEM'*._corrupted_rollback_segments=true*._offline_rollback_segments=true*._offline_rollback_segments=(_SYSSMU1_1880814008$,_SYSSMU2_237578013$,_SYSSMU3_3036648903$,_SYSSMU4_2554663710$,_SYSSMU5_2656872754$,_SYSSMU6_2560781624$,_SYSSMU7_362778077$,_SYSSMU8_3123962168$,_SYSSMU9_902607226$,_SYSSMU10_600653064$,_SYSSMU11_1908542605$,_SYSSMU12_681659328$,_SYSSMU13_2355401967$,_SYSSMU14_1898001506$,_SYSSMU15_2247781413$,_SYSSMU16_589156960$,_SYSSMU17_2366401286$,_SYSSMU18_1287317225$,_SYSSMU19_3322902554$,_SYSSMU20_2714089088$)*._corrupted_rollback_segments=(_SYSSMU1_1880814008$,_SYSSMU2_237578013$,_SYSSMU3_3036648903$,_SYSSMU4_2554663710$,_SYSSMU5_2656872754$,_SYSSMU6_2560781624$,_SYSSMU7_362778077$,_SYSSMU8_3123962168$,_SYSSMU9_902607226$,_SYSSMU10_600653064$,_SYSSMU11_1908542605$,_SYSSMU12_681659328$,_SYSSMU13_2355401967$,_SYSSMU14_1898001506$,_SYSSMU15_2247781413$,_SYSSMU16_589156960$,_SYSSMU17_2366401286$,_SYSSMU18_1287317225$,_SYSSMU19_3322902554$,_SYSSMU20_2714089088$)event = "10231 trace name context forever, level 10"event = "10233 trace name context forever, level 10"C:\Users\wang>oradim -new -sid ORCL1C:\Windows\system32>orapwd file=E:\app\wang\product\11.2.0\dbhome_1\database\PWDORCL1.ora password=hisC:\Users\wang>set oracle_sid=ORCL1SQL> startup nomount pfile='E:\oradata\orcl1\pfile_rc.txt';CREATE CONTROLFILE set DATABASE "ORCL1" RESETLOGS NOARCHIVELOGMAXLOGFILES 5MAXLOGMEMBERS 5MAXDATAFILES 100MAXINSTANCES 1MAXLOGHISTORY 292LOGFILEGROUP 1 'E:\oradata\orcl1\REDO01.LOG' SIZE 20M BLOCKSIZE 512,GROUP 2 'E:\oradata\orcl1\REDO02.LOG' SIZE 20M BLOCKSIZE 512,GROUP 3 'E:\oradata\orcl1\REDO03.LOG' SIZE 20M BLOCKSIZE 512DATAFILE'E:\oradata\orcl1\SYSTEM01.DBF'CHARACTER SET ZHS16GBK;oradebug setmypidoradebug event 10046 trace name context forever,level 12;oradebug tracefile_namealter database open resetlogs;
13)重建数据库
undo表空间处理、位图块处理、其余文件依次rename,recover;类似下面语法,本次未截图当前生产恢复图片,沿用以前恢复图片。





多个system的恢复思路:
多个system情况下,因为不确定这些system是对应的什么文件号,是不是system表空间的,所以只有利用dul工具先将关键信息抽取出来,然后shell处理生成bbed修改命令,全部文件统一修改,再拷贝到windows,全部文件的情况下创建控制文件,开库;
用新的system基表,初始化数据字典;替换参数,再用旧的system,unload出file$,ts$信息,构造shell,弄到linux去生成shell脚本修改所有文件的信息;然后统一创建控制文件,起库:




4、总结
勒索加密恢复还是比较考验dba技能的,需要掌握非常多的知识才能解决;
1、底层关键块、每个块作用,bbed使用,bbed批量修改各种数据办法、坏块各种构造恢复,一个细节不清楚就干不了这个事情。
2、心态,每次恢复都会遇到不一样的插曲,都需要深思熟虑的去分析和解决。
3、今年恢复了3个类似的case,该用户运气不错,数据加密较少,恢复率99%以上。




