zoukankan      html  css  js  c++  java
  • .netcore 堆栈调用方法小记

    背景

    上午临近午饭时,公司同事反馈验证码被攻击灌水。我们匆忙查询验证码明细,对已频繁出现的IP插入黑名单,但IP仍然隔断时间频繁变动,不得已之下只能先封禁对应公司id的验证码发送功能。年初时候,专门对SSO站点的发送验证码升级到极验的验证,已经杜绝了普通的攻击,没想到没升级的这个系统又遭受洗礼...

    思考办法

    防灌水通用解决办法一般有几种:

    • Ip+手机号限制

    频繁变化ip和手机号时,此办法无效

    • 发送验证码页面端提供简单图形验证码

    能解决部分攻击。

    • 采取12306图片库或极验等复杂手段

    能解决大部分攻击,但超过一定频率需要收费

    学到的知识点

    由于调用发送验证码的方法非常多,在这个方法内只能定位到IP和手机号,定位不到Web层具体的Action,在此过程中了解到https://www.cnblogs.com/huangtailang/p/4550177.html所提到的System.Diagnostics.StackTrace和System.Diagnostics.StackFrame定位到方法上层调用堆栈。然后就顺腾摸瓜把漏掉图形验证码的常用页面先补上,不常用的页面改掉发送接口。处理细节不再细述,只记录下Diagnostics的相关信息。

     /// <summary>
            /// 获取堆栈
            /// </summary>
            /// <returns></returns>
            public static string GetStackTraceModelName()
            {
                //当前堆栈信息
                System.Diagnostics.StackTrace st = new System.Diagnostics.StackTrace();
                System.Diagnostics.StackFrame[] sfs = st.GetFrames();
                //过虑的方法名称,以下方法将不会出现在返回的方法调用列表中
                string _fullName = string.Empty, _methodName = string.Empty;
                for (int i = 1; i < sfs.Length; ++i)
                {
                    //非用户代码,系统方法及后面的都是系统调用,不获取用户代码调用结束
                    if (System.Diagnostics.StackFrame.OFFSET_UNKNOWN == sfs[i].GetILOffset()) break;
                    var methedInfo = sfs[i].GetMethod();
                    _methodName = methedInfo.ReflectedType.FullName + "." + methedInfo.Name;//方法名称
                                                                                            //sfs[i].GetFileLineNumber();//没有PDB文件的情况下将始终返回0
                                                                                            // if (_filterdName.Contains(_methodName)) continue;
                    _fullName = _methodName + "()
    ->" + _fullName;
                }
                st = null;
                sfs = null;
                return _fullName.TrimEnd('-', '>');
            }
    

    下面我们定义一些代码来演示效果:

    
     public class First
        {
            public string Start()
            {
               return new Second().Start();
            }
        }
    
     public class Second
        {
            public string Start()
            {
              return  new Third().Start();
            }
        }
    
     public class Third
        {
            public string Start()
            {
                var msg = Utils.GetStackTraceModelName();
                return msg;
            }
        }
    

    然后在Web层调用First.Start

     public class HomeController : Controller
        {
            public IActionResult Start()
            {
                var msg = new First().Start();
                return Content(msg);
            }
        }
    

    访问结果如下:

    Web.Controllers.HomeController.Start()
    ->Venus.Common.First.Start()
    ->Venus.Common.Second.Start()
    ->Venus.Common.Third.Start()
    

    这个调用信息是由Third.Start记录,可见能追踪到完整的调用链。这只是简单的演示,如更复杂的交叉调用,异步、并行等的并未在这里实践。

    扩展思考

    以上方法适用于.netFramework和.netCore,可用于做日志记录,调用链等行为。
    asp.netcore里也有Microsoft.AspNetCore.Diagnostics,https://www.cnblogs.com/linezero/p/Diagnostics.html

    略作总结,本篇结束,那帮闲的蛋疼乱搞攻击的人,折腾了我一天。虽然已经禁了他们发送验证码,但还是一直在发请求,头疼ying....留个念头以待以后深思。

    安全和防护依然是重中之重啊!

    参考链接

    C#获取当前堆栈的各调用方法列表
    windows管理员利器之用Log Parser Studio分析IIS日志
  • 相关阅读:
    Codeforces Round #513解题报告(A~E)By cellur925
    Luogu P1463 [POI2002][HAOI2007]反素数【数论/dfs】By cellur925
    NOIp2016 蚯蚓 【二叉堆/答案单调性】By cellur925
    Luogu P4139 上帝与集合的正确用法【扩展欧拉定理】By cellur925
    hdu 4704 Sum【组合数学/费马小定理/大数取模】By cellur925
    poj 1723 Soldiers【中位数】By cellur925
    MyBatis 简介
    对象导航查询和OID查询(补)
    Hibernate查询方式(补)
    Hibernate一级缓存(补)
  • 原文地址:https://www.cnblogs.com/fancunwei/p/10146151.html
Copyright © 2011-2022 走看看