-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAnalysisEngine.cc
More file actions
76 lines (63 loc) · 2.87 KB
/
AnalysisEngine.cc
File metadata and controls
76 lines (63 loc) · 2.87 KB
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
#include <AnalysisEngine.hh>
AnalysisEngine::~AnalysisEngine() = default;
/**
* @brief This runs the entire analysis
* @TODO This will need to be refactored.
*/
void AnalysisEngine::Run() {
std::unique_lock lock(thread_events_mutex_);
// for each process
auto& logger = Logger::GetInstance();
const auto process_list = store_.GetProcesses();
logger.Logln(std::format("Running analysis on {} processes", process_list.size()) );
for (const auto& [pid, process] : process_list) {
// if we don't have any marked image loads, then who even cares.
const auto& image_loads = process.GetImageLoads();
logger.Logln(std::format("Process Id {} has {} Image loads", pid, image_loads.size()) );
if ( image_loads.empty() ) continue;
const auto& threads = process.GetThreads();
logger.Logln(std::format("Process Id {} has {} threads.", pid, threads.size()) );
size_t patched_thread_count = 0;
for (const auto& [tid, thread] : threads ) {
//Get Previous cycle thread events.
ThreadEvents current_thread_events{};
ThreadEvents previous_thread_events{};
current_thread_events.CLR = thread.GetEventCount(ImageLoad::Clr);
current_thread_events.WinHTTP = thread.GetEventCount(ImageLoad::WinHTTP);
current_thread_events.Wininet = thread.GetEventCount(ImageLoad::Wininet);
thread_events_.insert({tid, current_thread_events});
if ( auto it = previous_thread_events_.find(tid); it != previous_thread_events_.end() ) {
previous_thread_events = it->second;
}
// if current is less-than or equal previous, we have no new alerts.
if (previous_thread_events_.contains(tid) && (
(current_thread_events.CLR <= previous_thread_events.CLR && image_loads.contains(ImageLoad::Clr)) ||
(current_thread_events.WinHTTP <= previous_thread_events.WinHTTP && image_loads.contains(ImageLoad::WinHTTP)) ||
(current_thread_events.Wininet <= previous_thread_events.Wininet && image_loads.contains(ImageLoad::Wininet))
)){
++patched_thread_count;
}
} // thread
if ( patched_thread_count == threads.size() ) {
Alert alert{};
alert.process_id = pid;
alert.text = "Potential ETW Patching has been detected.";
alert.timestamp = std::time(nullptr);
alert.title = "[ETW ALERT]";
alert_ptr_.InsertAlert(alert);
}
} // process
// finished now so set previous to current and crack on.
previous_thread_events_ = thread_events_;
thread_events_.clear();
} // Run();
/**
* @brief Callback to handle thread exits.
* @param thread_id The thread identifier to remove
*/
void AnalysisEngine::OnThreadExit(unsigned int thread_id){
std::unique_lock lock(thread_events_mutex_);
if ( previous_thread_events_.contains(thread_id) ) {
previous_thread_events_.erase(thread_id);
}
}