SNMP報文抓取與分析(二)


SNMP報文抓取與分析(二)

在上一篇文章(SNMP報文抓取與分析(一))中已經介紹了怎么使用netcat來抓取數據包了。也給出了對數據包分析的結果。本篇文章將介紹具體的分析過程。

本文由烏合之眾 lym瞎編,歡迎轉載 blog.cnblogs.net/oloroso
本文由烏合之眾 lym瞎編,歡迎轉載 my.oschina.net/oloroso

1、SNMP報文表示簡介

SNMP(簡單網絡管理協議)是目前在計算機網絡中用得最廣泛的網絡管理協議,它使用ASN.1(Abstract Syntax Notation One抽象語法表示法.1)來定義SNMP報文格式和MIB(Management Information Base管理信息庫)變量的名稱。

ASN.1是一種描述數據和數據特征的正式語言,它和數據的存儲及編碼無關。
根據ASN.1標准定義,數據類型分為:
簡單數據類型: boolean布爾值、null空、integer整型、real實數、octerstring八進制字符串、object identifier對象標識、ipaddressIP地址、time ticks時刻值等。
構造數據類型:sequence序列、sequence of setset ofchoice等。構造數據類型提供一種或多種簡單數據類型進行復合的方法。

基本編碼規則BER

在具體系統中,我們需要用具體的編碼規則將ASN.1語法表示的抽象數據轉換成具體的比特流

SNMP使用的編碼方法是BER(Basic Encoding Rule)。BER的數據都由三個域構成:標識域(tag)+長度域(length)+值域(value)。

標識域Tag表示

數據類型 編碼十六進制表示
BOOL 0x01
INT 0x02
OCTSTR 0x04
NULL 0x05
OBJID 0x06
ENUM 0x0A
SEQ 0x30
SETOF 0x31
IPADDR 0x40
COUNTER 0x41
GAUGE 0x42
TIMETICKS 0x43
OPAQUE 0x44
GET 0xA0
GETNEXT 0xA1
GETResp 0xA2
SET 0xA3
TRAP 0xA4

長度域length表示

長度域用於指示后續的值域value的字節數。但是這個長度域自身多長怎么確定呢?SNMP使用的是變長表示法,這有點類似與UTF8的編碼方式。具體表示方法如下:
1、如果值域的長度在0127字節之間,那么就是一個字節來表示,即第一個最高位為0的時候,其值就代表了值域的長度。
2、如果值域的長度在127字節以上,那么第一個字節的第一個bit位(為1)就用於指示值域的長度在127字節以上,后7個bit位(實際值)以及后續用於表示值域長度的字節數。
例如:

值域長度(十進制) 編碼表示(十六進制) 解釋
16 0x10 0127之間,直接表示
160 0x81 0xA0 0x81的二進制為1000 0001第一位表示其超過127,低7位表示后續還有一個字節來表示值域字節數。0xA0表示值域的長度為160個字節。
1500 0x82 0x05 0xDC 第一個字節0x82表示后續還有兩個字節表示值域長度,0x05DC的十進制值為1500

因為絕大部分情況下,值域的長度都在【0,127】區間內,所有這種表示方法最節約。

2、SNMP報文詳細分析(以一個get-response報文為例)

先來看看報文數據

2.1、數據包分析結果(以get-response為例)

先使用hexdump來查看一下獲取到的報文內容。(hexdump是一個很好用的十六進制分析工具)

o@o-pc:~/snmpPUD$ hexdump -C b.hex 
00000000  30 30 02 01 01 04 06 70  75 62 6c 69 63 a2 23 02  |00.....public.#.|
00000010  04 22 70 8b d4 02 01 00  02 01 00 30 15 30 13 06  |."p........0.0..|
00000020  0e 2b 06 01 04 01 8c a6  5e 01 01 01 01 01 00 02  |.+......^.......|
00000030  01 2b                                             |.+|
00000032

get-response報文示例分析(b.hex)

十六進制數據 解釋
30 表示SNMP協議報文(整個報文是一個SEQUENCE)
30 消息長度48字節(表示后面還有44個字節的內容)
02 01 01 協議版本(2c)(前兩個字節02 01 表示INTEGER類型)
04 參數類型(OCTSTR)
06 群體(community)名長度
70 75 62 6c 69 63 群體名public的assic碼值
a2 PUD類型get-response
23 snmp pdu的長度為35個OctStr(后面的內容31字節)
02 04 22 70 8b d4 請求標識符Request ID
02 01 00 表示error-state為0
02 01 00 表示error-index為0
30 11 表示后面變量綁定是SEQUENCE類型17個字節長度
30 0f 表示(變量名1變量值1)是SEQUENCE類型15個字節長度
06 表示該字段是OID類型
0b OID長度11字節
2b 06 01 04 01 1.3.6.1.4.1(標識1.3被合並為2B)
8c a6 5e 201566 (這也是根據規則轉換得到的)
01 01 01 1.1.1
00 表示.0 即第一個實例\
  (下面的值實際是節點1.3.6.1.4.1.201566.1.1.1.0的)
02 01 2b 02 01 表示INTEGER類型,2b表示值(43)

2.1、SNMP首部

SNMP報文的首部指明了這個報文是SNMP協議報文,以及報文的字節數。
SNMP報文的第一個字節用於表示這是一個SNMP報文,就是0x30
在第一個字節之后是一個長度域,用於告知后面的SNMP報文的總字節數(不包括前面的0x30和這個長度域所占的字節數)。如下所示

0x30 length 后面的內容,字節數為length....
標識域 長度域 值域

-
這就是BER編碼規則出來的Byte流數據。

2.3、SNMP版本表示

上述值域部分,前三個字節是SNMP版本的內容。0x02,0x01,0x01
0x02是標識域,表示的是值域類型為Integer
0x01是長度域,表示后續值域的長度為1個字節
0x01是值域,表示版本為SNMP v2c

SNMP版本 編碼(十六進制)
V1 0x00
V2C 0x01
V3 0x02

2.4、Community共同體表示

還是以之前的數據包來做分析,共同體部分這里一共占了8個字節。0x04,0x06,0x70,0x75,0x62,0x6c,0x69,0x63
0x04是標識域,表示值域類型為(OCTSTR)
0x06是長度域,表示值域的長度為6個字節
70 75 62 6c 69 63是值域的內容,是群體名public的assic碼值

3、PUD表示

這個部分內容比較多,但都是基於BER形式編碼出來的。就不詳細分析了。
先把這一部分的內容貼出來
a2 23 02 04 22 70 8b d4 02 01 00 02 01 00 30 15 30 13 06 0e 2b 06 01 04 01 8c a6 5e 01 01 01 01 01 00 02 01 2b

PDU類型表示

上面的第一個字節0xa2就是表示這個PDU的類型。見下表

PDU類型編碼 名稱
0xA0 get-request
0xA1 get-next-request
0xA2 get-response
0xA3 set-request
0xA4 trap(notification)
0xA5 GetBulk(SNMPv2增加)
0xA6 Inform(SNMPv2增加)

0xa2后一個字節是這個PUD的長度域,0x23表示后面的值域是35個字節。

get/set的表示

SNMP應該說是有三種操作,get/set/trap,又可細分為上面表格中的5中PDU類型。其中getset有共同之處,這里先以get的來做說明。

請求標識符Request ID

這是由管理進程設置的一個整數值。代理進程在發送get-response報文時也要返回此請求標識符。管理進程可同時向許多代理發出get報文,這些報文都使用UDP傳送,先發送的有可能后到達。設置了請求標識符可使管理進程能夠識別返回的響應報文對於哪一個請求報文

先貼數據02 04 22 70 8b d4
0x02是標識域,表示值域為整型數據
0x04是長度域,表示值域長度為4個字節
0x22 70 8b d4是值域,就是一個整數而已。(577801172)

錯誤狀態error-state

錯誤狀態是用於告知管理進程,代理進程對其發出的請求的處理結果的狀態的。

還是貼數據02 01 00
0x02是標識域,表示值域為整型數據
0x01是長度域,表示值域長度為1個字節
0x00是值域,表示沒有出錯
錯誤狀態的編碼如下表所示

編碼 名字 說明
0 noError 一切正常
1 tooBig 代理無法將回答裝入到一個SNMP報文之中
2 noSuchName 操作指明了一個不存在的變量
3 badValue 一個set操作指明了一個無效值或無效語法
4 readOnly 管理進程試圖修改一個只讀變量
5 genErr 某些其他的差錯

錯誤索引error-index

當出現noSuchNamebadValuereadOnly的差錯時(見上表),由代理進程在回答時設置的一個整數,它指明有差錯的變量在變量列表中的偏移。

貼數據02 01 00
0x02是標識域,表示值域為整型數據
0x01是長度域,表示值域長度為1個字節
0x00是值域,因為沒有出錯,所以這里為0

變量綁定

變量綁定就是跟在錯誤索引后面的一系列變量。這些變量同樣也采取BER形式的編碼規則。
在get或get-next報文中,變量的值應忽略。

trap(notification)

PUD的類型如果不是上面的所述的get/set那就應該是trap(notification)類型了。這里沒有抓取相關的數據包,只是簡單的介紹一下。

trap部分的編碼字節流大致如下分布形式

OID trap類型 特定代碼 時間戳 變量綁定…

-

  • 1、第一個部分是指trap報文對應的網絡設備的對象標識符。此對象標識符肯定是在enterprise結點{1.3.6.1.4.1}下面的一棵子樹上。
  • 2、trap類型
    此字段正式的名稱是generic-trap,共分為下表中的7種。

    trap類型 名字 說明
    0 coldStart 代理進行了初始化
    1 warmStart 代理進行了重新初始化
    2 linkDown 一個接口從工作狀態變為故障狀態
    3 linkUp 一個接口從故障狀態變為工作狀態
    4 authenticationFailure 從SNMP管理進程接收到具有一個無效共同體的報文
    5 egpNeighborLoss 一個EGP相鄰路由器變為故障狀態
    6 enterpriseSpecific 代理自定義的事件,需要用后面的“特定代碼”來指明
  • 3、當使用上述類型2、3、5時,在報文后面變量綁定部分的第一個變量標識響應的接口。

  • 4、特定代碼(specific-code)
    指明代理自定義的時間(若trap類型為6),否則為0。
  • 5、時間戳(timestamp)
    指明自代理進程初始化到產生trap報告的事件發生所經歷的時間,例如時間戳為1230表明在代理初始化后1230ms發生了該時間。
  • 5、變量綁定(variable-bindings)
    指明一個或多個變量的名和對應的值。也是采用的BER編碼規則。

一些數據類型的編碼表示

前面的就只介紹到錯誤索引了,錯誤索引后門的內容就是變量和值的內容了。直接看分析結果就是了,就不做詳細介紹了。下面介紹一些變量類型的編碼表示方法。

Integer整型編碼表示

整型數據的標識域編碼是0x02,長度域不定,一般是1/2/4字節等。
整型數據的值域是帶符號類型,最高位是符號位,采取補碼的表示形式。要注意的是,其是大端表示法(高地址存低位)。

OID對象標識符編碼表示

SNMP服務器維護的所有管理信息庫(MIB)對象采用ObjectID表示,如,1.3.6.1.2.1.1.1表示MIB庫中的設備描述SysDesc變量,其編碼規則如下:
標識域編碼為0x06,長度域根據情況而定,值域的編碼比較復雜,如下所示。

  • 1、首兩個ID被合並為一個字節X * 40+Y
    例如:1.3合並為1x40+3 = 43 = 0x2B
  • 2、后續的ID,如果在區間[1,127]內,直接編碼表示,如果大於127,那么按照下面(3)所述方法編碼
  • 3、如果ID大於127,那么使用多個字節來表示。
    • a.這多個字節中除最后一個字節外,前面的字節最高位為1
    • b.這多個字節的最后一個字節的最高位為0
    • c.這里每個字節剩下的7個比特位用來表示實際的數值
      例如這里的201566這個數,用十六進制表示是0x03 13 5e
      那么用二進制表示是000 1100 010 0110 101 1110
      注意上面是以7個比特位為單位進行分划的,現在我們來填充最高位
      將前面的最高位填1,最后一個最高位填0即可得到
      1000 1100 1010 0110 0101 1110用十六進制表示為0x8c a6 5e

sequence組合類型

sequence表示其由多個數據組合而成,每一個數據也都還是采用的BER編碼方法。
例如我們這里分析的數據包中就要一個sequence類型的數據,其值域又是有一個OID類型的數據和一個Integer類型的數據組合而成的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM