基於DPAPI+RDP技術實現本地開啟遠端程式,並對映到本地機器桌面上

WeskyNet發表於2024-10-03
本教程使用工具所使用的環境說明:
啟動器開發工具:VS2022
啟動器所用客戶端技術:.NET 8 + WPF
啟動器其他技術:DPAPI
啟動器釋出的可執行程式,系統要求:Windows 7以及以上,X64
如果需要本程式,可以在網盤獲取。網盤地址:
透過網盤分享的檔案:RemoteShadowApp.7z 連結: https://pan.baidu.com/s/1QPstE5-1zPK-qOp8GQ90ew?pwd=6666 提取碼: 6666
接下來是該工具的具體使用教程。
先對遠端伺服器上面的登錄檔進行設定。路徑如下:HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services
如下圖所示,目前裡面沒啥東西。
0
可以透過當前工具進行設定,在伺服器上面開啟RemoteShadowApp程式,然後點選設定登錄檔,即可看到登錄檔被自動建立成功了。這樣可以直接快速設定登錄檔。
0
當然,如果不想在伺服器上面執行,也可以手動自己設定一下。自己建立一個登錄檔,建立DWORD鍵值對,名稱是 fAllowUnlistedRemotePrograms 對應的值設為1。如果覺得麻煩,那就用我上面的工具直接設定,效果也是一樣的。
0
0
在本機機器上面,就可以透過遠端訪問目標伺服器的程式了。操作如下:
例如我要開啟遠端桌面上的Notepad++程式
0
我需要獲取伺服器的IP、登陸的使用者名稱、密碼、以及NotePad++的啟動程式的絕對路徑,例如如下圖所示。我沒做記住資訊功能,所以大家也可以自己建立一個記事本之類的,儲存你的遠端程式資訊,方便貼上進去填寫。都輸入完畢以後,點選 【開啟遠端程式】 按鈕
0
注意事項:如果遠端伺服器有360等軟體,可能會限制你的許可權,例如一直卡在這個介面
0
此刻你需要點開 顯示詳細資訊,可以看到有一個登陸按鈕,點選登陸即可。這個只有部分遠端伺服器會出現,如果本機沒有一些限制設定或者安全軟體,這一步不會出現。僅在有出現這個現象的時候才需要這樣操作。
0
開啟的遠端的notepad++程式,效果如圖所示。
0
接著我們開啟遠端伺服器,看下現象。具體如圖所示效果。
0
支援開啟多個遠端程式,例如,我現在開啟一個以前自己寫的控制檯程式服務,地址如下
0
在剛才的程式裡面,更改啟動的路徑為上面的控制檯服務路徑,然後啟動。可以看到啟動成功了。並且和上一個notepad程式可以共存。
0
同樣,伺服器上面也並不存在控制檯程式的頁面,但是存在程序。控制檯程式也是佔用伺服器資源,而不會佔用本地資源。
0
如果當前沒啥需要,就可以退出啟動器,退出啟動器對已經開啟的遠端程式沒有任何影響。啟動器只是用來提供遠端程式作用,沒有其他功能。
0
啟動器核心功能,主要是DPAPI加密功能。DPAPI(資料保護應用程式程式設計介面)是微軟提供的一個用於幫助保護資料安全的API,它可以簡化在Windows平臺上的資料加密過程。DPAPI 提供了一個系統級別的加密服務,其特點是不需要應用程式自行處理加密金鑰的儲存和保護。DPAPI主要用於保護敏感資訊,如密碼、金鑰和其他個人或系統資料。
如下所示程式碼,我在Wesky.Net.Opentools開源專案上也有整合該功能。此處我在本程式內直接使用來加密。必須加密以後的密碼,才能被遠端伺服器識別。
0
下面是DPAPI具體的加密和解密過程:
 /// <summary>
 /// 加密資料
 /// </summary>
 /// <param name="dataToEncrypt"></param>
 /// <returns></returns>
 public static string EncryptData(string dataToEncrypt)
 {
     try
     {
         byte[] secret = Encoding.Unicode.GetBytes(dataToEncrypt);
         byte[] encryptedSecret = ProtectedData.Protect(secret, additionalEntropy, DataProtectionScope.LocalMachine);
         string res = string.Empty;
         foreach (byte b in encryptedSecret)
         {
             res += b.ToString("X2");
         }
         return res;

     }
     catch (Exception ex)
     {
         Console.WriteLine("加密過程中出現異常: " + ex.Message);
         return null;
     }
 }

 /// <summary>
 /// 解密資料
 /// </summary>
 /// <param name="dataToDecrypt"></param>
 /// <returns></returns>
 public static string DecryptData(string hexEncryptedData)
 {
     try
     {
         byte[] dataToDecrypt = ConvertHexStringToByteArray(hexEncryptedData);
         byte[] decryptedData = ProtectedData.Unprotect(dataToDecrypt, null, DataProtectionScope.LocalMachine);
         return Encoding.Default.GetString(decryptedData);
     }
     catch (Exception ex)
     {
         Console.WriteLine("解密過程中出現異常: " + ex.Message);
         return null;
     }
 }

設定登錄檔的地方,也是很簡單的一個寫死的程式碼,供參考
 // 指定登錄檔鍵的路徑
 string registryPath = @"SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services"; // 根據需要修改路徑
 string valueName = "fAllowUnlistedRemotePrograms"; // 登錄檔項名稱

 try
 {
     // 建立或開啟指定的登錄檔鍵
     using (RegistryKey key = Registry.LocalMachine.CreateSubKey(registryPath))
     {
         if (key != null)
         {
             // 設定值為 DWORD32 型別,並賦值為 1
             key.SetValue(valueName, 1, RegistryValueKind.DWord);
             MessageBox.Show("登錄檔鍵已建立並賦值成功。");
         }
         else
         {
             MessageBox.Show("無法建立登錄檔。");
         }
     }
 }
 catch (UnauthorizedAccessException)
 {
     MessageBox.Show("您沒有許可權設定登錄檔,請以管理員身份執行程式。");
 }
 catch (Exception ex)
 {
     MessageBox.Show($"設定登錄檔發生錯誤: {ex.Message}");
 }

後記:本工具開啟的遠端程式,支援區域網、外網,只要你可以透過遠端桌面訪問的伺服器或者電腦,都可以透過該方式進行啟動。

如果以上內容對你有幫助,歡迎點贊、在看、轉發和留言。感謝大家的支援。也歡迎關注公眾號:【Dotnet Dancer】

相關文章