父进程欺骗DidierStevens(三)

admin 2024年8月3日15:37:51评论5 views字数 4220阅读14分4秒阅读模式

创建新的进程完成父进程欺骗

OpenProcess 函数 (processthreadsapi.h)

    官方文档:https://learn.microsoft.com/zh-cn/windows/win32/api/processthreadsapi/nf-processthreadsapi-openprocess

    打开现有的本地进程对象。若要打开另一个本地进程的句柄并获取完全访问权限,必须启用 SeDebugPrivilege 特权。

HANDLE OpenProcess(  [in] DWORD dwDesiredAccess,  [in] BOOL  bInheritHandle,  [in] DWORD dwProcessId);
参数 作用
[in] dwDesiredAccess 对进程对象的访问。针对进程的安全描述符检查此访问权限。此参数可以是一个或多个 进程访问权限。如果调用方已启用 SeDebugPrivilege 特权,则会授予请求的访问权限,而不考虑安全描述符的内容。
[in] bInheritHandle 如果此值为 TRUE,则此进程创建的进程将继承句柄。否则,进程不会继承此句柄。
[in] dwProcessId 要打开的本地进程的标识符。

UpdateProcThreadAttribute 函数 (processthreadsapi.h)

    官方文档:https://learn.microsoft.com/zh-cn/windows/win32/api/processthreadsapi/nf-processthreadsapi-updateprocthreadattribute

    更新用于创建进程和线程的属性列表中的指定属性。属性列表是一个不透明的结构,它由一系列键/值对组成,每个属性对应一个键/值对。进程只能更新本主题中所述的属性键。

BOOL UpdateProcThreadAttribute(  [in, out]       LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList,  [in]            DWORD                        dwFlags,  [in]            DWORD_PTR                    Attribute,  [in]            PVOID                        lpValue,  [in]            SIZE_T                       cbSize,  [out, optional] PVOID                        lpPreviousValue,  [in, optional]  PSIZE_T                      lpReturnSize);
参数 作用
[in, out] lpAttributeList 指向 由 InitializeProcThreadAttributeList 函数创建的属性列表的指针。
[in] dwFlags 此参数是保留的,必须为零。
[in] Attribute 属性列表中要更新的属性键。
[in] lpValue 指向属性值的指针。此值必须保留,直到使用 DeleteProcThreadAttributeList 函数销毁属性列表。
[in] cbSize lpValue 参数指定的属性值的大小。
[out, optional] lpPreviousValue 此参数是保留的,必须为 NULL。
[in, optional] lpReturnSize 此参数是保留的,必须为 NULL。

    pAttributeList是要添加键/值对的属性列表,Attribute可取 PROC_THREAD_ATTRIBUTE_PARENT_PROCESS或PROC_THREAD_ATTRIBUTE_HANDLE_LIST,取前者时,lpValue 参数应指向另外一个进程的句柄,cbSize取值应为sizeof(HANDLE),否则,lpValue 指向子进程要继承的所有内核对象的句柄数组,cbSize取值应是sizeof(HANDLE)乘以该数组的大小。

    lpValue 参数是指向要使用 (的进程句柄的指针,而不是调用进程) 作为所创建进程的父进程的句柄。所用进程的句柄必须具有 PROCESS_CREATE_PROCESS 访问权限。

CreateProcessW 函数 (processthreadsapi.h)

官方文档:https://learn.microsoft.com/zh-cn/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessw

    创建新进程及其主线程。新进程在调用进程的安全上下文中运行。如果调用进程正在模拟其他用户,则新进程将令牌用于调用进程,而不是模拟令牌。若要在模拟令牌表示的用户的安全上下文中运行新进程,请使用 CreateProcessAsUser 或 CreateProcessWithLogonW 函数。

BOOL CreateProcessW(  [in, optional]      LPCWSTR               lpApplicationName,  [in, out, optional] LPWSTR                lpCommandLine,  [in, optional]      LPSECURITY_ATTRIBUTES lpProcessAttributes,  [in, optional]      LPSECURITY_ATTRIBUTES lpThreadAttributes,  [in]                BOOL                  bInheritHandles,  [in]                DWORD                 dwCreationFlags,  [in, optional]      LPVOID                lpEnvironment,  [in, optional]      LPCWSTR               lpCurrentDirectory,  [in]                LPSTARTUPINFOW        lpStartupInfo,  [out]               LPPROCESS_INFORMATION lpProcessInformation);
参数 作用
[in, optional] lpApplicationName 要执行的模块的名称。此模块可以是基于 Windows 的应用程序。lpApplicationName 参数可以为 NULL。
[in, out, optional] lpCommandLine 要执行的命令行。如果 lpApplicationName 为 NULL,则命令行的第一个空格分隔标记将指定模块名称。
[in, optional] lpProcessAttributes 指向 SECURITY_ATTRIBUTES 结构的指针,该结构确定子进程是否可以继承新进程对象的返回句柄。如果 lpProcessAttributes 为 NULL,则无法继承句柄。
[in, optional] lpThreadAttributes 指向 SECURITY_ATTRIBUTES 结构的指针,该结构确定子进程是否可以继承新线程对象的返回句柄。如果 lpThreadAttributes 为 NULL,则无法继承句柄。
[in] bInheritHandles 如果此参数为 TRUE,则调用进程中的每个可继承句柄都由新进程继承。如果 参数为 FALSE,则不继承句柄。
[in] dwCreationFlags 控制优先级类和进程的创建的标志。
[in, optional] lpEnvironment 指向新进程的环境块的指针。如果此参数为 NULL,则新进程将使用调用进程的环境。
[in, optional] lpCurrentDirectory 进程当前目录的完整路径。字符串还可以指定 UNC 路径。
[in] lpStartupInfo 指向 STARTUPINFO 或 STARTUPINFOEX 结构的指针。若要设置扩展属性,请使用 STARTUPINFOEX 结构,并在 dwCreationFlags 参数中指定EXTENDED_STARTUPINFO_PRESENT。
[out] lpProcessInformation 指向接收有关新进程的标识信息的 PROCESS_INFORMATION 结构的指针。

    CreateProcess会按下面的顺序查找该文件:

  1. 包含当前进程可执行文件的目录

  2. 当前进程的当前目录

  3. Windows系统目录,既GetSystemDirectory返回的目录

  4. Windows目录

  5. PATH环境变量列出的目录

源码分析

  1. 获取进程id为dwPid(父进程pid)的句柄;

  2. 调用UpdateProcThreadAttribute向属性链表添加键/值;

  3. 创建新的进程。

// 1. 获取进程id为dwPid(父进程pid)的句柄hParentProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);if (NULL == hParentProcess){    DisplayErrorMessage((LPTSTR)"OpenProcess error", GetLastError());    return 0;}// 2. 调用UpdateProcThreadAttribute向属性链表添加键/值if (!UpdateProcThreadAttribute(pAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, &hParentProcess, sizeof(HANDLE), NULL, NULL)){    DisplayErrorMessage((LPTSTR)"UpdateProcThreadAttribute error", GetLastError());    return 0;}// 3. 创建新的进程PROCESS_INFORMATION pi;ZeroMemory(&pi, sizeof(pi));sie.lpAttributeList = pAttributeList;if (!CreateProcess(NULL,argv[1],NULL, NULL, FALSE, EXTENDED_STARTUPINFO_PRESENT | CREATE_NEW_CONSOLE, NULL, NULL, &sie.StartupInfo, &pi)){    DisplayErrorMessage((LPTSTR)"CreateProcess error", GetLastError());    return 0;}

参考

[1]https://blog.didierstevens.com/2009/11/22/quickpost-selectmyparent-or-playing-with-the-windows-process-tree/

原文始发于微信公众号(蟹堡安全团队):父进程欺骗--DidierStevens(三)

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年8月3日15:37:51
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   父进程欺骗DidierStevens(三)http://cn-sec.com/archives/3028587.html

发表评论

匿名网友 填写信息