【未經贊成禁止轉載】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 – 工控業務流量分析