Telerik.Web.UI for ASP.NET AJAX某版本存在任意文件下载漏洞

Telerik.Web.UI for ASP.NET AJAX某版本存在任意文件下载漏洞:
在做渗透测试任务时,遇到一个ASP.NET站点.通过目录扫描发现存在Telerik.Web.UI.WebResource.axd路径。此路径是第三方控件Telerik UI FOR ASP.NET在web.config中映射的handler
QQ截图20210815230410.png
查阅历史相关漏洞后主要有以下

CVE 2014-2217
CVE-2017-11317
CVE-2017-11357
CVE-2017-9248
CVE-2019-18935

上面这几个已知漏洞基本都是围绕默认key实现序列化配置类上传恶意文件,后者是前者禁用../后的绕过。存储路径以及类型都是由反序列化内容后进行解密而来。key的配置一般都在web.config文件中。

而该系统类似于一个信息管理系统,在没有可登录账号的情况下。很难挖掘一些未授权漏洞。因此,打算从Telerik入手。挖掘其他未知漏洞。

在下载对应的Telerik.WEB.UI.dll后,进行审计。

常见的handler配置都是将Telerik.Web.UI.WebResource.axd路径的请求交给Telerik.Web.UI程序集下的WebResource类进行处理。

<add path="Telerik.Web.UI.WebResource.axd" type="Telerik.Web.UI.WebResource" verb="*" name="Telerik"/>

切入WebResource,根据ASP.NET的方法执行顺序,该类会先执行ProcessRequest方法。

public override void ProcessRequest(HttpContext context)
{
        HandlerRouter handlerRouter = new HandlerRouter();
        if (!handlerRouter.ProcessHandler(context))
        {
            CombinedScriptWriter.WriteCombinedScriptFile(this, context);
        }
}

先实例化了HandlerRouter类。后调用ProcessHandler方法。如果不满足if条件,则会进入WriteCombinedScriptFile方法。

ProcessHandler中会先调用ExtractKey方法,从请求中获取参数的值。

public bool ProcessHandler(HttpContext context)
{
            string text = this.ExtractKey(context);
            return !string.IsNullOrEmpty(text) && this.ProcessHandler(text, context);
}

        // Token: 0x0600362D RID: 13869 RVA: 0x000B2223 File Offset: 0x000B0423
private string ExtractKey(HttpContext context)
{
            return context.Request[HandlerRouter.HandlerUrlKey];
}

HandlerUrlKey成员的内容为type

internal static string HandlerUrlKey
{
    get
    {
        return "type";
        
    }
}

先从请求中获取变量type的值,不为空则进入ProcessHandler的重载方法,根据传入type内容进行分发。

public bool ProcessHandler(string handlerKey, HttpContext context)
        {
            if (string.IsNullOrEmpty(handlerKey))
            {
                throw new ArgumentNullException("handlerKey");
            }
            this.PopulateHandlers();
            if (this._handlers.ContainsKey(handlerKey))
            {
                this._handlers[handlerKey]().ProcessRequest(context);
                return true;
            }
            return false;
        
        }

_handlersPopulateHandlers方法中被赋值.

protected virtual void PopulateHandlers()
        {
            this.Handlers.Add(RadBinaryImage.HandlerRouterKey, () => new RadBinaryImageHandler());
            this.Handlers.Add(RadCaptcha.HandlerRouterKey, () => new CaptchaImageHandler());
            this.Handlers.Add(RadAsyncUpload.HandlerRouterKey, () => new AsyncUploadHandler());
            this.Handlers.Add(RadCaptcha.HandlerRouterKeyCaptchaAudio, () => new CaptchaAudioHandler());
            this.Handlers.Add(RadImageEditor.HandlerRouterKey, () => new ImageEditorCacheHandler());
        }

有以下几种Type

rbi -> RadBinaryImageHandler()
rca -> CaptchaImageHandler()
rau -> AsyncUploadHandler()
cah -> CaptchaAudioHandler()
iec -> ImageEditorCacheHandler()

根据type进行分发,调用指向handlerProcessRequest方法 已知历史漏洞都指向rau->AsyncUploadHandler.索性直接不看。因为这个版本不是很高,最终是在ImageEditorCacheHandler中发现了一处任意文件下载漏洞。

public void ProcessRequest(HttpContext context)
        {
            string text = context.Request["path"];
            string fileName = context.Request["fileName"];
            if (string.IsNullOrEmpty(text) || text == "1")
            {
                CacheImageProvider imageProvider = this.GetImageProvider(context);
                string key = context.Request["key"];
                EditableImage editableImage = imageProvider.Retrieve(key);
                this.SendImage(editableImage, context, text, fileName);
            }
            else
            {
                this.GetImageFromFileSystem(context, text, fileName);
            }
            context.ApplicationInstance.CompleteRequest();
        }

path参数不为空或者不等于1时,会进入GetImageFromFileSystem方法中。

private void GetImageFromFileSystem(HttpContext context, string filePath, string fileName)
        {
            filePath = context.Server.MapPath(filePath);
            if (filePath == null)
            {
                return;
            }
            StreamReader streamReader = new StreamReader(filePath);
            BinaryReader binaryReader = new BinaryReader(streamReader.BaseStream);
            byte[] array = new byte[streamReader.BaseStream.Length];
            binaryReader.Read(array, 0, (int)streamReader.BaseStream.Length);
            if (array == null)
            {
                return;
            }
            streamReader.Close();
            binaryReader.Close();
            string text = Path.GetExtension(filePath).Substring(1).ToLowerInvariant();
            fileName = (string.IsNullOrEmpty(fileName) ? Path.GetFileName(filePath) : (fileName + "." + text));
            this.WriteFile(array, fileName, "image/" + text, context.Response);
        }

GetImageFromFileSystem方法也比较好理解了。因为这里的filepathcontext.Server.MapPath重新赋值了一次,获得应用程序根目录所在的位置。后面就直接使用WriteFile返回了文件的内容。

导致了任意文件下载。

这个漏洞目前互联网上还没有公开,可能是影响范围比较小。在fofa上进行了资产整理以及漏洞验证。发现影响量不是很大。只能说后续可以留意下。

后续:

在asp.net中,任意文件下载的利用方法有很多,结合上文环境。可以利用以下两种方法。

1.读取web.config中的内容,获取到Telerik的key,使用已知漏洞进行利用

2.任意读取aspx文件,LOGIN.ASPX,INDEX.ASPX.获取程序集的命名。后直接从BIN目录下下载网站源代码所对应的程序集,进行代码审计

本文链接:

https://websecuritys.cn/index.php/archives/480/
1 + 8 =
2 评论
    TQLChrome 92Windows 10
    2021年08月26日 回复

    TQL

    Big Koala Bear Stuffed AnimalFirefox Browser 42Windows 7
    2021年08月25日 回复

    Its such as you learn my mind! You appear to grasp so much approximately this, such as you
    wrote the e book in it or something. I believe that you can do with some %
    to pressure the message house a bit, but instead of that, this is magnificent blog.
    An excellent read. I will certainly be back.