【未经赞成禁止转载】html
本题主要考察点是对常见工控协议的理解(modbus/tcp
和s7comm
),题目目标是寻找出报文中某条异常报文流量。很让人疑惑的是,题目中并无给出“异常流量”特征的定义,因此须要从多个角度探索出题人的意思。python
首先,观察整个抓包文件,其中包含了modbus/tcp
、s7comm
和极少的tcp
周期性握手挥手报文。安全
以后,针对modbus/tcp
和s7comm
分别进行深刻地分析。此外值得注意的是,一条工控协议报文中相当重要的字段是状态字/控制字/功能码
,它直接指示着该条报文的具体做用。网络
对于modbus/tcp
而言,本流量中包含的功能码是1:Read Coils
、2:Read Discrete Inputs
、3:Read Holding Registers
、4:Read Input Registers
。这些功能码的做用是读取PLC中一些输入量、输出量和中间变量的值。app
对于s7comm
而言,本流量中包含的功能码是0xf0:Setup Communication
,0x04:Read Var
和0x05:Write Var
。这些功能码的做用分别是创建链接,读变量和写变量。tcp
其中,最为敏感也是咱们最关心的必然是0x05:Write Var
,由于能够将一次写入异常地址/异常数据的行为看成是异常流量。函数
下面咱们着重分析s7comm
协议中0x05:Write Var
控制字的相关报文,wireshark的筛选条件为:code
s7comm&&s7comm.param.func==0x05
htm
筛选结果以下图所示:blog
能够看出,这些0x05:Write Var
命令是向PLC中数据块1(DB1)的0x00000起始地址连续写入50字节的数据。
接下来,笼统地排查是否有报文写地址或数据和其余报文不一样?wireshark的筛选条件为:
(((s7comm) && (s7comm.param.func == 0x05)) && (s7comm.header.rosctr == 1)) && (frame[73:12] == 12:0a:10:02:00:32:00:01:84:00:00:00)
以下图所示,如今已经定位到了这条异常报文,下图显示了其异常之处表如今:
在全部控制字为写变量(write var)的s7comm报文中,这条报文写变量的地址(DB 7)与其余报文地址不一样(DB 1)
虽然咱们已经定位到了这条异常报文,可是还没摸清真正答案flag在表现方式上的套路。
按照第三题的套路,直接将报文的hex码转为ascii码就是flag的套路,在这里彷佛无论用了,这是由于上图中wireshark
在hex码右侧已经显示出了ascii码,它并无实际的意义。
可是我观察到,这堆ascii码好像又是一串hex数据,所以我想到将这串hex再转换为ascii码试一试,编写转换函数以下:
def hex_to_ascii(payload): data = payload.decode("hex") flags = [] for d in data: _ord = ord(d) if (_ord > 0) and (_ord < 128): flags.append(chr(_ord)) return ''.join(flags) if __name__ == '__main__': res = hex_to_ascii("4943537365635363616e") print res res = hex_to_ascii("57696e") print res
获得结果以下
ICSsecScan Win
看到这一串有意义的字符串,才敢肯定这就是最终的答案flag。
最后,总结一下这种异常网络流量分析题的套路:
s7comm
和COTP
之间);flag
字符串,好比报文hex的ascii是否出现连续的hex型数值;参考资料:
2018年工业信息安全技能大赛(东北赛区)解题报告——工业网络数据分析
CTF WP – 工控业务流量分析