| 首页 | 技术文章 | 软件下载 | 博客 | 论坛 | 精品教程 | 黑客动画 | 视频资源 | 在线服务 | 黑客游戏 | 

您现在的位置: 中国X黑客小组 >> 技术文章 >> 编程技术 >> 黑客编程 >> 文章正文 用户登录 新用户注册
  BIOS Rootkit的简单设计过程          【字体:
BIOS Rootkit的简单设计过程
作者:Icelord    文章来源:CnXHacker.Net    点击数:    更新时间:2007-5-27    

[前言]

这是很早的一个想法了。//那是去听一位讲TPM,很长篇的,
打瞌睡,于是想怎么破坏那种限制(在一定条件下),自然而然想到了BIOS Coding,
后来就转化为BIOS Rootkit...

[国内外发展状况]

ACPI BIOS Rootkit
PCI Module BIOS Rootkit
CPU Micro Code...??? 


times 3K db 0 ;这里省略3K Bytes

[rootkit定义]
google yourself
[BIOS介绍]
google yourself
[BIOS RootKit的优缺点]
很明显
[IcLord BIOSRootkit的组成]

下面的方法很笨拙,但是我的目的只是让它能运行起来...
如果您有好的方法,欢迎指点/交流

(1).Flasher
(2).BIOS Module
(3).Bootstrap
(4).NT RootKit //?

[问题]
(1).植入
如何将rootkit植入到BIOS中...
(2).启动
如何在启动的过程中执行rootkit的指令...
(3).切换
BIOS在OS之前运行,要想启动OS,需要将CPU控制交还到BootLoader。
此时,CPU处于RealMode,没有多任务,没有VM...
那么,如何使得我们的RootKit再次获取CPU?...
(4).RootKit实体
怎样实现Rootkit的功能:hide,shell...

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[解决方法]
[流程]
ISAModule-->hook BIOS int svc,
从而在int svc中再Hook NTLDR!OsLoader.EXE,
在NTLDR!OsLoader.EXE中再进行kernel subversion

hehe,看起来很简单,实际遇到的问题那可是相当麻烦啊,follow me,逐个解决

[目标]
该程序能启动.sys类型的存在的rootkit,也就是能在NT操作系统中启动.sys(<64KB)文件...

BIOS RootKit本身要实现安装.sys到BIOS中,并在PC启动时使该.sys在特定的操作系统下生效

一、如何将代码植入到BIOS中

[目标]
将制定的代码植入到BIOS中,并且在BIOS初始化的末尾获得运行的机会。

[solution?]
将代码植入到BIOS,需要解决以下问题:
(1).如何修改BIOS,添加自己的代码
(2).如何刷新BIOS

//预备知识:
//
//BIOS(Basic Input/Output System)负责初始化各种硬件,Provide Runtime Service,并负责加载并执行BootSector,
//将CPU转交OSLoader。当前BIOS Provider主要为Phonix-Award,AMI好像很少(至少在我这里)。
//BIOS存储在FlashROM中。
//FlashROM(快速只读存储器)是当前主板、显卡的BIOS程序的主要存储介质。
//FlashROM在一般情况下为只读,写无效,即里面存储的数据无法被修改,而且断电之后数据仍然保存。
//FlashROM一般为字节读取,扇区/块擦除,byte/sector/page/bulk Program。
//BIOSROM影射在内存的高端。为防止程序运行时的内存写入破坏BIOS,一般FlashROM都软件和硬件保护。
//
//FlashROM一般连接在南桥的LPC(Low Pin Count)总线上,南桥芯片有不同的寄存器来控制FlashROM的WE和解码。
//
//[SST 49LFxxx系列的刷新问题]
// 我不知道SST应用是否广泛,但至少我这里有几台机器都是 SST 49LFXXX系列的FlashROM
// 
// 例如,SST 49LFxxx系列FlashROM,这种FlashROM提供SDP(Software data protect)和HDP(Hardware Data protect).
// 要对FlashROM写入,需要向FlashROM的特定位置发送特定的指令序列,而且TBL#(Top Boot Lock)和WP#(Write Protect)。
// 除此之外,还需要设置ICH的BIOS_CNTL和LPC_DEC_EN寄存器...(对ICH4芯片...),Firmware Hub的Block Locking register...
//
//[PCI配置寄存器的知识和问题]
//
// 不同的主板芯片需要不同的设置,不同的FlashROM需要不同的刷新方法,具体需要看相关的DataSheet和Specification.

BIOS是分模块的固件程序...

[Award BIOS 6.00PG(2Mb)的结构]
见<<awdBIOS 镜像结构简单分析>>
http://blog.csdn.net/icelord/archive/2007/05/11/1604122.aspx


[Award 2M BIOS src分析]
brief:只是为了了解初始化流程
见<<awdBIOS 2M Src简单分析>>
http://blog.csdn.net/icelord/archive/2007/05/11/1604133.aspx


[加入ISA模块和Hook问题]
见<<加入ISA模块和Hook问题>>
http://blog.csdn.net/icelord/archive/2007/05/11/1604151.aspx
见<<awdBIOS 数据结构>>
http://blog.csdn.net/icelord/archive/2007/05/11/1604156.aspx


[效验和问题]
怎样修复添加模块后的BIOS的效验和?
见<<关于BIOS效验和的问题>>
http://blog.csdn.net/icelord/archive/2007/05/11/1604179.aspx

[刷新的问题]
[UniFlash源码分析]
很好的开源软件,
见<<UniFlash简单分析>>
http://blog.csdn.net/icelord/archive/2007/05/11/1604188.aspx
[WinFlash的简单分析]
win平台的AWD BIOS刷新程序,IDA一下,看看它究竟怎么刷新...
见<<WinFlash_AwdFlash简单分析>>
http://blog.csdn.net/icelord/archive/2007/05/11/1604209.aspx

[关于辅助驱动]
在NT下刷新BIOS需要读写物理内存和/或IO端口,那么怎样快速的读写物理内存和/或IO端口。
见<<读写物理内存和IO端口>>
http://blog.csdn.net/icelord/archive/2007/05/11/1604229.aspx


[实际测试方法]

至少应该有两台相似的机器,即FlashROM相同(可拆卸的那种),BIOS相同,以确保在刷新失败后迅速恢复。
你也可以使用BootBlock的功能,用软盘恢复,不过试验时读盘之后就没了反应...

之后你就可以从ISA模块开始测试了。


[问题多多]

[complex hardware environment]

[diferent bios vendor & version]

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 

二、如何在BIOS/OsLoader中启动Rootkit

[目标]

将ring0/ring3 Rootkit隐藏于 BIOS中,并且能够在用户选择操作系统之后开始工作。
Rootkit以驱动(ring0 okay以后,ring3应该更简单)的形式存在(其实就是嵌入到 BIOS中)。

[当前状态]
Location: BIOS Module
Seq: BIOS POST Section...
state: 16Bit Real Mode

先看一下x86 PC/(using awdbios)初始化流程
>...
>BIOS_memsizing..
>XXXX (uncared...)
>ISA/PCI Module Init
>Int 0x19
>MBR
>PBR(obr?)
>Ntldr
>KernelImage/Drivers

这时,我们已经能够在实模式下执行代码了,而且有BIOS服务可以使用(???)。此时
操作系统还没有启动,没有文件系统,我们的目标是在操作系统支持下的一个特殊Shell
程序,所以我们需要放弃CPU将控制转交到BIOS,使之完成正常初始化。那么如何使我们的
代码再次获得CPU(被运行)?
(1).写文件
就是将需要运行的代码写入到磁盘文件中(OS 需要且会执行的文件),OS在启动中
再运行此文件,从而获取执行的机会。
很明显,此方法很复杂,需要很多特殊的环境,特别是文件系统的操作...
(2).Hook
老方法:Hook BIOS代码,再在hook代码中进行多级Hook,从而在运行loader时重新获取执行
的机会。
这个方法现在很流行...

注:Nt Loader在启动中,将使用BIOS服务来读取所需的磁盘数据,所以直接Hook BIOS服务即可
实现对 Loader的Hook,获得再次执行的机会。

在BIOS ISA模块中,可以使用BIOS服务(E8_POST?)//此处没有作深入的测试
在测试中直接在ISA ROM Init 阶段Hook int 13h失败,所以采用了Hook int 0x19-->hook int 0x13
的方式,比较罗嗦,但是可以将就着用...

[NTLDR分析]
已经有高人分析过了,但是没看懂,自己按需要记录了一下,需要知道流程:
见<<NTLDR.分析笔记>>
http://blog.csdn.net/icelord/archive/2007/05/11/1604312.aspx

[Signature Code的确定]
见<<x HookCode的选择>>
http://blog.csdn.net/icelord/archive/2007/05/11/1604320.aspx

首先要确保能hook用户选择的操作系统,所以要Hook的代码应该位于KeSelectKernel()函数之后
其次,当我们Hook的代码运行时,操作系统内核和BootDriver应已经加载到内存,这样就会方便
我们进一步Hook Kernel或者BootDriver,实现向VM32下的切换。要满足这个条件,要Hook的代码应该
在'BlLoadImage(NTOSKRNL)'之后了.
其实很简单。直接从Osloader将控制转交到NTOSKRNL.EXE处开始向前查找即可
即从代码(SystemEntry)(BlLoaderBlock);之前查找。
考虑到兼容性的问题,即如何适应不同版本的 OsLoader.
简单想法是查找CPU控制寄存器相关的指令来Hook,因为通用寄存器很难找到三个版本通用的Hook指令。
但是Turn On Paging时肯定会用到CR0(/CR3)寄存器。所以直接查找'mov eax,cr0'之类的指令,看是否
三个版本的OSLOADER.exe中是否有相同的代码。hehe,运气不错,在BlSetupForNT()中找到了三个OSLoader.exe
都存在的指令,可以说是童叟无欺,基本可用。


以下是代码片段:
代码如下:
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
[Ref_nt4: \boot]
//
// Mapped hardcoded virtual pointer to the boot processors PCR
// The virtual pointer comes from the HAL reserved area
//

//
// First zero out any PTEs that may have already been mapped for
// a SCSI card.
//

RtlZeroMemory(HalPT, PAGE_SIZE);
_asm {
mov eax, cr3 //拿CR3开刀,hehe
mov cr3, eax
}

HalPT[(KI_USER_SHARED_DATA - 0xFFC00000) >> PAGE_SHIFT].PageFrameNumber = PCR+1;
HalPT[(KI_USER_SHARED_DATA - 0xFFC00000) >> PAGE_SHIFT].Valid = 1;
HalPT[(KI_USER_SHARED_DATA - 0xFFC00000) >> PAGE_SHIFT].Write = 1;
RtlZeroMemory((PVOID)KI_USER_SHARED_DATA, PAGE_SIZE);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

三个版本的Osloader.exe中断汇编代码如下:

windows 2000 pro

AssembleCode:
.text:0031F244 010 mov edi, ds:dword_357670
.text:0031F24A 010 mov esi, 400h
.text:0031F24F 010 mov ecx, esi
.text:0031F251 010 xor eax, eax
.text:0031F253 010 rep stosd
.text:0031F255 010 mov eax, cr3
.text:0031F258 010 mov cr3, eax
.text:0031F25B 010 mov eax, ds:dword_357670
.text:0031F260 010 mov ecx, ds:dword_3324B0

HexCode:
8B 3D 70 76 35 00
BE 00 04 00 00
8B CE
33 C0
F3 AB
0F 20 D8
0F 22 D8
A1 70 76 35 00
8B 0D B0 24 33 00

---------------------------------------------------------------------------
windows xp sp2

AssembleCode:
.text:00428D81 018 mov edi, dword_46A410
.text:00428D87 018 mov ebx, 400h
.text:00428D8C 018 mov ecx, ebx
.text:00428D8E 018 xor eax, eax
.text:00428D90 018 rep stosd
.text:00428D92 018 mov eax, cr3
.text:00428D95 018 mov cr3, eax
.text:00428D98 018 mov eax, dword_46A410
.text:00428D9D 018 add eax, 7C0h

HexCode:
8B 3D 10 A4 46 00
BB 00 04 00 00
8B CB
33 C0
F3 AB
0F 20 D8
0F 22 D8
A1 10 A4 46 00
05 C0 07 00 00

---------------------------------------------------------------------------
windows 2003 sp0

AssembleCode:
.text:0042C6BD 018 mov edi, dword_471B90
.text:0042C6C3 018 mov ebx, 400h
.text:0042C6C8 018 mov ecx, ebx
.text:0042C6CA 018 xor eax, eax
.text:0042C6CC 018 rep stosd
.text:0042C6CE 018 mov eax, cr3
.text:0042C6D1 018 mov cr3, eax
.text:0042C6D4 018 mov eax, dword_471B90
.text:0042C6D9 018 add eax, 7C0h

HexCode:

8B 3D 90 1B 47 00
BB 00 04 00 00
8B CB
33 C0
F3 AB
0F 20 D8
0F 22 D8
A1 90 1B 47 00
05 C0 07 00 00

---------------------------------------------------------------------------

Signature Code:

------------------------------------------------
8B 3D ** ** ** ** ;mov edi,dword [addr]
** 00 04 00 00 ;mov reg,0x400
8B ** ;mov ecx,reg
------------------------------------------------
33 C0 ;xor eax,eax
F3 AB ;rep stosd
0F 20 D8 ;mov eax,cr3
0F 22 D8 ;mov cr3,eax
------------------------------------------------
A1 ** ** ** ** ;mov eax,dword [addr]
------------------------------------------------

finally:

code={33 c0 f3 ab , 0f 20 d8 0f , 22 d8 a1}
dword:0xabf3c033,0x0fd8200f,0x??a1d822

or

33
c0 f3 ab 0f,20 d8 0f 22,d8 a1


------------------------------------------------

haha,只要在int 0x13中hook上面所示的代码,即可在用户选择操作系统,并且OsLoader.exe
加载了内核和BootDriver之后获得执行的机会.那时,你可以再次任意hook Kernel。

为什么搞的这么麻烦?因为我的目的是加载一个额外的驱动。这要求在BootDriver初始化开始时才
运行的. 

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


三、切换

[当前状态]

当运行到这里时我们处于32Bit PM,Paging的状态下。
EIP位于BlSetupForNt()函数中...,Ntoskrnl.exe

[1] [2] [3] 下一页

文章录入:IceRiver    责任编辑:admin 
  • 上一篇文章:

  • 下一篇文章:
  • 发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
    最新热点 最新推荐 相关文章
    Microsoft 9月安全公告的摘要
    用Dos命令加锁 防止病毒格式
    活地运用SQL Injection做数据
    McAfee发布Windows Mobile风
    破解Session cookie的方法
    SIDVault Simple_Bind 函数多
    SIDVault Simple_Bind 函数多
    Sun Solaris ATA 磁盘驱动IO
    Mac OSX--攻破它像用它那么
    Cisco IOS中Secure Copy 实现
      网友评论:(只显示最新5条。评论内容只代表网友观点,与本站立场无关!)
    Powered by ICE RIVER - STUDIO
    » CnXHacker.CoM   © CopyRight 2002-2006, CnXHacker.CoM™, Inc. All Rights Reserved.