HRESULT STDMETHODCALLTYPE GetSecurity( _In_ IObjectSecurity * This, _In_ SECURITY_INFORMATION RequestedInformation, _Out_ PSECURITY_DESCRIPTOR *ppSecurityDescriptor, _In_ BOOL fDefault ) { HRESULT hResult; HANDLE hObject; ULONG bytesNeeded; NTSTATUS status; ACCESS_MASK DesiredAccess; PSECURITY_DESCRIPTOR PSD; if (fDefault) { return E_NOTIMPL; } //open object hObject = NULL; DesiredAccess = propGetObjectAccessMask(RequestedInformation, FALSE); if (!This->OpenObjectMethod(This->ObjectContext, &hObject, DesiredAccess)) { return HRESULT_FROM_WIN32(GetLastError()); } //query object SD //warning: system free SD with LocalFree on security dialog destroy bytesNeeded = 0x100; PSD = LocalAlloc(LPTR, bytesNeeded); if (PSD == NULL) { hResult = HRESULT_FROM_WIN32(GetLastError()); goto Done; } status = NtQuerySecurityObject(hObject, RequestedInformation, PSD, bytesNeeded, &bytesNeeded); if (status == STATUS_BUFFER_TOO_SMALL) { LocalFree(PSD); PSD = LocalAlloc(LPTR, bytesNeeded); if (PSD == NULL) { hResult = HRESULT_FROM_WIN32(GetLastError()); goto Done; } status = NtQuerySecurityObject( hObject, RequestedInformation, PSD, bytesNeeded, &bytesNeeded ); } hResult = HRESULT_FROM_WIN32(RtlNtStatusToDosError(status)); *ppSecurityDescriptor = PSD; Done: //cleanup This->CloseObjectMethod(This, hObject); return hResult; }
HANDLE OpenProcess( DWORD ProcessId ) { HANDLE processHandle = 0; processHandle = Process_Open( ProcessId, PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION | PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | SYNCHRONIZE ); if (!processHandle) { NTSTATUS status; ULONG bufferSize; SECURITY_DESCRIPTOR* securityDescriptor; bufferSize = 0x100; securityDescriptor = (SECURITY_DESCRIPTOR*)Memory_Allocate(bufferSize); // Get the DACL of this process since we know we have all rights in it. status = NtQuerySecurityObject( NtCurrentProcess(), DACL_SECURITY_INFORMATION, securityDescriptor, bufferSize, &bufferSize ); if (status == STATUS_BUFFER_TOO_SMALL) { Memory_Free(securityDescriptor); securityDescriptor = (SECURITY_DESCRIPTOR*)Memory_Allocate(bufferSize); status = NtQuerySecurityObject( NtCurrentProcess(), DACL_SECURITY_INFORMATION, securityDescriptor, bufferSize, &bufferSize ); } if (!NT_SUCCESS(status)) { Memory_Free(securityDescriptor); return NULL; } // Open it with WRITE_DAC access so that we can write to the DACL. processHandle = Process_Open(ProcessId, (0x00040000L)); //WRITE_DAC if (processHandle == 0) { Memory_Free(securityDescriptor); return NULL; } status = NtSetSecurityObject( processHandle, DACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION, securityDescriptor ); if (!NT_SUCCESS(status)) { Memory_Free(securityDescriptor); return NULL; } // The DACL is overwritten with our own DACL. We // should be able to open it with the requested // privileges now. Process_Close(processHandle); processHandle = 0; Memory_Free(securityDescriptor); processHandle = Process_Open( ProcessId, PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION | PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | SYNCHRONIZE ); } if (!processHandle) { return NULL; } return processHandle; }
BOOL BackupReadSecurityData(HANDLE hFile, BACKUPCONTEXT *pbuc, BACKUPIOFRAME *pbif) { if (!pbif->fProcessSecurity) { return(TRUE); } if (pbuc->fStreamStart) { while (TRUE) { NTSTATUS Status; DWORD cbSecurityInfo; // First try to read all the security data RtlZeroMemory(pbuc->pBuffer, pbuc->cbBuffer); Status = NtQuerySecurityObject( hFile, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION, pbuc->pBuffer, pbuc->cbBuffer, &cbSecurityInfo); if (!NT_SUCCESS(Status) && !BufferOverflow(Status)) { // Now just try everything but SACL Status = NtQuerySecurityObject( hFile, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, pbuc->pBuffer, pbuc->cbBuffer, &cbSecurityInfo); } #if 0 if (!NT_SUCCESS(Status) && !BufferOverflow(Status)) { // Now just try to read the DACL Status = NtQuerySecurityObject( hFile, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION, pbuc->pBuffer, pbuc->cbBuffer, &cbSecurityInfo); } #endif if (NT_SUCCESS(Status)) { pbuc->fBufferReady = TRUE; break; } if (!BufferOverflow(Status)) { return(TRUE); // No Security info, do next stream type } if (!GrowBuffer(pbuc, cbSecurityInfo)) { return(FALSE); // No memory } // else grow succeeded } pbuc->head.dwStreamId = mwStreamList[pbuc->StreamIndex]; pbuc->head.dwStreamAttributes = STREAM_CONTAINS_SECURITY; pbuc->head.dwStreamNameSize = 0; pbuc->cbHeader = CB_NAMELESSHEADER; pbuc->head.Size.LowPart = RtlLengthSecurityDescriptor(pbuc->pBuffer); pbuc->head.Size.HighPart = 0; pbuc->fStreamStart = FALSE; } else if (pbuc->liStreamOffset.HighPart != 0 || pbuc->liStreamOffset.LowPart >= pbuc->cbHeader) { BackupReadBuffer(pbuc, pbif); } return(TRUE); }