工业控制电力系统协议分析

当前,随着中国制造2025战略深入推进,工业控制系统从单机走向互联、从封闭走向开放、从自动化走向智能化,安全漏洞和隐患不断涌现、安全事件频繁发生。我国面临的工业信息安全形势日益严峻。

暑假期间去参加工业信息安全技能大赛时遇到的一个工控协议分析题目,当时没接触过此类题目所以一脸懵逼没解出来,现在有时间拿出来回顾一下,记录下解题过程。

题面:

1
智能变电站通过61850规约进行监控层到间隔层的数据采集,请分析网络数据包,了解mms规约,进一步发现数据中隐藏的flag

点我下载题目

解题思路

打开数据包,根据题目中所说的“了解MMS规约”可知此题考查的重点是mms协议,因此先排除其他协议的干扰,从数据包中筛选出mms协议的数据包

共8158个数据包,过滤出1538个mms协议的数据包,观察info栏发现此协议主要含有4个协议数据单元(PDU),分别为

English name 中文名称
initiate-RequestsPDU 启动-请求PDU
initiate-ResponsePDU 启动-应答PDU
confirmed-RequestsPDU 确认-请求PDU
confirmed-ResponsePDU 确认-应答PDU

四个PDU中前两个PDU只有两个数据包,而且查看后找不到什么有价值的内容,所以flag应该是隐藏在后面两个PDU中了

突然回想起当时解题时一心想通过ctrl+F大法来查找携带flag字符串的内容,然后发现了一个名为flag.txt的文件,那么flag八成是在这个里面了,但是通过追踪流的方式找到的这个文件名貌似没有找到文件的内容而只有文件名

当时看到这个文件名就像看到了希望的曙光疯狂在这个字符串附近寻找flag,但是当时的比赛环境并没有提供网络,也并没有机会查阅mms协议相关的资料,于是就像没头苍蝇乱撞,结果一无所获。

另外说一句,其实对于这种数据包的分析题,有个很好的软件叫做NetworkMiner这个软件可以自动分析出数据包中存在的文件或者消息,session维持的信息等,可以说功能十分强大,关键是方便,不过可能这个软件不支持mms协议的分析,所以用这个软件找不到flag.txt的内容。

对于这种大数据量的数据包,可以使用pyshark进行分析,我在这个网站上找到了很好的pyshark的教程,我是链接 ,文章中对pyshark有详细的介绍,很多用法可以在里面查到,另外在这个链接里有数据包摘要的介绍,在对数据包进行过滤的时候可以用到,我们可以使用类似如下的方法来获取对象的一些关键信息:

1
2
3
4
5
6
7
8
9
10
11
import pyshark

def get_service():
try:
captures = pyshark.FileCapture("test.pcap")
print(dir(captures[0]))
except Exception as e:
print(e)

if __name__ == '__main__':
get_service()

运行结果如下:

1
['__class__', '__contains__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattr__', '__getattribute__', '__getitem__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_packet_string', 'captured_length', 'cotp', 'eth', 'frame_info', 'get_multiple_layers', 'get_raw_packet', 'highest_layer', 'interface_captured', 'ip', 'layers', 'length', 'number', 'pres', 'pretty_print', 'ses', 'ses', 'show', 'sniff_time', 'sniff_timestamp', 'tcp', 'tpkt', 'transport_layer']

也可以直接在Pycharm里按tab键查看

通过此方法来确定我们要找的信息,写出脚本来统计数据包中MMS的服务个数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import pyshark

def get_service():
try:
captures = pyshark.FileCapture("test.pcap")
confirmed_services_request = {}
confirmed_services_response = {}
for capture in captures:
for pkt in capture:
if pkt.layer_name == "mms":
if hasattr(pkt, "confirmedservicerequest"):
service = pkt.confirmedservicerequest
if service in confirmed_services_request:
confirmed_services_request[service] += 1
else:
confirmed_services_request[service] = 1
if hasattr(pkt, "confirmedserviceresponse"):
service = pkt.confirmedserviceresponse
if service in confirmed_services_response:
confirmed_services_response[service] += 1
else:
confirmed_services_response[service] = 1
# print
print(confirmed_services_request)
print(confirmed_services_response)
except Exception as e:
print(e)


if __name__ == '__main__':
get_service()

得到如下结果:

1
2
{'77': 4, '4': 17, '12': 26, '6': 211, '72': 72, '1': 351, '73': 44, '74': 9, '5': 32}
{'77': 4, '4': 17, '12': 26, '6': 211, '72': 72, '1': 351, '73': 44, '74': 9, '5': 32}

发现数据包中使用到了9个服务,分别是1 (getNameList)4 (read)5 (write)6 (getVariableAccessAttributes)12 (getNamedVariableListAttributes)72 (fileOpen)73 (fileRead)74 (fileClose)77 (fileDirectory)

关于协议类型,可以参考文件GBT16720.2-2005_工业自动化系统制造报文规范第2部分_协议规范.pdf

结合之前找到的flag.txt,过滤一下:

找到了读取flag.txt的数据包,因而编写如下脚本找出读取的数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import pyshark

def flag():
try:
captures = pyshark.FileCapture("test.pcap")
flag_frsm = False
flag_frsm_id = None
flag_read = False
for capture in captures:
for pkt in capture:
if pkt.layer_name == "mms":
# file open
if hasattr(pkt, "confirmedservicerequest") and int(pkt.confirmedservicerequest) == 72:
if hasattr(pkt, "filename_item"):
filename_items = pkt.filename_item.fields
for f in filename_items:
file_name = str(f.get_default_value())
if file_name == "flag.txt":
flag_frsm = True
if hasattr(pkt, "confirmedserviceresponse") and int(pkt.confirmedserviceresponse) == 72 and flag_frsm:
# print(pkt.field_names)
if hasattr(pkt, "frsmid"):
flag_frsm_id = pkt.frsmid
flag_frsm = False
# file read
if hasattr(pkt, "confirmedservicerequest") and int(pkt.confirmedservicerequest) == 73 and flag_frsm_id:
if hasattr(pkt, "fileread"):
if str(pkt.fileread) == str(flag_frsm_id):
flag_read = True
flag_frsm_id = None
if hasattr(pkt, "confirmedserviceresponse") and int(pkt.confirmedserviceresponse) == 73 and flag_read:
if hasattr(pkt, "filedata"):
data = str(pkt.filedata).replace(":", "")
print(hex_to_ascii(data))
flag_read = False
except Exception as e:
print(e)


def hex_to_ascii(data):
data = data.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__':
flag()

得到flag.txt文件的内容:

1
61850@102

总结:

本题的难点在于学会用pyshark对数据包进行分析,并需要了解协议的组成成分以及指令含义

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×