一、使用分隔符做格式区分
1、我们观察之前的打印的symbol中的内容:
从这个内容中我们不难发现,在每一行的每个英文单词后面总会跟着一个“#”号,并且在每个井号后面跟着一些值,从这里就能说明,大概这个协议的消息存储方式是这样的:[域名]#[值],于是我们需要通过“#”这个字符来将消息分割。
在netzob/Inference/Vocabulary/Format.py中有一个函数名为splitDelimiter()这个函数可以根据某个字符来分割消息
所以很当然的,我们就要使用这个函数来将消息进行分割
Format.splitDelimiter(symbol,ASCII("#"))
print(symbol)
打印出来的结果是这样子的:
2、当然打印的结果也可以通过使用_str_debug()方法对这个symbol中的内容再进行结构化处理,然后输出来:
凭自己喜好,自己喜欢看那种样子的就用哪种,因为_str_debug()方法能够将每个域和值分隔开,可能对分析更加有利,具体看协议的内容。这里所有的Raw有一个‘b’的原因是python3的字符串表示方法,b表示bit,所以不用太在意这个b(下同)。
二、根据关键字段分簇
分簇是什么呢?分簇就是能够把拥有同一个关键字段的数据放在一起,这样对于协议分析来说当然作用是很大的啦
这里有这么一个函数,叫做clusterByKeyField(),它同样也在netzob/Inference/Vocabulary/Format.py这个里面,我们把它找出来,然后看看它的作用
这个就是用来分簇的函数啦,然后我们就用这个函数对处理过的symbol进行分簇,并将分簇的结果打印出来
symbols = Format.clusterByKeyField(symbol,symbol.fields[0])
print('[+] Number of symbols after clustering:{0}'.format(len(symbols)))
print('[+] Symbol list:')
for keyFieldName,s in symbols.items():
print('* {0}'.format(keyFieldName))
分簇算法生成了14个不同的symbol,每个symbol都由一个唯一的第一个字段
三、在每个symbol中以序列对齐来区分格式
在这一个步骤,我们将重组消息,并且将每个消息分解成三个基本字段:命令字段、分割字段(在这个报文消息中就是“#”)、不定长内容。这里重点关注不定长内容字段,具有动态大小的字段是我们在使用Netzob中将序列对齐的良好选择。这样就能很清晰地判断出来是这个子字段大小是可变还是不可变的。为了做到这个,使用splitAligned()函数,先看一下这个函数的内容(同样这个函数也在Format.py这个文件中):
for symbol in symbols.values():
Format.splitAligned(symbol.fields[2],doInternalSlick=True)
print('[+] Partitionned messages:')
print(symbol)
这段代码就将symbol中的第三个(0、1、2所以是第三个)域作为对齐的依据,进行对齐,结果如下(不完全展示):
四、找到每个symbol的关系
现在我们想看到每个消息之间的关系。Netzob的API提供了能够确定潜在关系的函数RelationFinder.findOnSymbol(),现在就用这个函数来确定一下是否有潜在关系吧。
for symbol in symbols.values():
rels = RelationFinder.findOnSymbol(symbol)print("[+] Relations found: ")
for rel in rels:
print(" " + rel["relation_type"] + ", between '" + rel["x_attribute"] + "' of:")
print(" " + str('-'.join([f.name for f in rel["x_fields"]])))
p = [v.getValues()[:] for v in rel["x_fields"]]
print(" " + str(p))
print(" " + "and '" + rel["y_attribute"] + "' of:")
print(" " + str('-'.join([f.name for f in rel["y_fields"]])))
p = [v.getValues()[:] for v in rel["y_fields"]]
print(" " + str(p))
找出的潜在关系如图(不完全展示):
五、应用找到的symbol结构之间的关系
我们从上图发现一个与下个字段大小相关的字段。关于这个结果,我们可以修改消息格式来应用我们找到的关系。我们通过创建一个Size字段来做这个,这个字段的值依赖目标字段的内容。我们也指定一个事实是Size字段的大小应该是缓冲区字段的八分之一(因为每个字段默认按位描述)。
for symbol in symbols.values():
rels = RelationFinder.findOnSymbol(symbol)for rel in rels:
# Apply first found relationship
rel = rels[0]
rel["x_fields"][0].domain = Size(rel["y_fields"], factor=1/8.0)print("[+] Symbol structure:")
print(symbol._str_debug())
CMDencrypt的结果如下:
我们已经显示了CMDencrypt的结果,但是我们协议的其他symbol需要做相同的工作。结果,我么能得到每个symbol的完整定义。