{"id":123,"date":"2014-08-28T07:00:00","date_gmt":"2014-08-28T07:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2014\/08\/28\/taking-advantage-of-the-fact-that-the-handle-returned-when-you-create-a-kernel-synchronization-object-has-full-access-regardless-of-the-actual-acl\/"},"modified":"2014-08-28T07:00:00","modified_gmt":"2014-08-28T07:00:00","slug":"taking-advantage-of-the-fact-that-the-handle-returned-when-you-create-a-kernel-synchronization-object-has-full-access-regardless-of-the-actual-acl","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20140828-00\/?p=123","title":{"rendered":"Taking advantage of the fact that the handle returned when you create a kernel synchronization object has full access regardless of the actual ACL"},"content":{"rendered":"<p>\nA customer wanted some help deciding what security attributes to place\non an event object intended to be used by multiple security contexts.\n<\/p>\n<blockquote CLASS=\"q\"><p>\nWe have two processes, call them A and B, running in different\nsecurity contexts.\nI have an event that process A creates and shares with process B.\nThe only thing process A does with the event is signal it,\nand the only thing process B does with the event is wait on it.\nOur question is what ACLs you recommend for the event.\nFor now, we&#8217;re using O:BAD:(A;;GR;;;WD)(A;;GA;;;LS)(A;;GA;;;BA).\n(In case it matters, process A is usually running as a service\nwith Local System privileges,\nthough for testing purposes it may be running as local administrator.\nProcess B runs as a service with Local Service privileges.)\n<\/p><\/blockquote>\n<p>\nFor those who don&#8217;t speak\n<a HREF=\"http:\/\/msdn.microsoft.com\/library\/aa379570\">\nSDDL<\/a>, that weird line noise is shorthand for\n<\/p>\n<ul>\n<li><u>O<\/u>wner:\n    <u>B<\/u>uiltin\n    <u>A<\/u>dministrators<\/p>\n<li><u>D<\/u>ACL:\n<ul>\n<li><u>A<\/u>llow\n        <u>G<\/u>eneric <u>R<\/u>ead\n        to\n        Everyone (aka <u>W<\/u>orl<u>d<\/u>).<\/p>\n<li><u>A<\/u>llow\n        <u>G<\/u>eneric <u>A<\/u>ll\n        to\n        <u>L<\/u>ocal <u>S<\/u>ervice.<\/p>\n<li><u>A<\/u>llow\n        <u>G<\/u>eneric <u>A<\/u>ll\n        to\n        <u>B<\/u>uiltin <u>A<\/u>dministrators.\n    <\/ul>\n<\/ul>\n<p>\nGiven the requirements, there is no need to grant Everyone\nany access at all, so we can delete the (A;;GR;;;WD) ACE.\n<\/p>\n<p>\nSince process&nbsp;B needs only to wait on the object,\ngranting it Generic All access is far too broad.\nThat would allow process&nbsp;B to signal the event or even change its ACL!\nTo wait on an object, all you need is Synchronize,\nso the second ACE can be tightened to\n(A;;0x00100000;;;LS).\n(There is no shorthand for Synchronize, so we use its hex value.)\n<\/p>\n<p>\nThe intention of the third ACE is to allow process&nbsp;A to\nsignal the event,\nbut for that all it needs is <code>EVENT_MODIFY_STATE<\/code>,\nnot Generic All.\nBut we can do better:\nWe can delete the ACE entirely.\n<\/p>\n<p>\n&#8220;But Mister Wizard,\nif you delete the third ACE,\nthen process&nbsp;A won&#8217;t be able to signal the event!&#8221;\n<\/p>\n<p>\nAh yes it can, thanks to a special feature of\n<a HREF=\"http:\/\/msdn.microsoft.com\/library\/ms682396\">\nthe <code>Create&shy;Event<\/code> function<\/a>:\n<\/p>\n<blockquote CLASS=\"m\"><p>\nThe handle returned by <b>Create&shy;Event<\/b>\nhas the <b>EVENT_ALL_ACCESS<\/b> access right.\n<\/p><\/blockquote>\n<p>\nIf you created the event, you get full access to the event\nregardless of what the ACLs on the event would normally say.\n<\/p>\n<p>\nTherefore, the event can be ACL&#8217;d with simply\nO:BAD:(A;;0x00100000;;;LS).\nWhen process&nbsp;A creates the event, it needs to hold on tight\nto that event handle, since that is the process&#8217;s only way of\nsetting the event!\n(If it loses the handle, it won&#8217;t be able to get it back because\nthe attempt to reacquire the handle will be blocked by the ACL.)\n<\/p>\n<p>\nHere&#8217;s a quick program that demonstrates the behavior.\n<\/p>\n<pre>\n#include &lt;windows.h&gt;\n#include &lt;sddl.h&gt;\n#include &lt;tchar.h&gt;\n\/\/ This is a demonstration, so there is no error checking\n\/\/ and we leak memory.\nint __cdecl _tmain(int, TCHAR **)\n{\n ULONG cb;\n SECURITY_ATTRIBUTES sa = { sizeof(sa), NULL, FALSE };\n \/\/ Create a security descriptor that grants access to no one.\n ConvertStringSecurityDescriptorToSecurityDescriptor(TEXT(\"D:\"),\n    SDDL_REVISION_1, &amp;sa.lpSecurityDescriptor, &amp;cb);\n \/\/ Create a handle with that security descriptor\n HANDLE h = CreateEvent(&amp;sa, TRUE, TRUE,\n             TEXT(\"<a HREF=\"http:\/\/en.wikipedia.org\/wiki\/Everybody_Loves_My_Baby\">NobodyCanAccessMeButMe<\/a>\"));\n \/\/ Even though nobody has access to the object, we can still\n \/\/ signal it using the handle returned by CreateEvent.\n SetEvent(h); \/\/ succeeds\n \/\/ But nobody else can obtain the handle via the object name.\n HANDLE h2 = OpenEvent(EVENT_MODIFY_STATE, FALSE,\n                       TEXT(\"NobodyCanAccessMeButMe\")); \/\/ fails\n return 0;\n}\n<\/pre>\n<p>\nThe customer wrote back,\n&#8220;This worked perfectly. Thanks!&#8221;\n<\/p>\n<p>\nFor bonus points, you can be even more specific and grant\nSynchronize access only to process&nbsp;B&#8217;s\n<a HREF=\"http:\/\/blogs.technet.com\/b\/voy\/archive\/2007\/03\/22\/per-service-sid.aspx\">\nservice SID<\/a>\n(<code>NT SERVICE\\<i>Service&shy;Name<\/i><\/code>)\nrather than to all local services.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A customer wanted some help deciding what security attributes to place on an event object intended to be used by multiple security contexts. We have two processes, call them A and B, running in different security contexts. I have an event that process A creates and shares with process B. The only thing process A [&hellip;]<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-123","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>A customer wanted some help deciding what security attributes to place on an event object intended to be used by multiple security contexts. We have two processes, call them A and B, running in different security contexts. I have an event that process A creates and shares with process B. The only thing process A [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/123","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=123"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/123\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=123"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=123"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=123"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}