Skip to content

Commit

Permalink
[FEATURE] Detect suspicious callstack (AceLdr)
Browse files Browse the repository at this point in the history
  • Loading branch information
hasherezade committed Sep 1, 2024
1 parent cfd20e5 commit 6607a3e
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 18 deletions.
4 changes: 2 additions & 2 deletions pe_sieve_ver_short.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
#define PESIEVE_MAJOR_VERSION 0
#define PESIEVE_MINOR_VERSION 3
#define PESIEVE_MICRO_VERSION 9
#define PESIEVE_PATCH_VERSION 5
#define PESIEVE_PATCH_VERSION 6

#define PESIEVE_VERSION_STR "0.3.9.5"
#define PESIEVE_VERSION_STR "0.3.9.6"
12 changes: 7 additions & 5 deletions scanners/module_scan_report.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,13 @@ namespace pesieve {
protected:
const virtual bool _toJSON(std::stringstream& outs, size_t level = JSON_LEVEL, const pesieve::t_json_level& jdetails = JSON_BASIC)
{
OUT_PADDED(outs, level, "\"module\" : ");
outs << "\"" << std::hex << (ULONGLONG)module << "\"" << ",\n";
if (moduleSize){
OUT_PADDED(outs, level, "\"module_size\" : ");
outs << "\"" << std::hex << (ULONGLONG)moduleSize << "\"" << ",\n";
if (module) {
OUT_PADDED(outs, level, "\"module\" : ");
outs << "\"" << std::hex << (ULONGLONG)module << "\"" << ",\n";
if (moduleSize) {
OUT_PADDED(outs, level, "\"module_size\" : ");
outs << "\"" << std::hex << (ULONGLONG)moduleSize << "\"" << ",\n";
}
}
if (moduleFile.length()) {
OUT_PADDED(outs, level, "\"module_file\" : ");
Expand Down
29 changes: 28 additions & 1 deletion scanners/thread_scanner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,21 @@ DWORD WINAPI enum_stack_thread(LPVOID lpParam)
return STATUS_UNSUCCESSFUL;
}

bool has_empty_gui_info(DWORD tid)
{
GUITHREADINFO gui = { 0 };
gui.cbSize = sizeof(GUITHREADINFO);
if (!GetGUIThreadInfo(tid, &gui)) {
return false;
}
bool hasWindows = gui.hwndActive || gui.hwndCapture || gui.hwndCaret || gui.hwndMenuOwner || gui.hwndMoveSize;
bool hasRcCaret = gui.rcCaret.left || gui.rcCaret.right || gui.rcCaret.bottom || gui.rcCaret.top;
if (hasWindows || hasRcCaret) {
return false;
}
return true;
}

//---

std::string ThreadScanReport::translate_wait_reason(DWORD thread_wait_reason)
Expand Down Expand Up @@ -126,6 +141,7 @@ size_t pesieve::ThreadScanner::analyzeStackFrames(IN const std::vector<ULONGLONG
size_t processedCntr = 0;
bool has_shellcode = false;
cDetails.is_managed = false;
cDetails.stackFramesCount = stack_frame.size();
#ifdef _SHOW_THREAD_INFO
std::cout << "\n" << "Stack frame Size: " << std::dec << stack_frame.size() << "\n===\n";
#endif //_SHOW_THREAD_INFO
Expand Down Expand Up @@ -411,7 +427,7 @@ ThreadScanReport* pesieve::ThreadScanner::scanRemote()
#endif
return nullptr;
}

const DWORD tid = GetThreadId(hThread);
ctx_details cDetails = { 0 };
const bool is_ok = fetchThreadCtxDetails(processHandle, hThread, cDetails);

Expand Down Expand Up @@ -463,5 +479,16 @@ ThreadScanReport* pesieve::ThreadScanner::scanRemote()
}
}
}
const bool hasEmptyGUI = has_empty_gui_info(tid);
if (hasEmptyGUI &&
cDetails.stackFramesCount == 1
&& this->info.is_extended && info.ext.state == Waiting && info.ext.wait_reason == UserRequest)
{
my_report->thread_state = info.ext.state;
my_report->thread_wait_reason = info.ext.wait_reason;
my_report->thread_wait_time = info.ext.wait_time;
my_report->susp_addr = 0;
my_report->status = SCAN_SUSPICIOUS;
}
return my_report;
}
33 changes: 23 additions & 10 deletions scanners/thread_scanner.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,16 @@ namespace pesieve {
OUT_PADDED(outs, level, "\"thread_id\" : ");
outs << std::dec << tid;
outs << ",\n";
OUT_PADDED(outs, level, "\"susp_addr\" : ");
outs << "\"" << std::hex << susp_addr << "\"";
outs << ",\n";
if (susp_addr) {
OUT_PADDED(outs, level, "\"susp_addr\" : ");
outs << "\"" << std::hex << susp_addr << "\"";
outs << ",\n";
}
else {
OUT_PADDED(outs, level, "\"susp_callstack\" : ");
outs << "\"" << std::hex << 1 << "\"";
outs << ",\n";
}
if (thread_state != THREAD_STATE_UNKNOWN) {
OUT_PADDED(outs, level, "\"thread_state\" : ");
outs << "\"" << translate_thread_state(thread_state) << "\"";
Expand All @@ -49,14 +56,18 @@ namespace pesieve {
if (thread_state == THREAD_STATE_WAITING) {
OUT_PADDED(outs, level, "\"thread_wait_reason\" : ");
outs << "\"" << translate_wait_reason(thread_wait_reason) << "\"";
outs << ",\n";
if (susp_addr) {
outs << ",\n";
}
}
}
OUT_PADDED(outs, level, "\"protection\" : ");
outs << "\"" << std::hex << protection << "\"";
if (stats.isFilled()) {
outs << ",\n";
stats.toJSON(outs, level);
if (susp_addr) {
OUT_PADDED(outs, level, "\"protection\" : ");
outs << "\"" << std::hex << protection << "\"";
if (stats.isFilled()) {
outs << ",\n";
stats.toJSON(outs, level);
}
}
}

Expand Down Expand Up @@ -86,9 +97,11 @@ namespace pesieve {
ULONGLONG rbp;
ULONGLONG ret_addr; // the last return address on the stack (or the address of the first shellcode)
bool is_managed; // does it contain .NET modules
size_t stackFramesCount;

_ctx_details(bool _is64b = false, ULONGLONG _rip = 0, ULONGLONG _rsp = 0, ULONGLONG _rbp = 0, ULONGLONG _ret_addr = 0)
: is64b(_is64b), rip(_rip), rsp(_rsp), rbp(_rbp), ret_addr(_ret_addr),
: is64b(_is64b), rip(_rip), rsp(_rsp), rbp(_rbp), ret_addr(_ret_addr),
stackFramesCount(0),
is_managed(false)
{
}
Expand Down

0 comments on commit 6607a3e

Please sign in to comment.