首页 > 系统相关 >Windows RPC 计划任务(MS-TSCH协议)

Windows RPC 计划任务(MS-TSCH协议)

时间:2022-11-27 20:33:30浏览次数:112  
标签:status TSCH Windows 句柄 Auth RPC WCHAR NULL

Windows RPC 计划任务(MS-TSCH协议)

参考链接

https://github.com/Rvn0xsy/SchtaskCreator

实现目标

上一篇文章实现了自己调用自己编写的rpc接口,达到了远程调用的效果。
本篇目标尝试调用windows系统自身的rpc接口,实现在本地机器和远程机器创建计划任务

环境和文件

开发环境
    windows10
    visual studio 2019

需要建立的文件
    SchRpc.idl文件(下载链接:https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-tsch/96c9b399-c373-4490-b7f5-78ec3849444e)

第一步 编译SchRpc.idl文件




第二步 创建一个工程,使用上一步生成的文件

#include <stdio.h>
#include <taskschd.h>
#include "SchRpc.h"

#pragma comment(lib, "rpcrt4.lib")

#define MAX_LOADSTRING 2048
WCHAR szDefaultTaskXML[MAX_LOADSTRING];


void __RPC_FAR* __RPC_USER midl_user_allocate(size_t cBytes)
{
    return((void __RPC_FAR*) malloc(cBytes));
}

void __RPC_USER midl_user_free(void __RPC_FAR* p)
{
    free(p);
}

BOOL RegisterNewTask(PWCHAR username, PWCHAR password, PWCHAR domain, PWCHAR task_xml, PWCHAR ip_address, BOOL is_local, BOOL just_run) {
    RPC_STATUS status;
    RPC_WSTR StringBinding = NULL;
    RPC_BINDING_HANDLE Binding = NULL;
    PWCHAR ConnectProtocol = NULL;
    WCHAR ConnectRemoteProtocol[] = L"ncacn_ip_tcp";
    WCHAR ConnectLocalProtocol[] = L"ncalrpc";
    RPC_WSTR Hostname = NULL;
    SEC_WINNT_AUTH_IDENTITY_W Auth;

    if (lstrlenW(domain) == 0) {
        Auth.Domain = NULL;
        Auth.DomainLength = 0;
    }
    else {
        Auth.Domain = (RPC_WSTR)domain;
        Auth.DomainLength = lstrlenW(domain);
    }

    //判断是不是本地执行,组装相应的参数
    if (is_local) {
        ConnectProtocol = ConnectLocalProtocol;
    }
    else {
        ConnectProtocol = ConnectRemoteProtocol;
        Auth.User = (RPC_WSTR)username; // username
        Auth.Password = (RPC_WSTR)password; // password
        Auth.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
        Auth.UserLength = lstrlenW(username);
        Auth.PasswordLength = lstrlenW(password);
        Hostname = (RPC_WSTR)ip_address;
    }

    //1.RpcStringBindingCompose 函数创建字符串绑定句柄
    status = RpcStringBindingCompose(
        NULL,                        // Interface's GUID, will be handled by NdrClientCall
        (RPC_WSTR)ConnectProtocol,   // Protocol sequence
        Hostname,                    // Network address
        NULL,                        // Endpoint
        NULL,                        // No options here
        &StringBinding               // Output string binding
    );

    if (status != RPC_S_OK) {
        // printf("RpcStringBindingCompose failed - %x\n", status);
        return FALSE;
    }

    //2.RpcBindingFromStringBinding 函数从绑定句柄的字符串表示形式返回绑定句柄
    //  记得绑定成功的话,最后要释放绑定的句柄
    status = RpcBindingFromStringBinding(
        StringBinding,              // Previously created string binding  指向绑定句柄的字符串表示形式的指针
        &Binding                    // Output binding handle  返回指向服务器绑定句柄的指针
    );

    if (status != RPC_S_OK) {
        // printf("RpcBindingFromStringBindingA failed - %x\n", status);
        return FALSE;
    }
    // 3.如果不是本地认证,则采用网络认证获取成功的认证信息,为后续远程调用打下基础
    if (!is_local) {
        RpcTryExcept{
            //RpcBindingSetAuthInfo 函数设置绑定句柄的身份验证和授权信息(认证成功的凭证应该在Binding中)
            status = RpcBindingSetAuthInfo(
                    Binding,
                    Hostname,
                    RPC_C_AUTHN_LEVEL_DEFAULT,
                    RPC_C_AUTHN_DEFAULT,
                    &Auth,
                    NULL
                );
            if (status != RPC_S_OK)
            {
                // printf("RpcBindingSetAuthInfo failed - %d\n", status);
                return FALSE;
            }
        }
        RpcExcept(EXCEPTION_EXECUTE_HANDLER);
        {
            return FALSE;
        }
        RpcEndExcept
    }
    status = RpcStringFree(&StringBinding);  //释放句柄


    // 4.开始调用 计划任务
    RpcTryExcept
    {
        /*
         SchRpcCreateFolder  创建一个新文件夹
         HRESULT SchRpcCreateFolder(
           [in, string] const wchar_t* path,
           [in, string, unique] const wchar_t* sddl,
           [in] DWORD flags
         );
        */
        static const WCHAR Folder[] = L"\\Hello";
        SchRpcCreateFolder(Binding, Folder, NULL, 0);

        /*
        SchRpcRegisterTask 方法必须向服务器注册任务
         HRESULT SchRpcRegisterTask(
           [in, string, unique] const wchar_t* path,   句柄
           [in, string] const wchar_t* xml,   xml文件的计划任务
           [in] DWORD flags,
           [in, string, unique] const wchar_t* sddl,
           [in] DWORD logonType,
           [in] DWORD cCreds,
           [in, size_is(cCreds), unique] const TASK_USER_CRED* pCreds,
           [out, string] wchar_t** pActualPath,
           [out] PTASK_XML_ERROR_INFO* pErrorInfo
         );
        */
        static const WCHAR TaskPath[] = L"\\Hello\\TaskName";
        WCHAR* path = NULL;
        TASK_XML_ERROR_INFO* info = NULL;
        status = SchRpcRegisterTask(
            Binding,   //rpc调用多一个参数,手册中没有这个参数
            TaskPath,
            task_xml,
            TASK_CREATE | TASK_UPDATE,
            NULL,
            TASK_LOGON_NONE,
            0,
            NULL,
            &path,
            &info);

        if (status == RPC_S_OK && just_run) {
            GUID  pGuid;
            //立即运行
            status = SchRpcRun(Binding, TaskPath, NULL, NULL, TASK_RUN_IGNORE_CONSTRAINTS, NULL, NULL, &pGuid);
        }
    }
    RpcExcept(EXCEPTION_EXECUTE_HANDLER);
    {
        return FALSE;
    }
    RpcEndExcept
    {
    }

    if (status != RPC_S_OK) {
        return FALSE;
    }

    //释放绑定的句柄
    status = RpcBindingFree(&Binding);
    return TRUE;
}

int main()
{
    WCHAR szUsername[100] = L"administrator";
    WCHAR szPassword[100] = L"123456";
    WCHAR szIPAddress[100] = L"192.168.139.122";
    WCHAR szTaskXML[MAX_LOADSTRING] = L"<Task xmlns=\"http://schemas.microsoft.com/windows/2004/02/mit/task\"><RegistrationInfo><Date>2005-10-11T13:21:17-08:00</Date><Author>AuthorName</Author><Version>1.0.0</Version><Description>Notepad starts every day.</Description></RegistrationInfo><Triggers><CalendarTrigger><StartBoundary>2005-10-11T13:21:17-08:00</StartBoundary><EndBoundary>2006-01-01T00:00:00-08:00</EndBoundary><Repetition><Interval>PT1M</Interval><Duration>PT4M</Duration></Repetition><ScheduleByDay><DaysInterval>1</DaysInterval></ScheduleByDay></CalendarTrigger></Triggers><Principals><Principal id=\"LocalSystem\"><UserId>S-1-5-18</UserId><RunLevel>HighestAvailable</RunLevel></Principal></Principals><Settings><Enabled>true</Enabled><AllowStartOnDemand>true</AllowStartOnDemand><AllowHardTerminate>true</AllowHardTerminate></Settings><Actions><Exec><Command>notepad.exe</Command></Exec></Actions></Task>";
    WCHAR szDomain[100] = { 0 };
    
    // 开始本地执行(需要管理员权限)
#if 0
    if (RegisterNewTask(NULL, NULL, NULL, szTaskXML, NULL, TRUE, TRUE)) {
        printf("[*] 本地执行计划任务  ==>  立即执行成功");
    }
#endif // 0


#if 1
    //远程执行
    if (RegisterNewTask(szUsername, szPassword, szDomain, szTaskXML, szIPAddress, FALSE, TRUE)) {
        printf("[*] 远程执行计划任务  ==>  立即执行成功");
    }
#endif // 0

    return 0;
}

本地和远程执行效果

标签:status,TSCH,Windows,句柄,Auth,RPC,WCHAR,NULL
From: https://www.cnblogs.com/startstart/p/16930546.html

相关文章

  • Windows RPC 探测出网(MS-RPRN协议)
    WindowsRPC探测出网(MS-RPRN协议)参考链接https://github.com/Rvn0xsy/SchtaskCreatorhttps://payloads.online/archivers/2022-03-04/1/通过WindowsRPC批量寻找......
  • CentOS 搭建 samba 服务器并通过 Windows 访问
    第一步下载安装samba、samba-clientsudoyum-yinstallsambasamba-client终端提示安装完成第二步创建共享文件夹,这个文件夹到时候可以通过Windows资源管理器......
  • windows下安装redis
    1.安装包安装1)下载安装包下载地址:https://github.com/rgl/redis/downloads,选择msi后缀的文件下载。2)安装打开下载好的安装包,按提示步骤一路安......
  • Basler的python库安装(windows)
    Basler官方的python支持放到了GitHub上,GitHub-basler/pypylon:TheofficialpythonwrapperforthepylonCameraSoftwareSuite截止到2022.11.27日,支持到python3.1......
  • 一个XP使用者眼中的Windows 7
    我本来想将这篇文章命名为“windows7试用报告”,但我想我没有太多资格这样命名,因为我在大多数时间用的是XP,vista没有深入使用过。只知道vista的UAC很烦人。根据统计,浏览​​......
  • Windows 7环境下HttpListener拒绝访问异常解决方法
      问题:Win7下在尝试搭建简单http服务器的时候,执行httpListener.Start();报错HttpListener拒绝访问异常 代码如下:HttpListenerhttpListener=newHttpListene......
  • 利用vs.net快速开发windows服务(总结)
    在很多应用中需要做windows服务来操作数据库等操作,比如(1)一些非常慢的数据库操作,不想一次性去做,想慢慢的通过服务定时去做,比如定时为数据库备份等(2)在.netRemoting中利用wi......
  • 调试Windows Service
       通常的处理办法是,在service运行后,在调试器中选择attachtoprocess.   然而这种做法也有一定的局限性,例如在service启动时的OnSta......
  • Python安装(Windows)
    个人喜欢从官网直接下载具体版本安装,然后通过cmd的pip安装其他包。1、官网下载Python,PythonReleasesforWindows|Python.org2、安装选择允许添加路径到系统环境,选择......
  • 分布式配置统一管理平台-Windows
    这里主要使用到disconf分布式配置管理平台支持window和linux下面是大家window环境步骤和一些操作总结。Git-2.6.4-64-bit.exe 1.下载并解压缩     nginx,解压缩到......