組播路由介紹以及攻擊實戰
前言
前段時間筆者在測試嵌入式設備的時候遇到了nmap掃不出端口的問題,當時非常迷惑這個設備的通信方式。后面研究發現不同于傳統的像http或者mqtt這種能通過常用的工具與設備進行通訊的協議,此設備所用的通訓方式更為底層,也涉及了筆者第一次接觸的通信方式——組播通信。
組播通信介紹
直白的講,組播就是為同一個網段下兩個或多個設備提供信息交換的渠道。這個渠道被稱作組播組,本質上是一個IP。如果以同一網段下的兩個設備A,B舉例,要實現他們直接的組播通信,首先需要A,B同時加入這個組播組,并且往這個IP的同一端口收發信息。我們發現這其中涉及了兩個協議——設備加入組播組所使用的協議,以及設備往組播端口發送信息的協議。筆者測試的設備所用的組播協議為IGMPV3,而設備和端口通信用的是UDP協議。具體的端口號的問題,后面會進行分析。
設備實戰
本次實戰中的設備ip為192.168.1.12
nmap掃描

發現什么也沒掃出來(試過了nmap -sS -sU -T4 -A -v也不太行)
wireshark抓包
通過wireshark抓包可以發現這個設備向230.1.1.1發了32字節的消息:

具體的消息能夠從下面的詳情里獲取:

發現是32個"\x00",很疑惑,先不管它
從關鍵點入手分析
這個“230.1.1.1”很值得我們思考,我們通過"grep"大法可以發現有一個二進制文件包含它,并通過ida逆向找到它的位置:
img
然后我們看查這一行所在的一整個函數能看見幾個重要的信息
重要信息一
從這里我們能夠找到設備往230.1.1.1發的32個0:

那么50001端口是怎么來的呢?這里就要先細說一下sendto函數了:
sendto(int s, const void * msg, int len, unsigned int flags, const struct sockaddr * to, int tolen);
它有一個關鍵的結構體"sockaadr",而這個結構體有個成員為“sin_port”一般的寫法為:
addr.sin_port = htons(PORT);
這里的htons其實是把機器上的整數轉換為網絡字節序,用人話說就是把小端自序轉大端回到這個函數中,我們通過逆向分析能夠確定addr這個結構體的十進制表示為1371734018:
img
通過計算器,我們能算出端口:


正好就是50001
重要信息二
這個設備如何接受信息可以從recvfrom看出:

recvfrom和sendto是配套函數,也能通過剛才的方法分析出具體的端口:



于是下一步我們就可以嘗試往50002端口發送信息了
重要信息三
發現我們發送的消息的低二字節必須是“\xAF\xE0”以及整體長度必須為0x220,然后就會進入switch

嘗試攻擊
switch中有很多能夠利用的地方,這里就挑兩個地方來談談
第一個

這里能夠將這個設備打reboot,不過前面會有檢查,這個檢查是能繞過的,具體是在第一個case:
img
通過wireshark抓包就能找到
第二個

這里是直接一個命令執行,但是,這里的v7和case選項是一個值而且不是0x2009,也就是說會卡在前面的v7!=0x2009而不能執行成功,筆者猜測這里可能是廠商臨時進行的一個修復,而導致不能直接執行。但是,在這個case分支中是存在一個注入點的,繞過以及執行的exp非常巧妙,但是因為廠商的要求等種種原因不能公布,于是無法與大家分享。但是筆者已經構思好了一道能夠把這個手法運用的CTF iotpwn題,或許在未來的某天能夠以題目的形式出現(狗頭)