create process as system privilege
2008-06-23 11:25
369 查看
here is a way to do this in kernel mode driver: (for WinXP/2003) Hook undocumented API: ZwCreateProcessEx then set the fouth parameter to SYSTEM handle info. typedef NTSTATUS (*ZWCreatePROCESSEX)( OUT PHANDLE ProcessHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN HANDLE ParentProcess, IN BOOLEAN InheritObjectTable, IN HANDLE SectionHandle OPTIONAL, IN HANDLE DebugPort OPTIONAL, IN HANDLE ExceptionPort OPTIONAL, IN HANDLE Unknown ); ZWCreatePROCESSEX OldZwCreateProcessEx; NTSTATUS NTAPI ZwOpenProcess(OUT PHANDLE ProcessHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN PCLIENT_ID ClientId ); NTSTATUS NewZwCreateProcessEx( OUT PHANDLE ProcessHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN HANDLE ParentProcess, IN BOOLEAN InheritObjectTable, IN HANDLE SectionHandle OPTIONAL, IN HANDLE DebugPort OPTIONAL, IN HANDLE ExceptionPort OPTIONAL, IN HANDLE Unknown OPTIONAL) { NTSTATUS ret; HANDLE h; CLIENT_ID id; OBJECT_ATTRIBUTES oa; id.UniqueProcess = (HANDLE)4; // run process as SYSTEM account id.UniqueThread = 0; InitializeObjectAttributes(&oa, NULL, 0, NULL, NULL); ZwOpenProcess(&h, PROCESS_ALL_ACCESS, &oa, &id); ret= OldZwCreateProcessEx(ProcessHandle,DesiredAccess,ObjectAttributes, h, InheritObjectTable,SectionHandle,DebugPort,ExceptionPort,Unknown); ZwClose(h); return ret; } SDT hook: typedef struct ServiceDescriptorEntry { unsigned int *ServiceTableBase; unsigned int *ServiceCounterTableBase; //Used only in checked build unsigned int NumberOfServices; unsigned char *ParamTableBase; } ServiceDescriptorTableEntry, *PServiceDescriptorTableEntry; extern PServiceDescriptorTableEntry KeServiceDescriptorTable; #define SYSTEMSERVICE(_function) KeServiceDescriptorTable.ServiceTableBase[ *(PULONG)((PUCHAR)_function+1)] int ServiceIndex = 0x32; // for WinXP/2003 Hook SDT(Service Descriptor Table): // save old system call locations // OldNtCreateProcessEx=(NTCreatePROCESSEX)(SYSTEMSERVICE(0x32)); OldZwCreateProcessEx=(ZWCreatePROCESSEX)(*(((PServiceDescriptorTableEntry)KeServiceDescriptorTable)->ServiceTableBase + ServiceIndex)); _asm { CLI //dissable interrupt MOV EAX, CR0 //move CR0 register into EAX AND EAX, NOT 10000H //disable WP bit MOV CR0, EAX //write register back } (ZWCreatePROCESSEX)(*(((PServiceDescriptorTableEntry)KeServiceDescriptorTable)->ServiceTableBase + ServiceIndex)) = NewZwCreateProcessEx; _asm { MOV EAX, CR0 //move CR0 register into EAX or EAX, 10000H //enable WP bit MOV CR0, EAX //write register back STI //enable interrupt } Unhook SDT: _asm { CLI //dissable interrupt MOV EAX, CR0 //move CR0 register into EAX AND EAX, NOT 10000H //disable WP bit MOV CR0, EAX //write register back } (ZWCreatePROCESSEX)(*(((PServiceDescriptorTableEntry)KeServiceDescriptorTable)->ServiceTableBase + ServiceIndex)) = OldZwCreateProcessEx; _asm { MOV EAX, CR0 //move CR0 register into EAX or EAX, 10000H //enable WP bit MOV CR0, EAX //write register back STI //enable interrupt } get SDI index by dynamic analyse NTDLL: #define DWORD unsigned long #define WORD unsigned short #define BOOL unsigned long #define BYTE unsigned char #define SEC_IMAGE 0x01000000 NTSTATUS NTAPI ZwCreateSection( OUT PHANDLE SectionHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN PLARGE_INTEGER MaximumSize OPTIONAL, IN ULONG SectionPageProtection, IN ULONG AllocationAttributes, IN HANDLE FileHandle OPTIONAL ); typedef struct _SECTION_IMAGE_INFORMATION { PVOID EntryPoint; ULONG StackZeroBits; ULONG StackReserved; ULONG StackCommit; ULONG ImageSubsystem; WORD SubsystemVersionLow; WORD SubsystemVersionHigh; ULONG Unknown1; ULONG ImageCharacteristics; ULONG ImageMachineType; ULONG Unknown2[3]; } SECTION_IMAGE_INFORMATION, *PSECTION_IMAGE_INFORMATION; DWORD GetDllFunctionAddress(char* lpFunctionName, PUNICODE_STRING pDllName) { HANDLE hThread, hSection, hFile, hMod; SECTION_IMAGE_INFORMATION sii; IMAGE_DOS_HEADER* dosheader; IMAGE_OPTIONAL_HEADER* opthdr; IMAGE_EXPORT_DIRECTORY* pExportTable; DWORD* arrayOfFunctionAddresses; DWORD* arrayOfFunctionNames; WORD* arrayOfFunctionOrdinals; DWORD functionOrdinal; DWORD Base, x, functionAddress; char* functionName; STRING ntFunctionName, ntFunctionNameSearch; PVOID BaseAddress = NULL; SIZE_T size=0; IO_STATUS_BLOCK iosb; OBJECT_ATTRIBUTES oa = {sizeof oa, 0, pDllName, OBJ_CASE_INSENSITIVE}; ZwOpenFile(&hFile, FILE_EXECUTE | SYNCHRONIZE, &oa, &iosb, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT); oa.ObjectName = 0; ZwCreateSection(&hSection, SECTION_ALL_ACCESS, &oa, 0,PAGE_EXECUTE, SEC_IMAGE, hFile); ZwMapViewOfSection(hSection, NtCurrentProcess(), &BaseAddress, 0, 1000, 0, &size, (SECTION_INHERIT)1, MEM_TOP_DOWN, PAGE_READWRITE); ZwClose(hFile); hMod = BaseAddress; dosheader = (IMAGE_DOS_HEADER *)hMod; opthdr =(IMAGE_OPTIONAL_HEADER *) ((BYTE*)hMod+dosheader->e_lfanew+24); pExportTable =(IMAGE_EXPORT_DIRECTORY*)((BYTE*) hMod + opthdr->DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT]. VirtualAddress); // now we can get the exported functions, but note we convert from RVA to address arrayOfFunctionAddresses = (DWORD*)( (BYTE*)hMod + pExportTable->AddressOfFunctions); arrayOfFunctionNames = (DWORD*)( (BYTE*)hMod + pExportTable->AddressOfNames); arrayOfFunctionOrdinals = (WORD*)( (BYTE*)hMod + pExportTable->AddressOfNameOrdinals); Base = pExportTable->Base; RtlInitString(&ntFunctionNameSearch, lpFunctionName); for(x = 0; x < pExportTable->NumberOfFunctions; x++) { functionName = (char*)( (BYTE*)hMod + arrayOfFunctionNames[x]); RtlInitString(&ntFunctionName, functionName); functionOrdinal = arrayOfFunctionOrdinals[x] + Base - 1; // always need to add base, -1 as array counts from 0 // this is the funny bit. you would expect the function pointer to simply be arrayOfFunctionAddresses[x]... // oh no... thats too simple. it is actually arrayOfFunctionAddresses[functionOrdinal]!! functionAddress = (DWORD)( (BYTE*)hMod + arrayOfFunctionAddresses[functionOrdinal]); if (RtlCompareString(&ntFunctionName, &ntFunctionNameSearch, TRUE) == 0) { ZwClose(hSection); return functionAddress; } } ZwClose(hSection); return 0; } use the above function like this: RtlInitUnicodeString(&dllName, L"//Device//HarddiskVolume1//Windows//System32//ntdll.dll"); functionAddress = GetDllFunctionAddress("ZwCreateProcessEx", &dllName); ServiceIndex = *((WORD*)(functionAddress+1)); // should = 0x32
相关文章推荐
- sendBroadcastAsUser——Calling a method in the system process without a qualified user
- CreateProcessAsUser的用法
- CreateProcessAsUser,C#写的windows服务弹框提示消息或者启动子进程
- Create process in UNIX like system
- how to set a user-defined process as the system key process
- Win7中如何在服务中启动一个当前用户的进程——函数CreateProcessAsUser()的一次使用记录
- CreateProcessAsUser
- CreateProcessAsUser
- 创建新进程,就三个函数CreateProcessAsUser CreateProcessWithLogonW CreateProcessWithTokenW(附网友的流程)
- CreateProcess As fork
- [SAP HANA]Cannot create Delivery Unit as content vendor is not defined for this system
- sendBroadcastAsUser——Calling a method in the system process without a qualified user 包含去电流程
- create an process with administrator privilege from service in Vista
- 浅析C++中的system/WinExec/ShellExecute/CreateProcess
- CreateProcessAsUser Function
- 以不同用户身份运行程序,/savecred只需要输入一次密码(GetTokenByName取得EXPLORER.EXE的令牌,然后调用CreateProcessAsUser,而且使用LoadUserProfile解决另存文件的问题)good
- Remote Thread Execution in System Process using NtCreateThreadEx for Vista & Windows7
- 【工作中学习】CreateProcessAsUser失败,错误码:1314
- mpich出现LaunchProcess failed,CreateProcessAsUser failed,拒绝访问
- CreateProcessAsUser() windowstations 和桌面