Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   RegGetKeySecurity (https://www.delphipraxis.net/123679-reggetkeysecurity.html)

CoRe.eXtreem 6. Nov 2008 14:02


RegGetKeySecurity
 
Hallo Zusammen,

leider ist es kein Delphi aber ich hoffe ihr könnt mir trotzdem helfen. Ich bin schon am verzweifeln!

Ich möchte mit einem einfachen API Call "RegGetKeySecurity" die DACL vom gewünschten Schlüssel auslesen.


Delphi-Quellcode:
    .data
   lpSubKey         db   "SOFTWARE\Classes\.7z\2",0
   phkResult          dd   0

   pSecurityDescriptor      SECURITY_DESCRIPTOR <>
   
    .code
   
start:
   xor   eax,eax

   push   offset phkResult
   push   KEY_ALL_ACCESS
   push   0
   push   offset lpSubKey
   push   HKEY_LOCAL_MACHINE
   call   RegOpenKeyEx


   push   sizeof pSecurityDescriptor      <-- Ich vermute der Fehler liegt hier
   push   offset pSecurityDescriptor
   push   DACL_SECURITY_INFORMATION
   push   offset phkResult
   call   RegGetKeySecurity

   push   phkResult
   call   RegCloseKey

   @_ExitProcess:
   push   0
   call   ExitProcess

end start
Was könnte da falsch sein?

Danke!

Greatz

Dezipaitor 6. Nov 2008 19:49

Re: RegGetKeySecurity
 
Weißt du, wie es in C geht?

CoRe.eXtreem 7. Nov 2008 09:29

Re: RegGetKeySecurity
 
Hier ein Auszug aus MSDN.

http://msdn.microsoft.com/en-us/library/aa379313(VS.85).aspx

Syntax

RegGetKeySecurity(HKEY hKey,SECURITY_INFORMATION SecurityInformation,PSECURITY_DESCRIPTOR pSecurityDescriptor,LPDWORD lpcbSecurityDescriptor);

Parameters

hKey [in]

A handle to an open key for which to retrieve the security descriptor.
SecurityInformation [in]

A SECURITY_INFORMATION value that indicates the requested security information.
pSecurityDescriptor [out, optional]

A pointer to a buffer that receives a copy of the requested security descriptor.
lpcbSecurityDescriptor [in, out]

A pointer to a variable that specifies the size, in bytes, of the buffer pointed to by the pSecurityDescriptor parameter. When the function returns, the variable contains the number of bytes written to the buffer.

CoRe.eXtreem 7. Nov 2008 10:29

Re: RegGetKeySecurity
 
Delphi-Quellcode:
    .data
   lpSubKey         db   "SOFTWARE\Classes\.7z\2",0
   phkResult          dd   0

    .data?
   pSecurityDescriptor      SECURITY_DESCRIPTOR <>

    .code
   
start:
   xor   eax,eax

   push   offset phkResult
   push   KEY_ALL_ACCESS
   push   0
   push   offset lpSubKey
   push   HKEY_LOCAL_MACHINE
   call   RegOpenKeyEx

   push   sizeof SECURITY_DESCRIPTOR      ;<-- Ich vermute der Fehler liegt hier
   push   offset pSecurityDescriptor
   push   DACL_SECURITY_INFORMATION
   push   offset phkResult
   call   RegGetKeySecurity

   push   phkResult
   call   RegCloseKey

   @_ExitProcess:
   push   0
   call   ExitProcess

end start
Der "SECURITY_DESCRIPTOR" gehört in die nicht initialisierte section. Jetzt ist nur noch die Frage wie ich diesen initialisiere vor der verwendung.

In der MSDN (http://msdn.microsoft.com/en-us/libr...61(VS.85).aspx) steht dazu folgendes,...

The SECURITY_DESCRIPTOR structure contains the security information associated with an object. Applications use this structure to set and query an object's security status.

Because the internal format of a security descriptor can vary, we recommend that applications not modify the SECURITY_DESCRIPTOR structure directly. For creating and manipulating a security descriptor, use the functions listed in the See Also section.


Vielleicht kann mir bei der initialisierung des SECURITY_DESCRIPTOR helfen.

Viele Grüße :coder2:

Volle 7. Nov 2008 10:32

Re: RegGetKeySecurity
 
http://msdn.microsoft.com/en-us/library/aa378863(VS.85).aspx
Code:
BOOL WINAPI InitializeSecurityDescriptor(
  __out PSECURITY_DESCRIPTOR pSecurityDescriptor,
  __in  DWORD dwRevision
);
pSecurityDescriptor [out]
A pointer to a SECURITY_DESCRIPTOR structure that the function initializes.

dwRevision [in]
The revision level to assign to the security descriptor. This parameter must be SECURITY_DESCRIPTOR_REVISION.



ich hoffe das hilft

CoRe.eXtreem 7. Nov 2008 10:34

Re: RegGetKeySecurity
 
Danke, genau das habe ich auch gerade gefunden.
Das Problem ist nur ich bekomme im CPU Register EAX 00000001 raus.

EAX 00000001 <---
ECX 00403020 RegAth.00403020
EDX 00292CA0
EBX 7FFD9000
ESP 0012FF8C
EBP 0012FF94
ESI 00000000
EDI 00000000
EIP 00401029 RegAth.00401029
C 0 ES 0023 32bit 0(FFFFFFFF)
P 0 CS 001B 32bit 0(FFFFFFFF)
A 0 SS 0023 32bit 0(FFFFFFFF)
Z 0 DS 0023 32bit 0(FFFFFFFF)
S 0 FS 003B 32bit 7FFDF000(FFF)
T 0 GS 0000 NULL
D 0
O 0 LastErr ERROR_SUCCESS (00000000)
EFL 00000202 (NO,NB,NE,A,NS,PO,GE,G)
ST0 empty 0.0
ST1 empty 0.0
ST2 empty 0.0
ST3 empty 0.0
ST4 empty 0.0
ST5 empty 0.0
ST6 empty 0.0
ST7 empty 0.0
3 2 1 0 E S P U O Z D I
FST 0000 Cond 0 0 0 0 Err 0 0 0 0 0 0 0 0 (GT)
FCW 027F Prec NEAR,53 Mask 1 1 1 1 1 1

Delphi-Quellcode:
    .data
   lpSubKey         db   "SOFTWARE\Classes\.7z\2",0
   phkResult          dd   0

    .data?
   pSecurityDescriptor      SECURITY_DESCRIPTOR <>

    .code
   
start:
   xor   eax,eax

   push   offset phkResult
   push   KEY_ALL_ACCESS
   push   0
   push   offset lpSubKey
   push   HKEY_LOCAL_MACHINE
   call   RegOpenKeyEx


   push   SECURITY_DESCRIPTOR_REVISION
   push   offset pSecurityDescriptor
   call   InitializeSecurityDescriptor


   push   sizeof SECURITY_DESCRIPTOR      ;<-- Ich vermute der Fehler liegt hier
   push   offset pSecurityDescriptor
   push   DACL_SECURITY_INFORMATION
   push   offset phkResult
   call   RegGetKeySecurity

   push   phkResult
   call   RegCloseKey

   @_ExitProcess:
   push   0
   call   ExitProcess

end start

Volle 7. Nov 2008 10:39

Re: RegGetKeySecurity
 
hoi,

sorry ich hab absolut keine ahnung von asm :P
Ich weis nich wie es mit dem Registry verhalten von windows ist aber wenn mit die Dacl's mit dateien verwendest musst du aufpassen ob du in einer domain bist oder nicht ... das is alles ein wenig undurchsichtig bzw ungeschickt.

wenn du es so garnich hinbekommst mach es doch auf die, zugegeben unschoene, art dass du einfach versuchst etwas zu aendern, sollte das nicht klappen wirds wohl an den zugriffsrechten liegen. wenns klappt dann machste es wieder rueckgaenig.

ich hab z.b. ueber die Dacl's versucht rauszufinden ob ich schreibrechte auf ne datei hab. kannste total erden. Ich hab keinen besseren weg als umbennen und bei bedarf wieder zurueck umbennen gefunden.

cYa

[edit]
probier mal Software anstatt SOFTWARE
[/edit]

[edit2]
ich mach das in C so: ( wie gesagt is mit dateien, is aber eigentlich gleich)
Code:
DWORD dwSizeNeeded=0;
AnsiString filePath=Edit1->Text;
BYTE* pSecDescriptorBuf;
pSecDescriptorBuf = new BYTE[1];
bool bSuccess = GetFileSecurity((filePath.c_str()),DACL_SECURITY_INFORMATION,pSecDescriptorBuf,1,&dwSizeNeeded);


delete pSecDescriptorBuf;
pSecDescriptorBuf = new BYTE[dwSizeNeeded];
bSuccess = GetFileSecurity((const_cast<char*>filePath.c_str()),DACL_SECURITY_INFORMATION,pSecDescriptorBuf,dwSizeNeeded,&dwSizeNeeded);
also erstmal anfragen und schauen wie gross der buffer sein muss und dann nochmal mit der richtigen groesse. vielleciht liegts bei dir da auch dran?

CoRe.eXtreem 7. Nov 2008 10:51

Re: RegGetKeySecurity
 
Hey Volle!

Vielen Dank für deine Hilfe!

Das mit dem DACL ist ein absoluter Müll! Bis ich das mal blicke,....

Das Problem ist, man findet dazu auch fast nichts im Internet oder zumindest nicht genug.

Ich versuche jetzt ganz einfach mal das hier http://www.codeproject.com/KB/dotnet...?display=Print in ASM zu portieren.

So wie es aussieht benötige ich die Größe schon bei der initialisierung vom SECURITY_DESCRIPTOR.

Von den Rechten her ist es kein Thema,... Probiere es hin und wieder mit Systemrechten. Also Vollzugriff auf alles, daran lag es nicht.

Komisches DACL,... :kotz:

Grüßle

Luckie 7. Nov 2008 11:01

Re: RegGetKeySecurity
 
Zitat:

Zitat von Volle
ich hab z.b. ueber die Dacl's versucht rauszufinden ob ich schreibrechte auf ne datei hab. kannste total erden. Ich hab keinen besseren weg als umbennen und bei bedarf wieder zurueck umbennen gefunden.

Nö, man muss es nur richtig machen: http://www.michael-puff.de/Developer...ileAccess.html

@ CoRe.eXtreem: Warum machst du das überhaupt alles mit ASM?

Volle 7. Nov 2008 11:05

Re: RegGetKeySecurity
 
vielleicht hilft dir das weiter:
msdn

bist sicher das dwRevision die grösse sein soll? hoert sich fuer mich nich so an .. das is doch eher ne konstante oder?

@luckie:

bist du sicher dass das auch in ner domain geht, wenn die datei von einem domain user angelegt wurde und ein nicht domain user die rechte abfragen will? Hab grad leider kein delphi da und hab nich so arg lust das sinnloser weise in c++ zu portieren um dann festzustellendass es genauso wenig klappt wie bei mir :P

CoRe.eXtreem 7. Nov 2008 11:11

Re: RegGetKeySecurity
 
Da steht doch

dwRevision [in]

The revision level to assign to the security descriptor. This parameter must be SECURITY_DESCRIPTOR_REVISION.

oder sehe ich das falsch?

Delphi-Quellcode:
    .data
   lpSubKey         db   "SOFTWARE\Classes\.7z\2",0
   phkResult          dd   0

    .data?
   pSecurityDescriptor      SECURITY_DESCRIPTOR <>

    .code
   
start:
   xor   eax,eax

   push   offset phkResult
   push   KEY_ALL_ACCESS
   push   0
   push   offset lpSubKey
   push   HKEY_LOCAL_MACHINE
   call   RegOpenKeyEx


   push   offset pSecurityDescriptor
   call   IsValidSecurityDescriptor

   test   eax,eax               ; EAX 00000000 (Das ist schonmal positiv)
   jnz   @_ExitProcess


   push   SECURITY_DESCRIPTOR_REVISION
   push   offset pSecurityDescriptor
   call   InitializeSecurityDescriptor


   push   sizeof SECURITY_DESCRIPTOR
   push   offset pSecurityDescriptor
   push   DACL_SECURITY_INFORMATION
   push   offset phkResult
   call   RegGetKeySecurity

   push   phkResult
   call   RegCloseKey

   @_ExitProcess:
   push   0
   call   ExitProcess

end start
Muss jetzt erstmal den SecurityDescriptor richtig erstellen bzw. Speicher zuweisen. Ich denke dort liegt der fehler.
Das mit der Domäne kommt später, muss jetzt erst mal den SecurityDescriptor erstellen. Bevor da nicht alle EAX rückgabewerte der API überall auf 0 ist geht es nicht weiter.

CoRe.eXtreem 7. Nov 2008 12:19

Re: RegGetKeySecurity
 
So, jetzt habe ich den code mal überarbeitet.
Ich initialisierte den "SecurityDescriptor" und prüfe diesen zum Schluss mit "IsValidSecurityDescriptor".
EAX gibt mir als wert EAX = 00000001 zurück. Alles super, d.h. der initialisierte SecurityDescriptor ist Gültig.

Kann jedoch mit dem API call "RegGetKeySecurity2 noch immer nicht die DACL in den SecurityDescriptor zurück geben lassen. Zugriffsverletzung. Könnte heulen. :wall:

Habe ich vieleicht irgendwas übersehen? Mir fliegen bald die :shock: raus....


Delphi-Quellcode:
    .data
   lpSubKey         db   "SOFTWARE\Classes\.7z\2",0
   phkResult          dd   0

    .data?
   pSecurityDescriptor      SECURITY_DESCRIPTOR <>
   buffer_addr         dd   ?

    .code
   
start:
   xor   eax,eax
   nop

   nop
   push   offset phkResult
   push   KEY_ALL_ACCESS
   push   0
   push   offset lpSubKey
   push   HKEY_LOCAL_MACHINE
   call   RegOpenKeyEx            ; EAX must zero
   nop

   nop
   xor   eax,eax
   nop

   nop
   push   SECURITY_DESCRIPTOR_MIN_LENGTH
   push   GPTR
   call   GlobalAlloc            ; EAX must nonzero
   nop                  ; EAX = (new object handle)

   nop   
   mov   buffer_addr,eax
   nop

   nop
   xor   eax,eax
   nop

   nop
   push   SECURITY_DESCRIPTOR_REVISION
   push   offset buffer_addr
   call   InitializeSecurityDescriptor      ; EAX must nonzero
   nop

   nop
   xor   eax,eax
   nop

   nop
   push   offset buffer_addr
   call   IsValidSecurityDescriptor      ; EAX must nonzero
   nop                  ; EAX = 00000001

   nop
   xor   eax,eax
   nop

   nop
   push   sizeof buffer_addr
   push   offset buffer_addr
   push   DACL_SECURITY_INFORMATION
   push   offset phkResult
   call   RegGetKeySecurity
   nop

   nop
   push   phkResult
   call   RegCloseKey
   nop

   nop
   push   offset buffer_addr
   call   GlobalFree
   nop

   @_ExitProcess:
   push   0
   call   ExitProcess

end start
Zugriffsverletzung:

Delphi-Quellcode:
EAX 00000004
ECX 00403017 RegAth.00403017
EDX 00000000
EBX 00000000
ESP 0012FF14
EBP 0012FF74
ESI 02000000
EDI 00000000
EIP 761BC7FD advapi32.761BC7FD
C 0  ES 0023 32bit 0(FFFFFFFF)
P 0  CS 001B 32bit 0(FFFFFFFF)
A 0  SS 0023 32bit 0(FFFFFFFF)
Z 0  DS 0023 32bit 0(FFFFFFFF)
S 0  FS 003B 32bit 7FFDE000(FFF)
T 0  GS 0000 NULL
D 0
O 0  LastErr ERROR_SUCCESS (00000000)
EFL 00010202 (NO,NB,NE,A,NS,PO,GE,G)
ST0 empty 0.0
ST1 empty 0.0
ST2 empty 0.0
ST3 empty 0.0
ST4 empty 0.0
ST5 empty 0.0
ST6 empty 0.0
ST7 empty 0.0
               3 2 1 0      E S P U O Z D I
FST 0000  Cond 0 0 0 0  Err 0 0 0 0 0 0 0 0  (GT)
FCW 027F Prec NEAR,53  Mask   1 1 1 1 1 1

Volle 7. Nov 2008 12:31

Re: RegGetKeySecurity
 
wie gesagt, hab kein plan davon :>
um Luckies frage neu aufzugreiffen: warum eigentlich asm ?

CoRe.eXtreem 7. Nov 2008 13:15

Re: RegGetKeySecurity
 
So, sieht gut aus. :cheer:

Jetzt funktioniert es ohne Zugriffsverletzung,...

Jetzt bekomme ich bei dem Api Call "RegGetKeySecurity" nur noch ERROR_ACCESS_DENIED (00000005) zurück.

Sehr seltsam, sogar unter Systemrechten. :coder2:

Warum ich das in ASM mach?
Gibt eigentlich keinen besonderen Grund, ich programmiere einfach gerne in ASM. Wenn ich ehrlich bin kann ich schon gar kein Delphi mehr. ;P

Delphi-Quellcode:
    .data
   lpSubKey         db   "SOFTWARE\Google",0
   phkResult          dd   0

    .data?
   pSecurityDescriptor      SECURITY_DESCRIPTOR <>
   buffer_addr         dd   ?
   buffer_size         dd   ?

    .code
   
start:
   xor   eax,eax
   nop

   nop
   push   offset phkResult
   push   KEY_ALL_ACCESS
   push   0
   push   offset lpSubKey
   push   HKEY_CURRENT_USER
   call   RegOpenKeyEx            ; EAX must zero
   nop

   nop
   xor   eax,eax
   nop

   nop
   push   SECURITY_DESCRIPTOR_MIN_LENGTH
   push   GPTR
   call   GlobalAlloc            ; EAX must nonzero
   nop                  ; EAX = (new object handle)

   nop   
   mov   buffer_addr,eax
   nop

   nop
   xor   eax,eax
   nop

   nop
   push   SECURITY_DESCRIPTOR_REVISION
   push   offset buffer_addr
   call   InitializeSecurityDescriptor      ; EAX must nonzero
   nop

   nop
   xor   eax,eax
   nop

   nop
   push   offset buffer_addr
   call   IsValidSecurityDescriptor      ; EAX must nonzero
   nop                  ; EAX = 00000001

   nop
   xor   eax,eax
   nop

   nop
   mov   eax,sizeof buffer_addr
   mov   buffer_size,eax
   nop

   nop
   xor   eax,eax
   nop

   nop
   push   offset buffer_size
   push   offset buffer_addr
   push   DACL_SECURITY_INFORMATION
   push   offset phkResult
   call   RegGetKeySecurity
   nop

   cmp   eax,ERROR_SUCCESS
   jne   @_Error

   @_CleanUp:

   nop
   push   phkResult
   call   RegCloseKey
   nop

   nop
   push   offset buffer_addr
   call   GlobalFree
   nop

   @_ExitProcess:
   push   0
   call   ExitProcess


   @_Error:

   push   0
   push   0
   push   0
   push   0
   Call   MessageBox

   jmp   @_CleanUp


end start

Volle 7. Nov 2008 13:24

Re: RegGetKeySecurity
 
Zitat:

Zitat von CoRe.eXtreem
So, sieht gut aus. :cheer:
Jetzt bekomme ich bei dem Api Call "RegGetKeySecurity" nur noch ERROR_ACCESS_DENIED (00000005) zurück.

Sehr seltsam, sogar unter Systemrechten. :coder2:
[/delphi]

Das ist genau das problem das ich auch bei den dateien habe.
Kann es sein dass dein XP von einem Domain Admin installiert wurde und du gerade mit nem lokalen Admin Account der nicht in der domain liegt arbeitest?

Genau in dieser konstellation habe ich probleme mit ACCESS_DENIED

CoRe.eXtreem 7. Nov 2008 13:34

Re: RegGetKeySecurity
 
Zitat:

Zitat von Volle
Zitat:

Zitat von CoRe.eXtreem
So, sieht gut aus. :cheer:
Jetzt bekomme ich bei dem Api Call "RegGetKeySecurity" nur noch ERROR_ACCESS_DENIED (00000005) zurück.

Sehr seltsam, sogar unter Systemrechten. :coder2:
[/delphi]

Das ist genau das problem das ich auch bei den dateien habe.
Kann es sein dass dein XP von einem Domain Admin installiert wurde und du gerade mit nem lokalen Admin Account der nicht in der domain liegt arbeitest?

Genau in dieser konstellation habe ich probleme mit ACCESS_DENIED

Wenigstens liegt es jetzt zu 99% nicht mehr an meinem Source-Code. Ok, wenn mir der EAX Register den Wert ERROR_ACCESS_DENIED zurück gibt, dann verweigert das System den Zugriff.

Das witzige ist ja das ich mir Systemrechte erschlichen habe und nicht einmal mit Systemrechten funktioniert es. :roteyes:

Habe Vista und arbeite nicht in einer Domäne.

Habe gerade noch etwas gefunden, vielleicht muss ich noch Privilegien setzen.

Siehe MSDN ganz unten (http://msdn.microsoft.com/en-us/libr...78(VS.85).aspx)

Zitat:

When you call the RegOpenKeyEx function, the system checks the requested access rights against the key's security descriptor. If the user does not have the correct access to the registry key, the open operation fails. If an administrator needs access to the key, the solution is to enable the SE_TAKE_OWNERSHIP_NAME privilege and open the registry key with WRITE_OWNER access. For more information, see Enabling and Disabling Privileges.
Ich denke, dass ist noch das Entscheidende was fehlt.

http://msdn.microsoft.com/en-us/libr...19(VS.85).aspx

Denke nicht das es mit der Domäne zusammenhängt, dass braucht man glaub ich nur wenn man die SID des USERS etc. ermitteln möchte.

:duck:

Greatz

EDIT:

Before enabling any of these potentially dangerous privileges, determine that functions or operations in your code actually require the privileges. :stupid:

EDIT2:

So, das Programm hat nun Debug-Rechte!

http://home.arcor.de/microware/Debug.png

Jetzt kann ich auf den Schlüssel zugreifen,.. aber es kommt jetzt wieder zu einer Zugriffsverletzung.

Bin echt gespannt ob ich das jemals in Griff bekomme. ;(

CoRe.eXtreem 7. Nov 2008 14:40

Re: RegGetKeySecurity
 
Die Zugriffsverletzung ist behoben.

Es lag ganz einfach daran das ich den Schlüssel den ich angegeben habe das hier --> \ vergessen habe.

"SOFTWARE\Google\",0

Wichtig zu wissen ist, wenn man mit dem API call "RegGetSecurity" z.B.: den DACL abfragen möchte, dann muss das Programm entsprechende Rechte besitzen. (siehe MSDN http://msdn.microsoft.com/en-us/libr...78(VS.85).aspx)

Meinem Programm habe ich "SeDebugPrivilege" zugteilt.

@Volle, wenn du das bei dir auch machst, dann klappt es sicherlich auch mit deinem "ACCESS_DENIED" Problem! :angel:

:dp:

Der komplette Source-Code wird in kürze nachgereicht.

Greatz Core

Volle 7. Nov 2008 14:52

Re: RegGetKeySecurity
 
ich werds versuchen, mal schauen was dann geht :P

Volle 7. Nov 2008 15:09

Re: RegGetKeySecurity
 
Also irgendwas laeuft z.Z. total schief

ich hab versucht den Code den Luckie verlinkt hat in C++ zu uebersetzen. Ich bekomme beim aufruf von

AccessCheck() den Errorcode 5 zurueck -> ACCESS_DENIED

Nagut, dann fehlen mir evtl die erwaehnten debug rechte. Den spass eingebaut:

AdjustTokenPrivileges() liefert 5 zurueck -> ACCESS_DENIED

ich weis grad echt nich mehr weiter :P
Eine Frage hab ich da noch: geht das ganze mit eingeschraenkten benutzerrechten ? Im moment bin ich zwar mit Adminrechten angemeldet, aber spaeter sollte das Prog mit eingeschraenkten Rechten laufen -> wenn das ueberhaupt nicht moeglich ist dann brauch ich garnicht weitermachen.

nicodex 7. Nov 2008 15:13

Re: RegGetKeySecurity
 
Zitat:

Zitat von CoRe.eXtreem
Ich versuche jetzt ganz einfach mal das hier http://www.codeproject.com/KB/dotnet...?display=Print in ASM zu portieren.

Schön, nur ergibt das in der Praxis wenig Sinn für HKCU, da der Benutzer dort (neben Administratoren, die den Zugriff ohnehin erzwingen können) als einziger Leserechte hat. Leserechte für den internen (Pseudo-)Account "RESTRICTED" bedeutet nicht, dass jeder Benutzer mit einem eingschränkten Token Zugriff hat - es dient als Filter, um die Rechte zu definieren, die man trotz eines eingschränkten Tokens hat (CreateRestrictedToken).

Kurz: Es stellt sich mir die Frage nach dem Sinn, die Sicherheitsbeschreibung ermitteln zu müssen. In den meisten Fällen kommt man ohne aus. Bleibt also offen, was eigentlich erreicht werden soll...

Edit: Definiere "mit eingeschraenkten Rechten".

CoRe.eXtreem 7. Nov 2008 15:49

Re: RegGetKeySecurity
 
Ich möchte mir ganz einfach ein Programm programmieren das von einem bestehenden Schlüssel die Rechte nimmt und auf einen anderen Schlüssel überträgt, welcher diese Rechte nicht hat.

Warum das ganze?

Bei mir sind ungefähr tausend Registry-Schlüssel in der Registry welche keine Berechtigung mehr haben. Die gesetzten berechtigungen verweisen auf einen nicht vorhandenen Account bzw. SID.

Wenn ich als Administrator auf den Schlüssel zugreifen möchte, also wie du sagst auf meine Schlüssel (siehe Bild) kommt eine Fehlermeldung, "Zugriff verweigert".

http://home.arcor.de/microware/Pic01.png

Zum vergleich, auf den Schlüssel direkt oben drüber besitze ich Zugriffsrechte.

http://home.arcor.de/microware/Pic02.png

Nur mit Systemrechten habe ich Zugriff auf den Schlüssel und kann mir die Berechtigungen anzeigen lassen bzw. diese verwalten.

http://home.arcor.de/microware/pic3.png

Das ganze ist ganz schön zum ko*zen.... Vielleicht verstehst du jetzt was ich vor habe.

http://home.arcor.de/microware/pic04.png

Delphi-Quellcode:
    .data
   ; /// Adjust some privileges for current process
   ; Do not change order
   szSeDebug         db     "SeDebugPrivilege",0
   szAdvApi         db     "advapi32.dll",0
               db     "AdjustTokenPrivileges", 0
               db     "InitializeAcl",0
               db     "LookupPrivilegeValueA",0
               db     "OpenProcessToken",0
               db     "SetSecurityInfo",0,0

   szKernel32         db     "kernel32.dll",0
               db     "RegisterServiceProcess",0,0

   dwAdjustTokenPrivileges      dd     0
   dwInitializeAcl         dd     0
   dwLookupPrivilegeValue      dd     0
   dwOpenProcessToken      dd     0
   dwSetSecurityInfo      dd     0
   dwRegServiceProcess      dd     0
   ; /// Adjust some privileges for current process

   ;lpSubKey         db   "SOFTWARE\Adobe\",0
   lpSubKey         db   "SOFTWARE\Classes\*",0
   lpSubKey_target         db   "SOFTWARE\Classes\.3gp2\",0

   phkResult         dd   0
   phkResult_target      dd   0

    .data?
   pSecurityDescriptor      SECURITY_DESCRIPTOR <>
   buffer_addr         dd   ?
   buffer_size         dd   ?

    .code

; Load dll functions
PayLoadDll proc uses ebx esi edi szLib, dwFuncs: DWORD
        INVOKE LoadLibrary, szLib
        test   eax, eax
        jz     @plg_err

        mov    ebx, eax
        mov    edi, szLib
        mov    esi, dwFuncs
@l:
        cld
        xor    eax, eax
        or     ecx, -1
        repnz scasb              
        cmp    byte ptr[edi], 0
        jz     @e
        INVOKE GetProcAddress, ebx, edi
        .IF    !eax
                ret
        .ENDIF
        mov    dword ptr[esi], eax
        add    esi, 4
        jmp    @l
@e:
        mov    eax, 1
@plg_err:
        ret
PayLoadDll endp

ZeroMemory proc uses edi lpMem, Len: DWORD
        cld
        mov    edi, lpMem
        mov    ecx, Len
        shr    ecx, 2
        xor    eax, eax
        rep stosd
        mov    ecx, Len
        and    ecx, 3
        rep stosb
        ret
ZeroMemory endp

; Adjust some privileges for current process
ProcessStartup proc uses esi edi
        LOCAL  hToken: DWORD
        LOCAL  SeDebugNameValue: QWORD
        LOCAL  tkp: TOKEN_PRIVILEGES
        LOCAL  len: DWORD
        LOCAL  myACL: ACL

        ; Load libraries
        INVOKE PayLoadDll, offset szAdvApi, offset dwAdjustTokenPrivileges
        INVOKE PayLoadDll, offset szKernel32, offset dwRegServiceProcess

        ; Win95/98 only

        ; Hide in taskmanager
        .IF    dwRegServiceProcess
                push   1
                INVOKE GetCurrentProcessId
                push   eax
                call   dwRegServiceProcess
        .ENDIF

        .IF    !dwAdjustTokenPrivileges || !dwInitializeAcl || !dwLookupPrivilegeValue || !dwOpenProcessToken || !dwSetSecurityInfo
                ret
        .ENDIF

        ; WinNT/2k/XP only

        ; Set debug status
        INVOKE ZeroMemory, addr myACL, sizeof ACL
        push   2
        push   sizeof ACL
        lea    eax, myACL
        push   eax
        call   dwInitializeAcl

        INVOKE GetCurrentProcess
        push   eax
        xchg   eax, edx
        push   0
        lea    eax, myACL
        push   eax
        push   0
        push   0
        push   4
        push   6
        push   edx
        call   dwSetSecurityInfo

        ; Adjust debug privilege
        pop    edx
        lea    eax, hToken
        push   eax
        push   TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY
        push   edx
        call   dwOpenProcessToken

        lea    eax, SeDebugNameValue
        push   eax
        push   offset szSeDebug
        push   NULL
        call   dwLookupPrivilegeValue

        lea    esi, SeDebugNameValue
        lea    edi, tkp.Privileges[0].Luid
        mov    ecx, 8
        rep movsb
        mov    tkp.PrivilegeCount, 1
        mov    tkp.Privileges[0].Attributes, SE_PRIVILEGE_ENABLED

        lea    eax, len
        push   eax
        lea    eax, tkp
        push   eax
        push   sizeof TOKEN_PRIVILEGES
        push   eax
        push   FALSE
        push   hToken
        call   dwAdjustTokenPrivileges
        ret
ProcessStartup endp
   
start:

   Call   ProcessStartup

   nop
   xor   eax,eax
   nop

   nop
   push   offset phkResult
   push   KEY_ALL_ACCESS
   push   0
   push   offset lpSubKey
   push   HKEY_LOCAL_MACHINE
   call   RegOpenKeyEx            ; EAX must zero
   nop

   nop
   xor   eax,eax
   nop

   nop
   push   SECURITY_DESCRIPTOR_MIN_LENGTH
   push   GPTR
   call   GlobalAlloc            ; EAX must nonzero
   nop                  ; EAX = (new object handle)

   nop   
   mov   buffer_addr,eax
   nop

   nop
   xor   eax,eax
   nop

   nop
   push   SECURITY_DESCRIPTOR_REVISION
   push   offset buffer_addr
   call   InitializeSecurityDescriptor      ; EAX must nonzero
   nop

   nop
   xor   eax,eax
   nop

   nop
   push   offset buffer_addr
   call   IsValidSecurityDescriptor      ; EAX must nonzero
   nop                  ; EAX = 00000001

   nop
   xor   eax,eax
   nop

   nop
   mov   eax,sizeof buffer_addr
   mov   buffer_size,eax
   nop

   nop
   xor   eax,eax
   nop

   nop
   push   offset buffer_size
   push   offset buffer_addr
   push   DACL_SECURITY_INFORMATION
   push   offset phkResult
   call   RegGetKeySecurity
   nop

   nop
   xor   eax,eax
   nop

   nop
   push   offset buffer_addr
   call   IsValidSecurityDescriptor      ; EAX must nonzero
   nop                  ; EAX = 00000001

   nop
   xor   eax,eax
   nop


   nop
   push   phkResult
   call   RegCloseKey
   nop

   nop
   xor   eax,eax
   nop

   nop
   push   offset phkResult_target
   push   KEY_ALL_ACCESS
   push   0
   push   offset lpSubKey_target
   push   HKEY_LOCAL_MACHINE
   call   RegOpenKeyEx            ; EAX must zero
   nop

   nop
   xor   eax,eax
   nop

   nop
   push   offset buffer_addr
   push   DACL_SECURITY_INFORMATION
   push   offset phkResult_target
   call   RegSetKeySecurity
   nop

   nop
   xor   eax,eax
   nop

COMMENT *

LONG WINAPI RegSetKeySecurity(
  __in HKEY hKey,
  __in SECURITY_INFORMATION SecurityInformation,
  __in PSECURITY_DESCRIPTOR pSecurityDescriptor
);

*

   @_CleanUp:

   nop
   push   phkResult
   call   RegCloseKey
   nop

   nop
   push   offset buffer_addr
   call   GlobalFree
   nop

   @_ExitProcess:
   push   0
   call   ExitProcess


   @_Error:

   push   0
   push   0
   push   0
   push   0
   Call   MessageBox

   jmp   @_CleanUp


end start

Dezipaitor 7. Nov 2008 16:59

Re: RegGetKeySecurity
 
Also mit dem Debugprivileg kannst du hier nichts machen. Das ist einfach für OpenProcess und erlaubt es damit auch Prozesse anderer Sessions mit vollem Zugriffsrechten öffnen zu lassen.

Wenn du die DACL einer Resource ansehen willst, dann muss der Benutzer, der auf die Resource zugreifen will, ...
* in der DACL mit dem Recht READ_CONTROL als positiver Eintrag (ACE) vorkommen oder
* er muss der Besitzer sein (wird automatisch READ_CONTROL und WRITE_DAC zugewiesen).
Will man zudem die DACL ändern, muss man das Recht WRITE_DAC in der DACL zugewiesen bekommen haben.
Man muss also zuerst Besitzer werden, um sich selbst in die DACL eintragen zu können. Dazu gibt es das Privileg SE_TAKE_OWNERSHIP. Damit kann man sich selbst zum Besitzer machen. Das Privileg SE_RESTORE_PRIVILEGE ermöglicht es, einen anderen Benutzer als den eigenen zum Besitzer zu machen (für Backupprogramme).

Der Vorteil mit AccessCheck zu überprüfen, ob und welchen Zugriff auf eine Resource besteht, sind folgende :
* Jeder erstmalige Zugriff auf eine Resource (Datei, RegKey, ...) erzeugt ein Auditlog in der Ereignisanzeige, sofern dies in der SACL (SystemACL) eingestellt wurde. Ein AccessCheck macht das nicht. Dafür gibt es AccessCheckAndAudit
* Mit AccessCheck und der Konstante MAXIMUM_ALLOWED kann man herausfinden, welche höchstmöglichen Rechte auf eine Resource angefordert werden können. Dann bekommt man z.B. sowas wie FILE_READ, KEY_ALL_ACCESS usw. ohne Ausprobieren heraus.


PS.
Das ganze Unterfangen wäre mit Delphi und der JWSCL in kürzester Zeit erledigt.

Volle 10. Nov 2008 07:41

Re: RegGetKeySecurity
 
Hoi,

ich muss das nochmal aufgreifen.
Ich denke ein neuer thread is dafuer ncih erforderlich weil es sich ja eigentlich um das gleiche thema handelt.

Also ich versuch gerade nico's CheckFileAccess in C++ hinzubekommen. Ich schaff mit dem BDS, von daher kann es sein dass ich auch ein paar Delphi/Borland funktionen verwende die nich so ganz C++ standard sind.

hier mal mein code:

Code:
int CheckAccess(DWORD DesiredAccess,AnsiString FileName)
{
// Var Decl.
DWORD dwSizeNeeded=0;
PSECURITY_DESCRIPTOR pSecDescriptorBuf;
HANDLE ClientToken=NULL;
DWORD AccessMask;
GENERIC_MAPPING GenericFileMapping= { FILE_GENERIC_READ,FILE_GENERIC_WRITE,FILE_GENERIC_EXECUTE,FILE_ALL_ACCESS};

PRIVILEGE_SET PrivilegeSet;
DWORD PrivilegeSetLength;
DWORD GrantedAccess;
BOOL AccessStatus;
bool result;

// Get needed size
pSecDescriptorBuf = new BYTE[1];
DWORD LastError=GetLastError();
GetFileSecurity(FileName.c_str(),
                 DACL_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
                 pSecDescriptorBuf,
                 1,
                 &dwSizeNeeded);
SetLastError(LastError);
delete[] pSecDescriptorBuf;
// Get Security_Descriptor
pSecDescriptorBuf = new BYTE[dwSizeNeeded];
if(!GetFileSecurity(FileName.c_str(),
                    DACL_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
                    pSecDescriptorBuf,
                    dwSizeNeeded,
                    &dwSizeNeeded))
{
   delete[] pSecDescriptorBuf;
   return -1;
}
if (!ImpersonateSelf(SecurityImpersonation))
{
   delete[] pSecDescriptorBuf;
   return -2;
}
if (!OpenThreadToken(GetCurrentThread(),
                     TOKEN_QUERY | TOKEN_IMPERSONATE | TOKEN_DUPLICATE |TOKEN_ADJUST_PRIVILEGES,
                     False,
                     &ClientToken))
{
   RevertToSelf();
   delete[] pSecDescriptorBuf;
   return -3;
}

// Get debug priv.
// SE_DEBUG_NAME  / SeDebugPrivilege
TOKEN_PRIVILEGES tp;
LUID luid;
if (!LookupPrivilegeValue(NULL,"SeDebugPrivilege",&luid))
{
   RevertToSelf();
   delete[] pSecDescriptorBuf;
   return -4;
}
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if ( !AdjustTokenPrivileges(
       ClientToken,
       FALSE,
       &tp,
       sizeof(TOKEN_PRIVILEGES),
       (PTOKEN_PRIVILEGES) NULL,
       (PDWORD) NULL) )
{
   RevertToSelf();
   delete[] pSecDescriptorBuf;
   return -5;
}



AccessMask=DesiredAccess;
MapGenericMask(&AccessMask,&GenericFileMapping);

PrivilegeSetLength = sizeof(PRIVILEGE_SET);

if (!AccessCheck(pSecDescriptorBuf,
                 ClientToken,
                 AccessMask,
                 &GenericFileMapping,
                 &PrivilegeSet,
                 &PrivilegeSetLength,
                 &GrantedAccess,
                 &AccessStatus))
{
   CloseHandle(ClientToken);
   RevertToSelf();
   delete[] pSecDescriptorBuf;
   return -6;
}


// Clean up

result=AccessStatus;
CloseHandle(ClientToken);
RevertToSelf();
delete[] pSecDescriptorBuf;

if (result)
   return 1;
else
   return 0;
}
ich bekomme bei AcessCheck() den Fehler 1338 zurueck, das bedeutet so viel wie "The security descriptor structure is invalid."
ich hab nur keine ahnung woran das liegen koennte, ich hab mich ziemlich genau an nico's Beispiel gehalten. Bitte nich meckern dass ich irgendwo vielleicht vergessen habe den speicher wieder freizugeben, ich will das teil erstmal zum laufen bekommen bevor ich mich um 'sauberen' code bemuehe. :>

Wenn jemand nen einfall hat dann bitte melden :>

[edit]
Hier mal die Links zu den verwendeten Seiten der MSDN
AdjustTokenPrivileges
ImpersonateSelf
OpenThreadToken
LookupPrivilegeValue
AdjustTokenPrivileges
MapGenericMask
AccessCheck

@Dezipaitor
Ich habd as mit den Debug rechten noch nicht aus dem Code entfernt, da es keinerlei auswirkung hat.
[/edit]

cYa

Dezipaitor 10. Nov 2008 16:38

Re: RegGetKeySecurity
 
AccessCheck erfordert im SD
* Owner
* Group
* DACL

Du hast aber in GetFileSecurity 2x DACL_SECURITY_INFORMATION.

@debug rechte:
Debugrecht setzen bring nur etwas für die WinAPI Fkt. OpenProcess

Volle 10. Nov 2008 17:00

Re: RegGetKeySecurity
 
omfg

ey wenn es daran liegt dann .....
danke ... hab wohl den wald vor lauter baeumen nichtmehr gesehen.

wegen debugrechten: jop das hast weiter oben schon geschrieben, ich wollte nur drauf hinweisen dass ich den code noch nicht rausgenommen hatte als ich den quellcode gepostet hab. nur damit du nich drauf ansprichst, der schuss ging wohl aber eher nach hinten los.

Werds morgen mal ausprobieren.
danke schonmal

mfg

Volle 11. Nov 2008 06:27

Re: RegGetKeySecurity
 
Es lag daran, nun geht es.

Vielen Dank nochma an alle die geholfen haben, das hat mir ne menge Arbeit abgenommen.

mfg
Volle


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:30 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz