今天看了一下snmp數據包的報文格式,用wireshark抓了兩個數據包來分析。
先說說snmp get-request的書報包格式吧,get-next-request,get-response,set-request這幾個格式都是差不多的,只是pdu類型不一樣。還有trap格式不大一樣。
好,先說說get-request報文格式(參考tcp/ip詳解 卷一)。
版本 + 團體名 + pdu類型 + 請求標識 + 差錯狀態 + 差錯索引 + 差錯索引 + 名稱 + 值 + 名稱 + 值 。。。。
trap的也說一下
版本 + 團體名 + pdu類型 + 企業 + 代理地址 + trap類型 + 特定代碼 + 時間戳 + 名稱 + 值。。。
okay,下面說一下我的環境
主機windows xp虛擬機Vmware ubuntu,抓包工具wireshark,使用的netsnmp,主機ip210.38.235.184,虛擬機ip210.38.235.186
這里虛擬機向主機發一條命令snmpget -v 1 -c public 210.38.235.184 sysDescr.0(oid為1.3.6.1.2.1.1.1.0)
先來看看snmp v1版的數據包吧
c8 1f 66 05 fb a6 00 0c 29 90 f7 6d 08 00 45 00 00 47 21 ba 40 00 40 11 9d 2b d2 26 eb ba d2 26 eb b8 96 f9 00 a1 00 33 8a 2d 30 29 02 01 00 04 06 70 75 62 6c 69 63 a0 1c 02 04 26 ca 2f cb 02 01 00 02 01 00 30 0e 30 0c 06 08 2b 06 01 02 01 01 01 00 05 00
c8 1f 66 05 fb a6//目的網卡地址
00 0c 29 90 f7 6d//源網卡地址
08 00//協議類型,這里是ip協議
45 00 00 47 21 ba 40 00 40 11 9d 2b d2 26 eb ba d2 26 eb b8//ip頭部20個字節
96 f9 00 a1 00 33 8a 2d//udp8個字節
30 29//30表示snmp消息用的是asn.1 sequence 29表示消息長度(29后面的字節數)41個字節
02 01 00 //這里采用的是BER(Basic encode rule)編碼(第一個字節表示數據類型,第二個字節表示數據長度,后面為數據)02表示INTEGER類型,01表示長度為1,00表示版本為v1
04 06 70 75 62 6c 69 63//這里是團體名public阿斯科馬,這里也采用的是BER編碼
a0 1c//pdu類型a0表示get-request 1c表示pdu數據長度28個字節
02 04 26 ca 2f cb//request-id管理進程設置的一個整數
02 01 00//差錯狀態,00表示沒有出現差錯
02 01 00//差錯狀態索引,00
30 0e//表示值名稱采用的是asn.1,數據長度為14個字節
30 0c//表示第一個值名稱采用的是asn.1,數據長度為12個字節
06 08 2b 06 01 02 01 01 01 00//這里采用的是BER,但是snmp,oid的編碼方式有點怪,后面我會有說明
05 00//snmp NULL 所以數據長度為0
okay上面已經分析完snmp v1的數據包
下面看看snmp v2數據包
c8 1f 66 05 fb a6 00 0c 29 90 f7 6d 08 00 45 00 00 47 21 b9 40 00 40 11 9d 2c d2 26 eb ba d2 26 eb b8 a8 8d 00 a1 00 33 d1 e6 30 29 02 01 01 04 06 70 75 62 6c 69 63 a0 1c 02 04 51 5a b7 e0 02 01 00 02 01 00 30 0e 30 0c 06 08 2b 06 01 02 01 01 01 00 05 00
c8 1f 66 05 fb a6 //目的網卡地址
00 0c 29 90 f7 6d //源網卡地址 這里應該是數據鏈路層封裝的頭部
08 00 //協議類型,這里是ip協議
45 00 00 47 21 b9 40 00 40 11 9d 2c d2 26 eb ba d2 26
eb b8 //ip首部
a8 8d 00 a1 00 33 d1 e6 //udp首部
//下面是snmp報文
30//表示snmp消息是asn.1 sequence類型
29//29表示該字段后面還有41個字節
02 01 01//最后一個01表示snmp版本為2c這里采用的是BER編碼方式 02表示該字段為INTEGER類型,第二個01表示數據長度為1
04 06 70 75 62 6c 69 63 //這里是團體名稱public,04表示數據類型為OCTET STRING類型,06表示數據長度為6個字節,后面6個為public 的阿斯科馬值,但是這里為什么后面的沒有采用這種BER編碼方式,即數據類型+數據長度+數據類容
a0 1c //a0表示報文類型為get-request,1c表示后面還有28個字節的數據,這里為什么沒有采用BER編碼方式?這里除了類型字段外,其他的都采用BER編碼方式
02 04 51 5a b7 e0 //request ID這是由管理進程設置的一個整數這是由管理進程設置的一個整數值。代理進程在發送get-response報文時也要返回此請求標識符。管理進程可同時向許多代理發出get報文,這些報文都使用UDP傳送,先發送的有可能后到達。設置了請求標識符可使管理進程能夠識別返回的響應報文對於哪一個請求報文
02 01 00 //差錯狀態 00表示noError
02 01 00 //差錯狀態索引00
//下面為名稱 值
30 0e //30 asn.1 sequence類型 0e長度為14
30 0c //第一個名值對編碼方式asn.1 sequence 長度為12
06 08 2b 06 01 02 01 01 01 00 //oid為1.3.6.1.2.1.1.1.0 關於SNMP的OID的編碼方式有些奇特:例如1.3.6.1.2…. 取前兩個數字分別記為x和y。編碼時40*x+y,這里x=1,y=3,因此結果為40*1+3=43,即表示十六進制的2b
05 00//asn.1的NULL類型 variable-value1的值為NULL
這里說明一下關於SNMP的OID的編碼方式有些奇特:例如1.3.6.1.2…. 取前兩個數字分別記為x和y。編碼時40*x+y,這里x=1,y=3,因此結果為40*1+3=43,即表示十六進制的2b
關於snmp trap數據包,我會面會分析。可以參考http://blog.chinaunix.net/uid-23069658-id-3251045.html這篇文章寫得還不錯
snmp報文中pdu只有pdu類型沒有采用BER編碼,其他的都采用了BER編碼
okay先到這
參考:http://blog.chinaunix.net/uid-23069658-id-3251045.html
接着昨天的寫
今天抓了一個snmpget -v 1 -c public 210.38.235.184 sysDescr.0,對應的get-response數據包
還是先上抓到的數據包
//getresponse數據包
//換成v1版
//從虛擬機linux ip:210.38.235.186
//發送snmpget -v 1 -c public 210.38.235.184 sysDescr.0
//到主機windwos xp ip:210.38.235.184
//使用wireshark抓取到的數據包
00 0c 29 90 f7 6d c8 1f 66 05 fb a6 08 00 45 00
00 cd 01 7d 00 00 40 11 fc e2 d2 26 eb b8 d2 26
eb ba 00 a1 d3 95 00 b9 cb ae 30 81 ae 02 01 00
04 06 70 75 62 6c 69 63 a2 81 a0 02 04 34 55 03
c4 02 01 00 02 01 00 30 81 91 30 81 8e 06 08 2b
06 01 02 01 01 01 00 04 81 81 48 61 72 64 77 61
72 65 3a 20 78 38 36 20 46 61 6d 69 6c 79 20 36
20 4d 6f 64 65 6c 20 35 38 20 53 74 65 70 70 69
6e 67 20 39 20 41 54 2f 41 54 20 43 4f 4d 50 41
54 49 42 4c 45 20 2d 20 53 6f 66 74 77 61 72 65
3a 20 57 69 6e 64 6f 77 73 20 32 30 30 30 20 56
65 72 73 69 6f 6e 20 35 2e 31 20 28 42 75 69 6c
64 20 32 36 30 30 20 4d 75 6c 74 69 70 72 6f 63
65 73 73 6f 72 20 46 72 65 65 29
下面是分析數據包
//get-response數據包
//snmpget -v 1 -c public 210.38.235.184 sysDescr.0
//得到對應的snmp get-response數據包
00 0c 29 90 f7 6d //目的網卡地址mac地址
c8 1f 66 05 fb a6 //源網卡地址mac地址
08 00 //協議類型,這里是ip協議
45 00 00 cd 01 7d 00 00 40 11 fc e2 d2 26 eb b8 d2 26 eb ba //ip首部
00 a1 d3 95 00 b9 cb ae //udp首部 16位源端口 + 16位目的端口 + 16udp長度 + 16位udp校驗和
30 81 ae //這里30表示asn.1中的sequence 81和ae同時表示數據長度,這里后面會重點講解一下數據長度為174,注意計算方法
02 01 00 //版本號v1
04 06 70 75 62 6c 69 63 //團體名public
a2 81 a0 //a2表示消息類型為get-response,81,a0表示數據長度
02 04 34 55 03 c4 //這里為request id整數
02 01 00 //這里是差錯狀態,noError值為0
02 01 00 //差錯索引,這里為0
30 81 91 //30值名稱為asn.1的sequence 81和91為值名稱的長度
30 81 8e //同上
06 08 2b 06 01 02 01 01 01 00 //這里應該是oid了,1.3.6.1.2.1.1.1.0
04 81 81 //這里為oid對應的值了Hardware: x86 Family 6 Model 58 Stepping 9 AT/AT COMPATIBLE - Software: Windows 2000 Version 5.1 (Build 2600 Multiprocessor Free)可以查阿斯科馬表
48 61 72
64 77 61 72 65 3a 20 78 38 36 20 46 61 6d 69 6c
79 20 36 20 4d 6f 64 65 6c 20 35 38 20 53 74 65
70 70 69 6e 67 20 39 20 41 54 2f 41 54 20 43 4f
4d 50 41 54 49 42 4c 45 20 2d 20 53 6f 66 74 77
61 72 65 3a 20 57 69 6e 64 6f 77 73 20 32 30 30
30 20 56 65 72 73 69 6f 6e 20 35 2e 31 20 28 42
75 69 6c 64 20 32 36 30 30 20 4d 75 6c 74 69 70
72 6f 63 65 73 73 6f 72 20 46 72 65 65 29//174個字節
通過分析,snmp 中get-response數據包,其實和get-request的格式是一樣的。不過今天由於數據包長度超過了127,使得計算上面差點沒看懂,通過谷歌看到了一個很好的解釋http://stackoverflow.com/questions/22998212/decode-snmp-pdus-where-to-start 這里面很好的解釋了,30 81 ae , udp首部后面,30 81 ae的原因。(順便吐槽一下度娘有點渣)
okay,下面重點說一下30 81 ae是怎么回事
算了,我還是把別人的貼過來吧,寫的很清楚
representing numbers larger than 255. To do this SNMP uses only the 7 least significant bits to store data, the most significant bit is a flag to signal that the data continues in the next byte. Numbers lower than 128 are stored in a single byte
0x127 = 0 111 1111 = 127 0x85 0x22 = 1 000 0101, 0 010 0010 = 000 0101 010 0010 = 674 0xc0 0x80 0x80 0x80 = 1 100 0000, 1 000 0000, 1 000 0000, 0 000 0000 = 100 0000 000 0000 000 0000 000 0000 = 0x8000000
This method is also used if the length of a TLV field is larger than 127.
RFC1592 describes the structure of the messages, take a look at page 11 for a similar example.
I can also recommend using Wireshark to analyze packets, it does an excellent job of translating them to something readable.
上面是stackoverflow上的解釋
在30 81 ae后面有174個字節(我數了一下)
照着上面的算法
81 ae
1000 0001 1010 1110
超過了127后面的數字也表示數據長度,這樣
實際表示的數據為
000 0001 010 1110
整理一下為0000 0000 1010 1110(十進制為174)
ps:snmp v1的trap數據包和v2的trap數據包格式不一樣,v2的trap數據包越來越接近普通報文數據包。snmp trap要配置一下,暫時不抓取snmp trap數據包分析了
待續
接着上午的寫,本來以為net-snmp的trap消息需要配置一些配置文件,后面man了一下snmptrap 和snmptrapd命令,發現如果要發送trap消息是不需要配置的,直接使用snmptrap命令就行了,因為snmptrap是一個發送trap消息的命令。snmptrapd需要配置,來接收snmp trap消息。好了,和以前一樣先上數據包,然后分析數據包(主機ip:210.38.235.184)
snmp v2 trap
//snmp v2 trap數據包
//snmptrap -v 2c -c public 210.38.235.184 "aaa" 1.3.6.1.4.1.2345 SNMPv2-MIB::sysLocation.0 s "just here"
// manager ip 主機名
c8 1f 66 05 fb a6 00 0c 29 90 f7 6d 08 00 45 00
00 67 21 31 40 00 40 11 9d 94 d2 26 eb ba d2 26
eb b8 a3 14 00 a2 00 53 92 5a 30 49 02 01 01 04
06 70 75 62 6c 69 63 a7 3c 02 04 7e df d8 73 02
01 00 02 01 00 30 2e 30 15 06 0a 2b 06 01 06 03
01 01 04 01 00 06 07 2b 06 01 04 01 92 29 30 15
06 08 2b 06 01 02 01 01 06 00 04 09 6a 75 73 74
20 68 65 72 65
分析數據包
c8 1f 66 05 fb a6 //目的網卡地址
00 0c 29 90 f7 6d //源網卡地址
08 00 //協議類型
45 00 00 67 21 31 40 00 40 11 9d 94 d2 26 eb ba d2 26 eb b8//ip首部
a3 14 00 a2 00 53 92 5a //udp首部
30 49 //asn.1 49數據長度73個字節
02 01 01 //snmp版本v2
04 06 70 75 62 6c 69 63 //團體名 public
a7 3c //這里a7指的是trap類型為廠家自定義類型 3c為數據長度60個字節
02 04 7e df d8 73 //這里是request id整數
02 01 00 //這里是差錯狀態00表示noError
02 01 00 //這里是差錯索引00
30 2e //30 asn.1 2e數據長度46個字節
30 15 //第一個值名稱用的是asn.1 sequence 數據長度為21個字節
06 0a 2b 06 01 06 03 01 01 04 01 00 //object name 1.3.6.1.6.3.1.1.4.1.0
06 07 2b 06 01 04 01 92 29 //value 1.3.6.1.4.1.2345
//第二個值名稱(這里不止一個名稱-值)
30 15 //第二個值名稱
06 08 2b 06 01 02 01 01 06 00 //object name 1.3.6.1.2.1.1.6.0
04 09 6a 75 73 74 20 68 65 72 65//value just here的阿斯科馬
這里通過分析snmp v2 trap數據包可以發現,其實snmp v2 trap數據包格式和snmp get-request的數據包格式越來越接近
下面還有snmp v1 trap數據包的分析
snmp v1 trap 數據包分析
先上數據包
//snmp v1 trap 數據包
//snmptrap -v1 -c public 210.38.235.184 1.3.6.1.4.1.1 210.38.235.186 2 3 1000 1.3.6.1.9.9.44.1.2.1 i 12 1.3.4.1.2.3.1 s test_snmptrap
c8 1f 66 05 fb a6 00 0c 29 90 f7 6d 08 00 45 00
00 6e 21 32 40 00 40 11 9d 8c d2 26 eb ba d2 26
eb b8 a7 c7 00 a2 00 5a e4 4c 30 50 02 01 00 04
06 70 75 62 6c 69 63 a4 43 06 06 2b 06 01 04 01
01 40 04 d2 26 eb ba 02 01 02 02 01 03 43 02 03
e8 30 29 30 0e 06 09 2b 06 01 09 09 2c 01 02 01
02 01 0c 30 17 06 06 2b 04 01 02 03 01 04 0d 74
65 73 74 5f 73 6e 6d 70 74 72 61 70
分析數據包
//snmp v1 trap 數據包
//snmptrap -v1 -c public 210.38.235.184 1.3.6.1.4.1.1 210.38.235.186 2 3 1000 1.3.6.1.9.9.44.1.2.1 i 12 1.3.4.1.2.3.1 s test_snmptrap
// manager ip 企業id agent ip trap類型 trap特征碼 uptime 被發送oid
c8 1f 66 05 fb a6 //manager 網卡地址
00 0c 29 90 f7 6d //agent 網卡地址
08 00 //協議類型
45 00
00 6e 21 32 40 00 40 11 9d 8c d2 26 eb ba d2 26 eb b8//ip首部20個字節
a7 c7 00 a2 00 5a e4 4c //udp首部8個字節
30 50 //asn.1 sequence 80個字節
02 01 00 //snmp 版本v1
04 06 70 75 62 6c 69 63 //團體名public
a4 43 //trap類型 67個字節
06 06 2b 06 01 04 01 01 //enterprise 1.3.6.1.4.1
40 04 d2 26 eb ba //代理地址210.38.235.186
02 01 02 //trap類型 02
02 01 03 //trap特征碼03
43 02 03 e8 //啟動時間 1000 0x 03e8
30 29 //名稱值 41個字節
30 0e //第一個名稱值 14個字節
06 09 2b 06 01 09 09 2c 01 02 01//object name 1.3.6.1.9.9.44.1.2.1
02 01 0c //value 12
30 17 //第二個名稱值 23個字節
06 06 2b 04 01 02 03 01 //1.3.4.1.2.3.1
04 0d 74 65 73 74 5f 73 6e 6d 70 74 72 61 70//test_snmptrap 阿斯科馬
這里snmp v1 trap數據包分析完,可以發現格式為版本號+團體名+trap類型+企業id+代理ip+trap類型+特定碼+時間戳+名稱+值。。
snmp v1和v2的數據包基本分析完成,snmp v3安全方面有點復雜,還沒怎么研究,以后研究了在另開一篇,進行記錄