<?xml version="1.0" encoding="UTF-8"?><!-- generator="wordpress/2.0.5" -->
<rss version="2.0" 
	xmlns:content="http://purl.org/rss/1.0/modules/content/">
<channel>
	<title>Comments on: Fun With Impersonation</title>
	<link>http://taossa.com/index.php/2006/12/19/fun-with-impersonation/</link>
	<description>Continued ramblings on software security and code auditing</description>
	<pubDate>Tue, 07 Sep 2010 10:56:23 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.0.5</generator>

	<item>
		<title>by: justin</title>
		<link>http://taossa.com/index.php/2006/12/19/fun-with-impersonation/#comment-52</link>
		<pubDate>Fri, 05 Jan 2007 05:12:16 +0000</pubDate>
		<guid>http://taossa.com/index.php/2006/12/19/fun-with-impersonation/#comment-52</guid>
					<description>Hey, I'm on vacation this week and should not be held accountable for anything I do or say. Anyway, I suppose I should learn my lesson about posting in a hurry. I was referencing the example from the book just to point out that I presented it correctly at some point. At this rate though, I may need to start forwarding all of my public correspondence through a team of pre-publication reviewers.</description>
		<content:encoded><![CDATA[<p>Hey, I&#8217;m on vacation this week and should not be held accountable for anything I do or say. Anyway, I suppose I should learn my lesson about posting in a hurry. I was referencing the example from the book just to point out that I presented it correctly at some point. At this rate though, I may need to start forwarding all of my public correspondence through a team of pre-publication reviewers.
</p>
]]></content:encoded>
				</item>
	<item>
		<title>by: jm</title>
		<link>http://taossa.com/index.php/2006/12/19/fun-with-impersonation/#comment-50</link>
		<pubDate>Fri, 05 Jan 2007 02:32:19 +0000</pubDate>
		<guid>http://taossa.com/index.php/2006/12/19/fun-with-impersonation/#comment-50</guid>
					<description>Ack! Our bad for some ambiguous wording there. The idea of you stealing the answer from the book never occurred to us, as it's absurd. I think you've demonstrated on numerous occasions that you know this stuff pretty damn well. :&#62;</description>
		<content:encoded><![CDATA[<p>Ack! Our bad for some ambiguous wording there. The idea of you stealing the answer from the book never occurred to us, as it&#8217;s absurd. I think you&#8217;ve demonstrated on numerous occasions that you know this stuff pretty damn well. :&gt;
</p>
]]></content:encoded>
				</item>
	<item>
		<title>by: Dave Aitel</title>
		<link>http://taossa.com/index.php/2006/12/19/fun-with-impersonation/#comment-49</link>
		<pubDate>Fri, 05 Jan 2007 01:59:35 +0000</pubDate>
		<guid>http://taossa.com/index.php/2006/12/19/fun-with-impersonation/#comment-49</guid>
					<description>I didn't steal the answer from the book...I only read enough of it so far to laud it publicly :&#62;</description>
		<content:encoded><![CDATA[<p>I didn&#8217;t steal the answer from the book&#8230;I only read enough of it so far to laud it publicly :&gt;
</p>
]]></content:encoded>
				</item>
	<item>
		<title>by: justin</title>
		<link>http://taossa.com/index.php/2006/12/19/fun-with-impersonation/#comment-40</link>
		<pubDate>Tue, 02 Jan 2007 02:14:32 +0000</pubDate>
		<guid>http://taossa.com/index.php/2006/12/19/fun-with-impersonation/#comment-40</guid>
					<description>Well, it seems like the fun's all over. Not only did Dave catch the race condition that I was shooting for, but he caught the problem I introduced when I cut out the supporting code. The point of this example was to demonstrate that a race between two connections could result in one process inheriting its own standard IO handles, plus those for another user context connecting at the same time.  Dave also pointed out that this minimized code example would not launch the child process in the impersonated thread's context. I have to claim the blame there.  I obfuscated an example from the book (page 634) and pulled out a wrapper function that would have performed the necessary token duplication and CreateProcessAsUser() call.</description>
		<content:encoded><![CDATA[<p>Well, it seems like the fun&#8217;s all over. Not only did Dave catch the race condition that I was shooting for, but he caught the problem I introduced when I cut out the supporting code. The point of this example was to demonstrate that a race between two connections could result in one process inheriting its own standard IO handles, plus those for another user context connecting at the same time.  Dave also pointed out that this minimized code example would not launch the child process in the impersonated thread&#8217;s context. I have to claim the blame there.  I obfuscated an example from the book (page 634) and pulled out a wrapper function that would have performed the necessary token duplication and CreateProcessAsUser() call.
</p>
]]></content:encoded>
				</item>
	<item>
		<title>by: Dave Aitel</title>
		<link>http://taossa.com/index.php/2006/12/19/fun-with-impersonation/#comment-36</link>
		<pubDate>Mon, 01 Jan 2007 22:46:26 +0000</pubDate>
		<guid>http://taossa.com/index.php/2006/12/19/fun-with-impersonation/#comment-36</guid>
					<description>Hmm. CreateProcess takes the primary thread token, if I recall correctly, and not the impersonation token. If I am not a bit out of practice (always possible) then the new process will have to be something that the impersonated user can read, but will end up with a primary token duplicated from the primary token of the parent process, which is probably not what they wanted here.

Assuming the primary token is low priviledged - If all the inputs and outputs are inheritable, can't my child process look at stdin- for previous handles?

-dave</description>
		<content:encoded><![CDATA[<p>Hmm. CreateProcess takes the primary thread token, if I recall correctly, and not the impersonation token. If I am not a bit out of practice (always possible) then the new process will have to be something that the impersonated user can read, but will end up with a primary token duplicated from the primary token of the parent process, which is probably not what they wanted here.</p>
<p>Assuming the primary token is low priviledged - If all the inputs and outputs are inheritable, can&#8217;t my child process look at stdin- for previous handles?</p>
<p>-dave
</p>
]]></content:encoded>
				</item>
	<item>
		<title>by: justin</title>
		<link>http://taossa.com/index.php/2006/12/19/fun-with-impersonation/#comment-35</link>
		<pubDate>Sun, 31 Dec 2006 05:17:10 +0000</pubDate>
		<guid>http://taossa.com/index.php/2006/12/19/fun-with-impersonation/#comment-35</guid>
					<description>olleB - Interesting idea, but the security context is set on connection to the pipe, and persists until the pipe is disconnected. Your end-goal is headed in the right direction though.</description>
		<content:encoded><![CDATA[<p>olleB - Interesting idea, but the security context is set on connection to the pipe, and persists until the pipe is disconnected. Your end-goal is headed in the right direction though.
</p>
]]></content:encoded>
				</item>
	<item>
		<title>by: olleB</title>
		<link>http://taossa.com/index.php/2006/12/19/fun-with-impersonation/#comment-32</link>
		<pubDate>Sat, 30 Dec 2006 14:34:57 +0000</pubDate>
		<guid>http://taossa.com/index.php/2006/12/19/fun-with-impersonation/#comment-32</guid>
					<description>OK, going back to MSDN I think I may have found it.

The docs for ImpersonateNamedPipeClient() say it "changes the thread of the calling process to start impersonating the security context of the [i]last message read from the pipe[/i]".

So if this thread was spawned by a low-priv users' message and then inbetween the CreateThread() and ImpersonateNamedPipeClient() calls a high-priv user sends a message to the same pipe, the low-priv users command would run as the high-priv user.

/olle</description>
		<content:encoded><![CDATA[<p>OK, going back to MSDN I think I may have found it.</p>
<p>The docs for ImpersonateNamedPipeClient() say it &#8220;changes the thread of the calling process to start impersonating the security context of the [i]last message read from the pipe[/i]&#8221;.</p>
<p>So if this thread was spawned by a low-priv users&#8217; message and then inbetween the CreateThread() and ImpersonateNamedPipeClient() calls a high-priv user sends a message to the same pipe, the low-priv users command would run as the high-priv user.</p>
<p>/olle
</p>
]]></content:encoded>
				</item>
	<item>
		<title>by: justin</title>
		<link>http://taossa.com/index.php/2006/12/19/fun-with-impersonation/#comment-31</link>
		<pubDate>Sat, 30 Dec 2006 05:20:27 +0000</pubDate>
		<guid>http://taossa.com/index.php/2006/12/19/fun-with-impersonation/#comment-31</guid>
					<description>&lt;p&gt;MarcheFunebre - You make legitimate points on both 1 and 2.  &lt;br /&gt;1) The return values are inconsistent, which certainly is bad form, though not necessarily exploitable in this context.  &lt;br /&gt;2) &lt;font face="Courier New"&gt;CreateProcess() &lt;/font&gt;could fail leaving &lt;font face="Courier New"&gt;pi &lt;/font&gt;containing potentially malicious stack junk.  However, the hang will only affect the client's thread and not the server that spawns them. &lt;br /&gt;There's a much more serious issue, though it's fairly subtle.  At least, it was to me because I read this code repeatedly before I eventually noticed it.&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;olleB - The &lt;font face="Courier New"&gt;tclient() &lt;/font&gt;function is a thread running in the named pipe server. So, io is passed as an open handle to &lt;font face="Courier New"&gt;DuplicateHandle()&lt;/font&gt;, and it will succeed without issue (barring lack of resources). However, the calls to &lt;font face="Courier New"&gt;DuplicateHandle() &lt;/font&gt;are at the root of the problem.&lt;br /&gt;&lt;/p&gt;
&lt;p&gt; As further encouragement, I'd like to drop a hint. Consider what could happen when this function is called in a race between two different user contexts.&lt;/p&gt;</description>
		<content:encoded><![CDATA[<p>MarcheFunebre - You make legitimate points on both 1 and 2.  <br />1) The return values are inconsistent, which certainly is bad form, though not necessarily exploitable in this context.  <br />2) <font face="Courier New">CreateProcess() </font>could fail leaving <font face="Courier New">pi </font>containing potentially malicious stack junk.  However, the hang will only affect the client&#8217;s thread and not the server that spawns them. <br />There&#8217;s a much more serious issue, though it&#8217;s fairly subtle.  At least, it was to me because I read this code repeatedly before I eventually noticed it.</p>
<p>olleB - The <font face="Courier New">tclient() </font>function is a thread running in the named pipe server. So, io is passed as an open handle to <font face="Courier New">DuplicateHandle()</font>, and it will succeed without issue (barring lack of resources). However, the calls to <font face="Courier New">DuplicateHandle() </font>are at the root of the problem.</p>
<p> As further encouragement, I&#8217;d like to drop a hint. Consider what could happen when this function is called in a race between two different user contexts.</p>
]]></content:encoded>
				</item>
	<item>
		<title>by: olleB</title>
		<link>http://taossa.com/index.php/2006/12/19/fun-with-impersonation/#comment-29</link>
		<pubDate>Fri, 29 Dec 2006 14:12:31 +0000</pubDate>
		<guid>http://taossa.com/index.php/2006/12/19/fun-with-impersonation/#comment-29</guid>
					<description>Didn't you just answer this question in the "HANDLE with care" post?
If the DuplicateHandle() call is going to work, the impersonated user has to have PROCESS_DUP_HANDLE permission for the NP server process, which means that the process spawned by CreateProcess() could gain full access to the NP server process.
I imagine the fix would be to DuplicateHandle() first and THEN ImpersonateNamedPipeClient().

Happy New Year!

/olle</description>
		<content:encoded><![CDATA[<p>Didn&#8217;t you just answer this question in the &#8220;HANDLE with care&#8221; post?<br />
If the DuplicateHandle() call is going to work, the impersonated user has to have PROCESS_DUP_HANDLE permission for the NP server process, which means that the process spawned by CreateProcess() could gain full access to the NP server process.<br />
I imagine the fix would be to DuplicateHandle() first and THEN ImpersonateNamedPipeClient().</p>
<p>Happy New Year!</p>
<p>/olle
</p>
]]></content:encoded>
				</item>
	<item>
		<title>by: MarcheFunebre</title>
		<link>http://taossa.com/index.php/2006/12/19/fun-with-impersonation/#comment-27</link>
		<pubDate>Fri, 29 Dec 2006 03:44:29 +0000</pubDate>
		<guid>http://taossa.com/index.php/2006/12/19/fun-with-impersonation/#comment-27</guid>
					<description>1) The function inconsistently returns either the result of GetLastError() which is DWORD or the result of RevertToSelf() which is a BOOL.

2) If CreateProcess() call fails, the pi structure is left uninitialized so pi.hProcess member can take an arbitrary value (!= NULL). Calling WaitForSingleObject on that handle will most likely fail but it can also block indefinitely if the handle happens to be valid (event, mutex, semaphore, process, thread handle opened with SYNCHRONIZE access) but never signaled.</description>
		<content:encoded><![CDATA[<p>1) The function inconsistently returns either the result of GetLastError() which is DWORD or the result of RevertToSelf() which is a BOOL.</p>
<p>2) If CreateProcess() call fails, the pi structure is left uninitialized so pi.hProcess member can take an arbitrary value (!= NULL). Calling WaitForSingleObject on that handle will most likely fail but it can also block indefinitely if the handle happens to be valid (event, mutex, semaphore, process, thread handle opened with SYNCHRONIZE access) but never signaled.
</p>
]]></content:encoded>
				</item>
</channel>
</rss>

<!-- Dynamic Page Served (once) in 0.065 seconds -->
