![]() |
Security_Descriptor ändern
Ich habe mir kürzlich mal Gedanken gemacht, wie man verhindern könnte, dass ein anderer Prozess mit WriteProcessMemory Variablen meines Programms verändert. Da bietet sich natürlich an, zu verhindern, dass ein Handle meines Prozesses mit den nötigen Rechten PROCESS_VM_WRITE und PROCESS_VM_OPERATION geöffnet wird. Da ließe sich ja etwas mit dem Security-Descriptor meines Prozesses drehen. Kann man denn den eigenen Security-Descriptor verändern, oder ist das (zum Beispiel für Debugging etc.) verboten? Wenn ja - wie geht es? Ich habe die MSDN durchforstet, da ist zu dem Thema auch viel zu finden, aber auf eine Funktion zum Setzen eines neuen Descriptors bin ich nicht gestoßen.
|
Re: Security_Descriptor ändern
Aehnliches Problem:
![]() Ansonsten frage "Dezipaitor" zum Thema :zwinker: |
Re: Security_Descriptor ändern
Du kannst die Prozess DACL mit
![]() SE_KERNEL_OBJECT setzen. Theoretisch, da ich es selbst nicht probiert habe. ABER: Der Besitzer eines Security Descriptor kann immer die ACL ändern! Besitzer kann jeder werden dem es über die ACL erlaubt ist. Zudem können bestimmte Gruppen, auch ohne diese ACL Rechte, Besitzer übernehmen. Administratoren können dies z.B. RestoreOperatoren (auch Administratoren) ist es auch erlaubt, den Besitzer beliebig zu wählen. Das gilt übrigens natürlich auch für DIENSTE. Debuggerbenutzer haben da jedoch nicht viel zu sagen, was den Security Descriptor angeht. Einen Security kann man auf verschiedene Arten bauen.. Die einfachste Art mit Win32API Mitteln ist ![]() Am einfachsten wird es sowieso mit meiner ![]() |
Re: Security_Descriptor ändern
Zitat:
Danke schonmal für eure Hilfe. |
Re: Security_Descriptor ändern
Zitat:
Man sieht es gut an dem Ordner "System Volume Information". Ein Admin kann es sich per default nicht ansehen. Er kann jedoch die DACL anpassen und dann sich den Inhalt ansehen. Das hemmt schonmal einige Programme, die normal auf etwas zugreifen wollen. Die meisten Programme geben dann auf. |
Re: Security_Descriptor ändern
Hm. Irgendwo in meinem Code ist noch ein Fehler, denn auch als Gast kriege ich ein gültiges Handle...
Programm 1:
Delphi-Quellcode:
Ich hoffe mal, dass ich da mit der Api nicht ganz falsch liege. Auf Buttonklick wird eine Nachricht an ein zweites Programm mit geschickt, dabei wird die Adresse einer Variablen im WParam und das Hauptfensterhandle im LParam mitgeliefert.
program Project2;
uses Forms, Windows, AclAPI, AccCtrl, sysutils, dialogs, Unit1 in 'Unit1.pas' {Form1}; {$R *.res} const PROTECTED_DACL_SECURITY_INFORMATION = $80000000; //DACLs werden nicht vererbt var desc: SECURITY_DESCRIPTOR; begin InitializeSecurityDescriptor(@desc, SECURITY_DESCRIPTOR_REVISION); SetSecurityDescriptorDACL(@desc, false, nil, false); Showmessage(SysErrorMessage(SetSecurityInfo(getCurrentProcess, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION or PROTECTED_DACL_SECURITY_INFORMATION, nil, nil, desc.Dacl, nil))); Application.Initialize; Application.CreateForm(TForm1, Form1); Application.Run; end.
Delphi-Quellcode:
Und ich kriege immer ein gültiges Handle. Wo steckt der Fehler?procedure TForm1.rec(var Message:TMessage); var ProcId, ProcHandle: Cardinal; buffer, dummy: cardinal; begin getWindowThreadProcessId(Message.LParam, ProcId); ProcHandle:=OpenProcess(PROCESS_VM_WRITE or PROCESS_VM_OPERATION, false, ProcID); if ProcHandle=0 then begin showmessage('Prozess-Handle ist Null!'); exit; end; showmessage('Gueltiges Prozess-Handle'); try buffer:=5; WriteProcessMemory(ProcHandle, Pointer(Message.WParam), @buffer, 4, dummy); finally closeHandle(ProcHandle); end; end; |
Re: Security_Descriptor ändern
Zitat:
Die DACL zu ändern ist etwas aufwendig in C. Deshalb meinte ich ja, dass du ConvertStringTo... verwenden sollst. |
Re: Security_Descriptor ändern
Hm. Ich zitiere mal aus SetSecurityDescriptorDACL:
Zitat:
Ich habe mir auch vorher schonmal diese tolle "Sprache" für die Descriptors angeschaut, aber das sieht einfach nur furchtbar aus. Und ich verstehe nicht ganz, wie ich zum Beispiel die Rechte, die es nur für Prozesse gibt, geben oder nehmen kann. |
Re: Security_Descriptor ändern
So richtig geklärt haben wir das ja nicht. Was für einen String brauche ich denn beispielsweise, wenn ich den Prozess-Handle-Öffnern das Recht PROCESS_VM_READ verwehren will, er aber alles andere bekommen soll? Diese Beschreibungen der Descriptor-Sprache sind für mich absolut kryptisch...
Danke im Vorraus Apollonius |
Re: Security_Descriptor ändern
Liste der Anhänge anzeigen (Anzahl: 1)
Ich habe mal schnell ein Progrämmchen geschrieben, dass Strings in einen Security Descriptor und zurück verwandelt.
Man kann den String ins Memo schreiben und dann den Button drücken - oder es einfach leer lassen und im ACL Editor die Einstellungen vornehmen und dann ins Memo schreiben lassen. Mit der ComboBox kann man bestimmen, welche Art Objekt umgegangen werden soll - ich habe sie nicht alle getestet, daher kann es noch zu Merkwürdigkeiten kommen. Ich hab das Programm sehr schnell runter-gehackt und daher nicht großartig getestet. Mit Fehlern müssen wir daher Leben. |
Re: Security_Descriptor ändern
Dein Programm funktioniert bei mir nicht, das einzige, was erscheint, ist ein Eintrag in der Taskleiste.
Ich habe mittlerweile mal versucht, mich selbst mit dem Thema auseinanderzusetzen, allerdings schmeißt mir der Aufruf der Convert-Funktion immer einen ERROR_INVALID_SID. :(
Delphi-Quellcode:
Irgendjemand Vorschläge? Bestürzenderweise bekomme ich selbst dann einen "invalid sid", wenn ich die Strings aus den Microsoft-Beispielen nehme...
program Project2;
uses Forms, Windows, AclAPI, AccCtrl, sysutils, dialogs, zuVeraendern in 'zuVeraendern.pas' {Form1}; {$R *.res} type PPSECURITY_DESCRIPTOR=^PSECURITY_DESCRIPTOR; SecDescToStrFunc=function(StringSecurityDescriptor: PChar; StringSDRevision: DWORD; var SecurityDescriptor: PSECURITY_DESCRIPTOR; var SecurityDescriptorSize: ULONG): boolean; stdcall; const PROTECTED_DACL_SECURITY_INFORMATION = $80000000; SDDL_REVISION_1=1; //Konstanten muss man sich wohl selbst deklarieren DLLName='Advapi32.dll'; var desc: PSECURITY_DESCRIPTOR; SecDescStr: ansistring; Size: ULong; func: SecDescToStrFunc; lib: hModule; begin lib:=loadLibrary(DLLName); showmessage(inttostr(lib)); func:=getProcAddress(lib, 'ConvertStringSecurityDescriptorToSecurityDescriptorA'); showmessage(inttostr(integer(@func))); SecDescStr:='D:P(A;;0x'+inttohex(Process_All_Access xor Process_VM_Read, 8)+';;;WD)';//Ich hoffe mal, das ist nicht zu falsch... func(PChar(SecDescStr), SDDL_REVISION_1, Desc, size); showmessage(SysErrorMessage(getLastError)); //Fehler showmessage(inttostr(size)); //null Showmessage(SysErrorMessage(SetSecurityInfo(getCurrentProcess, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION or PROTECTED_DACL_SECURITY_INFORMATION, nil, nil, SECURITY_DESCRIPTOR(desc^).Dacl, nil)));//Folgefehler Zugriffsverletzung Application.Initialize; Application.CreateForm(TForm1, Form1); Application.Run; LocalFree(Cardinal(desc)); FreeLibrary(lib); end. Apollonius |
Re: Security_Descriptor ändern
Das Programm funktioniert. Nur hast du keinen zweite Bildschirm :D
Das Fenster ist deshalb außerhalb des sichtbaren Bereichs und man muss es über die Taskleiste verschieben. Delphi setzt standardmäßig die Designkoordinaten für die Fensterposition. Ich habe erneut hinaufgeladen. |
Re: Security_Descriptor ändern
:firejump: :party: ES FUNKTIONIERT!!! :dancer: :dp:
Wenn man auf die DACL-Falgs verzichtet, glückt der Aufruf der Convert-Funktion. Danach ist es nur noch eine Frage der Zeit, bis man darauf kommt, dass man mit MakeAbsoluteSD den Security-Descriptor wandeln muss, damit SetSecurityInfo die DACL akzeptiert und man darüber hinwegkommen ist, dass MakeAbsoluteSD streikt, wenn man für Parameter, die man nicht braucht, einfach nil eizusetzen versucht. Zuguterletzt ist es mir aber gelungen, meine Prozesshandles nur mit ganz spezifischen Rechten öffnen zu lassen. Ich werde das ganze jetzt in eine Funktion packen und in der Codelibrary posten. :dp: und ein RIESEN-DANKE an Dezipaitor! |
Re: Security_Descriptor ändern
GetLastError ruft man nur dann auf, wenn eine API Funktion einen Fehler über den Rückgabewert meldet.
Es ist nämlich nicht definiert, dass LastError auf 0 gesetzt wird im Erfolgsfall. Daher kann es auch im Erfolgsfall einen Wert ungleich 0 von GetLastError zurückgegeben werden. Self-Relative SDs ist ein SD, der aus einem Stück Speicher besteht, der alles notwendige enthält. Diese Art wird von API Funktionen zurückgegeben. Manche API Funktionen melden einen Fehler, wenn man so einen angibt. Absolute SD ist ein SD, der zwar auch ein Speicherblock ist, aber nur Zeiger auf den Inhalt enthält. So zeigen Owner, Group, DACL und SACL alle auf anderen Speicher. Diese Art von SD wird nur durch den Benutzer erstellt und an API Funktionen übergeben. Wie sieht denn nun dein String aus? Meinst du mit DACL-Flags diese?: DACL_SECURITY_INFORMATION or PROTECTED_DACL_SECURITY_INFORMATION PROTECTED_DACL_SECURITY_INFORMATION verwendet man, wenn übergeordnete Objekte ihre SD nicht ins aktuelle Objekt einbringen/vererben sollen. Soweit ich weiß unterstützt MS automatische Vererung nur bei Datei und Registry. Wenn GetSecurityInfo bei einem Objekt UNPROTECTED_DACL_SECURITY_INFORMATION findet und es unterstützt Vererbund, dann sucht es beim Vorgänger rekursiv nach der DACL, bis es eine findet, die nicht vererbt ist. Dann wird die vererbte DACL zurückgegeben. Man kann dieses System auf eigene Objekte übernehmen. |
Re: Security_Descriptor ändern
Ja, das mit getLastError ist mir bekannt, das war ja auch nur Quick&Dirty.
Mit DACL-Flags meine ich den einen Bestandteil des Strings, der nach 'D:', aber vor dem ersten ACE-String steht:
Delphi-Quellcode:
Meine derzeitige Version für die Codelibrary (etwas verschönert :-D ), sieht so aus:
'D:P'{Dieses P!}+'(A;;0x'+inttohex(Process_All_Access xor Process_VM_Read, 8)+';;;WD)';
Delphi-Quellcode:
Es funktioniert auf jeden Fall schonmal. Falls du keine Einwände hast, werde ich das dann mal für die Library posten.
uses Sysutils,
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 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)]); 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; Du kriegst natürlich eine Erwähnung, schließlich hast du einen großen Teil dazu beigetragen. Apollonius [edit] Dank Dezipaitor noch einen Lapsus behoben. [/edit] |
Re: Security_Descriptor ändern
Warum konvertierst du den SD überhaupt? Die Arbeit kannst du dir sparen, da du den neuen SD sowieso nicht verwendest.
Benutze stattdessen ![]() |
Re: Security_Descriptor ändern
Zitat:
Irgendeine Idee wegen den DACL-Flags? Ist für die spezielle Aufgabe nicht von Belang, aber interessieren würde es mich trotzdem. |
Re: Security_Descriptor ändern
Zitat:
Meinst du die ![]() die ![]() Das erste gibt Information über den SD. Das zweite gibt einer API Funktion den Befehl, welche Art von Information (DACL, Group, usw + Protected, Unprotected) im SD des Objekts geändert werden soll. Die Grundlagen über Window Security Programming kannst du ![]() Warnung: Das Thema kann sehr aufregend, aber auch frustrierend sein. Bei der Implementierung der Security API hab ich das immer wieder durch gemacht. Aus Fehlern lernt man aber unglaublich viel :D |
Re: Security_Descriptor ändern
Ich meine mit DACL-Flags einen Bestandteil des Strings, der in die Control-Flags übersetzt wird. Wenn ich jedoch an der vorgesehenen Stelle den erlaubten string 'P' einsetze, ist das Format ungültig, wie getLastError sagt.
Zitat:
|
Re: Security_Descriptor ändern
also ich hab man dein Beitrag zur Codelib übersetzt
und konnte den String "D:P(..." damit ohne Probs ausführen. |
Re: Security_Descriptor ändern
Bei mir gehts jetzt auch, da habe ich wohl irgendwo anders einen Fehler provoziert. :roll: Ist ja auch egal.
Dann werde ich den Code mal für die Library posten. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:29 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz