点击蓝字,关注我们
日期:2022-11-17 作者:Zero 介绍:一场较为魔幻的比赛。
1、 前言
近日参加了一场甚是魔幻的工控方向比赛,查看排行榜不知道的还以为参加的是某行业赛,其中一道Modbus
题目未解出,但很接近正确答案,这道题在往年也有相似的题目,当时也是未解出,赛后网上也没有相关Writeup
,一度怀疑题目存在问题,有什么特殊用途那就不得而知了,当然,还是要相信比赛是公平、公正的!本着对知识的求知欲,在此分享下该题目的解题心路历程。
2、 题目情况
题目描述信息如下:
题目附件部分内容如下:
3、 解题尝试
看到这些数据,每行都是 16
字节长度,前四位都是相似的组合,再加上描述中说明了这是工控方面的协议,自然联想到这些大概率是Modbus RTU
的数据帧。
这里补充下Modbus
数据格式的基础知识,Modbus RTU
数据帧由四部分组成,设备地址,功能码,数据和校验。
题目附件中所给的是16
进制格式的,所以2
个字符对应上图中的一个字节,以题目附件中的数据03068d4a34049591
为例,按上述格式释义如下:
Part of Data Package | Description | Value |
---|---|---|
03 | Slave address | 0x03 (3) |
06 | Function code | 0x06 (6) - Write Single Register |
8D 4A | Register address | Physical: 0x8D4A (36170) Logical: 0x8D4B (36171) |
34 04 | Register value | 0x3404 (13316) |
95 91 | CRC | 0x9591 (38289) |
数据最后一部分是校验位,校验2
个字节,由发送设备计算,将校验码之前的数据按照CRC16
算法进行计算,生成2
个字节的数据,放置于发送信息的尾部。接受信息的设备再重新计算接收到的信息的CRC
码,比较计算得到的CRC
码是否与接收到的相符,如果不相符,则表明数据在传输过程中出错。通过数据校验增加了系统的安全与效率。
为了排版好看,就不在此贴完整代码了,只涉及读文件、字符串截断、十六进制解码比较简单,这里只给出Python
版本的校验计算方法,
def calc_crc(string):
data = bytearray.fromhex(string)
crc = 0xFFFF
for pos in data:
crc ^= pos
for i in range(8):
if ((crc & 1) != 0):
crc 1
crc ^= 0xA001
else:
crc 1
return hex(((crc & 0xff) << 8) + (crc 8))
以及MODBUS RTU
常用的功能码:
功能码 | 含义 |
---|---|
01 (0x01) | 读线圈 |
02 (0x02) | 读离散量输入 |
03 (0x03) | 读保持寄存器 |
04 (0x04) | 读输入寄存器 |
05 (0x05) | 写单个线圈 |
06 (0x06) | 写单个寄存器 |
15 (0x0F) | 写多个线圈 |
16 (0x10) | 写多个寄存器 |
有了上面的前置知识,接下来开始解题,题目附件中一共给出 200
条数据帧,编写脚本逐个检查校验位后发现,检验位正确的数据帧有 87
条,不正确的有 113
条,由于题目描述并未告知解题方向,所以需要挨个分析,先分析校验位正确的数据,将每个从机的每个功能号对应的数据单独提出,总览如下:
可以看到只有从机 01
的 06
功能号的数据存在意义,但直接提交平台发现不对,后面又进行了很多编码、密码学及脑洞方向的尝试,结果均无收获,在分析的过程中看到Register address
比较跳跃,不是连续地址,于是考虑到是否存在顺序方面的问题,地址及数据如下所示:
# (地址, 数据)
('b44f', 'XG')
('44c7', '3K')
('86b1', '1W')
('082c', '5Q')
('bb6d', '8A')
('5153', 'VR')
('d370', 'XM')
('bb91', 'VF')
('c7c2', '43')
('bb2b', '38')
按照地址由小到大排序,对数据进行拼接,由于题目描述中提到Flag
的格式为flag{}
,所以解题的尝试尽量往得到flag{}
格式的字眼的答案为主,于是对拼接后的字符串再次进行各种编码、密码学及脑洞方向的尝试,依然是没有收获,比赛时对该题的尝试也就到此为止。
赛后又重新看了看,还是觉得Register address
地址不是按顺序来的这点比较可疑,正考虑如何处理按顺序拼接的字符串的时候,大佬告知了赛后交流成果,这个题的正确答案正是按顺序拼接后的字符串,不需要后续解码,也不包括flag{}
格式,得知消息后大受震撼!!!
复盘反思下,一是过于相信题目描述了,二是没有将所有猜想产出的内容作为答案提交,导致与正确答案擦肩而过,当事人表示非常后悔,多亏了队友安慰说:“不要紧,就算做出来也是一样的排名!”,我觉得非常有道理,原称之为 CTF
竞赛的排行“相对论”,XD
。
4、结语
比赛嘛,尽力了,有所收获就好,不管是哪方面的收获,一篇水文,感谢您能看到此处~~~ 关注我们了解更多趣事,我们下期见!
免责声明:本文仅供安全研究与讨论之用,严禁用于非法用途,违者后果自负。
宸极实验室隶属山东九州信泰信息科技股份有限公司,致力于网络安全对抗技术研究,是山东省发改委认定的“网络安全对抗关键技术山东省工程实验室”。团队成员专注于 Web 安全、移动安全、红蓝对抗等领域,善于利用黑客视角发现和解决网络安全问题。
团队自成立以来,圆满完成了多次国家级、省部级重要网络安全保障和攻防演习活动,并积极参加各类网络安全竞赛,屡获殊荣。
对信息安全感兴趣的小伙伴欢迎加入宸极实验室,关注公众号,回复『招聘』,获取联系方式。
原文始发于微信公众号(宸极实验室):『工控』某工控比赛 Modbus 题目复盘
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论