Rootkit For Windows.docx
- 文档编号:27926874
- 上传时间:2023-07-06
- 格式:DOCX
- 页数:15
- 大小:25.46KB
Rootkit For Windows.docx
《Rootkit For Windows.docx》由会员分享,可在线阅读,更多相关《Rootkit For Windows.docx(15页珍藏版)》请在冰豆网上搜索。
RootkitForWindows
一.先说几句与技术无关的话。
现在很多人对rootkit认识不够,可以说空白。
而此愚文的目的就是让菜鸟认识rootkit→了解rootkit。
也让一些想研究它的人把这篇文章当作一个参考或是入门级的指导。
文章中介绍的rootkit的隐藏方法只是一部分。
还有很多技术没有提到,另外还有一些未公开的技术。
有些地方我未引用代码,因为不想占用过多的篇幅。
以免有玩弄代码的嫌疑,不过写完以后还是觉得代码太多,请个位见谅。
一-三的内容适合菜鸟看,也许第四部分之后对很多人来说都有些意义吧。
如果高手不幸看到了,请准备好,不要吐到屏幕上或身上。
以往的文章写的比较乱,而且格式不公正,这样的形式写文章也是第一次。
以前文章中引用代码和文字也没有详细说明,再此也对作者表示谦意。
感谢XX提的这个建议。
今天是9月11号,庆祝一下童童的生日。
顺便为911事件中的遇难者祈祷。
同时也感谢MGF病毒的作者指点。
*************************
二.简单的说说rootkit.
Rootkit的历史已经很悠久了。
存在于windows,unix,linux等操作系统中,不只局限在windows,此文我只以windows平台为例来说rootkit。
Root在英语中是根,扎根的意思,kit是包的意思。
rootkit我们可以把它理解成一个利用很多技术来潜伏在你系统中的一个后门,并且包含了一个功能比较多的程序包,例如有、清除日志,添加用户,b7cmdshell,添加删除启动服务等功能。
当然它的设计者也要用一些技术来隐藏自己,确保不被发现。
隐藏包括隐藏进程,隐藏文件,端口,或句柄,注册表的项,键值等等。
总之,写rootkit的人是狡尽乳汁利用很多办法不被发现。
现在人们最熟悉的windowsrootkit就是hackerdefender和ntrootkit了,还有使用了baiyuanfan在XCON提出的ring3rootkit新思路的byshell,呵呵。
而linux下就是knark了。
*************************
三.rootkit的一些以公开的隐藏技术以及检测技术。
1.删除进程双项链上的进程对象。
ps:
用的似乎很多,连现在的一些盗号的程序也利用上了
现在所有人查看进程一般都是通过任务管理器(taskmgr.exe)来查看。
了解一些编程知识的人都知道,任务管理器枚举进程信息是靠的NtQuerySystemInformation也就是ZwQuerySystemInformation函数。
众所周知,这个NativeApi(本机API)枚举进程是要通过进程活动链表的。
我们就来看看这个结构。
typedefstruct_OBJECT_ATTRIBUTES
{
ULONGLength;
HANDLERootDirectory;
PUNICODE_STRINGObjectName;
ULONGAttributes;
PVOIDSecurityDescriptor;
PVOIDSecurityQualityOfService;
}OBJECT_ATTRIBDTES,*POBJECT_ATTRIBUTES;
typedefstruct_IO_STATUS_BLOCK
{
NTSTATDSStatus;
ULONGInformation;
}IO_STATUS_BLOCK,*PIO_STATUS_BLOCK;
typedefstruct_LIST_ENTRY
{
Struct_LIST_ENTRY*Flink;
Struct_LIST_ENTRY*Blink;
}LIST_ENTRY,*PLIST_ENTRY;
双向链表的典型例子就是进程和线程链。
内部变量PsActiveProcessHead是一个LIST_ENTRY结构,在ntoskrnl.exe的数据段中,指定了系统进程列表的第一个成员。
仔细想想,如果我们将进程对象从进程双向链表中移除,那么调用NtQuerySystemInformation来枚举进程的任务管理器taskmgr.exe中就不会看到我们的进程了。
那么就有人会担心了。
如果进程从链表中删除,那还会被运行么?
答案是,会。
因为windows的ds,也就是线程分派器,也叫任务调度分配器(dispatcherscheduler)使用的是另一个数据结构,也就是说,进线程是否被调度处理与进程双向活动链表无关,不会被CPU忽略,不必担心。
2003年pjf在安全焦点上提出的就是这个方法且给出了这个方法的实现代码。
文章结尾处的参考资料中我会给出这个文章的URL。
2.修改系统调用表(sst)
rootkit可以通过在系统调用表中添加添加自己的服务然后运行想要执行的任务。
He4HookInv就是这样。
He4HookInv也是一个比较有名的windowsrootkit。
下面我们来看看He4HookInv具体的实现过程。
在以前人们不知道它是如何实现的这些,一些介绍rootkit的文章也是提到一点,不过只知道是修改的SST,细节也没有过多描述。
直到phrack杂志公布了He4HookInv的一些细节。
He4Hook在不同版本所使用的方法是有所不同的。
公布的方法中有两种。
这里只说说第一种方法。
如果想了解第二种方法和原版就看文章结尾的参考资料吧(phrack的连接)。
ZwCreateFile,ZwOpenFile,IoCreateFile,ZwQueryDirectoryFile,ZwClose这些函数在Ntdll.dll中是这样实现的。
moveax,NumberFunction
leaedx,[esp+04h]
int2eh;Syscallinterface
当然Ntdll.dll是一个maingate,真正的函数调用是在Ntoskrnl中完成的。
关于本机API的,可以看参考资料中我写的另一篇文章《浅析本机API》。
EAX中储存着系统调用号。
int2Eh代表转到中断描述符表IDT位置0x2E处的中断处理程序。
中断处理程序把EAX里的值作为查找表中的索引,去找到最终的目标函数。
这个表就是系统服务表SST。
ntoskrnl通过KeServiceDescriptorTable符号,导出了主要SDT的一个指针。
我们可以通过KeServiceDescriptorTable来访问SDT。
现在来看看KeServiceDescriptorTable的结构。
typedefstructSystemServiceDescriptorTable
{
SSDSystemServiceDescriptors[4];
}SSDT,*LPSSDT;
Otherstructures:
typedefVOID*SSTAT[];
typedefunsignedcharSSTPT[];
typedefSSTAT*LPSSTAT;
typedefSSTPT*LPSSTPT;
typedefstructSystemServiceDescriptor
{
LPSSTATlpSystemServiceTableAddressTable;
ULONGdwFirstServiceIndex;
ULONGdwSystemServiceTableNumEntries;
LPSSTPTlpSystemServiceTableParameterTable;
}SSD,*LPSSD;
KeServiceDescriptorTable指向的DescriptorTable只能从内核模式访问。
在用户模式下,有一个未输出的KeServiceDescriptorTableShadow。
底层服务有:
KeServiceDescriptorTable->SystemServiceDescriptors[0]
KeServiceDescriptorTableShadow->SystemServiceDescriptors[0]
内核模式图形化用户界面服务(GUI):
KeServiceDescriptorTableShadow->SystemServiceDescriptors[1]
在WinNt4(SP3-6)和Win2kbuild2195之前的所有版本中,DescriptorTable的其他的元素在写入时是空闲的,表中每个元素为SSID结构,包含有以下数据:
lpSystemServiceTableAddressTable指针表,当相关系统调用启用时,它指向被调用的函数内存地址数组。
dwFirstServiceIndex指向第一个函数的开始地址
dwSystemServiceTableNumEntries表中服务数目
lpSystemServiceTableParameterTable表示出入栈的字节数目
为了取得系统调用,He4HookInv用一个指针替代了KeServiceDescriptorTable->SystemServiceDescriptos[0].lpSystemServiceTableAddressTableIn中存储的地址,而指向其所属表。
你可以通过在系统调用表中添加自己的服务而界入He4HookInv。
He4HookInv将更新以下两表:
-KeServiceDescriptorTable
-KeServiceDescriptorTableShadow.
但是,如果He4HookInv只更新KeServiceDescriptorTable,新的服务项在用户模式下将不能被调用。
为了定位KeServiceDescriptorTableShadow,将用到以下技术:
KeAddSystemServiceTable函数能向内核驱动层添加服务,而且能向两个表中同时添加。
如果它的0指示符是相同的,通过扫描KeAddSystemServiceTable函数代码就可以找到shadow表的地址,具体可以在He4HookInv.c文件中的FindShadowTable(void)函数中查看是怎么实现的。
如果这个办法失败,He4Hook使用一个硬编码的地址((KeServiceDescriptorTable-0x230)来定位ShadowTable的位置.这个地址从WinNT-sp3来就没有变过.另外一个问题是如何找到系统服务的编号,这个其实很简单,由于系统服务的函数体都具有以下形式(moveax,NumberFunction),所以我们只要把系统服务的函数地址加上1bytes,就可以得到系统服务对应的编号。
He4HookInv利用的第二个方法就是修改文件系统驱动中DRIVER_OBJECT的回调表,这里就不在详细说明了。
3.端口隐藏
很多人检查自己中没中木马或后门,都会一些方法来查看自己本机所开的端口来判断是否有木马监听,而有些rootkit就开始想如何隐藏端口了。
最简单的枚举当前所开放的端口信息是调用iphlpapi.dll中的AllocateAndGetTcpTableFromStack和AllocateAndGetUdpTableFromStack函数,或者AllocateAndGetTcpExTableFromStack和AllocateAndGetUdpExTableFromStack函数。
DWORDWINAPIAllocateAndGetTcpTableFromStack(
OUTPMIB_TCPTABLE*pTcpTable,
INBOOLbOrder,
INHANDLEhAllocHeap,
INDWORDdwAllocFlags,
INDWORDdwProtocolVersion;
);
DWORDWINAPIAllocateAndGetUdpTableFromStack(
OUTPMIB_UDPTABLE*pUdpTable,
INBOOLbOrder,
INHANDLEhAllocHeap,
INDWORDdwAllocFlags,
INDWORDdwProtocolVersion;
);
DWORDWINAPIAllocateAndGetTcpExTableFromStack(
OUTPMIB_TCPTABLE_EX*pTcpTableEx,
INBOOLbOrder,
INHANDLEhAllocHeap,
INDWORDdwAllocFlags,
INDWORDdwProtocolVersion;
);
DWORDWINAPIAllocateAndGetUdpExTableFromStack(
OUTPMIB_UDPTABLE_EX*pUdpTableEx,
INBOOLbOrder,
INHANDLEhAllocHeap,
INDWORDdwAllocFlags,
INDWORDdwProtocolVersion;
);
还有另外一种方法。
当程序创建了一个套接字并开始监听时,它就会有一个为它和打开端口的打开句柄。
我们在系统中枚举所有的打开句柄并通过NtDeviceIoControlFile把它们发送到一个特定的缓冲区中,来找出这个句柄是否是一个打开端口的。
这样也能给我们有关端口的信息。
因为打开句柄太多了,所以我们只检测类型是File并且名字是\Device\Tcp或\Device\Udp的。
打开端口只有这种类型和名字。
而通过察看iphlpapi.dll的代码。
就会发现这些函数同样都是调用NtDeviceIoControlFile并发送到一个特定缓冲区来获得系统中所有打开端口的列表。
也就是说,我们挂接NtDeviceIoControlFile函数就可以隐藏端口。
我们来看看NtDeviceIoControlFile的原型
NTSTATUSNtDeviceIoControlFile(
INHANDLEFileHandle
INHANDLEEventOPTIONAL,
INPIO_APC_ROUTINEApcRoutineOPTIONAL,
INPVOIDApcContextOPTIONAL,
OUTPIO_STATUS_BLOCKIoStatusBlock,
INULONGIoControlCode,
INPVOIDInputBufferOPTIONAL,
INULONGInputBufferLength,
OUTPVOIDOutputBufferOPTIONAL,
INULONGOutputBufferLength
);
我们来看看《TheUndocumentedFunctions-MicrosoftWindowsNT_2000》中对这些参数的描述
FileHandle
HANDLEtoDeviceObjectopenedasafile.
Event
OptionalHANDLEtoEventObjectsignalledontheendofprocessingrequest.
ApcRoutine
Optionalpointertouser'sAPCRoutinecalledontheendofprocessingrequest.
ApcContext
User'sparametertoApcRoutine.
IoStatusBlock
IOresultofcall.
IoControlCode
IOControlcode[IOCTL_*].
InputBuffer
User'sallocatedbufferwithinputdata.
InputBufferLength
LengthofInputBuffer,inbytes.
OutputBuffer
User'sallocatedbufferforresultdata.
OutputBufferLength
LengthofOutputBuffer,inbytes.
主要的就是FileHandle,IoStatusBlock,IoControlCode,IoControlCode,InputBufferLength,OutputBuffer,
OutputBufferLength。
摘自《在NT系列操作系统里让自己“消失”》。
还有关于端口隐藏的技术就不提了因为在我说的文章中已经说的很清楚了,所以在写就是浪费篇幅了。
jiurl也曾经提到过了一种隐藏端口的方法,并且给出了代码。
在参考资料中有文章URL。
4文件隐藏。
在WINNT里在某些目录中寻找某个文件的方法是枚举它里面所有的文件和它的子目录下的所有文件。
文件的枚举是使用NtQueryDirectoryFile函数。
NTSTATUSNtQueryDirectoryFile(
INHANDLEFileHandle,
INHANDLEEventOPTIONAL,
INPIO_APC_ROUTINEApcRoutineOPTIONAL,
INPVOIDApcContextOPTIONAL,
OUTPIO_STATUS_BLOCKIoStatusBlock,
OUTPVOIDFileInformation,
INULONGFileInformationLength,
INFILE_INFORMATION_CLASSFileInformationClass,
INBOOLEANReturnSingleEntry,
INPUNICODE_STRINGFileNameOPTIONAL,
INBOOLEANRestartScan
);
在《TheUndocumentedFunctions-MicrosoftWindowsNT_2000》中对这些参数的描述
FileHandle
HANDLEtoFileObjectopenedwithFILE_DIRECTORY_FILEoptionandFILE_LIST_DIRECTORYaccess.
Event
OptionalHANDLEtoEventObjectsignaledafterquerycomplete.
ApcRoutine
Optinalpointertouser'sAPCroutinequeuedafterquerycomplete.
ApcContext
ParameterforApcRoutine.
IoStatusBlock
IOresultofcall.
FileInformation
User'sallocatedbufferforoutputdata.
Length
LengthofFileInformationbuffer,inbytes.
FileInformationClass
Informationclass.Canbeoneof:
FileDirectoryInformation
FileFullDirectoryInformation
FileBothDirectoryInformation
FileNamesInformation
FileOleDirectoryInformation
ReturnSingleEntry
Ifset,onlyoneentryisreturned.
FileMask
Ifspecified,onlyinformationaboutfilesmatchesthiswildcharmaskwillbereturned.
RestartScan
UsedwithReturnSingleEntryparameter.Ifset,NtQueryDirectoryFilecontinueenumerationafter
lastenumeratedelementinpreviouscall.Ifno,returnsthefirstentryindirectory.
与隐藏文件相关的重要参数是FileHandle,FileInformation,FileInformationClass.
FileInformationClass中的相关信息过多,只说其中重要的四个。
FileDirectoryInformation
FileFullDirectoryInformation
FileBothDirectoryInformation
FileNamesInformation
要写入FileInformation的FileDirecoryInformation记录的结构:
typedefstruct_FILE_DIRECTORY_INFORMATION{
ULONGNextEntryOffset;
ULONGUnknown;
LARGE_INTEGERCreationTime;
LARGE_INTEGERLastAccessTime;
LARGE_INTEGERLastWriteTime;
LARGE_INTEGERChangeTime;
LARGE_INTEGEREndOfFile;
LARGE_INTEGERAllocationSize;
ULONGFileAttributes;
ULONGFileNameLength;
WCHARFileName[1];
}FILE_DIRECTORY_INFORMATION,*PFILE_DIRECTORY_INFORMATION;
FileFullDirectoryInformation:
typedefstruct_FILE_FULL_DIRECTORY_INFORMATION{
ULONGNextEntryOffset;
ULONGUnknown;
LARGE_INTEGERCreationTime;
LARGE_INTEGERLastAccessTime;
LARGE_INTEGERLastWriteTime;
LARGE_INTEGERChangeTime;
LARGE_INTEGEREndOfFile;
LARGE_INTEGERAllocationSize;
ULONGFileAttributes;
ULONGFileNameLength;
ULONGEaInformationLength;
WCHARFileName[1];
}FILE_FULL_DIRECTORY_INFORMATION,*PFILE_FULL_DIRECTORY_INFORMATION;
FileBothDirectoryInformation:
typedefstruct_FILE_BOTH_DIRECTORY_INFORMATION{
ULONGNextEntryOffset;
ULONGUnknown;
LARGE_INTEGERCreationTime;
LARGE_INTEGE
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Rootkit For Windows