关注网络与数据安全

忘记密码
“游侠安全网”创建了网络安全从业者QQ大群(群号:389710688) ,欢迎各位同仁加入!有其它问题,请联系站长“网路游侠”,QQ:55984512


【安全研究】S7commPlus协议研究之动态调试

2020-06-28 11:21 推荐: 浏览: 129字号:

摘要: 1、概述 上一篇文章(https://www.anquanke.com/post/id/206579)对S7comm-Plus协议进行了初步研究,算是理论研究了,本篇以核心通信DLL(OMSp_core_managed.dll)为目标,使用动态调试的方式,对协...

1、概述

上一篇文章(https://www.anquanke.com/post/id/206579)对S7comm-Plus协议进行了初步研究,算是理论研究了,本篇以核心通信DLL(OMSp_core_managed.dll)为目标,使用动态调试的方式,对协议的握手、加密认证过程进行动态调试,以对通信过程做进一步探索认识。

基于之前的工作已经知道,更高版本的TIA Portal软件对应的OMSp_core_managed.dll版本亦更高、更复杂,因此调试工作使用较低版本的DLL为目标(即选择TIA Portal V13,则PLC只能使用V4.1及以下版本),以便于分析和掌握调试方法。

2、环境配置

调试研究的基本环境配置如下:Win7x86虚拟机、

PLC:S7-1200 , 6ES7 212-1BG40-0X0B

Firmware: V4.1.3

Software:TIA Portal V13

S7Comm-Plus Wireshark dissector plugin: V0.0.8

3、通信调试

3.1、加密函数入口定位

参考文章均指出PLC实现通信握手、加密认证的功能在模块OMSp_core_managed.dll中实现,由此可知对该文件的分析尤为重要。OMSp_core_managed.dll是一个使用C#和C++混合编写的.net程序,使用dnSpy对其进行反编译:

如何定位加密函数的入口呢?此处提供两种思路:

1、直接使用dnSpy对DLL文件进行动态调试

dnSpy加载DLL文件,使用“调试”->“附加到进程”功能,附加TIA的进程:

在DLL中先随便打一个断点,可参考文章中指出的SetServerPublicKey:

在dnSpy中尝试搜索关键字,结果如下:

可见该函数位于“ClientSession”类中,在此函数出设置一个断点,然后操作TIA将PLC“转到上线”,转到上线时TIA与PLC将建立通信连接,此时必然经过三次握手及通信加密过程,可看到函数执行到刚才打的断点位置:

查看“局部变量”中的“key”,发现其已经有值,长度为40的数组:

此值即为上一篇文章中提到的S7-1200系列的public key的值。

在dnSpy中继续进行单步执行,经过多次调试可以看到,当calli执行完毕之后,TIA与PLC通信建立完成,calli过程即是在C#中调用C++代码:

调试过程中关注指针session_ptr的值,此处为0x2B9E71C0:

停止dnSpy调试,使用IDA附加TIA进程,由于TIA进程一直处于运行中,其内存加载地址空间将保持不变,通过上述函数指针最终计算得0x65D77310:

F5查看伪代码发现其调用了三个函数:

继续跟进查看,可以发现函数sub_65D7CD40即为第一部分加密函数。

2、使用IDA对DLL文件进行动态调试

参考绿盟的文章可以发现其使用了Windbg进行调试,且留下一些“痕迹”,如下图所示:

因此可以考虑搜索上图中出现的字节码,于是使用IDA附加TIA进程,尝试搜索“e8 9e f9 ff ff”,结果如下:

此处定位到函数sub_65D793B0,发现与绿盟文章中的截图颇为相似:

使用0x65D793B0减去DLL函数的base(0x65BA0000)结果刚好为:0x1D93B0,与绿盟文章中的函数sub_1D93B0刚好对应,因此可以推断调试环境与其相同,那么函数sub_65D793B0即为sub_1D93B0,依次类推:sub_65D790B0即为IntegratyPartEncrytion函数。使用类似的方式搜索定位到加密1函数:

与论文中给出的效果一致:

进一步使用参考调用功能,可以追溯到加密函数入口sub_65D77310,与第一种方式得到的结果一致。

3.2、加密1内容计算

定位到了负责加密认证的函数之后,便可继续使用动态调试对整个加密算法流程进行验证和计算了。上图绿盟的文章中指出,加密1部分的内容为Value array(即上一篇文章中提到的20个字节的随机数)经过加密1函数加密之后的结果,加密的过程为一系列XOR运算,而最终加密的结果保存在v13-v16中。于是可以在加密1函数中下一个断点,然后进行单步调试,监控v13-v16的值:

同样打开wireshark抓包,操作TIA将PLC“转到上线”,函数执行到刚才打的断点位置。同时可以看到握手的前2步已完成,TIA收到PLC发送的20个字节随机数:

继续单步执行,当v13-v16运算完成之后,可从左边变量监控栏得到最终运算结果:

在此先记录v13-v16的值:v13(0x52CF7D4E)、v14(0x9603F213)、v15(0x50639E99)、v16(0xC452A5E3),待整个握手过程完成之后,在M3数据包中的“SecurityKeyEncryptedKey”字段中去验证:

注意大小端模式,由此可见,其值与加密1内容完全吻合。

4、总结

基于对西门子最新的S7Comm-Plus通信协议的理解,使用反汇编工具对核心通信DLL进行逆向和动态调试,介绍了两种定位加密函数入口的方法,同时使用IDA动态调试,计算并验证了加密1的结果内容,从动态调试的角度对加密算法进行了进一步理解。后续的加密步骤及算法的验证,可参照类似方法继续进行。

参考资料:

[1] https://www.blackhat.com/docs/eu-17/materials/eu-17-Lei-The-Spear-To-Break%20-The-Security-Wall-Of-S7CommPlus-wp.pdf

[2] https://www.blackhat.com/docs/eu-17/materials/eu-17-Lei-The-Spear-To-Break%20-The-Security-Wall-Of-S7CommPlus.pdf

[3] https://i.blackhat.com/USA-19/Thursday/us-19-Bitan-Rogue7-Rogue-Engineering-Station-Attacks-On-S7-Simatic-PLCs-wp.pdf

[4] https://i.blackhat.com/USA-19/Thursday/us-19-Bitan-Rogue7-Rogue-Engineering-Station-Attacks-On-S7-Simatic-PLCs.pdf

联系站长租广告位!

中国首席信息安全官
Copy link