今天蹭着学弟的队伍,玩了一下CTF,看到了一个有趣的Misc题目,这里记录一下
巅峰极客题解 Baby Forenics
初步分析
题目只给了一个流量包,打开之后里面基本上都看不懂。。。不过发现里面有一个协议的名字很扎眼,叫做IEC 60870-5 104
:
这是个啥玩意儿???不过misc向来都是学习新的协议的,于是一通搜索,搜出来写奇奇怪怪的文章,不过好像都提到说,这个协议是一个用于电力行业采用的应用通信协议。那只能假设出题人真的再考我们这个的知识点了,于是找了几个文档:
比较宽泛的文档
讲的比较细致
这里有格式图
从那篇格式图的博客中,我们能知道,这种协议被称为APDU(Application Protocol Data Unit 应用程序信息单元),结构如下:
可以看到它的魔数为0x68。看到我们的流量包,好像还真的出现过这个数字:
那看来考点没找错,就是考我们这个协议的事情
IEC 60870-5 104 学习笔记
由于是为了做题目,所以是飞快的过了一遍这个协议的内容。
协议种类 ---- I, S, U
大致看了一下,协议分成三种类型的
- I类型:编号的信息传输帧(通俗点来说就是主要传数据的)
- S类型:编号的监视功能(个人理解就是校验帧一类的)
- U类型:控制功能(也就是用于控制是否发送帧之类的)
协议传输与内部计数器
假设有A,B两个站使用这个协议进行通信,双方在通信过程中,内部都会维持三个计数器,分别是
- V(S):send,发送端的计数器(也就是自己发出去的帧数),每次发送一个数据包自增1
- V®:recive,接收的计数器(也就是自己收到的帧数),每次接受一个数据包自增1
- Ack:接收到的数据包中的V®值
用一个实例来说明一下:
假设A向B发送了一个I类型的数据包,那么发送包的当下,因为是第一个发送的包,所有的值都为初始值,所以A中的三个计数器为
- V(S)=0
- V®=0
- ACK=0
所以整个发送过程就类似
1 | A B |
其中,I中记录的内容为I(V(S), V®),具体的格式后面会提到
那假设A又往B发送了一个I类型的数据包,那么当发送的时候,A中的V(S)已经记录过第一次发送的数据了。状态变成了
- V(S)=1
- V®=0
- ACK=0
那么发送过程会变成
1 | A B |
假设之后B要回复一个数据包,那么我们来看一下当前B中的数据包的形式:
- V(S)=0
- V®=2
- ACK=0
于是就变成了
1 | A B |
再之后,A要回复B一个数据包,此时A中的状态为
- V(S)=2
- V®=1
- ACK=2
那么发送的时候数据包中内容就为:
1 | A B |
协议组成
这个协议APDU是由两部分组成的:
- APCI = Application Protocol Control Information 应用协议控制信息
- ASDU = Application Service Data Unit 应用服务数据单元
APCI
前面这个APCI其实就是相当于一些常见通信协议中的协议头,用来记录一些基本信息的:
如上,我们结合一下我们实际的数据包一起看:
- 68:开头数据
- 0e:表示当前ASDU数据包的长度
- 最低bit用于表示当前数据包为I类型
然后的这个Control Field控制域,会因为数据包种类不同而不同:
- I: 这里的4个字节分别表示发送者和接收者
- S: 这里的4个字节只有后两个字节在使用,表示接收者
- U: 这里只有第一个字节使用,用于表示当前的控制状态
然后回到我们前面的示例中,我们看的是一个I种类的数据包
- 0400和0200:表示发送者和接收者(小端)。但是根据协议,它们的最低bit是未被使用的,所以其其实表示的是发送者和接收者为2和1,正好就是I(2,1)
我们可以看一下别的数据类型的包:
- 0100:当前数据包为S类型,并且除了最低的两个bit其余bit并未使用
- 0400:表示接收者。这里表示的是接收者的计数器为2
43中的低量比特表示当前包类型为U,而高6bit表示当前控制为TESTER act。这个数据包之后需要跟随一个TESTER con的U类型包作为回应,用来确保当前传输的稳定性
ASDU
之后的数据表示的是ASDU,也就是数据信息,我猜测可以将这里理解成,从这里开始表示的是传输的内容:
- 01:表示当前信息的类型,显示是M_SP_NA_1(1),也就是遥信单点信息的意思
- 下一个01:表示的是信息的个数,也即是之后1个
- 03:表示传输原因,这里的原因是突发传输
- 00:表示传输发起人的地址,这里就是0
- 0100:表示通用ASDU的地址,同样是小段,这里是0001的意思
- 070000:表示当前对象地址,这里是7
- 01:表示当前传输的品质(不知道为啥是这么个翻译),这里可以看wireshark的解析:
总的来说,就是当前的SPI(状态)属于合(?)
反正总的来说,这个状态表示的是1,那么可以猜测如果没有信息传输的话,默认的信息应该为0
题解
大致学习了一下整个协议,发现这个协议本质上是一个信息传输协议。我猜测这个协议应该是用来传输一些非常底层的数据的,所以很可能每次tcp都只会传输一个bit的信息,而选择对象的下表,应该就是当前对象的地址。那么我们就只需要将这个传输过程中提到的对象地址取出来,将其设为1,其余比特设为0,那就能得到整个传输的数据了!
1 | content = ['0']*100 |
后记
这次比赛除了这个题目其实还有一些比较标准的CTF题,有空的话再整理到博客上吧。