剑道尘心 发布于2022年11月8日 分享 发布于2022年11月8日 0x00 前言 以前的文章《从内存加载.NET程序集(execute-assembly)的利用分析》和《从内存加载.NET程序集(Assembly.Load)的利用分析》已经介绍了加载的方法。使用C Sharp从内存中调用. NET程序集。这一次,我们将更进一步,介绍使用C Sharp从内存加载PE文件的方法。 0x01 简介 本文将介绍以下内容: 实现原则 凯西史密斯的开源PELoader.cs 扩展PELoader.cs的方法 SharpPELoaderGenerater的实现细节 使用方法 0x02 内存加载PE文件的实现原理 实现原理如下: 读取PE文件并根据PE格式解析它。 内存应用程序,ImageBase作为内存基址,SizeOfImage作为长度 将PE文件头复制到内存中 解析该段的地址,并将该段复制到内存中。 基于重定位表修改内存 解析该表并加载所需的Dll。 跳转到AddressOfEntryPoint并执行PE文件。 0x03 Casey Smith开源的PELoader.cs 目前可供参考的地址: https://github . com/re4 lity/subTee-gits-backups/blob/master/peloader . cs 此代码可以使用中的csc.exe进行编译。NET 4.0以上。 按如下方式编译该命令: C:\Windows\Microsoft。NET \ framework 64 \ v 4 . 0 . 30319 \ CSC . exe/unsafe peloader . cs 该代码实现了64位mimikatz.exe在内存中的加载。 PELoader.cs将编码的mimikatz.exe存储在字符串KatzCompressed中。 如果您想进行替换,您可以在以下地址查阅我的代码: https://github . com/3g student/home-of-C-Sharp/blob/master/gzipandbase 64 . cs 执行后,生成文件base64.txt,其中的内容用于替换字符串KatzCompressed。 0x04 扩展PELoader.cs的方法 1.增加支持的编译环境。 PELoader.cs不支持。Net3.5,因为它使用。Add(),可以替换为支持。Net3.5。 2.支持32位程序的加载 需要区分32位和64位程序的PE结构差异,重新计算偏移量。 扩展PELoader.cs的代码已经上传到github,地址如下: https://github . com/3g student/home-of-C-Sharp/blob/master/SharpMimikatz _ x86 . cs https://github . com/3g student/home-of-C-Sharp/blob/master/SharpMimikatz _ x64 . cs 32位和64位mimikatz代码分别载入存储器。 支持。Net3.5和更高版本 SharpMimikatz_x86.cs的编译命令如下: C:\Windows\Microsoft。NET \ Framework \ v 3.5 \ CSC . exe/unsafe/platform:x86 SharpMimikatz _ x86 . cs 或者 C:\Windows\Microsoft。NET \ Framework \ v 4 . 0 . 30319 \ CSC . exe/unsafe/platform:x86 SharpMimikatz _ x86 . cs SharpMimikatz_x64.cs的编译命令如下: C:\Windows\Microsoft。NET \ framework 64 \ v 3.5 \ CSC . exe/unsafe/platform:x64 SharpMimikatz _ x64 . cs 或者 C:\Windows\Microsoft。NET \ framework 64 \ v 4 . 0 . 30319 \ CSC . exe/unsafe/platform:x64 SharpMimikatz _ x64 . cs 0x05 SharpPELoaderGenerater的实现细节 以Casey Smith的开源PELoader.cs为模板,尝试用c#实现加载PE文件模板的自动生成。 这里以SharpMimikatz_x64.cs为例,代码可以分为以下三个部分: 调用代码的前半部分 exe文件的压缩字符串。 调用代码的第二部分 代码生成方法如下: 1.前半部分调用代码 由于调用代码的前半部分有很多转义字符,直接保存在字符串数组中比较麻烦。这里的思路是将调用代码的前半部分压缩编码后保存在字符串数组中,这样也可以大大减少代码长度(从31kb减少到6kb)。 以下c#代码可用于压缩的前半部分: 使用系统; 使用系统。木卫一; 使用系统。IO .压缩; 命名空间生成代码 { 班级计划 { 静态字节[]压缩(字节[]原始) { 使用(memory stream memory=new memory stream()) { 使用(GZipStream gzip=new GZipStream(内存、 压缩模式。压缩,真)) { gzip。写(raw,0,raw。长度); } 回归记忆。to array(); } } 静态void Main(string[] args) { byte[] AsBytes=File。read all bytes(@ ' SharpMimikatz _ x86 _ part . cs '); byte[]Compress=Compress(as bytes); String AsBase64String=Convert。ToBase64String(压缩); StreamWriter SW=new StreamWriter(@ ' SharpMimikatz _ x86 _ part . txt '); 西南。write(as base 64 string); 西南. close(); byte[] AsBytes2=文件读取所有字节(@ ' SharpMimikatz _ x64 _ part。cs’); byte[]Compress 2=Compress(作为字节2); String AsBase64String2=Convert .转换为基数64字符串(压缩2); StreamWriter sw2=new StreamWriter(@ ' SharpMimikatz _ x64 _ part。txt’); sw2 .write(作为base 64 string 2); sw2 .close(); } } } 执行后生成文件SharpMimikatz_x86_part.txt和SharpMimikatz_x64_part.txt,内容为压缩编码后的前半部分调用代码 2.exe文件经过压缩后的字符串 可使用以下代码生成: byte[] AsBytes=File .读取所有字节(@ ' mimikatz。exe’); byte[]Compress=Compress(以字节为单位); 字符串源=转换ToBase64String(压缩); 3.后半部分的调用代码 这里需要使用转义字符 可使用以下代码进行定义: 字符串来源3 _ x86=\ r \ n } \ r \ n }”; 作为代码生成模板,还需要区分可执行程序的扩展名是32位还是64位,判断方法如下: 通过图像文件标题结构体中的特征字段,如果存在属性图像_文件_ 32位_机器,那么该可执行程序的扩展名文件为32位 完整代码已上传至github,地址如下: https://github。com/3g student/home-of-C-Sharp/blob/master/sharppeloadergenerator。铯 用法实例: SharpPELoaderGenerater.exetest.exe 如果test.exe为32位的程序,将会生成文件sharppel loader _ x86。铯 编译方法: C:\Windows\Microsoft .NET \ Framework \ v 3.5 \ CSC。exe/unsafe/platform:x86 sharppel loader _ x86。铯 或者 C:\Windows\Microsoft .NET \ Framework \ v 4。0 .30319 \ CSC。exe/unsafe/platform:x86 sharppel loader _ x86。铯 如果test.exe为64位的程序,将会生成文件夏普装载机_ x64。铯 编译方法: C:\Windows\Microsoft .NET \ framework 64 \ v 3.5 \ CSC。exe/unsafe/platform:x64 sharppel loader _ x64。铯 或者 C:\Windows\Microsoft .NET \ framework 64 \ v 4。0 .30319 \ CSC。exe/unsafe/platform:x64 sharppel loader _ x64。铯 补充: 使用c编写test.exe时需要注意手动加上需要调用的动态链接库 实例代码如下: #include 'stdafx.h ' #包括 #杂注注释(lib,' User32.lib ') int main(int argc,char *argv[]) { LoadLibrary(L '用户32。dll’); MessageBox(NULL,NULL,NULL,MB _ OK); 返回0; } 0x06 小结 本文介绍了通过。网实现内存加载体育课文件的方法,以凯西史密斯开源的PELoader.cs为模板,编写代码生成工具SharpPELoaderGenerate,分享代码开发需要注意的细节 留下回复 链接帖子 意见的链接 分享到其他网站 更多分享选项…
推荐的帖子