利用.NET回调函数执行任意命令

0x01 背景

说起回调函数大家一定首先想到php语言提供的call_user_func、call_user_func_array等函数,但再.NET里也存在一个冷门的回调函数,它就是CallByName,位于:Microsoft.VisualBasic, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a,此DLL里包含了多个 方法可用于创建新进程。具体使用方法请跟随笔者一探究竟。.

1.1 使用方法

CallByName是个很灵活的函数。帮助说明:执行一个对象的方法,或者设置或返回一个对象的属性。通过名称来调用操作对象的属性和调用对象的方法。函数定义 CallByName(object ObjectRef, string ProcName, CallType UseCallType, params object[] Args),如下图

利用.NET回调函数执行任意命令

ProcName 包含对象的属性名或方法名的字符串表达式。CallType 枚举类型的枚举成员,表示所调用过程的类型。CallType 的值可以是 Method、Get 或 Set。Args 包含要传递给所调用的属性和方法的参数。

其中CallType.Get返回对象的属性的值,CallType.Method可以调用对象的方法执行,反编译后的代码如下

switch (UseCallType)            {                case CallType.Method:                    return LateBinding.InternalLateCall(ObjectRef, null, ProcName, Args, null, null, IgnoreReturn: false);                case CallType.Get:                    return LateBinding.LateGet(ObjectRef, null, ProcName, Args, null, null);                case CallType.Let:                case CallType.Set:                    {                        Type objType = null;                        LateBinding.InternalLateSet(ObjectRef, ref objType, ProcName, Args, null, OptimisticSet: false, UseCallType);                        return null;                    }                default:                    throw new ArgumentException(Utils.GetResourceString("Argument_InvalidValue1", "CallType"));            }

实际可用的demo如下回调Process类的Start启动计算器:CallByName(Obj, "Start", CallType.Get, "calc"),图2

利用.NET回调函数执行任意命令