ring0 暴力枚举进程
原理:遍历进程ID,然后openprocess,能打开的都枚举出来
ring0 :
#include "EnumProcessByForce.h" extern char* PsGetProcessImageFileName(PEPROCESS EProcess); extern POBJECT_TYPE* PsProcessType; NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegisterPath) { PDEVICE_OBJECT DeviceObject; NTSTATUS Status; int i = 0; UNICODE_STRING DeviceName; UNICODE_STRING LinkName; RtlInitUnicodeString(&DeviceName, DEVICE_NAME); RtlInitUnicodeString(&LinkName, LINK_NAME); Status = IoCreateDevice(DriverObject, 0, &DeviceName, FILE_DEVICE_UNKNOWN, 0, FALSE, &DeviceObject); if (!NT_SUCCESS(Status)) { return Status; } Status = IoCreateSymbolicLink(&LinkName, &DeviceName); if (!NT_SUCCESS(Status)) { //销毁设备对象 IoDeleteDevice(DeviceObject); DeviceObject = NULL; return Status; } DriverObject->DriverUnload = UnloadDriver; //设置派遣函数 for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) { DriverObject->MajorFunction[i] = DefaultPassThrough; } DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DeviceControlDispatch; //DeviceIoControl(DeviceObject) } NTSTATUS DefaultPassThrough(PDEVICE_OBJECT DeviceObject, PIRP Irp) { Irp->IoStatus.Information = 0; Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(Irp, IO_NO_INCREMENT); //将Irp返回给IO管理器,IO_NO_INCREMENT不增加优先级 return STATUS_SUCCESS; } void UnloadDriver(PDRIVER_OBJECT DriverObject) { PDEVICE_OBJECT DeviceObject = NULL; PDEVICE_OBJECT v1 = NULL; UNICODE_STRING LinkName; RtlInitUnicodeString(&LinkName, LINK_NAME); IoDeleteSymbolicLink(&LinkName); DeviceObject = DriverObject->DeviceObject; v1 = DeviceObject; while (DeviceObject != NULL) { v1 = DeviceObject->NextDevice; IoDeleteDevice(DeviceObject); DeviceObject = v1; } } NTSTATUS DeviceControlDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp) { NTSTATUS Status = STATUS_SUCCESS; ULONG IoControlCode = 0; PVOID InputBuffer = NULL; PVOID OutputBuffer = NULL; ULONG32 InputLength = 0; ULONG32 OutputLength = 0; char BufferData[MAX_PATH] = { 0 }; ULONG BufferLength = MAX_PATH; PIO_STACK_LOCATION IoStackLocation = IoGetCurrentIrpStackLocation(Irp); IoControlCode = IoStackLocation->Parameters.DeviceIoControl.IoControlCode; switch (IoControlCode) //IO控制码 { case CTL_GET_PROCESS_IMAGE_NAME_BY_PROCESSID: { InputBuffer = OutputBuffer = Irp->AssociatedIrp.SystemBuffer; //CopyBuffer InputLength = IoStackLocation->Parameters.DeviceIoControl.InputBufferLength; OutputLength = IoStackLocation->Parameters.DeviceIoControl.OutputBufferLength; //功能 if (InputLength == sizeof(ULONG) && InputBuffer != NULL&&OutputLength == MAX_PATH) { Status = EnumProcessByForce(*((PULONG)InputBuffer), BufferData, &BufferLength); if (NT_SUCCESS(Status)) { memcpy((char*)OutputBuffer, BufferData, BufferLength); } else { BufferLength = 0; } } } default: { break; } } Irp->IoStatus.Status = Status; Irp->IoStatus.Information = BufferLength; //指示有多少内存向Ring3拷贝 //最后派遣函数将IRP请求结束,通过IoCompleteRequest IoCompleteRequest(Irp, IO_NO_INCREMENT); //将Irp返回给IO管理器 return STATUS_SUCCESS; } NTSTATUS EnumProcessByForce(ULONG ProcessID, char* BufferData, ULONG* BufferLength) { //进程的名称存储在进程的EProcess当前 NTSTATUS Status = STATUS_UNSUCCESSFUL; PEPROCESS EProcess = NULL; Status = PsLookupProcessByProcessId((HANDLE)ProcessID, &EProcess); if (!NT_SUCCESS(Status)) { return Status; } //判断是否有效 if (IsRealProcess(EProcess) == TRUE) { ObDereferenceObject(EProcess); if (strlen(PsGetProcessImageFileName(EProcess)) < *BufferLength) { *BufferLength = strlen(PsGetProcessImageFileName(EProcess)); } else { *BufferLength = *BufferLength - 1; } memcpy(BufferData, PsGetProcessImageFileName(EProcess), *BufferLength); return STATUS_SUCCESS; } return Status; } BOOLEAN IsRealProcess(PEPROCESS EProcess) { ULONG_PTR ObjectType; ULONG_PTR ObjectTypeAddress; ULONG_PTR ProcessType = ((ULONG_PTR)*PsProcessType); //系统导出的全局变量 if (ProcessType && EProcess && MmIsAddressValid((PVOID)(EProcess))) { ObjectType = KeGetObjectType((PVOID)EProcess); //通过EProcess 获得进程对象特征码 if (ObjectType && ProcessType == ObjectType) { return TRUE; } } return FALSE; } ULONG_PTR KeGetObjectType(PVOID ObjectBody) { ULONG_PTR ObjectType = NULL; pfnObGetObjectType ObGetObjectType = NULL; /* kd> u ObGetObjectType nt!ObGetObjectType: 840a8b68 8bff mov edi,edi 840a8b6a 55 push ebp 840a8b6b 8bec mov ebp,esp 840a8b6d 8b4508 mov eax,dword ptr [ebp+8] 840a8b70 0fb640f4 movzx eax,byte ptr [eax-0Ch] 840a8b74 8b04858035f983 mov eax,dword ptr nt!ObTypeIndexTable (83f93580)[eax*4] 840a8b7b 5d pop ebp 840a8b7c c20400 ret 4 */ if (!MmIsAddressValid || !ObjectBody || !MmIsAddressValid(ObjectBody)) { return NULL; } ObGetObjectType = (pfnObGetObjectType)GetFunctionAddressByName(L"ObGetObjectType"); if (ObGetObjectType) { ObjectType = ObGetObjectType(ObjectBody); } return ObjectType; } PVOID GetFunctionAddressByName(WCHAR *FunctionName) { UNICODE_STRING v1; PVOID FunctionAddress = NULL; if (FunctionName && wcslen(FunctionName) > 0) { RtlInitUnicodeString(&v1, FunctionName); FunctionAddress = MmGetSystemRoutineAddress(&v1); //在系统第一个模块ntoskrnl.exe 导出表中搜索 } return FunctionAddress; } //对派遣函数的简单处理 //大部分的IRP都源于文件I / O处理的API,如CreateFile、ReadFile等。处理这些IRP最简单的方法是在相应的派遣函数中, //将IRP的状态设置成功,然后结束IRP的请求(使用IoCompleteRequest),并让派遣函数返回成功。
ring3 :
#include "stdafx.h" #include "EnumProcessForceRing3.h" #ifdef _DEBUG #define new DEBUG_NEW #endif // 唯一的应用程序对象 #include <windows.h> #include <WinIoCtl.h> #include <map> CWinApp theApp; using namespace std; #define LINK_NAME L"\\\\.\\LinkName" //rdata #define CTL_CODE( DeviceType, Function, Method, Access ) ( \ ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) ) #define CTL_GET_PROCESS_IMAGE_NAME_BY_PROCESSID \ CTL_CODE(FILE_DEVICE_UNKNOWN,0x830,METHOD_BUFFERED,FILE_ANY_ACCESS) void EnumProcessForce(HANDLE DeviceHandle, map<ULONG, CString>& ProcessInfo); BOOL GrantPriviledge(IN const WCHAR* PriviledgeName); map<ULONG, CString> __ProcessInfo; int main() { GrantPriviledge(L"SeDebugPrivilege"); HANDLE DeviceHandle = NULL; DeviceHandle = CreateFile(LINK_NAME, //设备名称 不是\\Device\\ 是要使用设备对象的LinkName GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (DeviceHandle == INVALID_HANDLE_VALUE) { return FALSE; } printf("已连接"); __ProcessInfo[4] = "System.exe"; EnumProcessForce(DeviceHandle, __ProcessInfo); //模块 if (DeviceHandle != NULL) { CloseHandle(DeviceHandle); DeviceHandle = NULL; } map<ULONG, CString>::iterator Travel; for (Travel = __ProcessInfo.begin(); Travel != __ProcessInfo.end(); Travel++) { printf("%4d %S\r\n", Travel->first, Travel->second); } printf("Input AnyKey To Exit\r\n"); getchar(); return 0; } void EnumProcessForce(HANDLE DeviceHandle, map<ULONG, CString>& ProcessInfo) { DWORD ReturnLength = 0; char ProcessImageName[MAX_PATH] = { 0 }; size_t i = 4; while (i < 100000) { HANDLE ProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, i); if (ProcessHandle == NULL) { i += 4; continue; } BOOL IsOk = DeviceIoControl(DeviceHandle, CTL_GET_PROCESS_IMAGE_NAME_BY_PROCESSID, //消息码 &i, //InputData sizeof(ULONG), //InputDataSize ProcessImageName, //OutputData MAX_PATH, //OutputDataSize &ReturnLength, NULL); if (IsOk == TRUE&&ReturnLength != 0) { ProcessImageName[ReturnLength] = '\0'; } ProcessInfo[i] = ProcessImageName; i += 4; } } BOOL GrantPriviledge(IN const WCHAR* PriviledgeName) { // 打开权限令牌 HANDLE ProcessHandle = GetCurrentProcess(); HANDLE TokenHandle = NULL; LUID uID; if (!OpenProcessToken(ProcessHandle, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &TokenHandle)) { return FALSE; } if (!LookupPrivilegeValue(NULL, PriviledgeName, &uID)) // 通过权限名称查找uID { CloseHandle(TokenHandle); TokenHandle = NULL; return FALSE; } TOKEN_PRIVILEGES TokenPrivileges; TokenPrivileges.PrivilegeCount = 1; // 要提升的权限个数 TokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; // 动态数组,数组大小根据Count的数目 TokenPrivileges.Privileges[0].Luid = uID; if (!AdjustTokenPrivileges(TokenHandle, FALSE, &TokenPrivileges, sizeof(TOKEN_PRIVILEGES), NULL, NULL)) { printf("%d\r\n", GetLastError()); CloseHandle(TokenHandle); TokenHandle = NULL; return FALSE; } CloseHandle(TokenHandle); TokenHandle = NULL; return TRUE; }