Panoptes 1.0.0
Endpoint Detection and Response
Loading...
Searching...
No Matches
container.cpp
Go to the documentation of this file.
1#include <grpcpp/grpcpp.h>
2#include "panoptes.grpc.pb.h"
3#include "panoptes.pb.h"
4#include "container_ipc.hpp"
5#include <ExtensibilityCore.h>
6#include <iostream>
7#include <atomic>
8
9namespace fs = std::filesystem;
10
14
17std::atomic_bool isConnected = true;
18std::unique_ptr<PanoptesService::Stub> stub;
19int BindPort = 0;
20
25{
26 HKEY hKey;
27 DWORD dwType = REG_DWORD;
28 DWORD dwSize = sizeof(DWORD);
29
30 // Open the key
31 LONG lResult = RegOpenKeyExA(
32 HKEY_LOCAL_MACHINE,
33 "SOFTWARE\\Panoptes",
34 0,
35 KEY_READ,
36 &hKey
37 );
38
39 if (lResult != ERROR_SUCCESS) {
40 std::cerr << "Error opening registry key. Error code: " << lResult << std::endl;
41 return false;
42 }
43
44 // Read the SRV_PORT value
45 lResult = RegQueryValueExA(
46 hKey,
47 "SRV_PORT",
48 NULL,
49 &dwType,
50 reinterpret_cast<LPBYTE>(&portValue),
51 &dwSize
52 );
53
54 RegCloseKey(hKey);
55
56 if (lResult != ERROR_SUCCESS) {
57 std::cerr << "Error reading registry value. Error code: " << lResult << std::endl;
58 return false;
59 }
60
61 if (dwType != REG_DWORD) {
62 std::cerr << "Unexpected value type in registry." << std::endl;
63 return false;
64 }
65
66 return true;
67}
68
73 while (isConnected) {
74 PeScan pe_data = message_queue_pe_->dequeue();
75 if (pe_data.PePath != "")
76 {
77 PanoEntry(&pe_data, NULL);
78 }
79 }
80}
81
84 DWORD portValue = 0;
85 if (!GetRegistryPortValue(portValue)) {
86 std::cerr << "Failed to get registry port value." << std::endl;
87 return;
88 }
89 std::string server_url = "localhost:" + std::to_string(portValue);
90
91 while (true)
92 {
93 std::shared_ptr<grpc::Channel> channel = grpc::CreateChannel(server_url,
94 grpc::InsecureChannelCredentials());
95
96 stub = PanoptesService::NewStub(channel);
97
98 grpc::ClientContext context;
99 HealthCheckRequest request;
100 HealthCheckResponse response;
101 request.set_ping(true);
102
103
104 grpc::Status status = stub->HealthCheck(&context, request, &response);
105
106 if (!status.ok()) {
107 isConnected.store(false);
108 return;
109 }
110
111 Sleep(2500);
112 }
113}
114
118bool LoadExtensibility(std::string dllFile) {
119 HMODULE extensibility = LoadLibraryA(dllFile.c_str());
120 if (extensibility == NULL) {
121 DWORD error = GetLastError();
122 return false;
123 }
124 else {
125 PanoBind = (ExtensibilityCore::PanoBindPtr)GetProcAddress(extensibility, "PanoBind");
126 if (PanoBind == NULL) {
127 return false;
128 }
129 PanoEntry = (ExtensibilityCore::PanoEntryPtr)GetProcAddress(extensibility, "PanoEntry");
130 if (PanoEntry == NULL) {
131 return false;
132 }
133 PanoUnbind = (ExtensibilityCore::PanoUnbindPtr)GetProcAddress(extensibility, "PanoUnbind");
134 if (PanoUnbind == NULL) {
135 return false;
136 }
137 }
138
139 return true;
140}
141
149bool BindToServiceWithRetry(int containerPort, int maxAttempts, int baseSleep, double multiplier) {
150
151 for (int attempt = 0; attempt < maxAttempts; ++attempt) {
152 PanoBind(containerPort);
153 if (BindPort > 0)
154 break;
155
156 if (attempt < maxAttempts - 1) { // Don't sleep after the last attempt
157 int sleep_duration_ms = baseSleep * std::pow(multiplier, attempt);
158 std::cout << "Sleeping for " << sleep_duration_ms << " ms" << std::endl;
159 std::this_thread::sleep_for(std::chrono::milliseconds(sleep_duration_ms));
160 }
161 }
162
163 return true;
164}
165
172int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
173{
174 if (__argc < 1) {
175 printf("No Args");
176 exit(1);
177 }
178
179 std::string dllPath(__argv[1]);
180 if (!LoadExtensibility(dllPath)) {
181 printf("Error Loading Extensibility");
182 exit(1);
183 }
184
185 HANDLE grpcServerThread = CreateThread(
186 NULL, // default security attributes
187 0, // default stack size
188 (LPTHREAD_START_ROUTINE)RunContainerServer, // thread function
189 &BindPort, // no thread function arguments
190 0, // default creation flags
191 NULL // receive thread identifier
192 );
193 Sleep(2000);
194 if (grpcServerThread == NULL || BindPort == 0)
195 {
196 std::cout << "Error creating thread: " << GetLastError() << std::endl;
197 PanoUnbind();
198 return 1;
199 }
200
201 if (!BindToServiceWithRetry(BindPort, 7, 1000, 2))
202 {
203 std::cout << "Error Binding to service: " << GetLastError() << std::endl;
204 PanoUnbind();
205 return 1;
206 }
207
208 HANDLE healthCheckThread = CreateThread(
209 NULL, // default security attributes
210 0, // default stack size
211 (LPTHREAD_START_ROUTINE)HealthCheck, // thread function
212 NULL, // no thread function arguments
213 0, // default creation flags
214 NULL // receive thread identifier
215 );
216 Sleep(2000);
217 if (healthCheckThread == NULL || BindPort == 0)
218 {
219 std::cout << "Error creating thread: " << GetLastError() << std::endl;
220
221 PanoUnbind();
222 return 1;
223 }
224
225 HANDLE messageQueueThread = CreateThread(
226 NULL, // default security attributes
227 0, // default stack size
228 (LPTHREAD_START_ROUTINE)MessageQueueThread, // thread function
229 NULL, // no thread function arguments
230 0, // default creation flags
231 NULL // receive thread identifier
232 );
233 Sleep(2000);
234 if (healthCheckThread == NULL || BindPort == 0)
235 {
236 std::cout << "Error creating thread: " << GetLastError() << std::endl;
237 PanoUnbind();
238 return 1;
239 }
240
241 while (true)
242 {
243 if (isConnected == false) {
244 exit(1);
245 }
246 Sleep(2500);
247 }
248
249 return 0;
250}
bool(* PanoEntryPtr)(PeScan *, MemScan *)
PeScan dequeue()
The dequeue function dequeues a PeScan messages from the queue.
std::unique_ptr< PanoptesService::Stub > stub
Definition container.cpp:18
void HealthCheck()
The HealthCheck function is a thread that checks the health of the Panoptes main service.
Definition container.cpp:83
ExtensibilityCore::PanoBindPtr PanoBind
Definition container.cpp:11
void MessageQueueThread()
The MessageQueueThread function is a thread that dequeues messages from the message queue and process...
Definition container.cpp:71
bool GetRegistryPortValue(DWORD &portValue)
Get the gRPC port value from the registry.
Definition container.cpp:24
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
The WinMain function is the entry point for the container.
int BindPort
Definition container.cpp:19
MemoryMessageQueue * message_queue_mem_
Definition container.cpp:16
std::atomic_bool isConnected
Definition container.cpp:17
bool BindToServiceWithRetry(int containerPort, int maxAttempts, int baseSleep, double multiplier)
The BindToServiceWithRetry function is a function that binds to the Panoptes main service with a retr...
ExtensibilityCore::PanoEntryPtr PanoEntry
Definition container.cpp:12
bool LoadExtensibility(std::string dllFile)
The LoadExtensibility function is a function that loads the extensibility DLL.
ExtensibilityCore::PanoUnbindPtr PanoUnbind
Definition container.cpp:13
PeMessageQueue * message_queue_pe_
Definition container.cpp:15
VOID RunContainerServer(LPVOID ContainerPort)
The RunContainerServer function is a function that runs the container server.
unsigned long DWORD
Definition inject.h:2
The information about the file to be scanned that passed between the container, extensibility and the...
std::string PePath