暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

.NET版“ShellCode”编写

K8实验室 2021-11-17
1079


0x000 前言

近几年大家都喜欢用Cobalt Strike来进行后渗透,所以对于ShellCode大家应该不会陌生。但是可能很多人并不懂CS的shellcode功能是什么,CS生成的ShellCode只是一段下载者。主要功能为下载becon.dll,然后内存加载,我们所用的相关功能都在becon里。ShellCode可能采用汇编或VC编写后转成机器码提取关键机器码,优势在于体积小。体积小就可以直接结合漏洞使用,什么Word文档、MS17010溢出、IE漏洞挂马等都可以直接结合CS来使用,直接CS上线,而不是非要先做其它操作再植入CS。网上关于汇编或VC编写ShellCode的文章很多,但是.NET的”ShellCode”很少见本文将教大家如何用操作码实现.NET版”ShellCode”的编写。


0x001 指令、操作码、字节码

在正式开始前,先给大家科普一下指令、操作码、机器码等的区别


指令: 命令cpu干什么,是由操作码字段和地址码字段(操作数字段)组成

操作码(Opcode): 就是执行某种操作的命令代码

BYTECODE(字节码):与机器代码相同,除了它主要由基于软件的解释器(如Java或CLR)使用

程序集:有两个“程序集” – 一个汇编程序是一系列的助记符和操作数,它们被馈送到“汇编程序”,“汇编程序”将助记符和操作数“汇编成可执行的机器代码”.可选地,“链接器”链接组件并生成可执行文件.

CLR语言:(.NET语言)中的第二个“程序集”是一系列CLR代码,其中注入了元数据信息,可执行代码库,但不能直接执行.

0x002 Payload ShellCode

机器码(溢出常用的ShellCode): 就是指令的二进制代码(包括操作码和地址码),功能打开和关闭计算机中的开关的数字序列,以执行某些工作 – 例如增加数字,分支,乘法等等.这是纯机器特有的,由处理器的实现者.


K8理解的ShellCode是子弹,用枪发射(好比处理器执行); 无论你用的是哪种子弹(ShellCode),都是用枪来射(处理器执行)。

Payload: K8的理解是弹药,弹药可装填到弹壳里用,也可直接点然,也可圈起来当成炮仗点燃,但是弹药不能直接被枪发射。


PS:发现很多搞安全的对很多概念搞混,如很多文章常把payload和shellcode混为一谈,看了以上释义,您应该了解明显shellcode只是payload中的一种了,不可能属于同一个。很多人把操作码误解为ShellCode还可以理解,起码长得像还有点类似,但真不是。不要看到二进制、16进制或者byte数组就说是shellcode,长得像人都不定是人呢。


0x003 .NET函数代码

.NET包含多种语言,这里我使用C#的代码做为例子

public int Add(int x, int y)
{
x = x * y;
return x + y;
}


0x003 反汇编得到IL指令

指令速查表:https://www.jb51.net/article/86802.htm
IL语言,可理解为.NET的汇编,无论你使用的是C#还是VB.NET或者F#开发功能,都可以将其反编译成IL代码。使用ildasm.exe工具反编译,可以看到IL代码和汇编差不多,可能是常用.NET吧,感觉比汇编简单好多。

  // Method begins at RVA 0x2170
// Code size 9 (0x9)
.maxstack 8
IL_0000: /* 03 | */ ldarg.1
IL_0001: /* 04 | */ ldarg.2
IL_0002: /* 5A | */ mul
IL_0003: /* 10 | 01 */ starg.s x
IL_0005: /* 03 | */ ldarg.1
IL_0006: /* 04 | */ ldarg.2
IL_0007: /* 58 | */ add
IL_0008: /* 2A | */ ret
} // end of method MethodBodyDemo::Add

0x004 IL指令转.NET操作码

如同VC反汇编提取机器码一样,我们将对应16进制复制出来,然后再对比指令速查表提取关键操作码

0x02,0x03,0x5A,0x10,0x00,0x02,0x03,0x58,0x2A

0x005 操作码加载


private static Func<int, int, int> LoadByteAssmbly(byte[] bytes)
{
var asmName = new AssemblyName("DynamicAssembly");
var asmBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.RunAndSave);
var module = asmBuilder.DefineDynamicModule("DynamicModule");
var typeBuilder = module.DefineType("DynamicType");
var method = typeBuilder.DefineMethod("DynamicMethod",
MethodAttributes.Public | MethodAttributes.Static,
typeof(int),
new[] { typeof(int), typeof(int) });
method.CreateMethodBody(bytes, bytes.Length);
var type = typeBuilder.CreateType();


return (Func<int, int, int>)type.GetMethod("DynamicMethod").CreateDelegate(typeof(Func<int, int, int>));
}


0x006 执行效果


文章转载自K8实验室,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论