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
查阅历史相关漏洞后主要有以下
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;
}
_handlers
在PopulateHandlers
方法中被赋值.
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
进行分发,调用指向handler
的ProcessRequest
方法 已知历史漏洞都指向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
方法也比较好理解了。因为这里的filepath
由context.Server.MapPath
重新赋值了一次,获得应用程序根目录所在的位置。后面就直接使用WriteFile
返回了文件的内容。
导致了任意文件下载。
这个漏洞目前互联网上还没有公开,可能是影响范围比较小。在fofa上进行了资产整理以及漏洞验证。发现影响量不是很大。只能说后续可以留意下。
后续:
在asp.net中,任意文件下载的利用方法有很多,结合上文环境。可以利用以下两种方法。
1.读取web.config中的内容,获取到Telerik的key,使用已知漏洞进行利用
2.任意读取aspx文件,LOGIN.ASPX
,INDEX.ASPX
.获取程序集的命名。后直接从BIN目录下下载网站源代码所对应的程序集,进行代码审计
TQL
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.