暴力枚举进程
Posted 13572980562
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了暴力枚举进程相关的知识,希望对你有一定的参考价值。
进程是操作系统中的一个非常重要的概念,学习的初级阶段可以先想办法枚举出它们,为以后的深入学习奠定基础。
枚举进程有许多方法,比较简单的有快照CreateToolhelp32Snapshot,psapi.dll提供的EnumProcesses()等。我们还可以通过进程ID去暴力枚举,只是可能权限不够,有些得不到,就需要驱动的帮忙了。
应用层:
#include <Windows.h>
#include <iostream>
using namespace std;
#define MAX 64
#define CTL_GETPROCESSIMAGNAMEBYID CTL_CODE(FILE_DEVICE_UNKNOWN,0x830,METHOD_BUFFERED,FILE_ANY_ACCESS)
BOOL EnableDebugPrivilege(); //提权
VOID EnumProcessByForce(); //暴力枚举
BOOL SendIoControl(int* InputData, ULONG InputSize, char* OutputData, DWORD* dwReturn); //发送请求
int main(int argc, char **argv)
{
if (EnableDebugPrivilege() == FALSE)
{
return 0;
}
EnumProcessByForce();
return 0;
}
VOID EnumProcessByForce()
{
int i = 0;
HANDLE hProcess = NULL;
DWORD dwReturn = 0;
char szProcessImageName[MAX] = { 0 };
for (i = 0; i < 10000000; i += 4) //进程ID一般是4的倍数
{
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, i);
if (hProcess == NULL)
{
continue;
}
else
{
//向驱动发送请求
if (SendIoControl(&i, sizeof(ULONG32), szProcessImageName, &dwReturn) == TRUE)
{
szProcessImageName[dwReturn] = ‘\0‘;
cout << "进程ID: " << i << " " << szProcessImageName << endl;
memset(szProcessImageName, 0, MAX);
}
}
}
}
BOOL SendIoControl(int* InputData, ULONG InputSize, char* OutputData, DWORD* dwReturn)
{
//打开设备
HANDLE hDevice = NULL;
BOOL bOk = FALSE;
hDevice = CreateFile(L"\\\\.\\EnumProcessByForceLinkName", //设备链接名
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hDevice == INVALID_HANDLE_VALUE)
{
return FALSE;
}
bOk = DeviceIoControl(hDevice,
CTL_GETPROCESSIMAGNAMEBYID,
InputData,
InputSize,
OutputData,
MAX,
dwReturn,
NULL);
if (bOk == FALSE)
{
CloseHandle(hDevice);
hDevice = NULL;
return FALSE;
}
CloseHandle(hDevice);
hDevice = NULL;
return TRUE;
}
BOOL EnableDebugPrivilege() //Debug
{
HANDLE hToken = NULL;
TOKEN_PRIVILEGES TokenPrivilege;
LUID uID;
//打开权限令牌
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
{
return FALSE;
}
if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &uID))
{
CloseHandle(hToken);
hToken = NULL;
return FALSE;
}
TokenPrivilege.PrivilegeCount = 1;
TokenPrivilege.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
TokenPrivilege.Privileges[0].Luid = uID;
//在这里我们进行调整权限
if (!AdjustTokenPrivileges(hToken, false, &TokenPrivilege, sizeof(TOKEN_PRIVILEGES), NULL, NULL))
{
CloseHandle(hToken);
hToken = NULL;
return FALSE;
}
CloseHandle(hToken);
return TRUE;
}
驱动层:
#include <ntifs.h>
#define MAX 64
#define DEVICE_NAME L"\\Device\\EnumProcessByForceDeviceName" //常量指针字符串
#define LINK_NAME L"\\DosDevices\\EnumProcessByForceLinkName"
extern char* PsGetProcessImageFileName(PEPROCESS EProcess); // 此函数已经实现,只需要申明出来
BOOLEAN GetProcessImageNameByProcessID(ULONG32 ulProcessID, char* szProcessImageName, ULONG32* ulProcessImageNameLength);
NTSTATUS DefaultPassDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp);
NTSTATUS ControlPassDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp);
#define CTL_GETPROCESSIMAGNAMEBYID \
CTL_CODE(FILE_DEVICE_UNKNOWN,0x830,METHOD_BUFFERED,FILE_ANY_ACCESS)
VOID DriverUnload(PDRIVER_OBJECT DriverObject);
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegisterPath)
{
NTSTATUS Status;
UNICODE_STRING uniDeviceName; //设备名
UNICODE_STRING uniLinkName; //链接名
int i = 0;
PDEVICE_OBJECT DeviceObject;
RtlInitUnicodeString(&uniDeviceName, DEVICE_NAME);
DbgPrint("Hello 10.8\r\n");
Status = IoCreateDevice(DriverObject, 0, &uniDeviceName, FILE_DEVICE_UNKNOWN, 0, FALSE, &DeviceObject);
if (!NT_SUCCESS(Status))
{
return STATUS_UNSUCCESSFUL;
}
//创建一个LinkName
RtlInitUnicodeString(&uniLinkName, LINK_NAME);
Status = IoCreateSymbolicLink(&uniLinkName, &uniDeviceName);
if (!NT_SUCCESS(Status))
{
IoDeleteDevice(DeviceObject);
DriverObject = NULL;
return STATUS_UNSUCCESSFUL;
}
DriverObject->DriverUnload = DriverUnload;
for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
{
DriverObject->MajorFunction[i] = DefaultPassDispatch;
}
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ControlPassDispatch;
return STATUS_SUCCESS;
return Status;
}
VOID DriverUnload(PDRIVER_OBJECT DriverObject)
{
//销毁链接名称
UNICODE_STRING uniLinkName;
//销毁所有DriverObject中的DeviceObject
PDEVICE_OBJECT CurrentDeviceObject = NULL;
PDEVICE_OBJECT NextDeviceObject = NULL;
RtlInitUnicodeString(&uniLinkName, LINK_NAME);
IoDeleteSymbolicLink(&uniLinkName);
if (DriverObject->DeviceObject != NULL)
{
CurrentDeviceObject = DriverObject->DeviceObject;
while (CurrentDeviceObject != NULL)
{
NextDeviceObject = CurrentDeviceObject->NextDevice;
IoDeleteDevice(CurrentDeviceObject);
CurrentDeviceObject = NextDeviceObject;
}
}
CurrentDeviceObject = NULL;
NextDeviceObject = NULL;
}
NTSTATUS ControlPassDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
PIO_STACK_LOCATION IrpSp = NULL;
ULONG_PTR ulIoControlCode = 0;
PVOID InputData = NULL;
PVOID OutputData = NULL;
ULONG_PTR ulInputSize = 0;
ULONG_PTR ulOutputSize = 0;
char szProcessImageName[MAX] = { 0 };
ULONG32 ulProcessImageNameLength = 0;
ULONG32 ulProcessID = 0;
IrpSp = IoGetCurrentIrpStackLocation(Irp);
ulIoControlCode = IrpSp->Parameters.DeviceIoControl.IoControlCode;
switch (ulIoControlCode)
{
case CTL_GETPROCESSIMAGNAMEBYID:
{
//InputData
//OutputData
InputData = OutputData = Irp->AssociatedIrp.SystemBuffer;
ulInputSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
ulOutputSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
if (InputData != NULL&&ulInputSize == sizeof(ULONG32))
{
memcpy(&ulProcessID, InputData, sizeof(ULONG32));
if (GetProcessImageNameByProcessID(ulProcessID, szProcessImageName, &ulProcessImageNameLength) == TRUE)
{
memcpy(OutputData, szProcessImageName, ulProcessImageNameLength);
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = ulProcessImageNameLength;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
}
break;
}
}
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
BOOLEAN GetProcessImageNameByProcessID(ULONG32 ulProcessID, char* szProcessImageName, ULONG32* ulProcessImageNameLength)
{
NTSTATUS Status;
PEPROCESS EProcess = NULL;
Status = PsLookupProcessByProcessId((HANDLE)ulProcessID, &EProcess);
if (!NT_SUCCESS(Status))
{
return FALSE;
}
if (EProcess == NULL)
{
return FALSE;
}
ObDereferenceObject(EProcess); //给定对象的引用计数和执行保留检查
if (strlen(PsGetProcessImageFileName(EProcess)) > MAX)
{
*ulProcessImageNameLength = MAX - 1;
}
else
{
*ulProcessImageNameLength = strlen(PsGetProcessImageFileName(EProcess));
}
memcpy(szProcessImageName, PsGetProcessImageFileName(EProcess), *ulProcessImageNameLength);
return TRUE;
}
NTSTATUS DefaultPassDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
代码亲测在win10下也有效。
以上是关于暴力枚举进程的主要内容,如果未能解决你的问题,请参考以下文章