<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-5143432091175065954</id><updated>2024-09-05T21:14:11.778-07:00</updated><title type='text'>The Final Stream</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://nsylvain.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5143432091175065954/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://nsylvain.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>nsylvain</name><uri>http://www.blogger.com/profile/16393263594312873401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUe6CR-d31Ox18_Sn1esXdvng5YmkxKAurMlxdQnJsvmaFwXgQJIbZA15H6or2jXC_5dwv1MR5AoRK9eJ57GI_fJEBg7hciqwAPHKGF2xfAQEJXtv3-pGs9xZfKzOJRv0/s220/face.JPG'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>17</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5143432091175065954.post-7643083670669052905</id><published>2008-09-02T21:38:00.000-07:00</published><updated>2008-09-02T22:11:55.146-07:00</updated><title type='text'>Google Chrome and the Chromium Sandbox</title><content type='html'>Chromium is finally out!! This is the moment I&#39;ve been waiting for. I can now share the details of the project I&#39;ve been working on: The Chromium sandbox.&lt;br /&gt;&lt;br /&gt;As you know, Chromium is open source, so is its sandbox. I welcome everyone to take a look at the code, contribute patches, suggest improvements, find security bugs and most importantly, USE IT. Yes, the sandbox is not tied to chromium; it can be easily reused by any projects in need of a sandboxing solution. In the next posts I will present different parts of the Chromium sandbox in details, and I will be talking more about how to integrate the sandbox with any application.&lt;br /&gt;&lt;br /&gt;Before going into the details, you must understand the high level architecture of Chromium, and what part of it is running in the sandbox. The best way to learn about this is to read the &lt;a href=&quot;http://www.google.com/googlebooks/chrome/#&quot;&gt;comic book&lt;/a&gt;!&lt;br /&gt;&lt;br /&gt;The &lt;a href=&quot;http://www.chromium.org&quot;&gt;official website&lt;/a&gt; also has a lot of &lt;a href=&quot;http://dev.chromium.org&quot;&gt;good information&lt;/a&gt; on Chromium and the sandbox, like our &lt;a href=&quot;http://dev.chromium.org/developers/design-documents/sandbox&quot;&gt;design document&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;This is it for now! Try Google Chrome!&lt;br /&gt;&lt;br /&gt;I&#39;ll be back with more information about the sandbox soon!</content><link rel='replies' type='application/atom+xml' href='http://nsylvain.blogspot.com/feeds/7643083670669052905/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/5143432091175065954/7643083670669052905' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5143432091175065954/posts/default/7643083670669052905'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5143432091175065954/posts/default/7643083670669052905'/><link rel='alternate' type='text/html' href='http://nsylvain.blogspot.com/2008/09/google-chrome-and-chromium-sandbox.html' title='Google Chrome and the Chromium Sandbox'/><author><name>nsylvain</name><uri>http://www.blogger.com/profile/16393263594312873401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUe6CR-d31Ox18_Sn1esXdvng5YmkxKAurMlxdQnJsvmaFwXgQJIbZA15H6or2jXC_5dwv1MR5AoRK9eJ57GI_fJEBg7hciqwAPHKGF2xfAQEJXtv3-pGs9xZfKzOJRv0/s220/face.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5143432091175065954.post-7125672812023848898</id><published>2008-01-20T16:54:00.000-08:00</published><updated>2008-01-22T09:56:41.014-08:00</updated><title type='text'>Namedpipe Impersonation Attack</title><content type='html'>&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;Privilege escalation through namedpipe impersonation attack was a real issue back in 2000 when a &lt;a href=&quot;http://www.microsoft.com/technet/security/Bulletin/MS00-053.mspx&quot;&gt;flaw in the service control manager&lt;/a&gt; allowed any user logged onto a machine to steal the identify of SYSTEM. We haven&#39;t heard a lot about this topic since then, is it still an issue?&lt;br /&gt;&lt;br /&gt;First of all, let&#39;s talk about the problem.&lt;br /&gt;&lt;br /&gt;When a process creates a namedpipe server, and a client connects to it, the server can impersonate the client. This is not really a problem, and is really useful when dealing with IPC. The problem arises when the client has more rights than the server. This scenario would create a privilege escalation. It turns out that it was pretty easy to accomplish.&lt;br /&gt;For example, let&#39;s assume that we have 3 processes: server.exe, client.exe and attacker.exe. &lt;strong&gt;&lt;em&gt;Server.exe&lt;/em&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;em&gt;client.exe&lt;/em&gt;&lt;/strong&gt; have more privileges than &lt;strong&gt;&lt;em&gt;attacker.exe&lt;/em&gt;&lt;/strong&gt;. &lt;strong&gt;&lt;em&gt;Client.exe&lt;/em&gt;&lt;/strong&gt; communicates with &lt;strong&gt;&lt;em&gt;server.exe&lt;/em&gt;&lt;/strong&gt; using a namedpipe. If &lt;strong&gt;&lt;em&gt;attacker.exe&lt;/em&gt;&lt;/strong&gt; manages to create the pipe server before &lt;strong&gt;&lt;em&gt;server.exe&lt;/em&gt;&lt;/strong&gt; does, then, as soon as &lt;strong&gt;&lt;em&gt;client.exe&lt;/em&gt;&lt;/strong&gt; connects to the pipe, &lt;strong&gt;&lt;em&gt;attacker.exe&lt;/em&gt;&lt;/strong&gt; can impersonate it and the game is over.&lt;br /&gt;&lt;br /&gt;Fortunately, Microsoft implemented and recently documented some restrictions and tools to help you manage the risk.&lt;br /&gt;&lt;br /&gt;First of all there are some flags buried in the &lt;a href=&quot;http://msdn2.microsoft.com/en-us/library/aa363858(VS.85).aspx&quot;&gt;CreateFile&lt;/a&gt; documentation to give control to the pipe client over what level of impersonation a server can perform. They are called the &quot;&lt;a href=&quot;http://msdn2.microsoft.com/en-us/library/aa379574(VS.85).aspx&quot;&gt;Security Quality Of Service&lt;/a&gt;&quot;.&lt;br /&gt;&lt;br /&gt;There are 4 flags to define the &lt;a href=&quot;http://msdn2.microsoft.com/en-us/library/aa379572(VS.85).aspx&quot;&gt;impersonation level&lt;/a&gt; allowed.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;SECURITY_ANONYMOUS&lt;/span&gt;&lt;br /&gt;The server process cannot obtain identification information about the client, and it cannot impersonate the client.&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;SECURITY_IDENTIFICATION&lt;/span&gt;&lt;br /&gt;The server process can obtain information about the client, such as security identifiers and privileges, but it cannot impersonate the client. &lt;a href=&quot;http://msdn2.microsoft.com/en-us/library/aa378618(VS.85).aspx&quot;&gt;ImpersonateNamedpipeClient&lt;/a&gt; will succeed, but no resources can be acquired while impersonating the client. The token can be opened and the information it contains can be read.&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;SECURITY_IMPERSONATION&lt;/span&gt; - &lt;span style=&quot;font-style:italic;&quot;&gt;This is the default&lt;/span&gt;&lt;br /&gt;The server process can impersonate the client&#39;s security context on its local system. The server cannot impersonate the client on remote systems.&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;SECURITY_DELEGATION&lt;/span&gt;&lt;br /&gt;The server process can impersonate the client&#39;s security context on remote systems.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;There are also 2 other flags:&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;SECURITY_CONTEXT_TRACKING&lt;/span&gt;&lt;br /&gt;Specifies that any changes a client makes to its security context is reflected in a server that is impersonating it. If this option isn&#39;t specified, the server adopts the context of the client at the time of the impersonation and doesn&#39;t receive any changes. This option is honored only when the client and server process are on the same system.&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;SECURITY_EFFECTIVE_ONLY&lt;/span&gt;&lt;br /&gt;Prevents a server from enabling or disabling a client&#39;s privilege or group while the server is impersonating.&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;&lt;em&gt;Note: Since the MSDN documentation for these flags is really weak, I used the definition that can be found in the book &quot;&lt;a href=&quot;http://www.microsoft.com/mspress/books/6710.aspx&quot;&gt;Microsoft® Windows® Internals, Fourth Edition&lt;/a&gt;&quot; by Mark Russinovich and David Solomon.&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;Every time you create a pipe in client mode, you need to find out what the server needs to know about you and pass the right flags to CreateFile. And if you do, don&#39;t forget to also pass SECURITY_SQOS_PRESENT, otherwise the other flags will be ignored.&lt;br /&gt;&lt;br /&gt;Unfortunately, you don&#39;t have access to the source code of all the software running on your machine. I bet there are dozen of software running on my machine right now opening pipes without using the SQOS flags. To &quot;fix&quot; that, Microsoft implemented some &lt;a href=&quot;http://msdn2.microsoft.com/en-us/library/aa378618(VS.85).aspx&quot;&gt;restrictions&lt;/a&gt; about who a server can impersonate in order to minimize the chances of being exploited.&lt;br /&gt;&lt;br /&gt;A server can impersonate a client only if one of the following is true.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;The caller has the SeImpersonatePrivilege privilege.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;The requested impersonation level is SecurityIdentification or SecurityAnonymous.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;The identity of the client is the same as the server.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;The token of the client was created using &lt;a href=&quot;http://msdn2.microsoft.com/en-us/library/aa378184(VS.85).aspx&quot;&gt;LogonUser&lt;/a&gt; from inside the same logon session as the server.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;Only Administrators/System/SERVICES have the SeImpersonatePrivilege privilege. If the attacker is a member of these groups, you have much bigger problems.&lt;br /&gt;&lt;br /&gt;The requested impersonation level in our case is SecurityImpersonation, so the second point does not apply.&lt;br /&gt;&lt;br /&gt;That leaves us with the last two conditions. Should we worry about them? I think so. Here are some examples:&lt;br /&gt;&lt;br /&gt;I&#39;m on XP. I want to run an untrusted application. Since I read my old posts, I know that I can run the process using a stripped down version of my token. Unfortunately, my restricted token has the same identity as the normal token. It can then try to exploit all applications running on my desktop. This is bad. &lt;br /&gt;&lt;br /&gt;My main account is not administrator on the machine. When I want to install software, I use RunAs. This brings up a new problem. RunAs uses LogonUser, and it is called from the same logon session! That means that my untrusted application using a restricted token derived from a standard user token can now try to exploit and impersonate a process running with administrator rights! This is worse.&lt;br /&gt;&lt;br /&gt;But how real is all this?&lt;br /&gt;&lt;br /&gt;This is hard to say. I don&#39;t have an idea about the percentage of applications using the SQOS flags. We must not forget that allowing impersonation is also required and desired in certain cases.&lt;br /&gt;&lt;br /&gt;For fun I took the first application using namedpipes that came to my mind: Windbg. There is an option in Windbg to do kernel debugging and if the OS you are debugging is inside vmware, you can specify the namedpipe corresponding the COM1 port of the vmware image. By default it is &quot;com_1&quot;. My untrusted application running with the restricted token was now listening on com_1, and, easy enough, as soon as I started windbg, the untrusted application was able to steal its token.&lt;br /&gt;&lt;br /&gt;To be fair I have to say that vmware displayed an error message telling me that the com_1 port was &quot;not configured as expected&quot;. I should not have started windbg knowing that. But, eh, who reads error messages? :)&lt;br /&gt;&lt;br /&gt;What should we do now?&lt;br /&gt;&lt;br /&gt;Well, it turns out that Microsoft implemented two new restrictions in windows Vista to fix these problems. I don&#39;t think they are documented yet.&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;If the token of a server is restricted, it can impersonate only clients also running with a restricted token.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;The server cannot impersonate a client running at a higher integrity level.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;These new restrictions are fixing both my issues. First of all my untrusted application can&#39;t be running with a restricted token anymore. Then, even if the untrusted application is running with my standard token, it won&#39;t be able to impersonate the processes that I start with the &quot;Run As Administrator&quot; elevation prompt because they are running with a High Integrity Level.&lt;br /&gt;&lt;br /&gt;Now it is time to come back to the main question: Is it still an issue?&lt;br /&gt;&lt;br /&gt;My answer is yes. Windows XP is still the most popular Windows version out there and there is no sign that Vista is going to catch up soon. But I have to admit that I&#39;m relieved to see the light at the end of the tunnel!&lt;br /&gt;&lt;br /&gt;--&lt;br /&gt;&lt;br /&gt;&lt;em&gt;Some technical details:&lt;br /&gt;When you call ImpersonateNamedPipeClient and none of the conditions is met, the function still succeeds, but the impersonation level of the token is SecurityIdentification.&lt;br /&gt;&lt;br /&gt;If you want to try for yourself, you can find the code to create a server pipe and a client pipe on my &lt;a href=&quot;http://nsylvain.googlepages.com/&quot;&gt;code page&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Related link:&lt;br /&gt;&lt;a href=&quot;http://blogs.msdn.com/david_leblanc/archive/2007/03/25/impersonation-isn-t-dangerous.aspx&quot;&gt;Impersonation isn&#39;t dangerous&lt;/a&gt; by David Leblanc&lt;br /&gt;&lt;/em&gt;&lt;br /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nsylvain.blogspot.com/feeds/7125672812023848898/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/5143432091175065954/7125672812023848898' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5143432091175065954/posts/default/7125672812023848898'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5143432091175065954/posts/default/7125672812023848898'/><link rel='alternate' type='text/html' href='http://nsylvain.blogspot.com/2008/01/namedpipe-impersonation-attack.html' title='Namedpipe Impersonation Attack'/><author><name>nsylvain</name><uri>http://www.blogger.com/profile/16393263594312873401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUe6CR-d31Ox18_Sn1esXdvng5YmkxKAurMlxdQnJsvmaFwXgQJIbZA15H6or2jXC_5dwv1MR5AoRK9eJ57GI_fJEBg7hciqwAPHKGF2xfAQEJXtv3-pGs9xZfKzOJRv0/s220/face.JPG'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5143432091175065954.post-3435589305791131596</id><published>2008-01-20T10:06:00.000-08:00</published><updated>2008-01-20T10:41:32.254-08:00</updated><title type='text'>DuplicateHandle and Access Mask.</title><content type='html'>&lt;div align=&quot;justify&quot;&gt;In the &lt;a href=&quot;http://msdn2.microsoft.com/en-us/library/ms724251(VS.85).aspx&quot;&gt;DuplicateHandle&lt;/a&gt; MSDN documentation there is not a lot of information about the Access Mask that can be passed to DuplicateHandle.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;What happens if you ask for MAXIMUM_ALLOWED?&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;The function succeeds, but the handle created does not have any granted access. This is not really useful.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Not all object types support the same flags in an access mask, what happens if you specify a mask that contains invalid flags?&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;It depends... &lt;br /&gt;&lt;br /&gt;The function fails if you use any of these flags:&lt;br /&gt;&lt;/div&gt;&lt;pre&gt;&lt;br /&gt;      0x00200000 = Unused standard right&lt;br /&gt;      0x00400000 = Unused standard right&lt;br /&gt;      0x00800000 = Unused standard right&lt;br /&gt;      0x01000000 = ACCESS_SYSTEM_SECURITY [You need a privilege]&lt;br /&gt;      0x04000000 = Reserved&lt;br /&gt;      0x08000000 = Reserved&lt;br /&gt;&lt;/pre&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;But if you don&#39;t, any other invalid flags are ignored and the call succeeds. The granted access is the union of all the valid flags present in the mask. It also means that if you duplicate the handle using invalid flags only, the handle will be created without any granted access.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;That said, in my &lt;a href=&quot;http://nsylvain.blogspot.com/2008/01/winverwin32winnt-mayhem.html&quot;&gt;previous post&lt;/a&gt; I talked about why you should not use PROCESS_ALL_ACCESS anymore on Windows XP. This is not true for the DuplicateHandle call, you can still use it since the new flag 0xF000 will be ignored on previous version of the OS.&lt;br /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nsylvain.blogspot.com/feeds/3435589305791131596/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/5143432091175065954/3435589305791131596' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5143432091175065954/posts/default/3435589305791131596'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5143432091175065954/posts/default/3435589305791131596'/><link rel='alternate' type='text/html' href='http://nsylvain.blogspot.com/2008/01/duplicatehandle-and-access-mask.html' title='DuplicateHandle and Access Mask.'/><author><name>nsylvain</name><uri>http://www.blogger.com/profile/16393263594312873401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUe6CR-d31Ox18_Sn1esXdvng5YmkxKAurMlxdQnJsvmaFwXgQJIbZA15H6or2jXC_5dwv1MR5AoRK9eJ57GI_fJEBg7hciqwAPHKGF2xfAQEJXtv3-pGs9xZfKzOJRv0/s220/face.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5143432091175065954.post-1902330710337017590</id><published>2008-01-12T11:17:00.000-08:00</published><updated>2008-01-21T07:48:22.519-08:00</updated><title type='text'>WINVER Mayhem. The PROCESS_ALL_ACCESS problem.</title><content type='html'>&lt;div align=&quot;justify&quot;&gt;If you are like me, you want to develop Windows applications that work on all the major versions of Windows. At the moment it is Windows Vista, Windows XP SP2 and maybe Windows 2000 SP4. You also want to use the new features introduced in the new versions.&lt;br /&gt;&lt;br /&gt;Suppose that you want to use a something that is defined only when you have &lt;strong&gt;_WIN32_WINNT=0x600&lt;/strong&gt;. What do you do?&lt;br /&gt;&lt;br /&gt;There are 3 options:&lt;br /&gt;&lt;br /&gt;1. Copy the definition manually to one of your file. This is not clean. I hope I won&#39;t have to do this.&lt;br /&gt;&lt;br /&gt;2. Create one build per OS version. Each of them will define &lt;a href=&quot;http://msdn2.microsoft.com/en-us/library/aa383745(VS.85).aspx&quot;&gt;_WIN32_WINNT&lt;/a&gt; accordingly and you just have to be sure that the code specific to an OS version is inside an &lt;strong&gt;#IF _WIN32_WINNT &gt;= VERSION&lt;/strong&gt;. This makes sense, but this is a lot of troubles. Who wants to have multiple sets of exes and dlls and ship different binaries depending on the user configuration.&lt;br /&gt;&lt;br /&gt;3. Define _WIN32_WINNT to the highest value (0x0600 for Vista in this case), and make sure that you don&#39;t use unsupported functions/structures on previous version. You need to use &lt;a href=&quot;http://msdn2.microsoft.com/en-us/library/ms724451(VS.85).aspx&quot;&gt;GetVersionEx&lt;/a&gt; to get the OS version and use &lt;a href=&quot;http://msdn2.microsoft.com/en-us/library/ms683212.aspx&quot;&gt;GetProcAddress&lt;/a&gt; to get the address of the functions that are not defined in prior versions.&lt;br /&gt;&lt;br /&gt;The third option is the one that I&#39;ve seen most of the time. Unfortunately, changing the value of _WIN32_WINNT to 0x0600 is causing some unexpected problems.&lt;br /&gt;&lt;br /&gt;One example is the define for PROCESS_ALL_ACCESS. It looks like this:&lt;br /&gt;&lt;/div&gt;&lt;pre&gt;&lt;br /&gt;#if (NTDDI_VERSION &gt;= NTDDI_LONGHORN)&lt;br /&gt;#define PROCESS_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | \&lt;br /&gt;0xFFFF)&lt;br /&gt;#else&lt;br /&gt;#define PROCESS_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | \&lt;br /&gt;0xFFF)&lt;br /&gt;#endif&lt;br /&gt;&lt;/pre&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;They changed the mask on Vista to include 0xF000. 0xF000 contains 3 unused flags and the new PROCESS_QUERY_LIMITED_INFORMATION.&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;Why is this a problem?&lt;br /&gt;&lt;br /&gt;Suppose that your code is doing this:&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;pre&gt;&lt;br /&gt;     OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);&lt;br /&gt;&lt;/pre&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;This call is now going to fail on XP and 2000 because you are trying to open a process with 0xF000, and you don&#39;t have that access on the process.&lt;br /&gt;&lt;br /&gt;You need to fix all PROCESS_ALL_ACCESS occurences in your code. The same problem exists with THREAD_ALL_ACCESS.&lt;br /&gt;&lt;br /&gt;What would have been a better solution? I thought PROCESS_QUERY_LIMITED_INFORMATION was only a subset of PROCESS_QUERY_INFORMATION already present in the mask. Did they really need to add it? Could they have used GENERIC_ALL instead? As we saw in this &lt;a href=&quot;http://nsylvain.blogspot.com/2008/01/more-genericmapping-changes-on-vista.html&quot;&gt;earlier post&lt;/a&gt;, GENERIC_ALL can mean different things on different OS versions.&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nsylvain.blogspot.com/feeds/1902330710337017590/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/5143432091175065954/1902330710337017590' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5143432091175065954/posts/default/1902330710337017590'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5143432091175065954/posts/default/1902330710337017590'/><link rel='alternate' type='text/html' href='http://nsylvain.blogspot.com/2008/01/winverwin32winnt-mayhem.html' title='WINVER Mayhem. The PROCESS_ALL_ACCESS problem.'/><author><name>nsylvain</name><uri>http://www.blogger.com/profile/16393263594312873401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUe6CR-d31Ox18_Sn1esXdvng5YmkxKAurMlxdQnJsvmaFwXgQJIbZA15H6or2jXC_5dwv1MR5AoRK9eJ57GI_fJEBg7hciqwAPHKGF2xfAQEJXtv3-pGs9xZfKzOJRv0/s220/face.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5143432091175065954.post-4220966905179498177</id><published>2008-01-06T18:56:00.000-08:00</published><updated>2008-01-12T19:03:15.963-08:00</updated><title type='text'>More GENERIC_MAPPING changes on vista</title><content type='html'>&lt;div align=&quot;justify&quot;&gt;In my &lt;a href=&quot;http://nsylvain.blogspot.com/2008/01/you-can-terminate-higher-integrity.html&quot;&gt;last post&lt;/a&gt; I talked about the change in the generic mapping of the Process type. It turns out that Thread, Token and Key also changed on Vista.&lt;br /&gt;&lt;br /&gt;For reference, these are the changes:&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;b&gt;TOKEN:&lt;/b&gt;&lt;br /&gt;                   Windows XP          Windows Vista&lt;br /&gt;+-----------------+-------------------+---------------------------+&lt;br /&gt; GENERIC_EXECUTE   READ_CONTROL        READ_CONTROL&lt;br /&gt;                                       &lt;strong&gt;ASSIGN_PRIMARY&lt;/strong&gt;&lt;br /&gt;                                       &lt;strong&gt;IMPERSONATE&lt;/strong&gt;&lt;br /&gt;+-----------------+-------------------+---------------------------+&lt;br /&gt; GENERIC_READ      READ_QUERY          READ_QUERY&lt;br /&gt;                   READ_CONTROL        READ_CONTROL&lt;br /&gt;                                       &lt;strong&gt;DUPLICATE&lt;/strong&gt;&lt;br /&gt;                                       &lt;strong&gt;QUERY_SOURCE&lt;/strong&gt;&lt;br /&gt;+-----------------+-------------------+---------------------------+&lt;br /&gt; GENERIC_WRITE     ADJUST_PRIVILEGES   ADJUST_PRIVILEGES&lt;br /&gt;                   ADJUST_GROUPS       ADJUST_GROUPS&lt;br /&gt;                   ADJUST_DEFAULT      ADJUST_DEFAULT&lt;br /&gt;                   READ_CONTROL        READ_CONTROL&lt;br /&gt;                                       &lt;strong&gt;ADJUST_SESSIONID&lt;/strong&gt;&lt;br /&gt;+-----------------+-------------------+---------------------------+&lt;br /&gt;&lt;em&gt;Note: The TOKEN_ prefix has been removed.&lt;/em&gt;&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;b&gt;THREAD:&lt;/b&gt;&lt;br /&gt;                    Windows XP          Windows Vista&lt;br /&gt;+-----------------+-------------------+---------------------------+&lt;br /&gt; GENERIC_EXECUTE   READ_CONTROL        READ_CONTROL&lt;br /&gt;                   SYNCHRONIZE         SYNCHRONIZE&lt;br /&gt;                                       &lt;strong&gt;QUERY_LIMITED_INFORMATION&lt;/strong&gt;&lt;br /&gt;+-----------------+-------------------+---------------------------+&lt;br /&gt; GENERIC_READ      GET_CONTEXT         GET_CONTEXT&lt;br /&gt;                   QUERY_INFORMATION   QUERY_INFORMATION&lt;br /&gt;                   READ_CONTROL        READ_CONTROL&lt;br /&gt;+-----------------+-------------------+---------------------------+&lt;br /&gt; GENERIC_WRITE     TERMINATE           TERMINATE&lt;br /&gt;                   SUSPEND_RESUME      SUSPEND_RESUME&lt;br /&gt;                   SET_CONTEXT         SET_CONTEXT&lt;br /&gt;                   SET_INFORMATION     SET_INFORMATION&lt;br /&gt;                   READ_CONTROL        READ_CONTROL&lt;br /&gt;                   0x00000004          0x00000004&lt;br /&gt;                                       &lt;strong&gt;SET_LIMITED_INFORMATION&lt;/strong&gt;&lt;br /&gt;+-----------------+-------------------+---------------------------+&lt;br /&gt;&lt;em&gt;Note: The THREAD_ prefix has been removed.&lt;/em&gt;&lt;br /&gt;  &lt;br /&gt; &lt;br /&gt; &lt;br /&gt;&lt;b&gt;KEY:&lt;/b&gt;&lt;br /&gt;                    Windows XP          Windows Vista&lt;br /&gt;+-----------------+-------------------+---------------------------+&lt;br /&gt; GENERIC_EXECUTE   QUERY_VALUE         QUERY_VALUE&lt;br /&gt;                   ENUMERATE_SUB_KEYS  ENUMERATE_SUB_KEYS&lt;br /&gt;                   NOTIFY              NOTIFY&lt;br /&gt;                   READ_CONTROL        READ_CONTROL&lt;br /&gt;                                       &lt;strong&gt;CREATE_LINK&lt;/strong&gt;&lt;br /&gt;+-----------------+-------------------+---------------------------+&lt;br /&gt; GENERIC_READ      QUERY_VALUE         QUERY_VALUE&lt;br /&gt;                   ENUMERATE_SUB_KEYS  ENUMERATE_SUB_KEYS&lt;br /&gt;                   NOTIFY              NOTIFY&lt;br /&gt;                   READ_CONTROL        READ_CONTROL&lt;br /&gt;+-----------------+-------------------+---------------------------+&lt;br /&gt; GENERIC_WRITE     SET_VALUE           SET_VALUE&lt;br /&gt;                   CREATE_SUB_KEY      CREATE_SUB_KEY&lt;br /&gt;                   READ_CONTROL        READ_CONTROL&lt;br /&gt;+-----------------+-------------------+---------------------------+&lt;br /&gt;&lt;em&gt;Note: The KEY_ prefix has been removed.&lt;/em&gt;&lt;br /&gt; &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;You want to dump the GENERIC_MAPPING structure for other object types? You can find the code on &lt;a href=&quot;http://nsylvain.googlepages.com/&quot;&gt;http://nsylvain.googlepages.com/&lt;/a&gt;.</content><link rel='replies' type='application/atom+xml' href='http://nsylvain.blogspot.com/feeds/4220966905179498177/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/5143432091175065954/4220966905179498177' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5143432091175065954/posts/default/4220966905179498177'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5143432091175065954/posts/default/4220966905179498177'/><link rel='alternate' type='text/html' href='http://nsylvain.blogspot.com/2008/01/more-genericmapping-changes-on-vista.html' title='More GENERIC_MAPPING changes on vista'/><author><name>nsylvain</name><uri>http://www.blogger.com/profile/16393263594312873401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUe6CR-d31Ox18_Sn1esXdvng5YmkxKAurMlxdQnJsvmaFwXgQJIbZA15H6or2jXC_5dwv1MR5AoRK9eJ57GI_fJEBg7hciqwAPHKGF2xfAQEJXtv3-pGs9xZfKzOJRv0/s220/face.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5143432091175065954.post-6854204594470795395</id><published>2008-01-06T16:20:00.000-08:00</published><updated>2008-01-06T19:24:38.980-08:00</updated><title type='text'>You can terminate a higher integrity process.</title><content type='html'>&lt;div align=&quot;justify&quot;&gt;Integrity levels have been publicized a lot like a &quot;No-Write-Up&quot; technology. It means that you can&#39;t write to objects with a higher integrity level than your token. But there is more to it. Microsoft also implemented &quot;No-Read-Up&quot; and &quot;No-Execute-Up&quot; and you can use them on your objects. It is even used today for processes, by default they have a No-Read-Up and No-Write-Up mandatory label. It would have been too much of a security hole to be able to read the process memory of a higher integrity level process.&lt;br /&gt;&lt;br /&gt;No-Execute-Up is not present though. What does it buy us?&lt;br /&gt;&lt;br /&gt;If it was on Windows XP, then not much, but on Vista the &lt;a href=&quot;http://msdn2.microsoft.com/en-us/library/aa491640.aspx&quot;&gt;Generic Mapping&lt;/a&gt; structures have changed. Let&#39;s take a look at them side by side for the &quot;Process&quot; object type on XP and Vista.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;pre&gt;&lt;br /&gt;                   Windows XP          Windows Vista&lt;br /&gt;+-----------------+-------------------+---------------------------+&lt;br /&gt; GENERIC_EXECUTE   READ_CONTROL        READ_CONTROL&lt;br /&gt;                   SYNCHRONIZE         SYNCHRONIZE&lt;br /&gt;                                       &lt;B&gt;TERMINATE&lt;/B&gt;&lt;br /&gt;                                       &lt;B&gt;QUERY_LIMITED_INFORMATION&lt;/B&gt;&lt;br /&gt;+-----------------+-------------------+---------------------------+&lt;br /&gt; GENERIC_READ      VM_READ             VM_READ&lt;br /&gt;                   QUERY_INFORMATION   QUERY_INFORMATION&lt;br /&gt;                   READ_CONTROL        READ_CONTROL&lt;br /&gt;+-----------------+-------------------+---------------------------+&lt;br /&gt; GENERIC_WRITE     CREATE_THREAD       CREATE_THREAD&lt;br /&gt;                   VM_OPERATION        VM_OPERATION&lt;br /&gt;                   VM_WRITE            VM_WRITE&lt;br /&gt;                   DUP_HANDLE          DUP_HANDLE&lt;br /&gt;                   CREATE_PROCESS      CREATE_PROCESS&lt;br /&gt;                   SET_QUOTA           SET_QUOTA&lt;br /&gt;                   SET_INFORMATION     SET_INFORMATION&lt;br /&gt;                   SUSPEND_RESUME      SUSPEND_RESUME&lt;br /&gt;                   READ_CONTROL        READ_CONTROL&lt;br /&gt;                   &lt;B&gt;TERMINATE&lt;/B&gt;&lt;br /&gt;+-----------------+-------------------+---------------------------+&lt;br /&gt;&lt;EM&gt;note: the prefix PROCESS_ has been removed.&lt;/EM&gt;&lt;br /&gt;&lt;a href=&quot;http://msdn2.microsoft.com/en-us/library/ms684880(VS.85).aspx&quot;&gt;http://msdn2.microsoft.com/en-us/library/ms684880(VS.85).aspx&lt;/a&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;As you can see GENERIC_EXECUTE has changed and now gives TERMINATE access. You can then kill processes with a higher integrity level!&lt;br /&gt;&lt;br /&gt;For completeness, PROCESS_QUERY_LIMITED_INFORMATION allows you to query the full process image name.&lt;br /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nsylvain.blogspot.com/feeds/6854204594470795395/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/5143432091175065954/6854204594470795395' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5143432091175065954/posts/default/6854204594470795395'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5143432091175065954/posts/default/6854204594470795395'/><link rel='alternate' type='text/html' href='http://nsylvain.blogspot.com/2008/01/you-can-terminate-higher-integrity.html' title='You can terminate a higher integrity process.'/><author><name>nsylvain</name><uri>http://www.blogger.com/profile/16393263594312873401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUe6CR-d31Ox18_Sn1esXdvng5YmkxKAurMlxdQnJsvmaFwXgQJIbZA15H6or2jXC_5dwv1MR5AoRK9eJ57GI_fJEBg7hciqwAPHKGF2xfAQEJXtv3-pGs9xZfKzOJRv0/s220/face.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5143432091175065954.post-2724778664529078720</id><published>2008-01-05T10:06:00.000-08:00</published><updated>2008-01-05T11:14:24.407-08:00</updated><title type='text'>The integrity drop - or - How to disable UIPI take 2</title><content type='html'>&lt;div align=&quot;justify&quot;&gt;On vista if you create a process with a low integrity level token, the &lt;a href=&quot;http://msdn2.microsoft.com/en-us/library/bb625963.aspx&quot;&gt;User Interface Privilege Isolation (UIPI) &lt;/a&gt;will prevent it from talking to windows owned my medium/high integrity level processes.&lt;br /&gt;&lt;br /&gt;What if you don&#39;t want that? Maybe you already have another plan for UI protection? Running in a job for example.&lt;br /&gt;&lt;br /&gt;There is the easy way: [&lt;a href=&quot;http://msdn2.microsoft.com/en-us/library/bb625963.aspx&quot;&gt;From MSDN&lt;/a&gt;]&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;p align=&quot;justify&quot;&gt;&lt;br /&gt; &lt;/p&gt;&lt;p align=&quot;justify&quot;&gt;By specifying &lt;strong&gt;UIAccess=”true”&lt;/strong&gt; in the requestedPrivileges attribute [of the application manifest], the application is stating a requirement to bypass UIPI restrictions on sending window messages across privilege levels. Windows Vista implements the following policy checks before starting an application with UIAccess privilege.&lt;br /&gt;The application&lt;strong&gt; must have a digital signature&lt;/strong&gt; that can be verified using a digital certificate that chains up to a trusted root in the local machine Trusted Root&lt;br /&gt;Certification Authorities certificate store.&lt;br /&gt;The application &lt;strong&gt;must be installed in a local folder application directory that is writeable only by administrators&lt;/strong&gt;, such as the Program Files directory. &lt;/p&gt;&lt;/blockquote&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;Unfortunately this is not going to work if you application can be installed by non-admin users.&lt;br /&gt;&lt;br /&gt;Fortunately, there is another (not documented) way to &quot;disable&quot; UIPI.&lt;br /&gt;&lt;br /&gt;Windows initializes UIPI during the process startup. If you create the process with a low integrity level, then UIPI will prevent it from accessing windows owned by medium/high integrity level processes.&lt;br /&gt;&lt;br /&gt;But no one said that it was not possible to change the integrity level of a process AFTER it is started. If you own the process, and you trust that it&#39;s not going to run any potentially malicious piece of code before main(), you can add code at the beginning of your main() to drop the integrity level. From now on, the process is going to run with the new integrity level and UIPI won&#39;t be updated.&lt;br /&gt;&lt;br /&gt;Dropping the integrity level is easy:&lt;br /&gt;&lt;br /&gt;Get a handle to the process token using &lt;a href=&quot;http://207.46.199.254/en-us/library/aa379295(VS.85).aspx&quot;&gt;OpenProcessToken&lt;/a&gt; and call &lt;a href=&quot;http://207.46.199.254/en-us/library/aa379591(VS.85).aspx&quot;&gt;SetTokenInformation&lt;/a&gt; on it with the &lt;a href=&quot;http://msdn2.microsoft.com/en-us/library/aa379626.aspx&quot;&gt;TokenIntegrityLevel&lt;/a&gt; information class to set the new integrity level.&lt;br /&gt;&lt;br /&gt;But this is not all. If you only do this, your process won&#39;t be able to play sound. This is because when you play sound, &lt;a href=&quot;http://blogs.msdn.com/larryosterman/archive/2007/01/31/what-is-audiodg-exe.aspx&quot;&gt;audiodg.exe&lt;/a&gt; creates some objects on your behalf. At some point it will impersonate your token and open your process. Since your process was created with a medium integrity level token, the integrity/mandatory label on the process is Medium. When audiodg tries to open your process with your token, it does not have access and it fails.&lt;br /&gt;&lt;br /&gt;What you must do is change the security label on the process to be low integrity level. The easy way to do this is to create a &lt;a href=&quot;http://msdn2.microsoft.com/en-us/library/aa379567(VS.85).aspx&quot;&gt;SDDL&lt;/a&gt; string for the integrity label and to follow the code in this &lt;a href=&quot;http://msdn2.microsoft.com/en-us/library/bb625960.aspx&quot;&gt;example&lt;/a&gt;. You should use this SDDL string: &quot;S:(ML;;NWNR;;;LW)&quot; It means that it&#39;s a SDDL for a SACL (S:), with a Mandatory Label ace type (ML), the ace access is No-Write-Up and No-Read-Up (NWNR) and the integrity level is low (LW). The example is using NW instead of NWNR but for a process it&#39;s better to prevent lower privileges processes from being able to read it&#39;s process memory.&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nsylvain.blogspot.com/feeds/2724778664529078720/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/5143432091175065954/2724778664529078720' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5143432091175065954/posts/default/2724778664529078720'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5143432091175065954/posts/default/2724778664529078720'/><link rel='alternate' type='text/html' href='http://nsylvain.blogspot.com/2008/01/integrity-drop-or-how-to-disable-uipi.html' title='The integrity drop - or - How to disable UIPI take 2'/><author><name>nsylvain</name><uri>http://www.blogger.com/profile/16393263594312873401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUe6CR-d31Ox18_Sn1esXdvng5YmkxKAurMlxdQnJsvmaFwXgQJIbZA15H6or2jXC_5dwv1MR5AoRK9eJ57GI_fJEBg7hciqwAPHKGF2xfAQEJXtv3-pGs9xZfKzOJRv0/s220/face.JPG'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5143432091175065954.post-4946609400469825539</id><published>2008-01-05T08:53:00.000-08:00</published><updated>2008-01-05T10:02:35.117-08:00</updated><title type='text'>SetWindowsHookEx and Restricted Token</title><content type='html'>One easy way on Windows to inject a DLL is to use &lt;a href=&quot;http://msdn2.microsoft.com/en-us/library/ms644990.aspx&quot;&gt;SetWindowsHookEx&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;From MSDN:&lt;br /&gt;&lt;blockquote&gt;&lt;p&gt;The SetWindowsHookEx function installs an application-defined hook procedure&lt;br /&gt;into a hook chain. You would install a hook procedure to monitor the system for&lt;br /&gt;certain types of events. These events are associated either with a specific&lt;br /&gt;thread or with all threads in the same desktop as the calling thread.&lt;/p&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;&lt;br /&gt;When the event you are interested in is triggered for the first time in a process, your DLL is going to get loaded and your hook procedure will be called. For example, if you set a mouse hook, the DLL is going to get loaded in the process as soon as you move the mouse over a window owned by this process.&lt;br /&gt;&lt;br /&gt;But the desktop is not a perfect security boundary. You can have applications on the desktop running as a different users, with different rights. You can also have some applications running as a restricted version of yourself. How can we ensure that an application can&#39;t use SetWindowsHookEx to elevate it&#39;s privilege?&lt;br /&gt;&lt;br /&gt;There are multiple answers.&lt;br /&gt;&lt;br /&gt;First of all you can put this application on a &lt;a href=&quot;http://msdn2.microsoft.com/en-us/library/ms684161.aspx&quot;&gt;job object&lt;/a&gt; and set the &lt;a href=&quot;http://msdn2.microsoft.com/en-us/library/ms684152(VS.85).aspx&quot;&gt;UILIMIT_HANDLES&lt;/a&gt; restriction. With this restriction a process in the job object can set hooks only on processes that are also in the job. But setting this flag also means that you can&#39;t access any user handles (HWND, etc) created by processes not associated with the job. If your application has some UI, then you have a lot of work to do if you want to fix everything that is going to break! (No icons, no cursors, can&#39;t access the desktop window). &lt;a href=&quot;http://msdn2.microsoft.com/en-us/library/ms686884(VS.85).aspx&quot;&gt;UserHandleGrantAccess&lt;/a&gt; can help you here...&lt;br /&gt;&lt;br /&gt;On vista it&#39;s a little bit easier, you can run the application with a low integrity level token and &lt;a href=&quot;http://msdn2.microsoft.com/en-us/library/bb625963.aspx&quot;&gt;User Interface Privilege Isolation (UIPI&lt;/a&gt;) will do the work for you. Internet Explorer 7 is using it to be more secure. It will prevent your application from setting hooks on other applications running with a higher integrity level.&lt;br /&gt;&lt;br /&gt;What if you can&#39;t use any of them? Well, if your application is running with a restricted token, you may not have to worry about this at all. A restricted token is a stripped down version of your token created with the &lt;a href=&quot;http://msdn2.microsoft.com/en-us/library/aa446583(VS.85).aspx&quot;&gt;CreateRestrictedToken&lt;/a&gt; api. The SidsToRestrict array passed to the function must be non-null. In other words, &lt;a href=&quot;http://msdn2.microsoft.com/en-us/library/aa379137(VS.85).aspx&quot;&gt;IsTokenRestricted&lt;/a&gt; must return true. If this is the case, Windows will do the right thing and will not trust your application if you try to set a hook.&lt;br /&gt;&lt;br /&gt;I haven&#39;t found any documentation on this... but during my tests I have seen two different behaviors:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;div align=&quot;justify&quot;&gt;For some hooks (WH_MOUSE for example), when the event is received in another process, instead of loading the DLL, it sends a message to the thread that registered the hook. The message is handled internally and will cause the hook procedure to be called. Your application is now receiving and parsing all the events from all processes by itself in its own process. That does not sounds very efficient to me, but at least it&#39;s not a security flaw. (Don&#39;t quote me on this)&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div align=&quot;justify&quot;&gt;For some other hooks (WH_CALLWNDPROC for example), the event seems to be ignored and the hook procedure is never called.&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p align=&quot;justify&quot;&gt;&lt;/p&gt;&lt;p align=&quot;justify&quot;&gt;&lt;/p&gt;&lt;p align=&quot;justify&quot;&gt;I haven&#39;t done a lot of testing so far on this, but it seems like a thread running with a restricted token can&#39;t inject a DLL using SetWindowsHookEx, which is good.&lt;/p&gt;&lt;p align=&quot;justify&quot;&gt;&lt;/p&gt;&lt;p align=&quot;justify&quot;&gt;&lt;/p&gt;&lt;p align=&quot;justify&quot;&gt;One warning: If you try to do this, there is a nasty side effect. Since the events are now sent to the calling thread using window messages, you must have a message loop, otherwise your system is going hang! I don&#39;t think there was any requirement before that the caller of SetWindowsHookEx have to peek messages.&lt;/div&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://nsylvain.blogspot.com/feeds/4946609400469825539/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/5143432091175065954/4946609400469825539' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5143432091175065954/posts/default/4946609400469825539'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5143432091175065954/posts/default/4946609400469825539'/><link rel='alternate' type='text/html' href='http://nsylvain.blogspot.com/2008/01/setwindowshookex-and-restricted-token.html' title='SetWindowsHookEx and Restricted Token'/><author><name>nsylvain</name><uri>http://www.blogger.com/profile/16393263594312873401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUe6CR-d31Ox18_Sn1esXdvng5YmkxKAurMlxdQnJsvmaFwXgQJIbZA15H6or2jXC_5dwv1MR5AoRK9eJ57GI_fJEBg7hciqwAPHKGF2xfAQEJXtv3-pGs9xZfKzOJRv0/s220/face.JPG'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5143432091175065954.post-5037039002895574760</id><published>2007-09-22T09:32:00.000-07:00</published><updated>2007-09-22T09:46:56.257-07:00</updated><title type='text'>Old Old New Thing</title><content type='html'>&lt;div align=&quot;justify&quot;&gt;Today I was trying to catch up with all the new entries on Raymond&#39;s blog and I found some interesting posts that are worth taking a look. &lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://blogs.msdn.com/oldnewthing/archive/2007/09/17/4948130.aspx&quot;&gt;What do I do with per-user data when I uninstall?&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div align=&quot;justify&quot;&gt;Microsoft says... oh wait...  I mean.. Raymond Chen says that we should not touch it!  Quick and Easy! I like that :)&lt;/div&gt;&lt;br /&gt;&lt;a href=&quot;http://blogs.msdn.com/oldnewthing/archive/2007/09/13/4886108.aspx&quot;&gt;Why isn&#39;t QuickEdit on by default in console windows?&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Because it breaks console mode applications using the mouse.&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://blogs.msdn.com/oldnewthing/archive/2007/09/04/4731478.aspx&quot;&gt;Does creating a thread from DllMain deadlock or doesn&#39;t it?&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div align=&quot;justify&quot;&gt;It does not. Except if you create the lock yourself by waiting for the thread to do something, because it&#39;s not going to run until you exit DllMain.&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nsylvain.blogspot.com/feeds/5037039002895574760/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/5143432091175065954/5037039002895574760' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5143432091175065954/posts/default/5037039002895574760'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5143432091175065954/posts/default/5037039002895574760'/><link rel='alternate' type='text/html' href='http://nsylvain.blogspot.com/2007/09/old-old-new-thing.html' title='Old Old New Thing'/><author><name>nsylvain</name><uri>http://www.blogger.com/profile/16393263594312873401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUe6CR-d31Ox18_Sn1esXdvng5YmkxKAurMlxdQnJsvmaFwXgQJIbZA15H6or2jXC_5dwv1MR5AoRK9eJ57GI_fJEBg7hciqwAPHKGF2xfAQEJXtv3-pGs9xZfKzOJRv0/s220/face.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5143432091175065954.post-3079828598197937574</id><published>2007-09-02T19:37:00.001-07:00</published><updated>2007-09-04T07:53:09.194-07:00</updated><title type='text'>Handle Format</title><content type='html'>&lt;div align=&quot;justify&quot;&gt;A couple of posts ago I talked about how to get the list of all open handles. When I started playing with that it did not work at the first try, so I had to use the brute force method to get all the handles in the current process. The code was doing a loop like this:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;for (LONG_PTR h = 0; h &lt; 0xFFFF; ++h) {&lt;br /&gt;  HANDLE handle = (HANDLE)(h);&lt;br /&gt;  DoSomething(handle);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;The result was unexpected to me. All handles in the process were duplicated 4 times. It looks like the lowest 2 bits in the handle value are ignored.&lt;br /&gt;&lt;br /&gt;If the handle to a file is 0x7C then you can use 0x7C, 0x7D, 0x7E or 0x7F to access the file.&lt;br /&gt;&lt;br /&gt;Is this documented somewhere?&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Updated on 9/3/2007: &lt;/b&gt;&lt;br /&gt;I was talking with Ivanlef0u about this and my assumption that the last 2 bits are ignored is right. He showed me the disassembly of the function to lookup the object in the handle table and it looks like this:&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;pre&gt;&lt;br /&gt;ExpLookupHandleTableEntry&lt;br /&gt;mov edi, edi&lt;br /&gt;push ebp&lt;br /&gt;mov ebp, esp&lt;br /&gt;and [ebp+Handle], 0FFFFFFFCh ; Unset the last 2 bits&lt;br /&gt;mov eax, [ebp+Handle]&lt;br /&gt;mov ecx, [ebp+HandleTable]&lt;br /&gt;mov edx, [ebp+Handle]&lt;br /&gt;shr eax, 2 ; Shift right the last 2 bits&lt;br /&gt;cmp edx, [ecx+38h] ; HandleTable-&gt;NextHandleNeedingPool&lt;br /&gt;jnb loc_49DDF8&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Thanks Ivanlef0u.</content><link rel='replies' type='application/atom+xml' href='http://nsylvain.blogspot.com/feeds/3079828598197937574/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/5143432091175065954/3079828598197937574' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5143432091175065954/posts/default/3079828598197937574'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5143432091175065954/posts/default/3079828598197937574'/><link rel='alternate' type='text/html' href='http://nsylvain.blogspot.com/2007/09/handle-format.html' title='Handle Format'/><author><name>nsylvain</name><uri>http://www.blogger.com/profile/16393263594312873401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUe6CR-d31Ox18_Sn1esXdvng5YmkxKAurMlxdQnJsvmaFwXgQJIbZA15H6or2jXC_5dwv1MR5AoRK9eJ57GI_fJEBg7hciqwAPHKGF2xfAQEJXtv3-pGs9xZfKzOJRv0/s220/face.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5143432091175065954.post-4863027793675811388</id><published>2007-09-02T15:21:00.000-07:00</published><updated>2007-09-04T07:53:45.862-07:00</updated><title type='text'>Using Visual Studio to debug your token.</title><content type='html'>&lt;div align=&quot;justify&quot;&gt;For as long as I remember I have been using TokenMaster to be able to see and dump the information contained in my access tokens.&lt;br /&gt;Recently greggm blogged about &lt;a href=&quot;http://blogs.msdn.com/greggm/archive/2006/03/30/565303.aspx&quot;&gt;another way to get this information&lt;/a&gt;. This is now integrated in the visual studio debugger. Just type &quot;$user&quot; in the watch window and you will get a complete view of the current token.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Updated on 9/4/2007&lt;/b&gt;&lt;br /&gt;Thanks to Marc-Antoine Ruel for the information, Windbg also does that! Just type this command to get the same information:&lt;br /&gt;&lt;/div&gt;&lt;pre&gt;&lt;br /&gt;      !token -n&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://nsylvain.blogspot.com/feeds/4863027793675811388/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/5143432091175065954/4863027793675811388' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5143432091175065954/posts/default/4863027793675811388'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5143432091175065954/posts/default/4863027793675811388'/><link rel='alternate' type='text/html' href='http://nsylvain.blogspot.com/2007/09/using-visual-studio-to-debug-your-token.html' title='Using Visual Studio to debug your token.'/><author><name>nsylvain</name><uri>http://www.blogger.com/profile/16393263594312873401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUe6CR-d31Ox18_Sn1esXdvng5YmkxKAurMlxdQnJsvmaFwXgQJIbZA15H6or2jXC_5dwv1MR5AoRK9eJ57GI_fJEBg7hciqwAPHKGF2xfAQEJXtv3-pGs9xZfKzOJRv0/s220/face.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5143432091175065954.post-4910458902053889218</id><published>2007-09-02T11:26:00.000-07:00</published><updated>2007-09-04T07:57:37.606-07:00</updated><title type='text'>How to list all the open handles?</title><content type='html'>&lt;p&gt;&lt;br /&gt;&lt;div align=&quot;justify&quot;&gt;Recently I had to get the list of all the handles open in a process. I searched on the web to find a good way to do it, and realized that most of the articles I found are wrong.&lt;br /&gt;&lt;br /&gt;I guess this is because the documentation in &quot;Windows NT/2000 Native API Reference&quot; by Gary Nebbett is a little bit misleading.&lt;br /&gt;&lt;br /&gt;Under the SystemHandleInformation class, the structure defined is:&lt;br /&gt;&lt;/div&gt;&lt;pre&gt;&lt;br /&gt;typedef struct _SYSTEM_HANDLE_INFORMATION {&lt;br /&gt;  USHORT ProcessId;&lt;br /&gt;  USHORT CreatorBackTraceIndex;&lt;br /&gt;  UCHAR ObjectTypeNumber;&lt;br /&gt;  UCHAR Flags;&lt;br /&gt;  USHORT Handle;&lt;br /&gt;  PVOID Object;&lt;br /&gt;  ACCESS_MASK GrantedAccess;&lt;br /&gt;} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;One could think that the buffer returned is actually a list of structures like this one. But this is not the case, it&#39;s actually returning a structure like this one:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;typedef struct _SYSTEM_HANDLE_INFORMATION_EX {&lt;br /&gt;  ULONG NumberOfHandles;&lt;br /&gt;  SYSTEM_HANDLE_INFORMATION Information[1];&lt;br /&gt;} SYSTEM_HANDLE_INFORMATION_EX, *PSYSTEM_HANDLE_INFORMATION_EX;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;Even though the description in the book is misleading, Gary Nebbett is not wrong. There is a remark saying: &quot;The data returning to the SystemInformation buffer is a ULONG count of he number of handles followed immediately by an array of SYSTEM_HANDLE_INFORMATION&quot;. &lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;There is another factor making this task a little bit more complex to achieve: The function is really picky about the buffer size.&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;Usually you can call the function with a NULL buffer and 0 for the size and then get back the size you need to allocate your buffer. This does not work here. The return value is 0xC0000004 : The specified information record length does not match the length required for the specified information class.&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;If you try with a SYSTEM_HANDLE_INFORMATION buffer, it won&#39;t work either. You need to pass to the function a buffer large enough to hold the number of handles and the first handle if you want to get the size needed back. This is a little bit weird.&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;Finally, the code:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  // Get the number of handles on the system&lt;br /&gt;  DWORD buffer_size = 0;&lt;br /&gt;  SYSTEM_HANDLE_INFORMATION_EX temp_info;&lt;br /&gt;&lt;br&gt;&lt;br /&gt;  NTSTATUS status = NtQuerySystemInformation(&lt;br /&gt;      SystemHandleInformation, &amp;temp_info, &lt;br /&gt;      sizeof(temp_info), &amp;amp;buffer_size);&lt;br /&gt;&lt;br&gt;&lt;br /&gt;  SYSTEM_HANDLE_INFORMATION_EX *system_handles =&lt;br /&gt;    (SYSTEM_HANDLE_INFORMATION_EX*)(new BYTE[buffer_size]);&lt;br /&gt;&lt;br&gt;&lt;br /&gt;  status = NtQuerySystemInformation(SystemHandleInformation,&lt;br /&gt;                                    system_handles,&lt;br /&gt;                                    buffer_size, &amp;buffer_size);&lt;br /&gt;&lt;br&gt;&lt;br /&gt;  printf(&quot;nb of handles = %d&quot;, system_handles-&gt;NumberOfHandles);&lt;br /&gt;&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://nsylvain.blogspot.com/feeds/4910458902053889218/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/5143432091175065954/4910458902053889218' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5143432091175065954/posts/default/4910458902053889218'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5143432091175065954/posts/default/4910458902053889218'/><link rel='alternate' type='text/html' href='http://nsylvain.blogspot.com/2007/09/how-list-all-open-handles.html' title='How to list all the open handles?'/><author><name>nsylvain</name><uri>http://www.blogger.com/profile/16393263594312873401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUe6CR-d31Ox18_Sn1esXdvng5YmkxKAurMlxdQnJsvmaFwXgQJIbZA15H6or2jXC_5dwv1MR5AoRK9eJ57GI_fJEBg7hciqwAPHKGF2xfAQEJXtv3-pGs9xZfKzOJRv0/s220/face.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5143432091175065954.post-1910290233159553588</id><published>2007-08-09T16:10:00.000-07:00</published><updated>2007-08-09T22:32:53.523-07:00</updated><title type='text'>sizeof Cheat Sheet</title><content type='html'>&lt;div align=justify&gt;It&#39;s hard to justify why this kind of cheat sheet is necessary. We should all know this information by heart. Unfortunately I realize that sometimes I&#39;m not 100% sure and I have to look it up. If it happens again, then I&#39;ll come back here!&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The size of the different types is in bytes.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;                win64  win32&lt;br /&gt;-------------------------------&lt;br /&gt;bool              1      1&lt;br /&gt;BYTE              1      1&lt;br /&gt;char              1      1&lt;br /&gt;-------------------------------&lt;br /&gt;SHORT             2      2&lt;br /&gt;wchar_t           2      2&lt;br /&gt;WORD              2      2&lt;br /&gt;-------------------------------&lt;br /&gt;BOOL              4      4&lt;br /&gt;DWORD             4      4&lt;br /&gt;float             4      4&lt;br /&gt;HRESULT           4      4&lt;br /&gt;int               4      4&lt;br /&gt;long              4      4&lt;br /&gt;unsigned int      4      4&lt;br /&gt;unsigned long     4      4&lt;br /&gt;-------------------------------&lt;br /&gt;HANDLE            8      4&lt;br /&gt;INT_PTR           8      4&lt;br /&gt;LONG_PTR          8      4&lt;br /&gt;ULONG_PTR         8      4&lt;br /&gt;void*             8      4&lt;br /&gt;-------------------------------&lt;br /&gt;__int64           8      8&lt;br /&gt;double            8      8&lt;br /&gt;LONGLONG          8      8&lt;br /&gt;ULONGLONG         8      8&lt;br /&gt;-------------------------------&lt;br /&gt;FLOAT128         16     16&lt;br /&gt;-------------------------------&lt;br /&gt;&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://nsylvain.blogspot.com/feeds/1910290233159553588/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/5143432091175065954/1910290233159553588' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5143432091175065954/posts/default/1910290233159553588'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5143432091175065954/posts/default/1910290233159553588'/><link rel='alternate' type='text/html' href='http://nsylvain.blogspot.com/2007/08/sizeof-cheat-sheet.html' title='sizeof Cheat Sheet'/><author><name>nsylvain</name><uri>http://www.blogger.com/profile/16393263594312873401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUe6CR-d31Ox18_Sn1esXdvng5YmkxKAurMlxdQnJsvmaFwXgQJIbZA15H6or2jXC_5dwv1MR5AoRK9eJ57GI_fJEBg7hciqwAPHKGF2xfAQEJXtv3-pGs9xZfKzOJRv0/s220/face.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5143432091175065954.post-6817163610281490537</id><published>2007-08-08T20:50:00.001-07:00</published><updated>2007-08-08T21:41:13.092-07:00</updated><title type='text'>ThreadHideFromDebugger! But Why?</title><content type='html'>&lt;div align=&quot;justify&quot;&gt;At BlackHat last week Mark Vincent Yason talked about the art of unpacking. One of the techniques used by some packers is to hide their threads from the debugger so it can&#39;t be easily debugged.&lt;br /&gt;&lt;br /&gt;It is really easy to hide a thread from the debugger, you just have to call :&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;pre&gt;NtSetInformationThread(hThread, ThreadHideFromDebugger, NULL, 0);&lt;/pre&gt;&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;At this point the debugger will stop receiving debug information or exceptions from this thread. But be careful! If you are debugging the process and you set a breakpoint and it happens to hit in the hidden thread, the process will crash and windbg won&#39;t even realize it.&lt;br /&gt;&lt;br /&gt;After the presentation I was not able to stop asking myself why did Microsoft implemented this feature. It seems like the only usage is to make &quot;malicious&quot; code harder to debug. Maybe they implemented it to mute some noisy threads? Or maybe they wanted to protect some system threads? If you know the answer, please let me know!&lt;br /&gt;&lt;br /&gt;The next thing to do was to check if Microsoft is in fact using this feature. I put a conditional breakpoint on NtSetInformationThread to hit when the ThreadInformationClass is equal to ThreadHideFromDebugger.&lt;br /&gt;Unfortunately it never hit. (Tested on XPSP2 and Vista). There is also the possibility that they are changing the ETHREAD structure manually, but I doubt so. I&#39;ll try to check that later.&lt;br /&gt;&lt;br /&gt;On the other hand, something interesting came up during this experiment. On Vista it seems like NtSetInformationThread is called really often with an invalid (or undocumented) ThreadInformationClass. I&#39;ll try to investigate that and write my results in another post. In the mean time, I dumped the number of occurrences of each ThreadInformationClass during the boot of windows. I haven&#39;t found any use for that yet, but anyway:&lt;br /&gt;&lt;br /&gt;Windows XP SP2&lt;br /&gt;&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;pre&gt;   4 ThreadPriority&lt;br /&gt;  16 ThreadBasePriority&lt;br /&gt;   2 ThreadAffinityMask&lt;br /&gt;2069 ThreadImpersonationToken&lt;br /&gt;  16 ThreadQuerySetWin32StartAddress&lt;br /&gt;  16 ThreadZeroTlsCell&lt;/pre&gt;&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;br /&gt;&lt;br /&gt;Windows VISTA&lt;br /&gt;&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;pre&gt;  16 ThreadPriority&lt;br /&gt; 490 ThreadBasePriority&lt;br /&gt;   4 ThreadAffinityMask&lt;br /&gt;6293 ThreadImpersonationToken&lt;br /&gt;  71 ThreadZeroTlsCell&lt;br /&gt;   1 ThreadPriorityBoost&lt;br /&gt; 460 Unknown - 0x16&lt;br /&gt; 481 Unknown - 0x18&lt;br /&gt;  10 Unknown - 0x19&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nsylvain.blogspot.com/feeds/6817163610281490537/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/5143432091175065954/6817163610281490537' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5143432091175065954/posts/default/6817163610281490537'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5143432091175065954/posts/default/6817163610281490537'/><link rel='alternate' type='text/html' href='http://nsylvain.blogspot.com/2007/08/threadhidefromdebugger-but-why.html' title='ThreadHideFromDebugger! But Why?'/><author><name>nsylvain</name><uri>http://www.blogger.com/profile/16393263594312873401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUe6CR-d31Ox18_Sn1esXdvng5YmkxKAurMlxdQnJsvmaFwXgQJIbZA15H6or2jXC_5dwv1MR5AoRK9eJ57GI_fJEBg7hciqwAPHKGF2xfAQEJXtv3-pGs9xZfKzOJRv0/s220/face.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5143432091175065954.post-81134032652099521</id><published>2007-08-06T19:57:00.000-07:00</published><updated>2007-08-09T11:44:58.630-07:00</updated><title type='text'>David LeBlanc @ BlackHat : Practical Windows Sandboxing</title><content type='html'>&lt;div align=&quot;justify&quot;&gt;One of the main reasons I went to BlackHat last week was for David LeBlanc and his presentation about windows sandboxing. Unfortunately I missed it. I really don&#39;t know what happened. David was the last one of a series of three 20minute talks. I was there for the first two but it looked like they cancelled both of them. Thinking that they cancelled the series, I left the room and went to see the fuzzing talk by Pedram Amini (Very interesting by the way).&lt;br /&gt;&lt;br /&gt;Fortunately David blogged about his presentation:&lt;br /&gt;&lt;br /&gt;Part 1: &lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;a href=&quot;http://blogs.msdn.com/david_leblanc/archive/2007/07/27/practical-windows-sandboxing-part-1.aspx&quot;&gt;http://blogs.msdn.com/david_leblanc/archive/2007/07/27/practical-windows-sandboxing-part-1.aspx&lt;/a&gt;&lt;br /&gt;Part 2:&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;a href=&quot;http://blogs.msdn.com/david_leblanc/archive/2007/07/30/practical-windows-sandboxing-part-2.aspx&quot;&gt;http://blogs.msdn.com/david_leblanc/archive/2007/07/30/practical-windows-sandboxing-part-2.aspx&lt;/a&gt;&lt;br /&gt;Part 3:&lt;/div&gt;&lt;div align=&quot;justify&quot;&gt;&lt;a href=&quot;http://blogs.msdn.com/david_leblanc/archive/2007/07/31/practical-windows-sandboxing-part-3.aspx&quot;&gt;http://blogs.msdn.com/david_leblanc/archive/2007/07/31/practical-windows-sandboxing-part-3.aspx&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This is actually really interesting and it&#39;s awesome that restricted tokens and job objects are now used for sandboxing by Microsoft. I really wish I hadn&#39;t missed this talk!&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nsylvain.blogspot.com/feeds/81134032652099521/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/5143432091175065954/81134032652099521' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5143432091175065954/posts/default/81134032652099521'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5143432091175065954/posts/default/81134032652099521'/><link rel='alternate' type='text/html' href='http://nsylvain.blogspot.com/2007/08/david-leblanc-blackhat-practical.html' title='David LeBlanc @ BlackHat : Practical Windows Sandboxing'/><author><name>nsylvain</name><uri>http://www.blogger.com/profile/16393263594312873401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUe6CR-d31Ox18_Sn1esXdvng5YmkxKAurMlxdQnJsvmaFwXgQJIbZA15H6or2jXC_5dwv1MR5AoRK9eJ57GI_fJEBg7hciqwAPHKGF2xfAQEJXtv3-pGs9xZfKzOJRv0/s220/face.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5143432091175065954.post-2266421731357679875</id><published>2007-08-04T19:33:00.000-07:00</published><updated>2007-08-09T11:45:26.468-07:00</updated><title type='text'>Why you should not trust CreateProcess&#39; PROCESS_INFORMATION</title><content type='html'>&lt;div align=&quot;justify&quot;&gt;At GreenBorder I was working on a complex multi-process application with a lot of interactions between the processes through IPC and &lt;a href=&quot;http://msdn2.microsoft.com/en-us/library/ms724251.aspx&quot;&gt;DuplicateHandle&lt;/a&gt;. The processes were created with &lt;a href=&quot;http://msdn2.microsoft.com/en-us/library/ms682425.aspx&quot;&gt;CreateProcess&lt;/a&gt;. This call returns a &lt;a href=&quot;http://msdn2.microsoft.com/en-us/library/ms684873.aspx&quot;&gt;PROCESS_INFORMATION&lt;/a&gt; structure containing the process ID of the newly created process, the thread ID of the main thread along with their handles.&lt;br /&gt;&lt;br /&gt;I was using the structure to initialize my IPC and was using the process handle to duplicate some others handles into this new process.&lt;br /&gt;&lt;br /&gt;Everything sounds good right? Wrong!&lt;br /&gt;&lt;br /&gt;The problems started happening the first time I had to debug a complex bug. Since this is a multi-process architecture, the easiest/best solution to debug the child processes is to set the &lt;a href=&quot;http://blogs.msdn.com/greggm/archive/2005/02/21/377663.aspx&quot;&gt;Image File Execution&lt;/a&gt; for the process to start your favorite debugger (Windbg in this case) automatically. Unfortunately it turned out to be a lot worse. After a little while I discovered that the PROCESS_INFORMATION structure returned by CreateProcess was not containing the information about my process... but the information about the debugger! All calls to DuplicateHandle were in fact duplicating handles into Windbg.&lt;br /&gt;&lt;br /&gt;I can see how I could have refactored the code to not depend on the hProcess, but my case was not that simple. I was in fact calling &lt;a href=&quot;http://msdn2.microsoft.com/en-us/library/ms682429.aspx&quot;&gt;CreateProcessAsUser&lt;/a&gt; with a restricted token. Too restricted for Windbg to be able to run properly!&lt;br /&gt;&lt;br /&gt;To solution was to change the way I debug child processes. I&#39;m now using the &quot;Debug Child Processes Also&quot; option in windbg. Oh, and if you don&#39;t control the creation of the parent process, you can still attach to it and type the command &quot;.childdbg 1&quot;.&lt;br /&gt;&lt;br /&gt;Note: While I was writing this post I looked on the web for some references and I found &lt;a href=&quot;http://blogs.msdn.com/oldnewthing/archive/2007/07/02/3652873.aspx&quot;&gt;a post&lt;/a&gt; about this exact same issue from Raymond Chen posted only 1 month ago. My blog should also be called &quot;The old new thing&quot; :)&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nsylvain.blogspot.com/feeds/2266421731357679875/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/5143432091175065954/2266421731357679875' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5143432091175065954/posts/default/2266421731357679875'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5143432091175065954/posts/default/2266421731357679875'/><link rel='alternate' type='text/html' href='http://nsylvain.blogspot.com/2007/08/why-you-should-not-trust-createprocess.html' title='Why you should not trust CreateProcess&#39; PROCESS_INFORMATION'/><author><name>nsylvain</name><uri>http://www.blogger.com/profile/16393263594312873401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUe6CR-d31Ox18_Sn1esXdvng5YmkxKAurMlxdQnJsvmaFwXgQJIbZA15H6or2jXC_5dwv1MR5AoRK9eJ57GI_fJEBg7hciqwAPHKGF2xfAQEJXtv3-pGs9xZfKzOJRv0/s220/face.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5143432091175065954.post-1068058849973435408</id><published>2007-08-04T08:41:00.000-07:00</published><updated>2008-01-20T08:48:10.163-08:00</updated><title type='text'>First Post!</title><content type='html'>&lt;div align=&quot;justify&quot;&gt;Hey!&lt;br /&gt;&lt;br /&gt;I&#39;m Nicolas Sylvain, software engineer in the SF Bay Area. This is my first post on this blog and hopefully not my last one. I just got the unexpected motivation to create a blog. I don&#39;t know yet how often I&#39;ll update this blog; I guess it will depend on what&#39;s happening and how much time I have. I&#39;m really curious to see!&lt;br /&gt;&lt;br /&gt;The main subject of this blog is Windows Internals and its security. It will be presented from the point of view of the developer. That does not mean that I&#39;m not going to talk about random stuff, but at the end, most of the posts should talk about the security of the Windows operating system.&lt;br /&gt;&lt;br /&gt;Why is this called &quot;The Final Stream”? I&#39;m not sure yet. I just think it sounds cool. I might rethink this later :)&lt;br /&gt;&lt;br /&gt;Who am I? Well, I&#39;m Nic. I&#39;m from Quebec, Canada so I speak French. Please forgive my English! I moved to Silicon Valley in 2005 to work for a startup called GreenBorder who developed a sandboxed virtual environment to protect the OS and the user data from malicious code running in the browsers or email clients. Recently I joined a much bigger company. I might talk a little bit more about what I&#39;m doing in a later post, but you should not be waiting for that :)&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nsylvain.blogspot.com/feeds/1068058849973435408/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/5143432091175065954/1068058849973435408' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5143432091175065954/posts/default/1068058849973435408'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5143432091175065954/posts/default/1068058849973435408'/><link rel='alternate' type='text/html' href='http://nsylvain.blogspot.com/2007/08/first-post.html' title='First Post!'/><author><name>nsylvain</name><uri>http://www.blogger.com/profile/16393263594312873401</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUe6CR-d31Ox18_Sn1esXdvng5YmkxKAurMlxdQnJsvmaFwXgQJIbZA15H6or2jXC_5dwv1MR5AoRK9eJ57GI_fJEBg7hciqwAPHKGF2xfAQEJXtv3-pGs9xZfKzOJRv0/s220/face.JPG'/></author><thr:total>1</thr:total></entry></feed>