Einzelnen Beitrag anzeigen

Apollonius

Registriert seit: 16. Apr 2007
2.325 Beiträge
 
Turbo Delphi für Win32
 

Prozess-Handles nur geringe Rechte erlauben

  Alt 8. Sep 2007, 15:24
Hier habe ich mit der großen Hilfe von Dezipaitor eine Methode entwickelt, mit der man verhindern kann, dass Prozess-Handles zu große Rechte erlangen. Auf diese Weise kann man verhindern (oder zumindest erschweren, wenn das "feindliche" Programm mit Administrator-Rechten arbeitet), dass ein Prozess terminiert wird, dass Write/ReadProcessMemory oder die Virtual...Ex-Funktionen verwendet werden und so ziemlich alles, wofür Prozess-Handles gebraucht werden.
Delphi-Quellcode:
uses Sysutils,
     Windows,
     AclApi, //Für SetSecurityInfo
     AccCtrl; //Für SE_KERNEL_OBJECT als Wert einer Aufzählung
function ConvertStringSecurityDescriptorToSecurityDescriptorA(StringSecurityDescriptor: PChar; StringSDRevision: DWORD; var SecurityDescriptor: PSECURITY_DESCRIPTOR; SecurityDescriptorSize: PULONG): boolean; stdcall; external 'Advapi32.dll';
//Der letzte Parameter wird nicht als var deklariert, damit nil eingesetzt werden kann

//Zugangsrechte für eigenen Prozess setzen
//Rights: eine or-Verknüpfung aller Rechte, die noch erlaubt sein sollen
procedure SetProcessHandleRights(Rights: Cardinal);
const PROTECTED_DACL_SECURITY_INFORMATION = $80000000;
      SDDL_REVISION_1=1;
var Desc: PSECURITY_DESCRIPTOR; SDDLString: ansistring;
    DACL: pACL; err: cardinal;
    d1, d2: LongBool; //Dummies
begin
SDDLString:='D:(A;;0x'+inttohex(Rights, 8)+';;;WD)'; //Näheres im PSDK unter SDDL
if not ConvertStringSecurityDescriptorToSecurityDescriptorA(PChar(SDDLString), SDDL_REVISION_1, Desc, nil) then
  raise EOSError.CreateFmt('Error in function ConverStringSecurityDescriptorToSecurityDescriptorA: %s', [syserrormessage(getLastError)]);
if not getSecurityDescriptorDACL(desc, d1, DACL, d2) then
  raise EOSError.CreateFmt('Error in function getSecurityDescriptorDACL: %s', [syserrormessage(getLastError)]);
//jetzt das Kernstück
err:=SetSecurityInfo(getCurrentProcess, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION or PROTECTED_DACL_SECURITY_INFORMATION, nil, nil, DACL, nil);
if err<>0 then
  raise EOSError.CreateFmt('Error in function setSecurityInfo: %s', [syserrormessage(err)]);
end;


//Beispielaufruf
procedure TForm1.Button1Click(Sender: TObject);
var ProcId, ProcHandle: Cardinal;
begin
SetProcessHandleRights(PROCESS_ALL_ACCESS and not PROCESS_VM_WRITE); //WriteProcessMemory kann auf eigenen Prozess nicht mehr verwendet werden

//Test, ob es funktioniert hat
getWindowThreadProcessId(self.Handle, ProcId);
ProcHandle:=OpenProcess(PROCESS_ALL_ACCESS, false, ProcId); //Null-Handle-> hat funktioniert
showmessage(inttostr(ProcHandle));
closeHandle(ProcHandle);
end;
Um das ganze sicher zu machen, muss man außerdem PROCESS_DUPLICATE_HANDLE verbieten, da sonst ein Handle mit PROCESS_ALL_ACCESS erlangt werden kann.

[edit=Matze]Dieses Thema reicht nicht ganz aus, um in die Code-Library aufgenommen zu werden. MfG, Matze[/edit]
Wer erweist der Welt einen Dienst und findet ein gutes Synonym für "Pointer"?
"An interface pointer is a pointer to a pointer. This pointer points to an array of pointers, each of which points to an interface function."
  Mit Zitat antworten Zitat