Panoptes 1.0.0
Endpoint Detection and Response
Loading...
Searching...
No Matches
container.cpp
Go to the documentation of this file.
1#include <format>
2//#include "message.hpp"
3//#include "score.hpp"
4#include "hash.hpp"
5#include "container.hpp"
6#include "ResourceCore.h"
7
8#define BUFFER_SIZE 4096
9#define BUFSIZE 4096
10
11using namespace std;
12
13//VOID IdentifyContainerConnection(PanoptesMessage::ContainerType containerType) {
14// if (containerType == Message::CONTAINER_TYPE_AMSI) {
15// serviceContext->LogInformationMessage("Container Connected: AMSI/YARA");
16// }
17// else if (containerType == Message::CONTAINER_TYPE_PE) {
18// serviceContext->LogInformationMessage("Container Connected: PE");
19// }
20// else if (containerType == Message::CONTAINER_TYPE_ML) {
21// serviceContext->LogInformationMessage("Container Connected: ML");
22// }
23// return;
24//}
25//
26//BOOL SendHelloToContainer(Pipe::PIPEINST* pipe)
27//{
28// DWORD bytesWritten;
29// PanoptesMessage::PipeData* data;
30// data->set_sender(PanoptesMessage::SENDER_SERVICE);
31// data->set_message_type(PanoptesMessage::MSG_TYPE_HELLO);
32//
33// BOOL fSuccess = WriteFile(
34// pipe->pipeInst,
35// data,
36// MESSAGE_SIZE,
37// &bytesWritten,
38// &pipe->overlap);
39//
40// return fSuccess;
41//}
42//
43//
44//BOOL ConnectToNewClient(ThreadContext* threadContext, HANDLE hPipe, LPOVERLAPPED lpo)
45//{
46// serviceContext = threadContext->serviceContext;
47// BOOL fConnected, pendingIO = FALSE;
48// Start an overlapped connection for this pipe instance.
49// fConnected = ConnectNamedPipe(hPipe, lpo);
50//
51// Overlapped ConnectNamedPipe should return zero.
52// if (fConnected)
53// {
54// string message = format("Error creating an overlapped connection {}", GetLastError());
55// serviceContext->LogErrorMessage(message);
56// return 0;
57// }
58//
59// //Set the read mode to blocking
60// DWORD dwMode = PIPE_READMODE_MESSAGE;
61// BOOL success = SetNamedPipeHandleState(
62// hPipe,
63// &dwMode,
64// NULL,
65// NULL);
66//
67// switch (GetLastError())
68// {
69// The overlapped connection in progress.
70// case ERROR_IO_PENDING:
71// pendingIO = TRUE;
72// break;
73//
74// Client is already connected, so signal an event.
75//
76// case ERROR_PIPE_CONNECTED:
77// if (SetEvent(lpo->hEvent))
78// break;
79//
80// //If an error occurs during the connect operation...
81// default:
82// {
83// string message = format("Error creating an overlapped connection {}", GetLastError());
84// serviceContext->LogErrorMessage(message);
85// return 0;
86// }
87// }
88//
89// return pendingIO;
90//}
91//DWORD StartContainerNamedPipe()
92//{
93// //ThreadContext* threadContext = static_cast<ThreadContext*>(lpParams);
94// //ServiceContext* serviceContext = threadContext->serviceContext;
95// Pipe* pipe = threadContext->pipeInstance;
96//
97// DWORD pipeIndex, dwWait;
98// BOOL fSuccess;
99//
100// if (!StartContainerInstances(4)) {
101// string message = format("Error creating {} container named pipes: {}", INSTANCES, threadContext->namedPipe.c_str());
102// serviceContext->LogErrorMessage(message);
103// exit(1);
104// }
105//
106// string message = format("Created {} container named pipes: {}", INSTANCES, threadContext->namedPipe.c_str());
107// serviceContext->LogInformationMessage(message);
108// PanoptesMessage::PipeData* responseData;
109// //Message::PipeData* responseData;
110// while (1)
111// {
112// dwWait = WaitForMultipleObjects(
113// INSTANCES, // number of event objects
114// pipe->hEvents, // array of event objects
115// FALSE, // does not wait for all
116// INFINITE); // waits indefinitely
117//
118// pipeIndex = dwWait - WAIT_OBJECT_0; // determines which pipe
119// if (pipeIndex < 0 || pipeIndex >(INSTANCES - 1))
120// {
121// string message = format("Error out of range when creating {} container named pipes: {}", INSTANCES, threadContext->namedPipe.c_str());
122// serviceContext->LogErrorMessage(message);
123// return 0;
124// }
125//
126// std::string serialized_data;
127// PanoptesMessage::PipeData data;
128// DWORD totalBytesRead = 0;
129// DWORD error = 0;
130// BOOL initCheck = false;
131// switch (pipe->PipeInst[pipeIndex].state)
132// {
133// case CONNECTING_STATE:
134// pipe->PipeInst[pipeIndex].state = READING_STATE;
135// break;
136// case READING_STATE:
137//
138// uint32_t size;
139// DWORD bytesRead;
140// initCheck = ReadFile(pipe->PipeInst[pipeIndex].pipeInst, &size, sizeof(size), &bytesRead, &pipe->PipeInst[pipeIndex].overlap);
141// error = GetLastError();
142// if (!initCheck && error != ERROR_MORE_DATA) {
143// exit(1);
144// }
145// char buffer[BUFFER_SIZE];
146// while (totalBytesRead < size) {
147// DWORD bytesToRead = min(BUFFER_SIZE, size - totalBytesRead);
148// fSuccess = ReadFile(pipe->PipeInst[pipeIndex].pipeInst, buffer, bytesToRead, &bytesRead, &pipe->PipeInst[pipeIndex].overlap);
149// serialized_data.append(buffer, bytesRead);
150// totalBytesRead += bytesRead;
151// }
152// data.ParseFromString(serialized_data);
153// //person.ParseFromString(serialized_data)
154// //fSuccess = ReadFile(
155// // pipe->PipeInst[pipeIndex].pipeInst,
156// // responseData,
157// // MESSAGE_SIZE,
158// // &pipe->PipeInst[pipeIndex].bytesRead,
159// // &pipe->PipeInst[pipeIndex].overlap);
160//
161// if (data.sender() == PanoptesMessage::SENDER_CONTAINER) {
162// if (data.message_type() == PanoptesMessage::MSG_TYPE_HELLO) {
163// pipe->PipeInst[pipeIndex].containerType = responseData->container_type();
164// IdentifyContainerConnection(responseData->container_type());
165// pipe->PipeInst[pipeIndex].state = WRITING_STATE;
166// break;
167// }
168// else if (responseData->message_type() == PanoptesMessage::MSG_TYPE_PROCESSED) {
169// string filePath = responseData->container_data().file_path();
170// if (filePath.length() > 4) {
171// string hash = Hash::Generate(filePath.c_str());
172// if (hash == "")
173// {
174// serviceContext->LogErrorMessage("Error generating file hash");
175// }
176// else {
177// Database::PPanoptesDBEntry entry = serviceContext->GetEntry(hash);
178//
179// if (pipe->PipeInst[pipeIndex].containerType == Message::CONTAINER_TYPE_AMSI) {
180// //INT score = Score::GenerateAMSIScore(responseData->ContainerData.StatusCode);
181// INT score = 0;
182// if (entry == NULL) {
183// entry = serviceContext->BuildEntry(score, Message::CONTAINER_TYPE_AMSI);
184// serviceContext->AddEntry(hash, entry);
185// }
186// else {
187// serviceContext->ModifyEntryScore(entry, score, Message::CONTAINER_TYPE_AMSI);
188// serviceContext->UpdateEntry(hash, entry);
189// }
190// }
191// else if (pipe->PipeInst[pipeIndex].containerType == Message::CONTAINER_TYPE_PE)
192// {
193// //INT score = Score::GeneratePEScore(responseData->ContainerData.StatusCode);
194// INT score = 0;
195// if (entry == NULL) {
196// entry = serviceContext->BuildEntry(score, Message::CONTAINER_TYPE_PE);
197// serviceContext->AddEntry(hash, entry);
198// }
199// else {
200// serviceContext->ModifyEntryScore(entry, score, Message::CONTAINER_TYPE_PE);
201// serviceContext->UpdateEntry(hash, entry);
202// }
203// }
204//
205// if (entry != NULL) {
206// bool allExtCheckDone = true;
207// int combinedScore = 0;
208// for (int i = 0; i < serviceContext->m_extensibilityListName.size(); i++) {
209// if (serviceContext->m_extensibilityListName[i] == "AMSI") {
210// if (entry->amsiScore >= 0) {
211// combinedScore += entry->amsiScore;
212// }
213// else {
214// allExtCheckDone = false;
215// }
216// }
217// else if (serviceContext->m_extensibilityListName[i] == "YARA") {
218// if (entry->yaraScore >= 0) {
219// combinedScore += entry->yaraScore;
220// }
221// else {
222// allExtCheckDone = false;
223// }
224// }
225// else if (serviceContext->m_extensibilityListName[i] == "PE") {
226// if (entry->peScore >= 0) {
227// combinedScore += entry->peScore;
228// }
229// else {
230// allExtCheckDone = false;
231// }
232// }
233// else if (serviceContext->m_extensibilityListName[i] == "ML") {
234// if (entry->mlScore >= 0) {
235// combinedScore += entry->mlScore;
236// }
237// else {
238// allExtCheckDone = false;
239// }
240// }
241// }
242//
243// if (allExtCheckDone) {
244// //TODO: get base name of file path
245// string message = format("Scan Done - {} Score: {}", filePath.c_str(), combinedScore);
246// serviceContext->LogInformationMessage(message);
247// //Tray::Notification("Panoptes EDR", message);
248//
249// //inject::InjectDLL(incomingRequest->ContainerData.ProcessId, "C:\\Users\\Research\\source\\repos\\PanoptesEDR\\bin\\x64\\Debug\\PanoptesHook_x64.dll");
250// }
251// }
252// }
253// }
254//
255// }
256// }
257// //else {
258// // free(responseData);
259// //}
260// break;
261// case WRITING_STATE:
262// if (responseData->sender() == Message::SENDER_CONTAINER && responseData->message_type() == Message::MSG_TYPE_HELLO) {
263// if (!SendHelloToContainer(&pipe->PipeInst[pipeIndex])) {
264// serviceContext->LogErrorMessage("Error sending HELLO message to container.");
265// }
266// }
267// pipe->PipeInst[pipeIndex].state = CONNECTING_STATE;
268// //free(responseData);
269// break;
270// }
271//
272// }
273//
274// return 0;
275//}
276
277
278//string GenerateGUID() {
279// GUID guid;
280// CoInitialize(NULL);
281//
282// HRESULT hr = CoCreateGuid(&guid);
283//
284// if (SUCCEEDED(hr)) {
285// char guid_string[37]; // 32 hex digits + 4 hyphens + null terminator
286// snprintf(guid_string, sizeof(guid_string),
287// "%08lx-%04hx-%04hx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx",
288// guid.Data1, guid.Data2, guid.Data3,
289// guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3],
290// guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]);
291// CoUninitialize();
292// return std::string(guid_string);
293// }
294//
295//
296// CoUninitialize();
297// return ""; // Return empty string if GUID creation failed
298//}
299
300//ERRORCODE Container::CreateEvents()
301//{
302// for (int i = 0; i < m_extensibilityListName.size(); i++)
303// {
304// string ranGUID = GenerateGUID();
305// m_eventNames.push_back(ranGUID);
306// string eventName = "Global\\" + m_eventNames[i]; // Use a unique name
307// m_Events[i] = CreateEvent(
308// NULL, // default security attribute
309// TRUE, // manual-reset event
310// TRUE, // initial state = signaled
311// eventName.c_str() // event name
312// );
313//
314// if (m_Events[i] == NULL)
315// {
316// //string message = format("Failed to create an container event: {}", GetLastError());
317// //LogErrorMessage(message);
318// return CONTAINER_START;
319// }
320// }
321//
322// return SUCCESS;
323//}
324
325//DWORD WINAPI Container::InstanceThread(LPVOID lpvParam) {
326// PanoptesMessage::ContainerMessage request;
327// DWORD cbBytesRead = 0, cbReplyBytes = 0, cbWritten = 0;
328// BOOL fSuccess = FALSE;
329//
330// if (lpvParam == NULL) {
331// printf("\nERROR - Pipe Server Failure:\n");
332// printf(" InstanceThread got an unexpected NULL value in lpvParam.\n");
333// printf(" InstanceThread exiting.\n");
334// return (DWORD)-1;
335// }
336//
337// ServiceContext* serviceContext = (ServiceContext*)lpvParam;
338// char buffer[1024]; // Adjust size as needed
339//
340// fSuccess = ReadFile(
341// serviceContext->m_pipeInst, // handle to pipe
342// buffer, // buffer to receive data
343// sizeof(buffer), // size of buffer
344// &cbBytesRead, // number of bytes read
345// NULL); // not overlapped I/O
346//
347// if (!fSuccess || cbBytesRead == 0) {
348// if (GetLastError() == ERROR_BROKEN_PIPE) {
349// printf("InstanceThread: client disconnected.\n");
350// }
351// else {
352// printf("InstanceThread ReadFile failed, GLE=%d.\n", GetLastError());
353// }
354// CloseHandle(serviceContext->m_pipeInst);
355// return (DWORD)-1;
356// }
357//
358// if (!request.ParseFromArray(buffer, cbBytesRead)) {
359// printf("Failed to parse the received message.\n");
360// CloseHandle(serviceContext->m_pipeInst);
361// return (DWORD)-1;
362// }
363//
364// PanoptesMessage::ContainerMessage reply;
365// std::string serialized_reply;
366//
367// if (request.message_type() == PanoptesMessage::MessageType::MSG_TYPE_GET_EVENT) {
368// reply.set_message_type(request.message_type());
369// reply.set_event_name(serviceContext->m_eventNames[0]);
370// if (!reply.SerializeToString(&serialized_reply)) {
371// printf("Failed to serialize the reply message.\n");
372// CloseHandle(serviceContext->m_pipeInst);
373// return (DWORD)-1;
374// }
375// }
376// else {
377// printf("Unsupported message type received.\n");
378// CloseHandle(serviceContext->m_pipeInst);
379// return (DWORD)-1;
380// }
381//
382// fSuccess = WriteFile(
383// serviceContext->m_pipeInst, // handle to pipe
384// serialized_reply.c_str(), // buffer to write from
385// serialized_reply.size(), // number of bytes to write
386// &cbWritten, // number of bytes written
387// NULL); // not overlapped I/O
388//
389// if (!fSuccess || cbWritten != serialized_reply.size()) {
390// printf("InstanceThread WriteFile failed, GLE=%d.\n", GetLastError());
391// CloseHandle(serviceContext->m_pipeInst);
392// return (DWORD)-1;
393// }
394//
395// FlushFileBuffers(serviceContext->m_pipeInst);
396// DisconnectNamedPipe(serviceContext->m_pipeInst);
397// CloseHandle(serviceContext->m_pipeInst);
398// return 1;
399//}
400
401//DWORD WINAPI Container::CreateThreadRequest(LPVOID lpvParam) {
402// ServiceContext* serviceContext = (ServiceContext*)lpvParam;
403// BOOL fConnected = ConnectNamedPipe(serviceContext->m_pipeInst, NULL) ?
404// TRUE : (GetLastError() == ERROR_PIPE_CONNECTED);
405//
406// if (fConnected)
407// {
408// HANDLE hPipe = NULL;
409// DWORD dwThreadId = 0;
410// // Create a thread for this client.
411// HANDLE hThread = CreateThread(
412// NULL, // no security attribute
413// 0, // default stack size
414// InstanceThread, // thread proc
415// (LPVOID)serviceContext, // thread parameter
416// 0, // not suspended
417// &dwThreadId); // returns thread ID
418//
419// if (hThread == NULL)
420// {
421// printf("CreateThread failed, GLE=%d.\n", GetLastError());
422// return NOT_SET;
423// }
424// else CloseHandle(hThread);
425// }
426//
427// return SUCCESS;
428//}
429
430
431
432
433