当前位置: 首页 > 工具软件 > Netzob > 使用案例 >

尝试netzob(协议逆向)(三)

端木皓君
2023-12-01

状态机的概念,想必能搜到我这篇博客的人,应该都不陌生,这一篇博客,便是用netzob,利用给出的pcap文件,生产三种状态机。

一、生成链式状态机

我们将生成一个基本的自动机,用于说明从 PCAP 文件中提取的命令和响应序列。对于发送的每条消息,将创建一个到新状态的新转换,这就是链式状态机的由来

代码如下:

# Create a session of messages
session = Session(messages_session1)

# Abstract this session according to the inferred symbols
abstractSession = session.abstract(list(symbols.values()))

# Generate an automata according to the observed sequence of messages/symbols
automata = Automata.generateChainedStatesAutomata(abstractSession, list(symbols.values()))

# Print the dot representation of the automata
dotcode = automata.generateDotCode()
print(dotcode)

大致过程就是将messages_session1中生成一个Session,然后session.abstract方法将其抽象成一个abstractSession,再使用Automata.generateChainedStatesAutomata这一自动生成链式状态机的函数,自动生成automata这一状态机链。最后使用automata.generateDotCode函数将状态机链转化为一个图的形式。

其中abstractSession的内容如下,可以看到其实是127.0.0.1:57831和127.0.0.1:4242这两个ip在通信

[('127.0.0.1:57831', '127.0.0.1:4242', Symbol_CMDidentify), 
('127.0.0.1:4242', '127.0.0.1:57831', Symbol_RESidentify), 
('127.0.0.1:57831', '127.0.0.1:4242', Symbol_CMDinfo),
('127.0.0.1:4242', '127.0.0.1:57831', Symbol_RESinfo), 
('127.0.0.1:57831', '127.0.0.1:4242', Symbol_CMDstats), 
('127.0.0.1:4242', '127.0.0.1:57831', Symbol_RESstats),
('127.0.0.1:57831', '127.0.0.1:4242', Symbol_CMDauthentify), 
('127.0.0.1:4242', '127.0.0.1:57831', Symbol_RESauthentify),
('127.0.0.1:57831', '127.0.0.1:4242', Symbol_CMDencrypt), 
('127.0.0.1:4242', '127.0.0.1:57831', Symbol_RESencrypt),
('127.0.0.1:57831', '127.0.0.1:4242', Symbol_CMDdecrypt), 
('127.0.0.1:4242', '127.0.0.1:57831', Symbol_RESdecrypt), 
('127.0.0.1:57831', '127.0.0.1:4242', Symbol_CMDbye), 
('127.0.0.1:4242', '127.0.0.1:57831', Symbol_RESbye)]

代码的最终输出如下:

digraph G {
"Start state" [shape=doubleoctagon, label="Start state", style=filled, fillcolor=white, URL="139657506502880"];
"State 1" [shape=ellipse, label="State 1", style=filled, fillcolor=white, URL="139657506624944"];
"State 2" [shape=ellipse, label="State 2", style=filled, fillcolor=white, URL="139657506624848"];
"State 3" [shape=ellipse, label="State 3", style=filled, fillcolor=white, URL="139657506627488"];
"State 4" [shape=ellipse, label="State 4", style=filled, fillcolor=white, URL="139657506626384"];
"State 5" [shape=ellipse, label="State 5", style=filled, fillcolor=white, URL="139657506624272"];
"State 6" [shape=ellipse, label="State 6", style=filled, fillcolor=white, URL="139657506625712"];
"State 7" [shape=ellipse, label="State 7", style=filled, fillcolor=white, URL="139657506625520"];
"State 8" [shape=ellipse, label="State 8", style=filled, fillcolor=white, URL="139657506626720"];
"End state" [shape=ellipse, label="End state", style=filled, fillcolor=white, URL="139657506626336"];
"Start state" -> "State 1" [fontsize=5, label="OpenChannelTransition", URL="139657506625232"];
"State 1" -> "State 2" [fontsize=5, label="Transition (Symbol_CMDidentify;{Symbol_RESidentify})", URL="139657506626432"];
"State 2" -> "State 3" [fontsize=5, label="Transition (Symbol_CMDinfo;{Symbol_RESinfo})", URL="139657506626624"];
"State 3" -> "State 4" [fontsize=5, label="Transition (Symbol_CMDstats;{Symbol_RESstats})", URL="139657506627056"];
"State 4" -> "State 5" [fontsize=5, label="Transition (Symbol_CMDauthentify;{Symbol_RESauthentify})", URL="139657506626864"];
"State 5" -> "State 6" [fontsize=5, label="Transition (Symbol_CMDencrypt;{Symbol_RESencrypt})", URL="139657506627104"];
"State 6" -> "State 7" [fontsize=5, label="Transition (Symbol_CMDdecrypt;{Symbol_RESdecrypt})", URL="139657506626192"];
"State 7" -> "State 8" [fontsize=5, label="Transition (Symbol_CMDbye;{Symbol_RESbye})", URL="139657506625904"];
"State 8" -> "End state" [fontsize=5, label="CloseChannelTransition", URL="139657506626048"];
}

这个官方例子的大致通信过程就是identify、info、stats、authentify、encrypt、decrypt、bye,差不多就是识别身份建立连接,传递信息、统计、认证、加解密、断开连接这些操作。

二、生成一个单一状态机

这一次,我们不是将 PCAP 转换为观察到的每条消息的状态序列,而是生成一个 uniq 状态,该状态接受任何观察到的已发送消息以触发新的转换。为了响应每个发送的消息(例如“CMDencrypt”),我们期望有一个特定的响应(例如“REDencrypt”),大致代码与链式状态机相同,只是生成状态机的方法改成了generateOneStateAutomata。

代码如下:

# Create a session of messages
session = Session(messages_session1)

# Abstract this session according to the inferred symbols
abstractSession = session.abstract(list(symbols.values()))

# Generate an automata according to the observed sequence of messages/symbols
automata = Automata.generateOneStateAutomata(abstractSession, list(symbols.values()))

# Print the dot representation of the automata
dotcode = automata.generateDotCode()
print(dotcode)

输出如下,也就是没有太多的State,只有个Main state作为唯一态。

digraph G {
"Start state" [shape=doubleoctagon, label="Start state", style=filled, fillcolor=white, URL="140095250880736"];
"Main state" [shape=ellipse, label="Main state", style=filled, fillcolor=white, URL="140095251002800"];
"End state" [shape=ellipse, label="End state", style=filled, fillcolor=white, URL="140095251004192"];
"Start state" -> "Main state" [fontsize=5, label="OpenChannelTransition", URL="140095251003088"];
"Main state" -> "Main state" [fontsize=5, label="Transition (Symbol_CMDidentify;{Symbol_RESidentify})", URL="140095251002704"];
"Main state" -> "Main state" [fontsize=5, label="Transition (Symbol_CMDinfo;{Symbol_RESinfo})", URL="140095251003664"];
"Main state" -> "Main state" [fontsize=5, label="Transition (Symbol_CMDstats;{Symbol_RESstats})", URL="140095251004288"];
"Main state" -> "Main state" [fontsize=5, label="Transition (Symbol_CMDauthentify;{Symbol_RESauthentify})", URL="140095251005344"];
"Main state" -> "Main state" [fontsize=5, label="Transition (Symbol_CMDencrypt;{Symbol_RESencrypt})", URL="140095251003856"];
"Main state" -> "Main state" [fontsize=5, label="Transition (Symbol_CMDdecrypt;{Symbol_RESdecrypt})", URL="140095251004480"];
"Main state" -> "Main state" [fontsize=5, label="Transition (Symbol_CMDbye;{Symbol_RESbye})", URL="140095251004240"];
"Main state" -> "End state" [fontsize=5, label="CloseChannelTransition", URL="140095251003712"];
}

三、生成基于 PTA 的状态机

最后,我们转换来自不同PCAP文件的多个消息序列,以生成一个自动机,我们已经为其合并了相同的路径。底层合并策略称为前缀树接受器( Prefix Tree Acceptor):

实际的意思就是将第一个和第三个数据包转化为Session,以PTA(Prefix-Tree Acceptor)的策略将状态机进行合并(Generation of a Prefix Tree Acceptor (PTA) automaton according to a captured sequence of messages)

代码如下:

# Create sessions of messages
messages_session1 = PCAPImporter.readFile("target_src_v1_session1.pcap").values()
messages_session3 = PCAPImporter.readFile("target_src_v1_session3.pcap").values()

session1 = Session(messages_session1)
session3 = Session(messages_session3)

# Abstract this session according to the inferred symbols
abstractSession1 = session1.abstract(list(symbols.values()))
abstractSession3 = session3.abstract(list(symbols.values()))

# Generate an automata according to the observed sequence of messages/symbols
automata = Automata.generatePTAAutomata([abstractSession1, abstractSession3], list(symbols.values()))

# Print the dot representation of the automata
dotcode = automata.generateDotCode()
print(dotcode)

输出如下:

digraph G {
"Start state" [shape=doubleoctagon, label="Start state", style=filled, fillcolor=white, URL="139755584109632"];
"State 0" [shape=ellipse, label="State 0", style=filled, fillcolor=white, URL="139755584100720"];
"State 1" [shape=ellipse, label="State 1", style=filled, fillcolor=white, URL="139755584100624"];
"State 2" [shape=ellipse, label="State 2", style=filled, fillcolor=white, URL="139755584100816"];
"State 3" [shape=ellipse, label="State 3", style=filled, fillcolor=white, URL="139755584100336"];
"State 4" [shape=ellipse, label="State 4", style=filled, fillcolor=white, URL="139755584099808"];
"State 9" [shape=ellipse, label="State 9", style=filled, fillcolor=white, URL="139755584098512"];
"State 10" [shape=ellipse, label="State 10", style=filled, fillcolor=white, URL="139755584098560"];
"End state 11" [shape=ellipse, label="End state 11", style=filled, fillcolor=white, URL="139755584098944"];
"State 5" [shape=ellipse, label="State 5", style=filled, fillcolor=white, URL="139755584099712"];
"State 6" [shape=ellipse, label="State 6", style=filled, fillcolor=white, URL="139755584100048"];
"State 7" [shape=ellipse, label="State 7", style=filled, fillcolor=white, URL="139755584099472"];
"End state 8" [shape=ellipse, label="End state 8", style=filled, fillcolor=white, URL="139755584099184"];
"Start state" -> "State 0" [fontsize=5, label="OpenChannelTransition", URL="139755584100960"];
"State 0" -> "State 1" [fontsize=5, label="Transition (Symbol_CMDidentify;{Symbol_RESidentify})", URL="139755584100480"];
"State 1" -> "State 2" [fontsize=5, label="Transition (Symbol_CMDinfo;{Symbol_RESinfo})", URL="139755584100240"];
"State 2" -> "State 3" [fontsize=5, label="Transition (Symbol_CMDstats;{Symbol_RESstats})", URL="139755584099520"];
"State 3" -> "State 4" [fontsize=5, label="Transition (Symbol_CMDauthentify;{Symbol_RESauthentify})", URL="139755584099568"];
"State 4" -> "State 5" [fontsize=5, label="Transition (Symbol_CMDencrypt;{Symbol_RESencrypt})", URL="139755584100000"];
"State 4" -> "State 9" [fontsize=5, label="Transition (Symbol_CMDdecrypt;{Symbol_RESdecrypt})", URL="139755584099088"];
"State 9" -> "State 10" [fontsize=5, label="Transition (Symbol_CMDbye;{Symbol_RESbye})", URL="139755584098368"];
"State 10" -> "End state 11" [fontsize=5, label="CloseChannelTransition", URL="139755584098608"];
"State 5" -> "State 6" [fontsize=5, label="Transition (Symbol_CMDdecrypt;{Symbol_RESdecrypt})", URL="139755584099664"];
"State 6" -> "State 7" [fontsize=5, label="Transition (Symbol_CMDbye;{Symbol_RESbye})", URL="139755584099904"];
"State 7" -> "End state 8" [fontsize=5, label="CloseChannelTransition", URL="139755584098416"];
}

这样合并的原因是session1和session3的前8步都是一样的,可以进行合并前缀,后几步不再相同,session1是encrypt -> encrypt,decrypt -> decrypt, bye -> bye。而session3是decrypt -> decrypt, bye -> bye。所以后几步分开了。如果感兴趣的话,可以print(session1.messages),print(session3.messages)查看一下通信过程。

四、其他

官方文档里还有一些东西,但是相关资源找不到了,所以到这了就告一段落了。

这三篇博客大致的过程就是读取pcap文件,查看其内容(Format.splitDelimiter),对流量信息进行聚类(Format.clusterByKeyField),对聚类后的文件信息进行序列对齐(Format.splitAligned),从而推断其语法语义之类的内容(RelationFinder.findOnSymbol)。然后利用其自带的函数,生成状态机(Automata.generateOneStateAutomata)。

但其实这也就是一个未知协议逆向的过程,但非常简略,只能说这玩意儿真的任重而道远。

 类似资料: