Unmanaged PowerShell

简介

在渗透测试当中经常会使用到PowerShell来执行脚本, 但是直接使用PowerShell.exe是一个非常敏感的行为, EDR等产品对PowerShell.exe进程的创建监控的很密切, 并且随着PowerShell的渗透测试工具的普及, 越来越多的EDR会利用微软提供的AMSI接口对PS脚本进行扫描, 但是对于低版本的PowerShell并没有引入AMSI;

如果我们可以自己实现一个PowerShell, 而不是去调用系统的PowerShell.exe来执行PS脚本, 就会使得我们的行为更加的隐蔽, 甚至我们可以将自实现的PowerShell模块注入到一个第三方进程中去(例如svchost.exe), 可能会使行为更加隐蔽;

通过C#实现PS调用

Powershell实际上是属于C#的子集(System.Management.Automation), 所以实际上我们在C#中调用Powershell就是调用 System.Management.Automation对象:

cpp 复制代码
using System;
using System.Reflection;
using System.Text;
using System.Management.Automation;
using System.Collections.ObjectModel;
using System.Management.Automation.Runspaces;

namespace Test
{
    class Program
    {
        public static void Main(string[] args)
        {
            InvokePS("PS> ");
        }

        public static int InvokePS(string ps)
        {
            Runspace runspace = RunspaceFactory.CreateRunspace();
            runspace.Open();
            while (true)
            {
                try
                {
                    Console.Write(ps);
                    string cmd = Console.ReadLine();
                    if (cmd.Contains("exit"))
                    {
                        break;
                    }
                    Pipeline pipeline = runspace.CreatePipeline();
                    pipeline.Commands.AddScript(cmd);
                    pipeline.Commands.Add("Out-String");
                    Collection<PSObject> results = pipeline.Invoke();
                    StringBuilder stringBuilder = new StringBuilder();
                    foreach (PSObject obj in results)
                    {
                        foreach (string line in obj.ToString().Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None))
                        {
                            stringBuilder.AppendLine(line.TrimEnd());
                        }
                    }
                    Console.Write(stringBuilder.ToString());
                }
                catch (Exception e)
                {
                    string errorText = e.Message + "\n";
                    Console.Write(errorText);
                }
            }
            return 0;
        }
    }
}

需要注意的是在引用System.Management.Automation时, 需要手动找System.Management.Automation.dll的路径, 然后添加到引用中去:

相关推荐
anew___5 小时前
蜂鸣器播放音乐——让 Arduino 唱出旋律
c++·stm32·单片机·嵌入式硬件·c
stolentime7 小时前
洛谷P10515 转圈题解
c++·算法·数学建模·贪心算法
tdtsmt8 小时前
穿戴硬件量产工艺实录:天地通电子智能手表主板 SMT 贴片案
c++
m0_7345717611 小时前
深入理解C++ 析构函数<一>基本概念
开发语言·c++
t-think12 小时前
C++ string 类(上)—— string类初识与常用接口详解
开发语言·c++
cpp_learners12 小时前
C++ 实现责任链模式(Chain of Responsibility):从一堆 if-else 到可插拔的处理管道
开发语言·c++·责任链模式
郝学胜_神的一滴12 小时前
C++11 工程级应用 12:编译期类型魔法,干掉重复与臃肿的代码
c++·visual studio
David猪大卫14 小时前
【C++修炼】哈希表的实现
数据结构·c++·笔记·学习·算法·哈希算法·散列表
广州山泉婚姻14 小时前
列表初始化:C++11全新初始化体系
c++·人工智能
莫生灬灬14 小时前
灵码 LingBuilder:用中文写代码,确定性生成真实 C++ 工程(开源)
c++·开源·mfc