暴力枚举进程

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下也有效。

以上是关于暴力枚举进程的主要内容,如果未能解决你的问题,请参考以下文章

ring0 暴力枚举进程

蓝桥系列212道「暴力枚举」真题,夯实你的刷题基本功(暴力枚举模板)

UVa 10603 Fill [暴力枚举路径搜索]

暴力枚举

暴力枚举

暴力枚举篇