Understanding security

>> Sunday, October 18, 2009



- When users log in, they receive access token. An access token contains the users'ID, the users'groups, and the users's privileges according to the groups.
- Each object has a security descriptor, which acts as its lock. A security descriptor contains an owner and group identifier, a System ACL and a Discretionary ACL.
- A DACL controls who is allowed to do what to the object.
- A SACL controls who is audited for doing what to the object.
- ACLs consist of ACEs. Each ACE contains a SID, which identifies the user or group, an access mask, which determines the actions allowed to the user or group, and an ACE header, which determines the type of ACE.

First sample code: A simple security program (without any error checking) that creates a file that only the user "guest" can read. This code will not work unless you have formatted your hard disk with the NT File System

#include "windows.h"
#include "iostream"
using namespace std;

SECURITY_ATTRIBUTES sa;
SECURITY_DESCRIPTOR sd;
BYTE aclBuffer[1024];
PACL pacl = (PACL) &aclBuffer;
BYTE sidBuffer[100];
PSID psid = (PSID) &sidBuffer;
DWORD sidBufferSize = 100;
char domainBuffer[80];
DWORD domainBufferSize = 80;
SID_NAME_USE snu;
HANDLE file;

void main(void)
{
InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
InitializeAcl(pacl, 1024, ACL_REVISION);
LookupAccountName(0, "guest", psid, &sidBufferSize, domainBuffer,
&domainBufferSize, &snu);
AddAccessAllowedAce(pacl, ACL_REVISION, GENERIC_READ, psid);
SetSecurityDescriptorDacl(&sd, TRUE, pacl, FALSE);

sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = FALSE;
sa.lpSecurityDescriptor = &sd;

file = CreateFile("c:\\testfile", GENERIC_READ | GENERIC_WRITE, 0, &sa,
CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0);
CloseHandle(file);
}

Understand the code:
+ The creation of a security descriptor starts with a call to theInitialize SecurityDescriptor function


BOOL InitializeSecurityDescriptor(
PSECURITY_DESCRIPTOR psd,
DWORD revision)
where psd - a pointer to the security descriptor
and revision - revision level, must be SECURITY_DESCRIPTOR_REVISION

The new security descriptor initially contains no information besides the revision level: no owner identifier, no group identifier, no SACL, and no DACL.
+ The next line calls InitializeAcl to create the ACL that will become the DACL for the security descriptor.


BOOL InitializeAcl(
PACL pacl,
DWORD bufferLen,
DWORD revision)

where
pacl - a pointer to an ACL
bufferLen - the length of the ACL buffer supplied
revision - revision level, must be ACL_REVISION

When the InitializeAcl function returns, pacl points to an empty ACL. That is, the ACL contains no ACEs. If you were to comment out the next two lines so that this empty ACL was placed into the security descriptor, and that security descriptor was then applied to the file, no one would be able to access the file.
+ The LookupAccountName function returns a SID for the specified account name.


BOOL LookupAccountName(
LPCTSTR system,
LPCTSTR accountName,
PSID psid,
LPDWORD sidBufferSize,
LPTSTR domainName,
LPDWORD domainNameLen,
PSID_NAME_USE psnu)

where
system - name of a remote system, or 0 for local
accountName - the name of the account to look up
psid - a pointer to a buffer for the returned SID
sidBufferSize - the size of the psid buffer
domainName - a pointer to a buffer for the returned domain name
domainNameLen - size of the domain name buffer
psnu - returned enumerated type indicating the type of account

The function returns a SID for the account, the domain where it was found if the SID came from a domain controller, and an enumerated value that indicates the type of account:


SidTypeUser
SidTypeGroup
SidTypeDomain
SidTypeAlias
SidTypeWellKnownGroup
SidTypeDeletedAccount
SidTypeInvalid
SidTypeUnknown

A SID is asecurity identifier. It uniquely identifies a user or a group to the system.

+ The SID returned by the LookupAccountName function is used in a call to the AddAccessAllowedAce function to create an access-allowed (as opposed to access-denied) ACE and add it to the currently-empty ACL.


BOOL AddAccessAllowedAce(
PACL pacl,
DWORD revision,
DWORD accessMask,
PSID psid)

where
pacl - a pointer to an ACL
revision - revision level. Must be ACL_REVISION
accessMask - access mask bits
Psid - A SID

+ Now we has an ACL containing one ACE that specifies that the user "guest" should have read access. This ACL needs to be placed into the Discretionary ACL of the security descriptor using the Set SecurityDescriptorDacl function.


BOOL SetSecurityDescriptorDacl(
PSECURITY_DESCRIPTOR psd,
BOOL daclPresent,
PACL pacl,
BOOL daclDefaulted)

where
psd - a pointer to a security descriptor
daclPresent - a boolean that if TRUE says pacl contains an ACL. If it is FALSE, the function ignores anything in pacl and sets the DACL in the security descriptor to NULL
pacl - a pointer to the ACL to add
daclDefaulted - a boolean indicating the source of the DACL


0 comments: