ITPub博客

首页 > IT基础架构 > 网络安全 > [Pipe]跨域访问命名管道 (转)

[Pipe]跨域访问命名管道 (转)

原创 网络安全 作者:amyz 时间:2007-08-15 15:47:59 0 删除 编辑
[Pipe]跨域访问命名管道 (转)[@more@]

跨域访问命名管道

 XML:namespace prefix = o ns = "urn:schemas-microsoft-com:Office:office" />

版本

创建时间

创建人

备注

1.0.0604.1

2003-6-4

郑 昀

第一稿

 

 

 

 

Implementation SCOpe:

本文档将说明如何跨越两个互相不信任的windows 2000 域使用命名管道。问题最终解决,我有幸记录下了排查、解决问题的全过程。

 

继续阅读之前,我们假设您熟悉以下知识:

n  Named Pipe

n  Access Control List

n  Discretionary Access Control List

n  iis 5.0

 

现象

同事遇到了这么一个问题:

“我做了一个com(dll),这个com将被ASP调用,连接到一个namedpipe。现在遇到了一些访问权限问题:

COM和namedpipe位于同一个计算机

  使用vbs测试,com可访问管道

  使用iis,则com不能访问管道,错误代码是:5,Access is denied.  

 

COM和namedpipe位于不同的域中的计算机,IIS与COM位于同一个计算机

  使用vbs测试,com不能访问管道,错误代码:1326,Logon failure: unknown user name or bad password 

  使用iis,不能访问..错误代码是:5,Access is denied.

 

COM和namedpipe位于不同的域中的计算机

  但在COM所在计算机上使用.NET use server2pipe /USER:xxx

  指定了用户名,密码之后

  使用vbs测试,com可访问管道

  使用iis,不能访问..错误代码是:5,Access is denied.

 

综合起来,问题在于IIS进程调用的COM,访问另外的程序创建的命名管道时候,因权限问题而无法访问。”

解决步骤

需要做两步:

u  管道服务器端  在创建命名管道的时候,要明确指定DACL为NULL。如果不指定这一步,客户端将返回错误码:5(拒绝访问)。事实上只有管道创建者才可以访问管道。

u  客户端  客户端连接之前,使用WNetAddConnection2 进行网络连接登录。实际测试中发现,如果不进行这一步,运行结果返回错误码:1326。

 

DACL的指定

  Pipes的安全是由ACL控制的。

  同时我们需要了解IIS的进程身份。如果IIS虚拟目录指定的“应用程序保护”是”中”,那么IIS的ASP执行线程运行在IUSER_MachineName身份下。参见如下表格:

序号

应用

程序

保护

匿名账号

Thread Token

Process Token

1

低(IIS进程)

admin

TOMOSOFTadmin

Token Type:

 Impersonation
Impersonation Level:

Delegation

NT AUTHORITYSYSTEM

Token Type:

Primary
Impersonation Level:

 Anonymous

2

中

IUSR_SERVER

SERVERIUSR_SERVER

Token Type:

Impersonation
Impersonation Level:

 Impersonation

TOMOSOFTadmin

Token Type:

Primary
Impersonation Level:

Delegation

3

低(IIS进程)

IUSR_SERVER

UMSERVERIUSR_UMSERVER

Token Type:

 Impersonation
Impersonation Level:

 Impersonation

NT AUTHORITYSYSTEM

Token Type:

Primary
Impersonation Level:

 Anonymous

 

 

  详细情况请参见我的另一篇文档:

http://www.csdn.net/Develop/read_article.asp?id=14257

  《IIS 5.0的运行身份》

 

  当你创建了一个命名管道,它的安全参数指定了NULL,这就表明只有创建者才可以作为Client访问这个命名管道。

  所以,ASP执行线程是无权访问命名管道的。

 

  那么在我们遇到的这种情况下,希望指定命名管道为所有人所能访问,那就可以通过创建一个空的DACL来做到。

   你很容易就想到要用以下两个函数:

InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION)和

SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE)。

 

提请注意:第二个参数bDaclPresent参一定要是TRUE,这样才表明第三个参数pDacl有意义。这样我们才明确指定了一个NULL DACL作为安全描述符。

  创建这样一个Everyone可以访问的命名管道,代码如下(已经删除了错误处理代码):

 

  SECURITY_ATTRIBUTES  sa;

  PSECURITY_DESCRIPTOR  pSD;

  // create a security NULL security

  // descriptor, one that allows anyone

  // to write to the pipe... WARNING

  // entering NULL as the last attribute

  // of the CreateNamedPipe() will

   // indicate that you wish all

  // clients connecting to it to have

  // all of the same security attributes

  // as the user that started the

  // pipe server.

 

  pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR,

  SECURITY_DESCRIPTOR_MIN_LENGTH);

 

 

  if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION))

  {

  LocalFree((HLOCAL)pSD);

  return;

  }

 

  // add a NULL disc. ACL to the

  // security descriptor.

 

  if (!SetSecurityDescriptorDacl(pSD, TRUE, (PACL) NULL, FALSE))

  {

  LocalFree((HLOCAL)pSD);

  return;

  }

 

  sa.nLength = sizeof(sa);

  sa.lpSecurityDescriptor = pSD;

  sa.bInheritHandle = TRUE;

 

  // Create a local named pipe with

  // the name '.PIPEdemo'.  The

  // '.' signifies local pipe.

  hPipe = CreateNamedPipe ("\.PIPEdemo",  // Pipe name = 'demo'.

  PIPE_ACCESS_DUPLEX  // 2 way pipe.

  | FILE_FLAG_OVERLAPPED,  // Use overlapped structure.

  PIPE_WAIT  // Wait on messages.

  | PIPE_READMODE_MESSAGE   // Specify message mode pipe.

  | PIPE_TYPE_MESSAGE,

  MAX_PIPE_INSTANCES,  // Maximum instance limit.

  OUT_BUF_SIZE,  // Buffer sizes.

  IN_BUF_SIZE,

  TIME_OUT,  // Specify time out.

  &sa);  // Security attributes.

 

  // Check Errors.

  if ((DWORD)(DWORD_PTR)hPipe == 0xFFFFFFFF)

  {

    printf("hPipe == 0xFFFFFFFF  !!!!!!!!!!!!");

};

网络连接显式登录

在指定了命名管道可为Everyone访问之后,我们的试验依旧一再遭遇错误码“1326”。

 

后来发现,客户端连接命名管道时出错,其实和命名管道无关,即使试图打开一个不存在的NamedPipe,依然遭遇错误“1326”。所以我们认为还是需要网络连接显式登录。

 

所以,用到了以下代码:

  NETREsource ns;

  ns.dwScope =RESOURCE_CONNECTED; 

  ns.dwType =RESOURCETYPE_ANY;

  ns.dwDisplayType =RESOURCEDISPLAYTYPE_GENERIC;

  ns.dwUsage =RESOURCEUSAGE_CONNECTABLE;

  ns.lpRemoteName=(char*)PipeName;//服务器端的管道名

  ns.lpLocalName =NULL;

  ns.lpProvider =NULL;

  DWORD dwErr;

  dwErr=WNetAddConnection2(&ns, "password", "username", 0);

这样,就可以了。

 

更多信息

没有指定NULL DACL之前,我们很容易利用指定IIS的虚拟目录的匿名身份做到让IIS访问命名管道的。就是,设置 虚拟目录à属性à目录安全性à“匿名访问和身份验证控制”编辑à匿名访问使用账户 为一个创建命名管道的那个账户。当然,这样做很不安全,但是有效。

我们没有采用这个做法。

 

解决了NULL DACL问题之后,我们甚至按照以下这篇文章的指示,修改了服务器端的本地安全策略:

《Q126645 Access Denied When Opening a Named Pipe from a Service》

这上面说,一个SYSTEM账户身份运行的服务打开一个命名管道遇到访问禁止的错误,那么请修改注册表:

HKEY_LOCAL_MACHINE


SYSTEM


CurrentControlSet


Services


LanmanServer


    Parameters

NullSessionPipes

把你的命名管道名字加入,然后重启计算机。

 

我们试过了,没有作用。

看来我们的问题不在于NULL Session。

 

其实,修改注册标的这个动作,你完全可以在 本地安全策略à本地策略à安全选项à网络访问:可匿名访问的命名管道 中找到。效果是一样的。

 

 

总结:

跨域(两个互相不信任的Windows2000域)访问命名管道的解决之道:

 

1:

管道服务器端,在创建命名管道的时候,要指定DACL为NULL;这个很必要;

 

2:

客户端端连接之前,一定要进行模拟网络连接登录。

 

要不然,什么1326、1398、53、998等等错误码你都可以见到。

 

Disclaimers:

本文档所包含的信息代表了在发布之日,zhengyun对所讨论问题的当前看法。本文档不应理解为zhengyun一方的承诺,zhengyun不保证所给信息在发布之日以后的准确性。

本文档仅供参考。

用户必须遵守所有适用的版权法。在不对版权法所规定的权利加以限制的情况下,如未得到 zhengyun和CSDN.Net明确的书面许可,不得出于任何目的、以任何形式或手段(电子的、机械的、影印、录制等等)复制、传播本文的任何部分,也不得将其存储或引入到检索系统中。

 

Thank zy_zhang;

Written by zhengyun (at) tomosoft.com

 

 


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/10752019/viewspace-958550/ ,如需转载,请注明出处,否则将追究法律责任。

上一篇: Delphi与Excel (转)
请登录后发表评论 登录
全部评论
  • 博文量
    3982
  • 访问量
    7895803