Development Impacts of Security Changes in Windows Server 2003

原创 2004年10月12日 13:32:00

Michael Howard
Secure Windows Initiative

June 16, 2003

Summary: Michael Howard outlines some of the security changes made to Microsoft Windows Server 2003 to reduce its attack surface, and discusses how these changes impact the software developer. (9 printed pages)

Note   The security changes discussed in this article are in no particular order.

Is That Service You Rely on Running?

One of the first things we did when developing Microsoft Windows Server™ 2003 was to turn off less-commonly used services. If a service has a security bug, and it's not running by the default, then the exploit potential is dramatically reduced. The prime example is Internet Information Services (IIS). Many Web application applications build on IIS and their setup tools expect the Web server to be there—but guess what—by default it's not. You should determine your operating system dependencies, and then update your setup tool to inform the user if a dependency is not running. A good example is NetDDE. If your application uses NetDDE you'll need to (a) start the service because it's disabled by default or (b) migrate your application to a more modern protocol like, say, sockets!

IIS 6.0 Runs No User Code as SYSTEM

By default, all worker processes run as a Network Service. Once again, it's an in-depth defense mechanism. Some ISAPI applications perform the following steps:

  1. Call RevertToSelf, expecting the resulting process identity to be SYSTEM.
  2. Do some tasks that only SYSTEM can perform.
  3. Impersonate the user again.

This scenario does not work on IIS 6.0 because step 2 fails since user code runs in much lower privilege than SYSTEM. So how do you fix this? The only truly secure way to fix it is to change the way your ISAPI works. Frankly, you shouldn't process user's requests as SYSTEM, just in case your code is compromised. If you need to perform some request in elevated privilege, then create a service that runs with the required privileges and passes the request to the service over a pipe or socket. Another way to remedy the issue is to run the worker process as SYSTEM. However, this second solution is a kludge, and it's not the best scenario.

Impersonation Functions May Fail

I already discussed this in detail in the March 2003 article Impersonation Issues, but it's worth repeating. In Windows Server 2003 impersonation is a privilege granted only to admins, service accounts and COM+ processes running as specific identities. If your application calls any impersonation function, including SetThreadToken, it may fail unless it has the SeImpersonatePrivilege privilege. In short, if your code does fail, the token returned to you will be an identify token, and not an impersonation function. Refer to my previous article for more information and remedies.

Creating Various Global Objects May Fail

Starting with Windows Server 2003, the creation of some global objects, such as file mapping will fail unless the calling process has the SeCreateGlobalPrivilege privilege enabled. Note that the privilege check is limited to the creating of said objects, and does not apply to opening existing ones. For example, the following code will fail on Windows Server 2003 unless the process account has this privilege:

0, 0xFFFF,"Global//MyMapping");

By default this privilege is assigned to all services and administrators. This privilege also applies when creating symbolic links in the object manager. The way around this is to either grant the account in question this privilege, or do not make the object name global. Of course, the latter may not be possible.

DLL Search Order Has Changed

No longer is the current directory searched first when loading DLLs! This change was also made in Windows XP SP1. The default behavior now is to look in all the system locations first, then the current directory, and finally any user-defined paths. This will have an impact on your code if you install a DLL in the application's directory because Windows Server 2003 no longer loads the 'local' DLL if a DLL of the same name is in the system directory. A common example is if an application won't run with a specific version of a DLL, an older version is installed that does work in the application directory. This scenario will fail in Windows Server 2003.

The reason this change was made was to mitigate some kinds of trojaning attacks. An attacker may be able to sneak a bad DLL into your application directory or a directory that has files associated with your application. The DLL search order change removes this attack vector.

The SetDllDirectory function, also available in Windows XP SP1, modifies the search path used to locate DLLs for the application and affects all subsequent calls to the LoadLibrary and LoadLibraryEx functions by the application.

Implications of Security Enhanced Internet Explorer

During the Windows Server 2003 security audit in December 2002, we asked the Internet Explorer team to evaluate the potential threats (I don't mean bugs or vulnerabilities—I mean avenues of attack and damage potential) when an administrator is browsing untrusted Internet-based Web sites from a computer acting as a domain controller. This led us to disable all mobile code capabilities in the browser including VBScript, JScript, ActiveX controls, Java, and .NET Framework components. The way the mobile code functionality is disabled is by setting very tight zone security policy and setting strict enhanced security settings. I'm not going to outline all the settings as they are available in the article Internet Explorer Enhanced Security Configuration. You should print this document out and read it a couple of times.

So what does this mean for you? That's a complex question because it depends on what you're doing. If you write Web server code that creates Web pages containing mobile code, then the client may not work correctly. But this is no different from a security-conscious user disabling, say, scripting.

In short, you should thoroughly test any application you use that relies on Internet Explorer technologies. If you find problems, the easiest fix is to change the browser settings to a more permissive setting, but I don't think that's necessarily the correct thing to do for your customers. Rather, I would recommend you add the Web server name to the Trusted Sites zone. Please don't ask the administrator to loosen the settings unless there is a really, really good reason.

Secure Root ACLs

We changed the ACLs on the file system root to be much more secure than Everyone (Full Control). The ACL is now:

Admin, SYS, Creator – Full Control
Everyone – Read/Execute
Users – Read/Execute
   Create Folders/Append Data (this and sub folders)
   Create Files/Write Data (sub folders)

If you want to understand why this change has been made, read Windows 2000 Default Permissions Could Allow Trojan Horse Program. Essentially, this means that your application cannot write to C:/ unless the user is an administrator. So, unless you have good reason to write to C:/ don't do it.

Secure Share ACLs

This is a favorite change of mine. Shares are no longer Everyone: Full Control, but rather Everyone: Read. This was changed as a direct consequence of the Nimda worm that wrote its payload to network shares on other computers. Of course, if you have good ACLs on the files and directories, then the ACL on the share is moot, but this is a defense in depth measure.

Tighter ACLs on Event Logs

We also tightened up the ACLs on the event logs to restrict what accounts can read and write to the logs. Better still, the security of each log is configured locally through the values in the following registry key:


For example, the Application log Security Descriptor is configured through the following registry value:


And the System log Security Descriptor is configured through the following:


The Security Descriptor for each log is specified by using Security Descriptor Definition Language (SDDL) syntax. The following is an example from the Application event log:


Quick, what is this ACL in English? You can read about SDDL at This string means:

Entry Meaning
O:BA Object owner is Built-in Admin (BA).
G:SY Primary group is System (SY).
D: This is a DACL, rather than an audit entry or SACL.
(D;;0xf0007;;;AN) Deny Anonymous (AN) all access.
(D;;0xf0007;;;BG) Deny Built-in Guests (BG) all access.
(A;;0xf0005;;;SY) Allow System Read and Clear, including DELETE, READ_CONTROL, WRITE_DAC, and WRITE_OWNER (indicated by the 0xf0000).
(A;;0x7;;;BA) Allow Built-in Admin READ, WRITE and CLEAR.
(A;;0x7;;;SO) Allow Server Operators READ, WRITE and CLEAR.
(A;;0x3;;;IU) Allow Interactive Users READ and WRITE.
(A;;0x3;;;SU) Allow Service accounts READ and WRITE.
(A;;0x3;;;S-1-5-3) Allow Batch accounts (S-1-5-3) READ and WRITE.

The specific event log access mask bits are:

0x0001 ELF_LOGFILE_READ Permission to read log files.
0x0002 ELF_LOGFILE_WRITE Permission to write log files.
0x0004 ELF_LOGFILE_CLEAR Permission to clear log files.

The only time you should see a failure in your application when writing to the event log is because of an ACL issue. Please do not relax the ACL too much. Add your own ACE to the SDDL string and then restart the Event Log service. For example, if your process runs under an account MyAccount, that has the SID S-1-5-21-853885456-2109860151-3743179773-1190, and you want the process to write to the Application log, simply add this string to the SDDL string in the registry:

(A;;0x2;;; S-1-5-21-853885456-2109860151-3743179773-1190)

Restricting Remote Execution of Console Applications

To help mitigate bad guys calling into cmd.exe (and other tools) remotely, we changed the ACL on some critical console applications. Compare the Windows® 2000 ACL on cmd.exe with the ACL on Windows Server 2003:

Windows 2000
Administrators (Full Control)
System (Full Control)
Users (Read & Execute)
Windows Server 2003
Administrators (Full Control)
System (Full Control)
Interactive (Read & Execute)
Services (Read & Execute)

Now, this probably won't affect you, but you should be aware of the ACL change just in case.

More Restrictions on Anonymous Users

This should not affect too many applications, unless it makes anonymous connections to Windows Server 2003 computers to gather information. Essentially, we removed the Everyone SID out of the anonymous token. Now you must explicitly grant anonymous access through Policy settings. To do so, load the Group Policy Object snap-in, and navigate to Computer Configuration -> Windows Settings -> Security Settings -> Local Policies -> Security Options.

In-Memory Encryption

Okay, this is hardly a security change that may cause your application to fail, but it's something you should be aware of, and frankly, it's one of my pet peeve features.

We added two new functions to Windows Server 2003 that allow you to encrypt and decrypt secret data, such as passwords and cryptographic keys, in memory. This reduces the potential data exposure. The new functions are CryptProtectMemory and CryptUnprotectMemory. Note this functionality is also available in Windows 2000 SP3 and Windows XP using the RtlEncryptMemory and RtlDecryptMemory functions, but they have no associated import library. They are available as resources named SystemFunction040 and SystemFunction041 in Advapi32.dll. You must use the LoadLibrary and GetProcAddress functions to dynamically link to Advapi32.dll.

The following C++ class code shows how to access the functions from Windows 2000 and Windows XP:

#include "windows.h"
#include "strsafe.h" 

#   define RTL_ENCRYPT_MEMORY_SIZE           16
#   define RTL_ENCRYPT_OPTION_SAME_PROCESS         0x00
#   define RTL_ENCRYPT_OPTION_SAME_LOGON           0x02

class CMemCrypt {
public : 

   CMemCrypt() {
      char szDir[MAX_PATH+1];
      UINT cchDir = sizeof(szDir)/sizeof(szDir[0]);
      if (GetSystemDirectory(szDir,cchDir) == 0)
         throw GetLastError();

      if (FAILED(StringCchCat(szDir,cchDir,"//advapi32.dll")))

      m_hMod = LoadLibrary(szDir);
      if (NULL == m_hMod) 
         throw GetLastError();

      m_pEM = (EM)(GetProcAddress(m_hMod,"SystemFunction040"));
      m_pDM = (DM)(GetProcAddress(m_hMod,"SystemFunction041"));

        if (!m_pEM || !m_pDM) 
         throw GetLastError();

   virtual ~CMemCrypt() {
      if (m_hMod)

      m_pEM = m_pDM = NULL;
      m_hMod = NULL;

   DWORD Encrypt(PVOID pMem, ULONG cbMem, ULONG flags) {
      return (m_pEM)(pMem,cbMem,flags);

   DWORD Decrypt(PVOID pMem, ULONG cbMem, ULONG flags) {
      return (m_pDM)(pMem,cbMem,flags);

private :
   HMODULE m_hMod;

   typedef LONG (__stdcall *EM)(PVOID,ULONG,ULONG);
   typedef LONG (__stdcall *DM)(PVOID,ULONG,ULONG);
   EM m_pEM;
   DM m_pDM;

// example test code
int main(int argc, char* argv[]) {
   char p[16+1];
   p[16] = 0;

   CMemCrypt m;
   if (m.Encrypt(p,16,0))

   return 0;

A good starting point for more information regarding these functions is


In short, you should actively test your applications on a clean install of Windows Server 2003 to verify if any of the security changes affect your application. You can troubleshoot many security failures using the event log. In the case of ACL issues this will involve setting an audit ACE on the resource in question, and auditing for object access. For privilege issues, make sure you're auditing for failed privilege use.

Spot the Security Flaw

A bunch of people worked out my last error—it was a simple SQL injection attack. You can piggyback other SQL statements in the Id parameter, and thanks to the wonders of string concatenation, end up with a SQL query that does more than you expected, such as deleting database files, adding new user accounts, gathering credit card details, and so on. The remedy is to use SQL parameters, not string concatenation.

There are also a couple of other flaws people didn't pick up on, including connecting as the sysadmin account. Since when did you need to be sysadmin to query a table? Also, the code embeds a difficult-to-guess password in the code. Don't do that, ever! Finally, if the code fails for some reason, the code in exception handler tells the attacker exactly what failed.

Okay, onto the next error. What's up with this C# code?

// Restrict access to only non-FILE requests
// For example HTTP:// is valid, FILE:// is not
if (string.Compare("FILE",0,url.ToUpper(),0,4) != 0)

I'll give a hint in a week or so. You'll probably need it!

Michael Howard is a Senior Security Program Manager in the Secure Windows Initiative group at Microsoft and is the coauthor of Writing Secure Code, now in its second edition, and the main author of Designing Secure Web-based Applications for Windows 2000. His main focus in life is making sure people design, build, test, and document nothing short of a secure system. His favorite line is "One person's feature is another's exploit."

Windows Server 2003 SP2 中文版下载

    简体中文32位x86的版    在以下版本的Windows系统上安装:    Windows Server 2003 Editions     Windows Server 2003 R2 E...
  • tanaya
  • tanaya
  • 2007年04月14日 11:53
  • 1573

windows2003下ftp服务器FileZilla Server安装简要(非常简要)

windows2003的ftp服务很麻烦,第三方的用下来,我比较喜欢FileZilla Server。 安装过程中,会问道管理员登陆的密码,端口。一定要修改,并且记住。 ...
  • wuyt2008
  • wuyt2008
  • 2012年08月31日 17:02
  • 5204

Windows Storage Server 2003

前言:专用的存储服务器已成为市场趋势 企业为了打造出一个完善的存储平台以满足其未来高速成长的存储需求,非常需要用一套有效的方式去进行评估与考虑。尤其目前 NAS 的存储市场几乎是愈来愈小,对企业而言,...
  • zyqlc
  • zyqlc
  • 2004年07月01日 17:56
  • 1873

Windows Server 2003下无官方显卡驱动,看我如何解决

  我的机器装了个windows server 2003,以前没什么问题,用得挺好的,最近要运行DirectX的程序,怎么都没法渲染出图像。整了半天,总算把问题解决了。  首先,程序没有图像,肯定是显...
  • zxcred
  • zxcred
  • 2008年07月21日 16:36
  • 23465

Windows Server 2003 Standard Edition安装心得

Windows Server 2003 Standard Edition序列号:C4C24-QDY9P-GQJ4F-2DB6G-PFQ9WM6RJ9-TBJH3-9DDXM-4VX9Q-K8M8M我的...
  • china2wto
  • china2wto
  • 2005年03月02日 19:03
  • 3500

Windows Server 2003 PSDK February 2003 Edition VC6 配置

  • strategycn
  • strategycn
  • 2010年10月13日 17:34
  • 2617

Windows Server 2003 密钥

最新:微软学生Windows Server 2003密钥免费提供!(不信者,勿下载) 电驴资源 下...
  • qq794858207
  • qq794858207
  • 2014年04月19日 18:34
  • 5298

windows server 2003环境下安装oracle 10g

一、软件安装过程 1. 双击setup.exe,点击“开始安装” 2. 选择安装路径数据库类型为高级 3. 选择安装企业版 4. 选择安装目录 4. 检查先决条件 5....
  • tjujacob
  • tjujacob
  • 2012年08月21日 20:09
  • 1675

windows server 2003 serial key windows2003 sp2可用序列号大全(准版与企业版)

原文链接: 现在用2003的基本上是没有了,但是,我这里还有一些珍藏,通用性好的win2003序列号: FJ8DH-TQPYG-...
  • Mecoolshow
  • Mecoolshow
  • 2017年09月06日 22:50
  • 2342

入侵Windows server 2003 测试

1.         勘察主机 首先需要发现收集目标更多的信息,其中包括: l         目标网络上主机的IP地址 l         目标系统上可访问的TCP和UDP端口 l     ...
  • tham_
  • tham_
  • 2014年12月04日 17:10
  • 7461
您举报文章:Development Impacts of Security Changes in Windows Server 2003