如题win7操作系统,写了个dll被SNMP服务加载,打算调用WTSQueryUserToken得到令牌,
用来CreateProcessAsUser。结果返回ERROR_PRIVILEGE_NOT_HELD。对win7用户权限机制不太熟悉,
请问这个问题该怎么解决啊?

解决方案 »

  1.   

    得到的令牌是否正确,获取Explorer.exe的令牌来模拟
      

  2.   

    确定snmp服务具有tcb特权,一般看它进程的用户名是不是SYSTEM
      

  3.   


    To call this function successfully, the calling application must be running within the context of the LocalSystem account and have the SE_TCB_NAME privilege. ------from MSDN从资源管理器可以看到该服务运行于system账户,session 0。我看看有没有办法确定该服务是否有SE_TCB_NAME权限。
      

  4.   

    另外,自己写的服务程序,都能够成功调用WTSQueryUserToken,而系统自带的snmp服务不行。
      

  5.   

    用procexp看了 SeTcbPrivilege没有开启
      

  6.   

    并且SeTcbPrivilege在权限里根本就不存在,所以调用AdjustTokenPrivileges也不能够开启。现在该怎么办呢?
      

  7.   

    是SYSTEM ,工作在session 0
      

  8.   

    win7啊 找了半天找不到这方面的解决方法我自己写的别的service中调用就没问题,可是在windows snmp 服务下面加载dll就有问题。通过procexp查看,自己写的服务有SeTcbPrivilege并且默认启用,snmp服务就没有这个权限。求解~
      

  9.   

     win7可以指定服务特权,你去注册表看看
      

  10.   

    注册表HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SNMP\ 
    下的RequiredPrivileges项,这里应该是修改service特权的,我加入了SeTcbPrivilege,
    用sc qprivs SNMP命令,可以查看特权列表,也是可以查到增加了eTcbPrivilege的,但是
    procexp下仍然看不到snmp服务有该特权,并且WTSQueryUserToken仍然返回ERROR_PRIVILEGE_NOT_HELD。
    同时,我也尝试了在本地策略用户权限分配的以操作系统方式执行,仍然不行。
    重启过也都不行。继续跟进
      

  11.   

    你可以创建一个具有tcb特权的服务,然后用ipc让这个服务办事
      

  12.   

    嗯 每个服务都有自己的特权,肯定有个地方对这些进行管理,从一篇文章看是在注册表RequiredPrivileges项中进行管理,但是修改了没用。而且特权中有SeLoadDriverPrivilege,也就是说可以调用driver,这个特权能够忽略session隔离吗? 试试有没有解决办法, 实在不行只能进程间通信了。
      

  13.   

    试验过了,即使服务有SE_LOAD_DRIVER_NAME特权,并且enabled,也是不能穿透session隔离的。
      

  14.   

    那么在snmp服务中,没有SeTcbPrivilege特权,它本身无法创建子进程。要想在snmp服务中得到驱动信息,只能够创建一个有tcb特权的服务,在该服务中创建子进程,由该子进程和tcb特权服务通信,tcb特权服务再和snmp服务通信。是不是有点太绕了啊
      

  15.   

    就想在snmp服务中调用显卡驱动
      

  16.   

    snmp不是网络的吗,为何要显卡
      

  17.   

    SNMP是网络协议,通常用于网络监管,查看多个设备的状态。一台计算机作为被监管的设备,需要向监控方汇报自己的很多状态,比如计算机名、硬盘大小等等,这些基础信息都由windows自带的snmp服务实现。作为用户,可能要对snmp服务进行扩展,加进自己设备的监管,这个过程就可能调用设备的驱动查询设备状态,比如显卡驱动,这也是我要在snmp服务中调用显卡驱动的原因。
      

  18.   

    为什么要 load driver ?
    与驱动通信,不是用 CreateFile 加 DeviceIoControl 吗?
      

  19.   

    windows还有几个王牌特权
    debug
    create token
    take ownership
    你看你有几个
      

  20.   

    如果要回报信息,可以自写服务检测,再通过网络上报,你的服务可以调用 SNMP (不太清楚 SNMP 工作方式,和你的dll的工作方式。说法可能有误,或者是socket ?)
      

  21.   


    没错,SNMP服务本身是socket通信。但是重新写一套服务检测、上报等于是重做了一遍SNMP协议,windows做好了现成的snmp服务没道理不借用。windows SNMP服务本身已经做好了用户扩展接口,我只要做一个dll并实现init、query、close等接口并在注册表中把该dll和snmp注册就会被snmp服务加载。CreateFile 加 DeviceIoControl是可以访问设备驱动,但是显卡等设备有自己成熟的api。而且win7操作系统是服务和application进行了session隔离,服务无法直接访问驱动,即使用DeviceIoControl也无法穿透session隔离。服务中拿到桌面token并创建子进程调用驱动,然后与子进程进行通信是Impact of Session 0 Isolation on Services and Drivers in Windows Vista这篇微软官方文档给出的方案。
      

  22.   

    无奈的是,只有SeChangeNotifyPrivilege,默认启用。没有任何其它特权。如果能找到增加服务特权的地方也行,注册表那里我试了不管用。
      

  23.   

    没有assign primary token特权,估计连createprocessasuser都不能调用,你还是再弄个服务,他这样设计也是为安全着想你巴snmp服务的注册表信息发上来给我看看
      

  24.   

    Windows Registry Editor Version 5.00[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SNMP]
    "Type"=dword:00000010
    "Start"=dword:00000002
    "ErrorControl"=dword:00000001
    "ImagePath"=hex(2):25,00,53,00,79,00,73,00,74,00,65,00,6d,00,52,00,6f,00,6f,00,\
      74,00,25,00,5c,00,53,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,00,5c,00,73,\
      00,6e,00,6d,00,70,00,2e,00,65,00,78,00,65,00,00,00
    "DisplayName"="SNMP Service"
    "ObjectName"="LocalSystem"
    "Description"="@%SystemRoot%\\system32\\snmp.exe,-4"
    "ServiceSidType"=dword:00000001
    "FailureActions"=hex:80,51,01,00,00,00,00,00,01,00,00,00,03,00,00,00,14,00,00,\
      00,01,00,00,00,60,ea,00,00,01,00,00,00,60,ea,00,00,00,00,00,00,00,00,00,00
    "RequiredPrivileges"=hex(7):53,00,65,00,54,00,63,00,62,00,50,00,72,00,69,00,76,\
      00,69,00,6c,00,65,00,67,00,65,00,00,00,53,00,65,00,4c,00,6f,00,61,00,64,00,\
      44,00,72,00,69,00,76,00,65,00,72,00,50,00,72,00,69,00,76,00,69,00,6c,00,65,\
      00,67,00,65,00,00,00,00,00[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SNMP\Parameters]
    "NameResolutionRetries"=dword:00000010
    "EnableAuthenticationTraps"=dword:00000001[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SNMP\Parameters\ExtensionAgents]
    "snmptools"="SOFTWARE\\snmptools\\CurrentVersion"[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SNMP\Parameters\PermittedManagers]
    "1"="10.7.5.18"
    "2"="localhost"
    "3"="10.7.5.6"[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SNMP\Parameters\RFC1156Agent]
    "sysServices"=dword:0000004c
    "sysLocation"=""
    "sysContact"=""[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SNMP\Parameters\TrapConfiguration][HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SNMP\Parameters\TrapConfiguration\public]
    "1"="localhost"
    "2"="10.7.5.5"
    "3"="10.7.5.18"[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SNMP\Parameters\TrapConfiguration\testxie]
    "1"="10.7.5.6"
    "2"="localhost"[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\SNMP\Parameters\ValidCommunities]
    "public"=dword:00000008
    "testxie"=dword:00000008
      

  25.   

    RequiredPrivileges是我自己加的,我加的是SeTcbPrivilege
    SeLoadDriverPrivilege
      

  26.   

    很奇怪啊,看你22楼的形容
    既然Windows提供这种支持,不应该出现问题啊我baidu了一下,没清楚 SNMP服务是啥,
    你的dll在 Server 端 还是在 client端?
      

  27.   


    因为进程一旦启动,就不能增加新的privilege。
    so, 这个是策略吗,设置以后每次启动这个服务就要包含某个指定这个特权?说真的,Windows 7 已经慢慢的如xp那样普及了。
    很多新问题,还真是不好找答案(因为你不知道你不知道什么)。
      

  28.   


    你写的扩展DLL的接口是谁来调用,snmp服务?snmp陷阱服务?无所谓,那么是谁引起了这样一个调用?我根据自己的理解,应该是机器A,与机器B的snmp服务通信,最终落到你的dll上
    不知道我的理解对不对,如果对的话,感觉就像是 客户端程序在调用 WebService. SNMP服务就相当于IIS服务,你写的dll就相当于.asmx(编译后得到的.dll)……如果不对的话:
    如果是由.dll所在机器本地程序调用的话,我还真不理解……-_-如果是由.dll被加载后,创建线程,然后在线程内获取设备信息,在发给监管服务器端。如果是这样。服务器端你用的是神马接口来接受回报信息,也是SNMP服务吗?使用socket的程序? 还是在该.dll中直接使用 数据库访问接口?
      

  29.   

    The privileges for a particular service can be set programmatically using the ChangeServiceConfig2 API and are stored in clear text here in the registry:
    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\<service name>\ RequiredPrivileges是有API去设置服务特权,但本质还是修改注册表,修改特权后在我的程序中不起作用。
      

  30.   

    DLL是SNMP服务来调用,当别的机器与我的机器通信时,会落到我的dll中。有请求时,snmp服务会找我的DLL要结果,我的结果直接给snmp服务,返回数据由snmp服务去做。
      

  31.   

    哈哈,学了一招,在我的系统服务上试试。不过话说回来,你怎么不写 回报数据接收服务器端的dll呢?
    客户端用别的方式获取完了后,与服务器端的snmp通信,你写的dll 连接数据库 保存回报数据,这就不需要什么很特殊的特权级了。。你要求现有获取机制不变,并且有现成的库使用,WMI 也很强大远程查询计算机信息。。
      

  32.   

    采用snmp是统一监控标准,我没权限修改;我也只能控制我这边的机器。。我试试额外起个服务然后与该服务通信的办法吧。通信中转越多 越容易出错,哎
      

  33.   

      在我看的文章和参考的资料中,都说如果service如果要和应用程序交互,都需要拿到桌面令牌,用该令牌创建一个进程,在该进程中进行操作,然后service再与该进程通信达到目标。
      为什么不能直接创建一个application,然后service和该进程直接通信,达到目标?
      对于我的问题来说,直接创建一个访问驱动的application(不用任何token,就是一个exe程序),然后用snmp service和它通信,就能够要到驱动信息了。
      这样不是也能解决问题了吗?
      

  34.   

    可以,谁来运行这个exe?
    这个程序不能运行在session 0
      

  35.   

    创建的进程的最高 特权级 也就是和创建者一样。甚至更低。最简单的就是 再写一个系统服务,自动启动我不知道你要获取什么状态,不过可以在里面定时获取,把结果放到一个地方
    然后你的dll可以从这个地方取。。(file mapping ...)不然你就折腾于函数调用的 同步与数据封送 吧
      

  36.   

    嗯,通信的同步问题也挺麻烦,file mapping就舍弃了实时性。我再综合考虑下。
      

  37.   

    擦,忘记一件事件。你说有session隔离一直用 系统服务做些事情,不过也没用到什么特殊的(视频驱动)。
    不是和自己写的 文件系统驱动,就是 访问插入的磁盘,没啥意外情况啊。不知道你用的是什么方式……
      

  38.   

    这个也受UAC的限制,如果你获取网卡信息不需要管理员权限就可以
      

  39.   

    本机的话,内存映射是各种IPC方式中最快的。不过当其中一个关闭句柄的时候另一个得不到通知。我试着写过一个服务中调用另一个api,实际上是想用用户进程调用,不过没权限。所以就是A程序通过ipc把参数打包,传递给 系统服务B,并指明要调用 函数funa(...)
    funa 是在进程B中调用的,得出另一个结构体,在打包传给进程A。A进程超时等待进程B的回应,想象起来很简单,实现起来我花了好久,原因之一就是 没有断开通知,所以并不知道没反应到底是对方死了,还是怎么了。
      

  40.   

    自己创建的系统服务因为有SE_TCB_NAME特权,所以可以WTSQueryUserToken得到令牌,
    CreateProcessAsUser来穿透session隔离。所以这个问题不再重要了,snmp服务没有SE_TCB_NAME特权,
    才引出了上面这么多讨论。具体我还是想不做成服务,直接做一个application通信就行了。管理员权限还是能够保证的。也不想在通信同步上纠结太多,所以在考虑采用何种进程通信方式来满足我的需求。