1、 正常情況下,QQ可以順利的登錄:
這時通過抓包可以發現,QQ協議的數據包,正常情況下(後面有不正常的情況),都是通過udp協議傳送的。在udp的數據載荷中,可以看到QQ對應用層數據做的封裝格式。其中有一個叫做“命令”的字段(這個名字是科來給起的,真實名稱估計是沒有),這一字段在數據包所處位置固定、長度固定,通過分析登錄過程中的一系列數據包,我大概可以斷定這個“命令”字段就是QQ用來識別每一個數據包的作用和包含內容的(比如有請求登錄、發送消息、接受消息、加個好友什麼的)。正好科來在概要中有描述:其中有一個命令就是“請求登錄令牌”,這個數據包聽上去在登錄過程中比較關鍵,所以我想測試一下,如果阻止這個數據包發送,能不能就阻斷掉QQ登錄。在包結構中看到,這個命令字段距離3層頭開始的位置有31個字節,大小爲2字節,它的值是“00BA”(注意是16進制數值)。
於是在路由器中定義一個class來匹配“請求登錄令牌”這個數據包:
class-map type access-control match-any qq_udp
match start l3-start offset 31 size 2 eq 0xBA
然後通過policy將這個數據包記錄下來並drop掉:
policy-map type access-control qq_udp
class qq_udp
log
drop
2、 第一次測試結果:
在科來的抓包和路由器的日誌中可以看到,路由器將“請求登錄令牌”丟棄掉後,QQ客戶端在不斷的重新發送這個數據包,這一點可以證明這個數據包的作用還是很大的,送不出去,它是不會罷休的。
過了很久很久(大約1、2分鐘後),我估計QQ是覺得通過udp發送是沒戲了,這時它突然開始通過HTTP登錄,並且很快就登上去了。這時再通過科來分析這些HTTP數據包,發現在HTTP數據載荷中都是無法識別的2進制數據,我估計它可能是把登陸數據加密後通過HTTP傳輸了:
但是繼續分析多個HTTP數據後可以看出:
在這些封裝在HTTP中的2進制數據,第3、4個字節的值都是0x02和0x16,根據這個規律,再做一個class匹配所有符合這樣特徵的數據包,執行drop:
class-map type access-control match-any qq_tcp
match start l3-start offset 42 size 2 eq 0x216
policy-map type access-control qq_tcp
class qq_tcp
log
drop
最後再測試一次:
路由器上顯示,先把QQ客戶端的udp請求給drop了,一會又把它的tcp請求給drop了。這回QQ沒招了,給出了“超時”提示!
通過對數據包的深層識別,就能夠阻止QQ利用80、443這些必開端口進行登錄的詭異行爲。
最後介紹一下這個feature:12.4(15)T裏面就有了,從18到72都帶!