{"id":274,"date":"2021-08-05T21:25:57","date_gmt":"2021-08-05T19:25:57","guid":{"rendered":"https:\/\/theredwindows.net\/?p=274"},"modified":"2021-08-06T20:43:44","modified_gmt":"2021-08-06T18:43:44","slug":"modele-de-securite-windows","status":"publish","type":"post","link":"https:\/\/theredwindows.net\/index.php\/2021\/08\/05\/modele-de-securite-windows\/","title":{"rendered":"Mod\u00e8le de s\u00e9curit\u00e9 Windows"},"content":{"rendered":"\n<p>Cet article se veut \u00eatre le prolongement de mon premier sur ilearned, un blog communautaire. Dans celui-ci j\u2019abordais dans les grandes lignes le fonctionnement du mod\u00e8le s\u00e9curit\u00e9 de Windows (je ne voulais rentrer autant en profondeur pour que l&#8217;article soit compr\u00e9hensible de vraiment tout le monde m\u00eame les plus linuxiens). Ici, je vais apporter une vision plus technique et plus profonde sur certains passages.<\/p>\n\n\n\n<p>Durant tout l\u2019article, chaque valeur (que ce soit un droit ou une structure relative au descripteur de s\u00e9curit\u00e9) sera indiqu\u00e9e sous son format alphanum\u00e9rique, et SDDL (pour ceux ne sachant pas ce qu\u2019est SDDL, ne soyez pas effrayez&nbsp;!).<\/p>\n\n\n\n<h2>SecurableObject<\/h2>\n\n\n\n<p>Je souhaite ici introduire plus de d\u00e9tail sur le <code>SecurityDescriptor<\/code> dont la structure est la suivante:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">typedef struct _SECURITY_DESCRIPTOR {\n  BYTE                        Revision;\n  BYTE                        Sbz1;\n  SECURITY_DESCRIPTOR_CONTROL Control;\n  PSID                        Owner;\n  PSID                        Group;\n  PACL                        Sacl;\n  PACL                        Dacl;\n} SECURITY_DESCRIPTOR, *PISECURITY_DESCRIPTOR;<\/pre>\n\n\n\n<p>Ils sont donc compos\u00e9s de plusieurs choses: le SID du propri\u00e9taire de l\u2019objet (<code>O:<\/code>), ainsi que le SID du groupe propri\u00e9taire de l\u2019objet (<code>G:<\/code>); une <code>System Access Control List<\/code> (SACL, <code>S:<\/code>) qui permet de garder une trace des objets qui ont acc\u00e9d\u00e9 au propri\u00e9taire du <code>SecurityDescriptor<\/code>, nous ne nous y int\u00e9resserons pas; une <code>Discretionary Access Control List<\/code> (DACL, <code>D:<\/code>). Les descripteurs de s\u00e9curit\u00e9 sont usuellement au format SDDL (Security Descriptor Definition Langage) bien que peu reluisant, il est en r\u00e9alit\u00e9 tr\u00e8s pratique car simple d\u2019utilisation (non pas de compr\u00e9hension). L\u2019acc\u00e8s \u00e0 chaque objet est donc d\u00e9finit gr\u00e2ce \u00e0 cette structure.<\/p>\n\n\n\n<h2>Token d\u2019acc\u00e8s<\/h2>\n\n\n\n<p>Le token d\u2019acc\u00e8s contient pr\u00e9cis\u00e9ment le SID de l\u2019utilisateur, le SID de son groupe, des privil\u00e8ges d\u2019acc\u00e8s (nous y reviendrons plus tard), un SID pour la session, une DACL par d\u00e9faut (utilis\u00e9e lorsqu\u2019il cr\u00e9er un objet). Il y a de plus certain nombre de statistiques, le type d\u2019Access Token, une liste \u00e9ventuel qui restreint les SIDs auxquels nous pouvons acc\u00e9der et le niveau &#8220;d\u2019impersonnation&#8221;, la source du token. Ces informations sont pr\u00e9sente sous forme de structure:<\/p>\n\n\n\n<p>La DACL par d\u00e9faut:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">typedef struct _TOKEN_DEFAULT_DACL {\n  PACL DefaultDacl;\n} TOKEN_DEFAULT_DACL, *PTOKEN_DEFAULT_DACL;<\/pre>\n\n\n\n<p>Les groupes d\u2019appartenance:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">typedef struct _TOKEN_GROUPS {\n  DWORD              GroupCount;\n#if ...\n  SID_AND_ATTRIBUTES *Groups[];\n#else\n  SID_AND_ATTRIBUTES Groups[ANYSIZE_ARRAY];\n#endif\n} TOKEN_GROUPS, *PTOKEN_GROUPS;<\/pre>\n\n\n\n<p>Le possesseur du token:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">typedef struct _TOKEN_OWNER {\n  PSID Owner;\n} TOKEN_OWNER, *PTOKEN_OWNER;<\/pre>\n\n\n\n<p>Le groupe primaire:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">typedef struct _TOKEN_PRIMARY_GROUP {\n  PSID PrimaryGroup;\n} TOKEN_PRIMARY_GROUP, *PTOKEN_PRIMARY_GROUP;<\/pre>\n\n\n\n<p>La liste des privil\u00e8ges:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">typedef struct _TOKEN_PRIVILEGES {\n  DWORD               PrivilegeCount;\n  LUID_AND_ATTRIBUTES Privileges[ANYSIZE_ARRAY];\n} TOKEN_PRIVILEGES, *PTOKEN_PRIVILEGES;<\/pre>\n\n\n\n<p>etc. Vous pouvez trouver toutes ces structures (et celles que je n&#8217;ai cit\u00e9) \u00e0 cette page <a href=\"https:\/\/docs.microsoft.com\/en-us\/windows\/win32\/secauthz\/access-tokens\">https:\/\/docs.microsoft.com\/en-us\/windows\/win32\/secauthz\/access-tokens<\/a>. Il existe 2 types de token, ceux dit primaires, c\u2019est \u00e0 dire cr\u00e9\u00e9s par le kernel de windows, et ceux &#8220;usurp\u00e9s&#8221;, c\u2019est \u00e0 dire cr\u00e9\u00e9s par un utilisateur poss\u00e9dant un privil\u00e8ge le permettant. Le token d\u2019acc\u00e8s est alors gard\u00e9 dans un processus un peu particulier appel\u00e9 <code>LSASS.exe<\/code> pour &#8220;Local Security Autority SubSystem Service&#8221;. Ce dernier est donc vital et tr\u00e8s sensible. Lorsqu\u2019un utilisateur se connecte il fournit ses informations de connexion dans le processus <code>Winlogon.exe<\/code> qui se chargera de l&#8217;authentification et la cr\u00e9ation du token. Pour cela il fait appel \u00e0 la fonction <code data-enlighter-language=\"cpp\" class=\"EnlighterJSRAW\">LsaLogonUser()<\/code> pour obtenir un token d\u2019acc\u00e8s, et ce dernier sera r\u00e9utilis\u00e9 par la suite. Attention, contrairement \u00e0 ce que j\u2019ai pu peut-\u00eatre faire comprendre, le condensat du mot de passe n\u2019est pas contenu dans le token d\u2019acc\u00e8s&nbsp;!<\/p>\n\n\n\n<p>Lorsque l\u2019on cr\u00e9er un nouveau processus (\u00e0 l\u2019aide de la fonction <code data-enlighter-language=\"cpp\" class=\"EnlighterJSRAW\">CreateProcess()<\/code> par exemple) c\u2019est un token h\u00e9rit\u00e9 de l\u2019utilisateur qui est utilis\u00e9. Pour utiliser un autre token d\u2019acc\u00e8s il faudra appeler plut\u00f4t <code data-enlighter-language=\"cpp\" class=\"EnlighterJSRAW\">CreateProcessWithToken()<\/code>. Cependant, ce genre de fonction n\u00e9cessite un certain nombre de privil\u00e8ges dans le token d\u2019acc\u00e8s du programme qui utilise l&#8217;une de ces derni\u00e8res.<\/p>\n\n\n\n<h2>Privil\u00e8ges d\u2019acc\u00e8s<\/h2>\n\n\n\n<p>Pour information, il existe un autre nom pour les privil\u00e8ges que l\u2019on peut retrouver dans <code>winnt.h<\/code>:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">#define SE_CREATE_TOKEN_NAME\t\tTEXT(\"SeCreateTokenPrivilege\")\n#define SE_ASSIGNPRIMARYTOKEN_NAME\tTEXT(\"SeAssignPrimaryTokenPrivilege\")\n#define SE_LOCK_MEMORY_NAME\t\tTEXT(\"SeLockMemoryPrivilege\")\n#define SE_INCREASE_QUOTA_NAME\t\tTEXT(\"SeIncreaseQuotaPrivilege\")\n#define SE_UNSOLICITED_INPUT_NAME\tTEXT(\"SeUnsolicitedInputPrivilege\")\n#define SE_MACHINE_ACCOUNT_NAME \tTEXT(\"SeMachineAccountPrivilege\")\n#define SE_TCB_NAME\t\t\tTEXT(\"SeTcbPrivilege\")\n#define SE_SECURITY_NAME\t\tTEXT(\"SeSecurityPrivilege\")\n#define SE_TAKE_OWNERSHIP_NAME\t\tTEXT(\"SeTakeOwnershipPrivilege\")\n#define SE_LOAD_DRIVER_NAME\t\tTEXT(\"SeLoadDriverPrivilege\")\n#define SE_SYSTEM_PROFILE_NAME\t\tTEXT(\"SeSystemProfilePrivilege\")\n#define SE_SYSTEMTIME_NAME\t\tTEXT(\"SeSystemtimePrivilege\")\n#define SE_PROF_SINGLE_PROCESS_NAME\tTEXT(\"SeProfileSingleProcessPrivilege\")\n#define SE_INC_BASE_PRIORITY_NAME\tTEXT(\"SeIncreaseBasePriorityPrivilege\")\n#define SE_CREATE_PAGEFILE_NAME \tTEXT(\"SeCreatePagefilePrivilege\")\n#define SE_CREATE_PERMANENT_NAME\tTEXT(\"SeCreatePermanentPrivilege\")\n#define SE_BACKUP_NAME \t\t\tTEXT(\"SeBackupPrivilege\")\n#define SE_RESTORE_NAME\t\t\tTEXT(\"SeRestorePrivilege\")\n#define SE_SHUTDOWN_NAME\t\tTEXT(\"SeShutdownPrivilege\")\n#define SE_DEBUG_NAME\t\t\tTEXT(\"SeDebugPrivilege\")\n#define SE_AUDIT_NAME\t\t\tTEXT(\"SeAuditPrivilege\")\n#define SE_SYSTEM_ENVIRONMENT_NAME\tTEXT(\"SeSystemEnvironmentPrivilege\")\n#define SE_CHANGE_NOTIFY_NAME\t\tTEXT(\"SeChangeNotifyPrivilege\")\n#define SE_REMOTE_SHUTDOWN_NAME\t\tTEXT(\"SeRemoteShutdownPrivilege\")\n#define SE_UNDOCK_NAME                  TEXT(\"SeUndockPrivilege\")\n#define SE_ENABLE_DELEGATION_NAME       TEXT(\"SeEnableDelegationPrivilege\")\n#define SE_MANAGE_VOLUME_NAME           TEXT(\"SeManageVolumePrivilege\")\n#define SE_IMPERSONATE_NAME             TEXT(\"SeImpersonatePrivilege\")\n#define SE_CREATE_GLOBAL_NAME           TEXT(\"SeCreateGlobalPrivilege\")<\/pre>\n\n\n\n<p>Pour savoir o\u00f9 sont pr\u00e9cis\u00e9ment renseign\u00e9s les privil\u00e8ges d\u2019acc\u00e8s, il faut \u00e9tudier plus en profondeur la structure <code>_TOKEN_PRIVILEGES<\/code>. Le second objet de la structure est une liste de <code>LUID_AND_ATTRIBUTES<\/code> qui est une structure dont voici la d\u00e9finition:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">typedef struct _LUID_AND_ATTRIBUTES {\n  LUID  Luid;\n  DWORD Attributes;\n} LUID_AND_ATTRIBUTES, *PLUID_AND_ATTRIBUTES;<\/pre>\n\n\n\n<p>Le champ <code>Attributes<\/code> nous renseigne sur l\u2019activation o\u00f9 nom du <code>LUID<\/code>. Le <code>LUID<\/code> est une structure qui d\u00e9finit le privil\u00e8ge en question:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">typedef struct _LUID {\n  DWORD LowPart;\n  LONG  HighPart;\n} LUID, *PLUID;<\/pre>\n\n\n\n<p>Pour obtenir un <code>LUID<\/code> en accord avec un droit pr\u00e9cis, on utilise la fonction <code data-enlighter-language=\"cpp\" class=\"EnlighterJSRAW\">LookupPrivilegeValueA()<\/code> (un article arrive bient\u00f4t sur la manipulation des tokens d\u2019acc\u00e8s en C++).<\/p>\n\n\n\n<h2>Les listes d\u2019acc\u00e8s<\/h2>\n\n\n\n<p>Comme je l\u2019ai dis, qu\u2019importe le type d\u2019ACL, elles porteront un header commun que voici:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">typedef struct _ACL {\n  BYTE AclRevision;\n  BYTE Sbz1;\n  WORD AclSize;\n  WORD AceCount;\n  WORD Sbz2;\n} ACL;<\/pre>\n\n\n\n<p>o\u00f9 <code>AceCount<\/code> est le nombre d\u2019ACE, <code>AclSize<\/code> la taille de l\u2019ACL (qui est au maximum de 64 kb), <code>Sbz1\/Sbz2<\/code> un compl\u00e9ment permettant d\u2019aligner les \u00e9l\u00e9ments de l\u2019en-t\u00eate. On peut ais\u00e9ment en d\u00e9duire qu\u2019elle contient une liste d\u2019ACE. Pour d\u00e9finir une DACL il faut utiliser le SDDL lors de la cr\u00e9ation du <code>SecurityDescriptor<\/code> avec la partie <code>D:<\/code> dans laquelle les diff\u00e9rentes ACEs sont renseign\u00e9es.<\/p>\n\n\n\n<p>Les <code>Access Control Entry<\/code> sont les \u00e9l\u00e9ments individuels d\u2019une ACL qui permettent de d\u00e9finir les acc\u00e8s. Il existe deux types d\u2019ACE diff\u00e9rentes: g\u00e9n\u00e9riques et objets. Dans le premier cas, elles sont utilis\u00e9es pour d\u00e9crire les permissions sur les fichiers notamment:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">typedef struct _ACE_HEADER {\n  BYTE AceType;\n  BYTE AceFlags;\n  WORD AceSize;\n} ACE_HEADER;<\/pre>\n\n\n\n<p>O\u00f9 <code>AceType<\/code> d\u00e9signe comme son nom l\u2019indique le type d\u2019ACE, les principales \u00e9tant <code>ACCESS_ALLOWED <\/code>(<code>A<\/code>, en SDDL), <code>ACCESS_DENIED <\/code>(<code>D<\/code>, en SDDL). <code>AceSize<\/code> indique la taille de l\u2019ACE, <code>AceFlags<\/code> contr\u00f4le l&#8217;h\u00e9ritage du droit accord\u00e9 par l\u2019ACE. On retrouve <code>CONTAINER_INHERIT_ACE<\/code> (<code>CI<\/code>) qui signifie que l\u2019acc\u00e8s est accord\u00e9 dans tous les objets enfants (que peuvent \u00eatre les dossiers et fichiers, les groupes etc), <code>INHERIT_ONLY_ACE<\/code> (<code>IO<\/code>) est dans la continuit\u00e9 du pr\u00e9c\u00e9dent puisqu\u2019il indique que l\u2019acc\u00e8s conf\u00e9r\u00e9 est le m\u00eame que celui du parent (on peut donc remonter comme ceci jusqu\u2019\u00e0 l\u2019ACE <code>CONTAINER_INHERIT_ACE<\/code>), <code>INHERITED_ACE<\/code> (<code>ID<\/code>) indique que l\u2019ACE, a \u00e9t\u00e9 h\u00e9riter. La structure d\u2019une ACE est d\u00e9finie en fonction du type d\u2019acc\u00e8s, il existe logiquement&nbsp; <code>ACESS_DENIED<\/code> et <code>ACCESS_ALLOWED<\/code>:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">typedef struct _ACCESS_ALLOWED_ACE {\n  ACE_HEADER  Header;\n  ACCESS_MASK Mask;\n  DWORD       SidStart;\n} ACCESS_ALLOWED_ACE;\n\ntypedef struct _ACCESS_DENIED_ACE {\n  ACE_HEADER  Header;\n  ACCESS_MASK Mask;\n  DWORD       SidStart;\n} ACCESS_DENIED_ACE;<\/pre>\n\n\n\n<p>O\u00f9 <code>ACE_HEADER<\/code> est la structure vue pr\u00e9c\u00e9demment, <code>ACCESS_MASK<\/code> est une structure permettant de d\u00e9finir le type d\u2019acc\u00e8s accord\u00e9. <code>SidStart<\/code> est le Security Identifier (SID) de l\u2019objet auquel on conf\u00e8re l\u2019acc\u00e8s qui peut \u00eatre pr\u00e9sent\u00e9 en tant que &#8220;well known identifier&#8221; (i.e <code>AN<\/code>=Anonymous, <code>BA<\/code>=Builtin Administrators, <code>BU<\/code>=Builtin Users, <code>DA<\/code>=Domain Administrators &#8230;), ce dernier est d\u00e9nomm\u00e9 &#8220;trustee&#8221;. En SDDL on d\u00e9clare une ACE avec des parenth\u00e8ses et est structur\u00e9e comme ceci (<code>ace_type;ace_flags;rights;object_guid;inherit_object_guid;account_sid;resource_attribute<\/code>) lorsqu\u2019une information n\u2019est pas pr\u00e9cis\u00e9 il faut toujours garder les points virgules; si on souhaite ajouter plusieurs ACEs il suffit d\u2019ajouter plusieurs structures \u00e0 la suite.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img loading=\"lazy\" width=\"289\" height=\"144\" src=\"http:\/\/theredwindows.net\/wp-content\/uploads\/2021\/02\/ACEGenerique.png\" alt=\"\" class=\"wp-image-132\"\/><figcaption>Vision sch\u00e9matique d&#8217;une ACE<\/figcaption><\/figure><\/div>\n\n\n\n<p>Le masque d\u2019acc\u00e8s est essentiel pour comprendre le syst\u00e8me de permission, car c\u2019est lui qui contient les droits accord\u00e9s. Il poss\u00e8de la structure suivante:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">typedef DWORD ACCESS_MASK; \ntypedef ACCESS_MASK* PACCESS_MASK; <\/pre>\n\n\n\n<p>Il contient une unique valeur de type <code>DWORD<\/code> qui repr\u00e9sente l\u2019ensemble des droits. Ces derniers peuvent \u00eatre des droits standard qui sont issues du fichier <code>winnt.h<\/code> et sont originellement d\u00e9finis comme ceci:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">#define DELETE                           (0x00010000L)\n#define READ_CONTROL                     (0x00020000L)\n#define WRITE_DAC                        (0x00040000L)\n#define WRITE_OWNER                      (0x00080000L)\n#define SYNCHRONIZE                      (0x00100000L)\n\n#define STANDARD_RIGHTS_REQUIRED         (0x000F0000L)\n\n#define STANDARD_RIGHTS_READ             (READ_CONTROL)\n#define STANDARD_RIGHTS_WRITE            (READ_CONTROL)\n#define STANDARD_RIGHTS_EXECUTE          (READ_CONTROL)\n\n#define STANDARD_RIGHTS_ALL              (0x001F0000L)\n\n#define SPECIFIC_RIGHTS_ALL              (0x0000FFFFL)<\/pre>\n\n\n\n<p>Ces droits standards permettent alors de construire ce que l\u2019on appelle les droits g\u00e9n\u00e9riques. Une mani\u00e8re d\u00e9finir ces droits pour un objet est d\u2019utiliser la structure <code>_GENERIC_MAPPING<\/code> (qui explique pourquoi, parfois <code>GENERIC_ALL<\/code> n&#8217;est pas la combinaison des autres acc\u00e8s):<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">typedef struct _GENERIC_MAPPING {\n  ACCESS_MASK GenericRead;\n  ACCESS_MASK GenericWrite;\n  ACCESS_MASK GenericExecute;\n  ACCESS_MASK GenericAll;\n} GENERIC_MAPPING;<\/pre>\n\n\n\n<p>Cependant, ils sont \u00e9galement d\u00e9finit de mani\u00e8re g\u00e9n\u00e9rale dans <code>winnt.h<\/code>:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">#define GENERIC_READ               0x80000000\n#define GENERIC_WRITE              0x40000000\n#define GENERIC_EXECUTE            0x20000000\n#define GENERIC_ALL                0x10000000<\/pre>\n\n\n\n<p>Pour que ces droits soient effectifs, nous devons les lier \u00e0 des droits sp\u00e9cifique d\u2019objet, propre donc \u00e0 chaque objet. Ainsi pour un fichier, ou pour un processus, ce ne seront pas les m\u00eames. Pour les fichiers par exemple:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">#define FILE_READ_DATA            0x0001    \/* file &amp; pipe *\/\n#define FILE_LIST_DIRECTORY       0x0001    \/* directory *\/\n#define FILE_WRITE_DATA           0x0002    \/* file &amp; pipe *\/\n#define FILE_ADD_FILE             0x0002    \/* directory *\/\n#define FILE_APPEND_DATA          0x0004    \/* file *\/\n#define FILE_ADD_SUBDIRECTORY     0x0004    \/* directory *\/\n#define FILE_CREATE_PIPE_INSTANCE 0x0004    \/* named pipe *\/\n#define FILE_READ_EA              0x0008    \/* file &amp; directory *\/\n#define FILE_READ_PROPERTIES      FILE_READ_EA\n#define FILE_WRITE_EA             0x0010    \/* file &amp; directory *\/\n#define FILE_WRITE_PROPERTIES     FILE_WRITE_EA\n#define FILE_EXECUTE              0x0020    \/* file *\/\n#define FILE_TRAVERSE             0x0020    \/* directory *\/\n#define FILE_DELETE_CHILD         0x0040    \/* directory *\/\n#define FILE_READ_ATTRIBUTES      0x0080    \/* all *\/\n#define FILE_WRITE_ATTRIBUTES     0x0100    \/* all *\/\n#define FILE_ALL_ACCESS           (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x1ff)\n\n#define FILE_GENERIC_READ         (STANDARD_RIGHTS_READ | FILE_READ_DATA | FILE_READ_ATTRIBUTES | FILE_READ_EA | SYNCHRONIZE)\n#define FILE_GENERIC_WRITE        (STANDARD_RIGHTS_WRITE | FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | FILE_APPEND_DATA | SYNCHRONIZE)\n#define FILE_GENERIC_EXECUTE      (STANDARD_RIGHTS_EXECUTE | FILE_EXECUTE | FILE_READ_ATTRIBUTES | SYNCHRONIZE)<\/pre>\n\n\n\n<p>Pour les processus:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">#define PROCESS_TERMINATE          0x0001\n#define PROCESS_CREATE_THREAD      0x0002\n#define PROCESS_VM_OPERATION       0x0008\n#define PROCESS_VM_READ            0x0010\n#define PROCESS_VM_WRITE           0x0020\n#define PROCESS_DUP_HANDLE         0x0040\n#define PROCESS_CREATE_PROCESS     0x0080\n#define PROCESS_SET_QUOTA          0x0100\n#define PROCESS_SET_INFORMATION    0x0200\n#define PROCESS_QUERY_INFORMATION  0x0400\n#define PROCESS_SUSPEND_RESUME     0x0800\n#define PROCESS_QUERY_LIMITED_INFORMATION 0x1000\n#define PROCESS_ALL_ACCESS         (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0xfff)<\/pre>\n\n\n\n<p>Lors de la cr\u00e9ation d\u2019un masque d\u2019acc\u00e8s, ces valeurs sont combin\u00e9es dans la structure. Lorsqu\u2019un programme souhaite acc\u00e9der \u00e0 un objet, il doit pr\u00e9ciser les droits qu&#8217;il utilisera, plus exactement, il doit pr\u00e9ciser un masque d\u2019acc\u00e8s avec les droits qu\u2019il voudra obtenir sur l&#8217;objet (le processus d&#8217;acc\u00e8s lui verra ou non accorder ce qu&#8217;il demande). La fonction <code data-enlighter-language=\"cpp\" class=\"EnlighterJSRAW\">CreateFileA()<\/code> demande simplement ce droit, seulement, beaucoup de fonctions font appel \u00e0 des fonctions de <code>ntdll.dll<\/code> ce qui est le cas ici. Plus pr\u00e9cis\u00e9ment elle fait appelle \u00e0 <code data-enlighter-language=\"cpp\" class=\"EnlighterJSRAW\">NtCreateFile()<\/code>:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">__kernel_entry NTSTATUS NtCreateFile(\n  PHANDLE            FileHandle,\n  ACCESS_MASK        DesiredAccess,\n  POBJECT_ATTRIBUTES ObjectAttributes,\n  PIO_STATUS_BLOCK   IoStatusBlock,\n  PLARGE_INTEGER     AllocationSize,\n  ULONG              FileAttributes,\n  ULONG              ShareAccess,\n  ULONG              CreateDisposition,\n  ULONG              CreateOptions,\n  PVOID              EaBuffer,\n  ULONG              EaLength\n);<\/pre>\n\n\n\n<p>Et effectivement, le masque d\u2019acc\u00e8s appara\u00eet et la documentation nous confirme qu&#8217;il faut ajouter des droits sp\u00e9cifiques aux fichiers. Pour mieux comprendre la mani\u00e8re dont s&#8217;agencent les droits dans un masque d&#8217;acc\u00e8s, je vous propose le sch\u00e9ma suivant (merci Microsoft):<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img loading=\"lazy\" width=\"597\" height=\"180\" src=\"http:\/\/theredwindows.net\/wp-content\/uploads\/2021\/02\/AccessMask.png\" alt=\"\" class=\"wp-image-134\" srcset=\"https:\/\/theredwindows.net\/wp-content\/uploads\/2021\/02\/AccessMask.png 597w, https:\/\/theredwindows.net\/wp-content\/uploads\/2021\/02\/AccessMask-300x90.png 300w, https:\/\/theredwindows.net\/wp-content\/uploads\/2021\/02\/AccessMask-400x121.png 400w\" sizes=\"(max-width: 597px) 100vw, 597px\" \/><\/figure><\/div>\n\n\n\n<p>J\u2019esp\u00e8re que les petites pr\u00e9cisions apport\u00e9es ici vous auront permis de comprendre plus en profondeur le contenu de mon pr\u00e9c\u00e9dent article, si vous voulez savoir comment on applique ce mod\u00e8le sur les objets Active Directory, je vous invite \u00e0 consulter mon article sur l\u2019abus des ACLs&nbsp;!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Cet article se veut \u00eatre le prolongement de mon premier sur ilearned, un blog communautaire. Dans celui-ci j\u2019abordais dans les grandes lignes le fonctionnement du mod\u00e8le s\u00e9curit\u00e9 de Windows (je ne voulais rentrer autant en profondeur pour que l&#8217;article soit compr\u00e9hensible de vraiment tout le monde m\u00eame les plus linuxiens). Ici, je vais apporter une [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[3],"tags":[],"_links":{"self":[{"href":"https:\/\/theredwindows.net\/index.php\/wp-json\/wp\/v2\/posts\/274"}],"collection":[{"href":"https:\/\/theredwindows.net\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/theredwindows.net\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/theredwindows.net\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/theredwindows.net\/index.php\/wp-json\/wp\/v2\/comments?post=274"}],"version-history":[{"count":3,"href":"https:\/\/theredwindows.net\/index.php\/wp-json\/wp\/v2\/posts\/274\/revisions"}],"predecessor-version":[{"id":281,"href":"https:\/\/theredwindows.net\/index.php\/wp-json\/wp\/v2\/posts\/274\/revisions\/281"}],"wp:attachment":[{"href":"https:\/\/theredwindows.net\/index.php\/wp-json\/wp\/v2\/media?parent=274"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/theredwindows.net\/index.php\/wp-json\/wp\/v2\/categories?post=274"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/theredwindows.net\/index.php\/wp-json\/wp\/v2\/tags?post=274"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}