问答
发起
提问
文章
攻防
活动
Toggle navigation
首页
(current)
问答
商城
实战攻防技术
漏洞分析与复现
NEW
活动
摸鱼办
搜索
登录
注册
关于获取指定进程Pid的讨论
渗透测试
如何获取指定进程的pid这是个比较有意思的话题,本文会介绍一些常用的或不常用的方法。
由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,文章作者不为此承担任何责任。(本文仅用于交流学习) 前言 -- 如何获取指定进程的pid,这是一个非常有趣的话题,我们常用的方式就是拍摄快照然后进行枚举CreateToolhelp32Snapshot、Process32First、Process32Next等几个函数结合使用,本篇文章将会介绍一些常用或者不常用的其他方法。 NtQuerySystemInformation ------------------------ NtQuerySystemInformation这个函数是个内核函数,MSDN上有详细的解释,让我们来看看 <https://learn.microsoft.com/zh-cn/windows/win32/api/winternl/nf-winternl-ntquerysysteminformation>  ```php __kernel_entry NTSTATUS NtQuerySystemInformation( [in] SYSTEM_INFORMATION_CLASS SystemInformationClass, [in, out] PVOID SystemInformation, [in] ULONG SystemInformationLength, [out, optional] PULONG ReturnLength ); ``` 我们来看看第一个参数,非常明了了,我们可以直接获得指定进程的pid  我们看看实现的效果  WTSEnumerateProcessesW ---------------------- WTSEnumerateProcessesW函数使用RPC服务来获取进程列表。 <https://learn.microsoft.com/zh-cn/windows/win32/api/wtsapi32/nf-wtsapi32-wtsenumerateprocessesw>  ```php BOOL WTSEnumerateProcessesW( [in] HANDLE hServer, [in] DWORD Reserved, [in] DWORD Version, [out] PWTS_PROCESS_INFOW *ppProcessInfo, [out] DWORD *pCount ); ``` 我们看看WTS\_PROCESS\_INFOW这个结构体  ```php typedef struct _WTS_PROCESS_INFOA { DWORD SessionId; DWORD ProcessId; LPSTR pProcessName; PSID pUserSid; } WTS_PROCESS_INFOA, *PWTS_PROCESS_INFOA; ``` DWORD ProcessId即可获得进程的pid 参考MSDN官方文档参数,很容易就可以实现,我们看看实现的效果  RegQueryValueExA ---------------- 注册表HKEY\_LOCAL\_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Lsa中,包含本地安全机构服务器服务 (LSASS) 进程,其主要作用就是验证本地用户和远程用户的登录,并强制本地安全策略。Windows 8.1及其以上的版本具有LSA保护,其主要作用就是防止非受保护的进程读取内存和代码注入。 其中的LsaPid键所对应的值即是lsass进程的pid  我们来看看RegQueryValueExA函数 <https://learn.microsoft.com/zh-cn/windows/win32/api/winreg/nf-winreg-regqueryvalueexa>  对的就是查询注册表,这样就简单了 - RegOpenKeyExA打开要读取的注册表的项 - RegQueryValueExA读取注册表项中指定名称的类型和数据  QueryServiceStatusEx -------------------- LSASS提供的服务 - CNG KeyIsolation (KeyIso) - Security Accounts Manager (SamSs) - Credential Manager (VaultSvc) 我们通过打开这些服务的任意一个,来获取进程的pid 我们先来看看QueryServiceStatusEx函数 <https://learn.microsoft.com/zh-cn/windows/win32/api/winsvc/nf-winsvc-queryservicestatusex>  其中参数的SERVICE\_STATUS\_PROCESS结构  - OpenSCManagerW建立与指定计算机上的服务控制管理器的连接,并打开指定的服务控制管理器数据库 - 利用OpenServiceW打开现有服务 - QueryServiceStatusEx函数检索指定服务的当前状态  NtQueryInformationFile ---------------------- 我们先来看看这个函数的官方解释 <https://learn.microsoft.com/zh-cn/windows-hardware/drivers/ddi/ntifs/nf-ntifs-ntqueryinformationfile>  我们来看看# FILE\_INFORMATION\_CLASS枚举 [https://learn.microsoft.com/zh-cn/windows-hardware/drivers/ddi/wdm/ne-wdm-\_file\_information\_class](https://learn.microsoft.com/zh-cn/windows-hardware/drivers/ddi/wdm/ne-wdm-_file_information_class) `FileProcessIdsUsingFileInformation`  显示此值保留,官网不提供看不到具体结构,借助未公开函数查询  参数很明了了 主要结合NtOpenFile去打开指定文件,以获得其句柄,然后利用NtQueryInformationFile函数返回其指定句柄进程的各种信息。 没有代码基础的实现起来可能有点费劲,都用的内核函数 NtOpenFile <https://learn.microsoft.com/zh-cn/windows/win32/api/winternl/nf-winternl-ntopenfile>  - NtOpenFile函数去打开lsass.exe进程,文件对象的句柄 - NtQueryInformationFile函数接收NtOpenFile返回的对象句柄,返回有关文件对象的各种信息  NtFsControlFile --------------- 通过命名管道去获取指定进程的pid,首先我们来了解一下什么是Windows命名管道。 管道 本质是用于进程间通信的共享内存区域,管道有两端,一个端口进程可以进行写入数据,另外一个端口进程可以进行读取数据。我们把创建管道的进行成为管道服务器,连接管道的进程成为管道客户端。 Windows管道分类 匿名管道:只能本地实现,半双工通信(即单向通信)。 命名管道:可以用于网络通信、可以对客户端连接、可以双向通信、可以在本机或者跨网络在不同进程间进行通信(即客户端可以是本地进程本地访问:.\\pipe\\PipeName或者远程访问远程:\\ServerName\\pipe\\PipeName) 本地查看管道(远程查看不讨论) ```php [System.IO.Directory]::GetFiles("\\.\pipe\") Get-ChildItem \\.\pipe\ ```  利用Process Explorer,搜索\\Device\\NamedPipe  Windows中利用CreateNamedPipeA函数创建一个有名称的命名管道 服务端可以使用ConnectNamedPipe函数等待客户端的连接请求 客户端可以使用CreateFile或CallNamedPipe函数进行连接 其中GetNamedPipeServerProcessId函数可以检索指定命名管道的服务器进程标识符,但是其内部最终调用的是NtFsControlFile,因此我们的思路就很清晰了 先连接管道,然后使用NtFsControlFile(或者GetNamedPipeServerProcessId)函数去获取指定命名管道进程的标识符。 NtFsControlFile <https://learn.microsoft.com/zh-CN/windows-hardware/drivers/ddi/ntifs/nf-ntifs-ntfscontrolfile>  ```php __kernel_entry NTSYSCALLAPI NTSTATUS NtFsControlFile( [in] HANDLE FileHandle, [in, optional] HANDLE Event, [in, optional] PIO_APC_ROUTINE ApcRoutine, [in, optional] PVOID ApcContext, [out] PIO_STATUS_BLOCK IoStatusBlock, [in] ULONG FsControlCode, [in, optional] PVOID InputBuffer, [in] ULONG InputBufferLength, [out, optional] PVOID OutputBuffer, [in] ULONG OutputBufferLength ); ``` - NtOpenFile函数去打开lsass.exe进程,文件对象的句柄 - NtFsControlFile函数获得其对象的句柄,然后函数将控制代码发送到lsass进程,通过OutputBuffer获得其pid  安全事件日志 ------ 事件4608 (S):Windows 正在启动,其中包含着lsass进程的pid。当LSASS.EXE进程启动并初始化审核子系统时,将记录此事件,通常在操作系统启动过程中生成。 <https://learn.microsoft.com/zh-cn/windows/security/threat-protection/auditing/event-4608> 我们需要管理员权限,因此我们可以利用OpenProcessToken、GetTokenInformation函数判断当前进程是否拥有管理员权限 - EvtQuery函数进行查询事件,返回值为一个句柄 - EvtSeek接收EvtQuery返回的句柄,在查询结果集中查找特定事件 - 利用EvtNext函数查询下一个事件 - 利用EvtCreateRenderContext函数,创建一个上下文,用于指定要呈现的事件中的信息 - EvtRender函数根据指定的呈现上下文呈现 XML 片段,即可获得进行的pid 
发表于 2023-02-08 11:12:17
阅读 ( 7142 )
分类:
内网渗透
1 推荐
收藏
0 条评论
请先
登录
后评论
事与愿违
9 篇文章
×
发送私信
请先
登录
后发送私信
×
举报此文章
垃圾广告信息:
广告、推广、测试等内容
违规内容:
色情、暴力、血腥、敏感信息等内容
不友善内容:
人身攻击、挑衅辱骂、恶意行为
其他原因:
请补充说明
举报原因:
×
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!