C# 使用 CredWrite 访问 C$

2023-11-22

我正在尝试使用没有该服务器权限的域帐户访问该服务器的 C$。我需要以本地登录的形式保存该服务器的凭据,以便程序正常工作。

如何使用 CredWrite 保存这些凭据

我找到的凭证管理器类:(编辑:以下是功能代码。)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;

namespace Test_Manager
{
    public class Win32CredMan
    {
        [DllImport("Advapi32.dll", EntryPoint = "CredReadW", CharSet = CharSet.Unicode, SetLastError = true)]
        static extern bool CredRead(string target, CRED_TYPE type, int reservedFlag, out IntPtr CredentialPtr);

        [DllImport("Advapi32.dll", EntryPoint = "CredWriteW", CharSet = CharSet.Unicode, SetLastError = true)]
        static extern bool CredWrite([In] ref NativeCredential userCredential, [In] UInt32 flags);

        [DllImport("Advapi32.dll", EntryPoint = "CredFree", SetLastError = true)]
        static extern bool CredFree([In] IntPtr cred);

        public enum CRED_TYPE : uint
        {
            GENERIC = 1,
            DOMAIN_PASSWORD = 2,
            DOMAIN_CERTIFICATE = 3,
            DOMAIN_VISIBLE_PASSWORD = 4,
            GENERIC_CERTIFICATE = 5,
            DOMAIN_EXTENDED = 6,
            MAXIMUM = 7,      // Maximum supported cred type
            MAXIMUM_EX = (MAXIMUM + 1000),  // Allow new applications to run on old OSes
        }
        public enum CRED_PERSIST : uint
        {
            SESSION = 1,
            LOCAL_MACHINE = 2,
            ENTERPRISE = 3,
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        private struct NativeCredential
        {
            public UInt32 Flags;
            public CRED_TYPE Type;
            public IntPtr TargetName;
            public IntPtr Comment;
            public System.Runtime.InteropServices.ComTypes.FILETIME LastWritten;
            public UInt32 CredentialBlobSize;
            public IntPtr CredentialBlob;
            public UInt32 Persist;
            public UInt32 AttributeCount;
            public IntPtr Attributes;
            public IntPtr TargetAlias;
            public IntPtr UserName;

            /// <summary>
            /// This method derives a NativeCredential instance from a given Credential instance.
            /// </summary>
            /// <param name="cred">The managed Credential counterpart containing data to be stored.</param>
            /// <returns>A NativeCredential instance that is derived from the given Credential
            /// instance.</returns>
            internal static NativeCredential GetNativeCredential(Credential cred)
            {
                NativeCredential ncred = new NativeCredential();
                ncred.AttributeCount = 0;
                ncred.Attributes = IntPtr.Zero;
                ncred.Comment = IntPtr.Zero;
                ncred.TargetAlias = IntPtr.Zero;
                ncred.Type = (CRED_TYPE)cred.Type;
                ncred.Persist = (UInt32)cred.Persist;
                ncred.CredentialBlobSize = (UInt32)cred.CredentialBlobSize;
                ncred.TargetName = Marshal.StringToCoTaskMemUni(cred.TargetName);
                ncred.CredentialBlob = Marshal.StringToCoTaskMemUni(cred.CredentialBlob);
                ncred.UserName = Marshal.StringToCoTaskMemUni(cred.UserName);
                return ncred;
            }
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        private struct Credential
        {
            public UInt32 Flags;
            public CRED_TYPE Type;
            public string TargetName;
            public string Comment;
            public System.Runtime.InteropServices.ComTypes.FILETIME LastWritten;
            public UInt32 CredentialBlobSize;
            public string CredentialBlob;
            public CRED_PERSIST Persist;
            public UInt32 AttributeCount;
            public IntPtr Attributes;
            public string TargetAlias;
            public string UserName;
        }

        #region Critical Handle Type definition
        sealed class CriticalCredentialHandle : CriticalHandleZeroOrMinusOneIsInvalid
        {
            // Set the handle.
            internal CriticalCredentialHandle(IntPtr preexistingHandle)
            {
                SetHandle(preexistingHandle);
            }

            internal Credential GetCredential()
            {
                if (!IsInvalid)
                {
                    // Get the Credential from the mem location
                    NativeCredential ncred = (NativeCredential)Marshal.PtrToStructure(handle,
                          typeof(NativeCredential));

                    // Create a managed Credential type and fill it with data from the native counterpart.
                    Credential cred = new Credential();
                    cred.CredentialBlobSize = ncred.CredentialBlobSize;
                    cred.CredentialBlob = Marshal.PtrToStringUni(ncred.CredentialBlob,
                          (int)ncred.CredentialBlobSize / 2);
                    cred.UserName = Marshal.PtrToStringUni(ncred.UserName);
                    cred.TargetName = Marshal.PtrToStringUni(ncred.TargetName);
                    cred.TargetAlias = Marshal.PtrToStringUni(ncred.TargetAlias);
                    cred.Type = ncred.Type;
                    cred.Flags = ncred.Flags;
                    cred.Persist = (CRED_PERSIST)ncred.Persist;
                    return cred;
                }
                else
                {
                    throw new InvalidOperationException("Invalid CriticalHandle!");
                }
            }

            // Perform any specific actions to release the handle in the ReleaseHandle method.
            // Often, you need to use Pinvoke to make a call into the Win32 API to release the 
            // handle. In this case, however, we can use the Marshal class to release the unmanaged memory.

            override protected bool ReleaseHandle()
            {
                // If the handle was set, free it. Return success.
                if (!IsInvalid)
                {
                    // NOTE: We should also ZERO out the memory allocated to the handle, before free'ing it
                    // so there are no traces of the sensitive data left in memory.
                    CredFree(handle);
                    // Mark the handle as invalid for future users.
                    SetHandleAsInvalid();
                    return true;
                }
                // Return false. 
                return false;
            }
        }
        #endregion

        public int WriteCred(string key, string user, string secret)
        {
            // Validations.

            byte[] byteArray = Encoding.Unicode.GetBytes(secret);
            if (byteArray.Length > 512)
                throw new ArgumentOutOfRangeException("The secret message has exceeded 512 bytes.");

            // Go ahead with what we have are stuff it into the CredMan structures.
            Credential cred = new Credential();
            cred.TargetName = key;
            cred.UserName = user;
            cred.CredentialBlob = secret;
            cred.CredentialBlobSize = (UInt32)Encoding.Unicode.GetBytes(secret).Length;
            cred.AttributeCount = 0;
            cred.Attributes = IntPtr.Zero;
            cred.Comment = null;
            cred.TargetAlias = null;
            cred.Type = CRED_TYPE.DOMAIN_PASSWORD;
            cred.Persist = CRED_PERSIST.ENTERPRISE;
            NativeCredential ncred = NativeCredential.GetNativeCredential(cred);
            // Write the info into the CredMan storage.
            bool written = CredWrite(ref ncred, 0);
            int lastError = Marshal.GetLastWin32Error();
            if (written)
            {
                return 0;
            }
            else
            {
                string message = string.Format("CredWrite failed with the error code {0}.", lastError);
                throw new Exception(message);
            }
        }

        public static string ReadCred(string key)
        {
            // Validations.

            IntPtr nCredPtr;
            string readPasswordText = null;

            // Make the API call using the P/Invoke signature
            bool read = CredRead(key, CRED_TYPE.GENERIC, 0, out nCredPtr);
            int lastError = Marshal.GetLastWin32Error();

            // If the API was successful then...
            if (read)
            {
                using (CriticalCredentialHandle critCred = new CriticalCredentialHandle(nCredPtr))
                {
                    Credential cred = critCred.GetCredential();
                    readPasswordText = cred.CredentialBlob;
                }
            }
            else
            {
                readPasswordText = string.Empty;

                //1168 is "element not found" -- ignore that one and return empty string:
                if (lastError != 1168)
                {
                    string message = string.Format("ReadCred failed with the error code {0}.", lastError);
                    throw new Exception(message);
                }
            }
            return readPasswordText;
        }
    }
}

长话短说,这是我尝试使用的上述代码中的方法:

public int WriteCred(string key, string user, string secret)
{
    // Validations.

    byte[] byteArray = Encoding.Unicode.GetBytes(secret);
    if (byteArray.Length > 512)
        throw new ArgumentOutOfRangeException("The secret message has exceeded 512 bytes.");

    // Go ahead with what we have are stuff it into the CredMan structures.
    Credential cred = new Credential();
    cred.TargetName = key;
    cred.UserName = user;
    cred.CredentialBlob = secret;
    cred.CredentialBlobSize = (UInt32)Encoding.Unicode.GetBytes(secret).Length;
    cred.AttributeCount = 0;
    cred.Attributes = IntPtr.Zero;
    cred.Comment = null;
    cred.TargetAlias = null;
    cred.Type = CRED_TYPE.DOMAIN_PASSWORD;
    cred.Persist = CRED_PERSIST.ENTERPRISE;
    NativeCredential ncred = NativeCredential.GetNativeCredential(cred);
    // Write the info into the CredMan storage.
    bool written = CredWrite(ref ncred, 0);
    int lastError = Marshal.GetLastWin32Error();
    if (written)
    {
        return 0;
    }
    else
    {
        string message = string.Format("CredWrite failed with the error code {0}.", lastError);
        throw new Exception(message);
    }
}

这就是我在程序正文中所做的事情:

Win32CredMan cm = new Win32CredMan();
cm.WriteCred("TheServer-18", @"TheServer-18\Administrator", "P4SSw0rD!");

我假设我无法访问,因为未正确添加凭据。

UPDATE:

我列出的过程是将通用凭据添加到 Windows 凭据管理器。但是,如果未使用 WriteCred 方法中指定的用户名。我不明白为什么。


问题已经解决,上面的代码现在可以正常运行了。 该问题与 GetNativeCredential 有关,它没有使用在 WriteCred 方法中分配给 cred 的值,而是使用一些已设置的静态值。

另外,我将信息输入 WriteCred 方法的方式不正确。上面的代码已被修复,因此它可以完全运行。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C# 使用 CredWrite 访问 C$ 的相关文章

  • 启动时出现 OData v4 错误:找不到段“Whatever”的资源

    我正在构建新的 v4 服务 一切进展顺利 直到我为新模型 实体添加了新控制器 并在启动站点进行测试运行时收到此错误 控制器似乎编码正确 就像其他控制器一样 控制器 CustomersOData 中的操作 GetFeed 上的路径模板 Cus
  • 如何为 C 分配的 numpy 数组注册析构函数?

    我想在 C C 中为 numpy 数组分配数字 并将它们作为 numpy 数组传递给 python 我可以做的PyArray SimpleNewFromData http docs scipy org doc numpy reference
  • 如何将 #ifdef DEBUG 添加到 Xcode?

    我的项目中有一些代码永远不应该在发布版本中使用 但在测试时很有用 我想做这样的事情 ifdef DEBUG Run my debugging only code endif 在 Xcode 4 中哪里添加 DEBUG 设置 我尝试将其放入
  • 互斥体实现可以互换(独立于线程实现)

    所有互斥体实现最终都会调用相同的基本系统 硬件调用吗 这意味着它们可以互换吗 具体来说 如果我使用 gnu parallel算法 使用openmp 并且我想让他们称之为线程安全的类我可以使用boost mutex用于锁定 或者我必须编写自己
  • 存储来自其他程序的事件

    我想将其他应用程序的事件存储在我自己的应用程序中 事件示例 打开 最小化 Word 或打开文件时 这样的事可能吗 运行程序 http msdn microsoft com en us library ms813609 aspx and 打开
  • 如何为 Python 中的应用程序设置专用屏幕区域?

    MS OneNote 就是一个很好的例子 它可以选择固定在屏幕的一侧 并将所有其他窗口推到一侧 当最大化或调整其他窗口大小时 它们只能扩展到 OneNote 的边缘 Python 使用 Tkinter 或其他模块是否具有此功能 感谢您的帮助
  • 用于检查项目文件中的项目变量和引用路径的 api

    我正在研究一个 net application VS2010 与 x 没有 解和变量号这些解决方案中的项目数量 我需要检查项目属性 特定于一定数量的项目 是否同质 并且检查 验证构建期间的参考路径 有没有一个API是这样的吗 如果没有 我该
  • 无法在 Windows 运行时组件库的 UserControl 中创建依赖项属性

    我想在用户控件内创建数据可绑定属性 这个用户控件包含一个 Windows 运行时组件 项目 我使用下面的代码来创建属性 public MyItem CurrentItem get return MyItem GetValue Current
  • 如何在 C# 中定义文本框数组?

    您好 当我在 Windows 申请表上创建文本框时 我无法将其命名为 box 0 box 1 等 我这样做的目的是因为我想循环使用它们 其实我发现TextBox array firstTextBox secondTextBox 也有效
  • 回发或回调参数无效。使用“”启用事件验证

    当我从客户端回发页面时 出现以下错误 我有修改客户端 asp ListBox 的 JavaScript 代码 我们该如何解决这个问题 错误详细信息如下 Server Error in XXX Application Invalid post
  • ASP.NET:获取自 1970 年 1 月 1 日以来的毫秒数

    我有一个 ASP NET VB NET 日期 我试图获取自 1970 年 1 月 1 日以来的毫秒数 我尝试在 MSDN 中寻找方法 但找不到任何东西 有谁知道如何做到这一点 从 NET 4 6 开始 该方法ToUnixTimeMillis
  • 单击 form2 上的按钮触发 form 1 中的方法

    我对 Windows 窗体很陌生 我想知道是否可以通过单击表单 2 中的按钮来触发表单 1 中的方法 我的表格 1 有一个组合框 我的 Form 2 有一个 保存 按钮 我想要实现的是 当用户单击表单 2 中的 保存 时 我需要检查表单 1
  • 未经许可更改内存值

    我有一个二维数组 当我第一次打印数组的数据时 日期打印正确 但其他时候 array last i 的数据从 i 0 到 last 1 显然是一个逻辑错误 但我不明白原因 因为我复制并粘贴了 for 语句 那么 C 更改数据吗 I use g
  • PlaySound 可在 Visual Studio 中运行,但不能在独立 exe 中运行

    我正在尝试使用 Visual Studio 在 C 中播放 wav 文件 我将文件 my wav 放入项目目录中并使用代码 PlaySound TEXT my wav NULL SND FILENAME SND SYNC 我按下播放按钮 或
  • C++:.bmp 到文件中的字节数组

    是的 我已经解决了与此相关的其他问题 但我发现它们没有太大帮助 他们提供了一些帮助 但我仍然有点困惑 所以这是我需要做的 我们有一个 132x65 的屏幕 我有一个 132x65 的 bmp 我想遍历 bmp 并将其分成小的 1x8 列以获
  • 如何编写一个同时需要请求和响应Dtos的ServiceStack插件

    我需要提供本地化数据服务 所有本地化的响应 Dto 都共享相同的属性 IE 我定义了一个接口 ILocalizedDto 来标记那些 Dto 在请求端 有一个ILocalizedRequest对于需要本地化的请求 Using IPlugin
  • C++ 密码屏蔽

    我正在编写一个代码来接收密码输入 下面是我的代码 程序运行良好 但问题是除了数字和字母字符之外的其他键也被读取 例如删除 插入等 我知道如何避免它吗 特q string pw char c while c 13 Loop until Ent
  • 线程和 fork()。我该如何处理呢? [复制]

    这个问题在这里已经有答案了 可能的重复 多线程程序中的fork https stackoverflow com questions 1235516 fork in multi threaded program 如果我有一个使用 fork 的
  • 检查Windows控制台中是否按下了键[重复]

    这个问题在这里已经有答案了 可能的重复 C 控制台键盘事件 https stackoverflow com questions 2067893 c console keyboard events 我希望 Windows 控制台程序在按下某个
  • 防止在工厂方法之外实例化对象

    假设我有一个带有工厂方法的类 class A public static A newA Some code logging return new A 是否可以使用 a 来阻止此类对象的实例化new 那么工厂方法是创建对象实例的唯一方法吗 当

随机推荐

  • 从一个容器到另一个容器运行命令

    我有两个 dockerized 项目 一个使用 NodeJS 另一个使用 Python 我想从 NodeJS 应用程序触发 Python 脚本执行 在带有 Python 应用程序的容器上 基本上 NodeJS 应用程序会运行类似的东西exe
  • 为什么 iostream 包含 time.h?

    考虑这段代码 include
  • jQuery - 使用变量作为函数名称

    在 Jquery 中 我想通过更改变量名称来禁用我想要的任何插件 但是下面的代码不起作用 function disablePlugin functionName divID functionName disable disablePlugi
  • 在@implementation中添加ivars

    对于良好的封装 体面Objective C程序员把他们的private伊瓦尔 在 私人extension在主实现文件中声明 如下所示 MyClass m interface MyClass float value end implement
  • 如何在运行时检查 Mac OS X 版本

    我正在使用下面的代码在运行时检查 OS X 版本 if floor NSAppKitVersionNumber lt NSAppKitVersionNumber10 10 On a 10 10 x or earlier system 但这个
  • tilelayer 上的 noWrap 选项仅部分起作用

    为了防止我使用的最高缩放级别出现多个重复的世界地图noWrap true选项 它运行良好 但仅在地图的左侧 灰色区域 右侧仍然显示额外的图块 这是为什么 UPDATE1 看起来这是特定 Mapbox 图块或其加载方式的问题 这里没有包裹和h
  • d3.js 在悬停时传递多个函数

    我使用了一个教程来在鼠标悬停时获得此功能 function arcTween outerRadius delay return function d3 select this transition delay delay attrTween
  • NHibernate 一对一映射,其中第二个表数据可以为空

    我有一个现有数据库 其中包含事务表 我添加了一个名为 TransactionSequence 的新表 其中每个事务最终只有一条记录 我们使用序列表来计算给定帐户的交易 我已将其映射为一对一映射 其中 TransactionSequence
  • 如何通过 Angular 方式示例在 Angular DataTables 中使用服务器端选项?

    我正在尝试使用角度数据表与服务器端处理选项 但是当我尝试在他们的 角度方式示例 仅呈现第一个请求 发送后续请求 分页 排序 搜索 但它们从不更新表 经过一番挖掘 我发现了一个不相关的用户贡献的注释这表明您覆盖ajax选项与您自己的函数来处理
  • 启用 Code First 实体框架 VS Web Express 2012

    我正在尝试在 Visual Studio Web Express 2012 中启用 Code First 根据我目前所读到的内容 我必须使用包管理器控制台和命令 Enable Migrations 当我这样做时 我收到以下错误 Except
  • Google 地点自动完成功能从结果中删除州和国家/地区

    https google developers appspot com maps documentation javascript examples places autocomplete 我有一个类似于上面的谷歌位置自动完成演示网址的页面
  • 经典 ASP:捕获错误

    是否有可能在全局级别捕获经典 ASP 中的所有 500 个错误 也许是 IIS 中的东西 我现在用的是II6 我喜欢捕获错误消息 然后将其存储在数据库中 我知道它在 ASPX 页面中是可能的 但不确切知道你在经典的 asp 中是如何做的 谢
  • 在附加元素上触发 CSS 转换

    As 这个问题观察到 新附加元素上的立即 CSS 转换会以某种方式被忽略 转换的最终状态会立即呈现 例如 给定这个 CSS 此处省略前缀 box opacity 0 transition all 2s background color re
  • 根据日期和时间检索 IMAP 电子邮件?

    我正在尝试使用 IMAP 检索不到特定小时数的电子邮件 我查看了规范 有一个 SINCE 方法接受 RFC 日期 但是 它忽略时间和时区 我可以使用另一种方法根据日期和时间检索电子邮件吗 谢谢 RFC 5032记录引入搜索关键字的WITHI
  • jQuery - 如何根据选定的下拉列表显示/隐藏文本框

    抱歉 如果这是非常明显的 但我已经寻找并寻找解决方案 但没有找到任何东西 我对 jQuery 很陌生 所以即使寻找我想做的事情也很困难 我有一个页面 其中包含一堆字段和下拉框 这些字段和下拉框是从数据库填充的 因此 每个下拉列表都在页面加载
  • 如果用户登录到其他网站,则自动登录到当前网站

    我有大约 100 个用 ASP classic 编码的网站 每个网站都接受订单并将其存储在数据库中 然而 这些订单的支付必须在另一个同样使用 ASP classic 进行编码的网站上进行 所有网站均属于同一家公司 托管在同一 IIS 服务器
  • 如何在 Solaris 10 上构建 Qt 5.2?

    Qt 页面未列出适用于 Solaris 的预编译 Qt 5 软件包 搜索了一下 它似乎也没有包含在流行的软件包存储库 OpenCSW 中 一些谷歌点击表明在 Solaris 下构建 Qt 5 涉及 Solaris 10 下的一些工作 因此我
  • 如何查看 .tflite 文件中的权重?

    我获取了 MobileNet 的预训练 pb 文件 发现它没有量化 而完全量化的模型应该转换为 tflite 格式 由于我不熟悉移动应用程序开发工具 如何从 t flite 文件中获取 MobileNet 的完全量化权重 更准确地说 如何提
  • 导致其他标签呈现为纯文本的 HTML 标签[重复]

    这个问题在这里已经有答案了 我想向页面添加一个区域 其中所有动态内容都呈现为纯文本而不是标记 例如
  • C# 使用 CredWrite 访问 C$

    我正在尝试使用没有该服务器权限的域帐户访问该服务器的 C 我需要以本地登录的形式保存该服务器的凭据 以便程序正常工作 如何使用 CredWrite 保存这些凭据 我找到的凭证管理器类 编辑 以下是功能代码 using System usin