InitiateShutdown因远程计算机

时间:2016-01-17 03:17:39

标签: windows winapi remote-access rpc

我尝试使用以下代码使用InitiateShutdown API重新启动远程计算机,但它失败并显示RPC_S_SERVER_UNAVAILABLE1722错误代码:

//Process is running as administrator

//Select a remote machine to reboot:
//INFO: Tried it with and w/o two opening slashes.
LPCTSTR pServerName = L"192.168.42.105";
//Or use 127.0.0.1 if you don't have access to another machine on your network.
//This will attempt to reboot your local machine.
//In that case make sure to call shutdown /a /m \\127.0.0.1 to cancel it.

if(AdjustPrivilege(NULL, L"SeShutdownPrivilege", TRUE) &&
    AdjustPrivilege(pServerName, L"SeRemoteShutdownPrivilege", TRUE))
{
    int nErrorCode = ::InitiateShutdown(pServerName, NULL, 30,
                                        SHUTDOWN_INSTALL_UPDATES | SHUTDOWN_RESTART, 0);

    //Receive nErrorCode == 1722, or RPC_S_SERVER_UNAVAILABLE
}



BOOL AdjustPrivilege(LPCTSTR pStrMachine, LPCTSTR pPrivilegeName, BOOL bEnable)
{
    HANDLE hToken; 
    TOKEN_PRIVILEGES tkp;
    BOOL bRes = FALSE;

    if(!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
        return FALSE; 

    if(LookupPrivilegeValue(pStrMachine, pPrivilegeName, &tkp.Privileges[0].Luid))
    {
        tkp.PrivilegeCount = 1;  
        tkp.Privileges[0].Attributes = bEnable ? SE_PRIVILEGE_ENABLED : SE_PRIVILEGE_REMOVED; 

        bRes = AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0);
        int nOSError = GetLastError();
        if(bRes)
        {
            if(nOSError != ERROR_SUCCESS)
                bRes = FALSE;
        }
    }

    CloseHandle(hToken);

    return bRes;
}

因此,要准备运行此代码,请在this计算机上执行以下操作,Windows 7 Pro(就像我对Microsoft的shutdown工具所做的那样):

  • 以管理员身份运行以下""允许SMB访问D1计算机上的登录用户192.168.42.105this answer):
 NET USE \\192.168.42.105\IPC$ 1234 /USER:D1
  • 使用上面的代码"以管理员"。
  • 运行流程

然后在具有192.168.42.105(每answer here with most upvotes)的远程计算机或Windows 7 Pro上执行以下操作:

  • 控制面板,网络和共享中心,更改高级共享设置 "私人"启用"启用文件和打印机共享"

  • 设置以下键:

    HKEY_LOCAL_MACHINE \ SOFTWARE \微软\的Windows \ CurrentVersion \政策\系统

    LocalAccountTokenFilterPolicy = DWORD:1

  • 运行secpol.msc,然后转到本地安全策略,安全设置,本地策略,用户权限分配。添加"每个人" to"强制从远程系统关闭"。 (记得在你完成测试后删除它!)

请注意,以下shutdown命令似乎可以正常重启远程计算机:

shutdown /r /m \\192.168.42.105 /t 30

我的代码缺少什么?

修改

行。我承认我只是对InitiateShutdown似乎没有"想要"使用远程服务器连接,而InitiateSystemShutdownExInitiateSystemShutdown完全没有问题。 (不幸的是后两者没有dwShutdownFlags参数,我需要将SHUTDOWN_INSTALL_UPDATES标志传递给它,这导致了我的持久性......)

在这一点上,除了WinDbg的副本之外,我没有别的方法可以找到它......我还在试图深入研究它,但到目前为止,这是我发现的......

(A)事实证明InitiateSystemShutdownEx内部使用完全不同的RPC调用。没有太多细节,它使用以下参数启动与RpcStringBindingComposeW的RPC绑定:

   ObjUuid = NULL
   ProtSeq = ncacn_np
   NetworkAddr = \\192.168.42.105
   EndPoint = \\PIPE\\InitShutdown
   Options = NULL

或以下绑定字符串:

ncacn_np:\\\\192.168.42.105[\\PIPE\\InitShutdown]

(B)另一方面,InitiateShutdown使用以下绑定参数:

   ObjUuid = 765294ba-60bc-48b8-92e9-89fd77769d91
   ProtSeq = ncacn_ip_tcp
   NetworkAddr = 192.168.42.105
   EndPoint = NULL
   Options = NULL

它后来转换为以下绑定字符串:

ncacn_np:\\\\192.168.42.105[\\PIPE\\lsarpc]

它用于获取传递给WsdrInitiateShutdown的RPC句柄(似乎有own specification):

enter image description here

如您所见,InitiateShutdown调用在技术上被视为Unknown RPC service(对于UUID {765294ba-60bc-48b8-92e9-89fd77769d91}),后来在服务器和客户端之间进行了大量的凭据检查:

enter image description here

老实说,我不确定我是否想要使用低级调试器:)

在这个阶段,我会说我不太熟悉地方安全局"接口(或\PIPE\lsarpc命名管道配置。)因此,如果有人知道服务器端缺少什么配置以允许此RPC调用通过,我将不胜感激,如果你可以发布你的服务吗?

0 个答案:

没有答案