Closed KINGSABRI closed 6 years ago
Started looking at this issue for fun. This is some code using scapy to help dissect the problem.
from scapy.all import *
# I was having issues with the pkt in the example, this is the cleaned one
pkt = IP(src="192.168.30.100", dst="192.168.30.199")/UDP(sport=161)/SNMP(community="private",PDU=SNMPset(varbindlist=SNMPvarbind(oid=ASN1_OID("1.3.6.1.4.1.9.2.1.55.192.168.30.10"),value="pwnd-router.config")))
# get snmp layer
snmp = pkt.getlayer("SNMP")
# get PDU from snmp layer
pdu = snmp.PDU
# => <SNMPset varbindlist=<SNMPvarbind oid=<ASN1_OID['.1.3.6.1.4.1.9.2.1.55.192.168.30.10']> value='pwnd-router.config' |> |>
The Python code for PSNMPset is here.
I seem to be getting somewhere using this and this.
snmp = PacketGen::Header::SNMP.new
snmp.data.root.chosen = 3
snmp.pdu
# => pdu (SetRequest) pdu SEQUENCE:
# id INTEGER: 0
# error ENUMERATED: 0
# error_index INTEGER: 0
# bindings (VariableBindings) SEQUENCE OF:
snmp.pdu[:varbindlist]
# => bindings (VariableBindings) SEQUENCE OF:
snmp.pdu[:varbindlist] << { name: '1.3.6.1.4.1.9.2.1.55.192.168.30.10', value: 'pwnd-router.config' }
# => [ varbind (VarBind) varbind SEQUENCE:
# name OBJECT ID: "1.3.6.1.4.1.9.2.1.55.192.168.30.10"
# value (ANY) "pwnd-router.config"
# ]
I have a hunch I may not be doing the oid=<ASN1_OID['.1.3.6.1.4.1.9.2.1.55.192.168.30.10']>
part right when translating to Ruby, but I think @sdaubert will know how. π
To help debug the issue further I used wrpcap('example.pcap', pkt)
with scapy, and see this in Wireshark:
pkt_binary = "E\x00\x00^\x00\x01\x00\x00@\x11\xBC\x12\xC0\xA8\x1Ed\xC0\xA8\x1E\xC7\x00\xA1\x00\xA1\x00J\xCD\x990@\x02\x01\x01\x04\aprivate\xA32\x02\x01\x00\x02\x01\x00\x02\x01\x000'0%\x06\x0F+\x06\x01\x04\x01\t\x02\x017\x81@\x81(\x1E\n\x04\x12pwnd-router.config"
Working my way backwards with the pcap I generated with scapy, I've gotten this @KINGSABRI π
pkt = PacketGen.gen('IP', src: '192.168.30.100', dst: '192.168.30.199')
pkt.add('UDP', dport: 162, sport: 162)
pkt.add('SNMP', community: 'private')
pkt.snmp.data.root.chosen = 3
pkt.snmp.pdu[:varbindlist] << { name: '1.3.6.1.4.1.9.2.1.55.192.168.30.10', value: 'pwnd-router.config' }
=> -- PacketGen::Packet -------------------------------------------------
---- PacketGen::Header::IP -------------------------------------------
Int8 u8: 69 (0x45)
version: 4
ihl: 5
Int8 tos: 0 (0x00)
Int16 length: 20 (0x0014)
Int16 id: 12303 (0x300f)
Int16 frag: 0 (0x0000)
flags: none
frag_offset: 0 (0x0000)
Int8 ttl: 64 (0x40)
Int8 protocol: 17 (0x11)
Int16 checksum: 0 (0x0000)
Addr src: 192.168.30.100
Addr dst: 192.168.30.199
Options options:
---- PacketGen::Header::UDP ------------------------------------------
Int16 sport: 162 (0x00a2)
Int16 dport: 162 (0x00a2)
Int16 length: 8 (0x0008)
Int16 checksum: 0 (0x0000)
---- PacketGen::Header::SNMP -----------------------------------------
ENUMERATED version: v2c (0x01)
OCTET STRING community: "private"
PDUs data: SetRequest
---- ASN.1 content ---------------------------------------------------
pdu (SetRequest) pdu SEQUENCE:
id INTEGER: 0
error ENUMERATED: 0
error_index INTEGER: 0
bindings (VariableBindings) SEQUENCE OF:
varbind (VarBind) varbind SEQUENCE:
name OBJECT ID: "1.3.6.1.4.1.9.2.1.55.192.168.30.10"
value (ANY) "pwnd-router.config"
---- ASN.1 DER -------------------------------------------------------
00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15
----------------------------------------------------------------------
30 3e 02 01 01 04 07 70 72 69 76 61 74 65 a3 30 0>.....private.0
02 01 00 02 01 00 02 01 00 30 25 30 23 06 0f 2b .........0%0#..+
06 01 04 01 09 02 01 37 81 40 81 28 1e 0a 70 77 .......7.@.(..pw
6e 64 2d 72 6f 75 74 65 72 2e 63 6f 6e 66 69 67 nd-router.config
----------------------------------------------------------------------
pkt_binary = "E\x00\x00\x140\x0F\x00\x00@\x11\x00\x00\xC0\xA8\x1Ed\xC0\xA8\x1E\xC7\x00\xA2\x00\xA2\x00\b\x00\x000>\x02\x01\x01\x04\aprivate\xA30\x02\x01\x00\x02\x01\x00\x02\x01\x000%0#\x06\x0F+\x06\x01\x04\x01\t\x02\x017\x81@\x81(\x1E\npwnd-router.config"
There's only one weird thing I see where the value
from scapy is "\x04\x12pwnd-router.config"
, where the \x04\x12
doesn't show up in Ruby. π€·ββοΈ
Looking at the SNMP
layer in python with scapy to figure out the \x04\x12
part...
snmp.PDU
#=> <SNMPset id=0x0 <ASN1_INTEGER[0]> error='no_error' 0x0 <ASN1_INTEGER[0]> error_index=0x0 <ASN1_INTEGER[0]> varbindlist=[<SNMPvarbind oid=<ASN1_OID['.1.3.6.1.4.1.9.2.1.55.192.168.30.10']> value=<ASN1_STRING[b'pwnd-router.config']> |>] |>
I wonder if it's some sort of property of being an ASN1_STRING
? π€·ββοΈ
@picatz wouh! You are too fast for me.
@KINGSABRI my only add: a VarBind object (kind of items in VariableBindings object) is a sequence of an ObjectId and another type, which depends on object id. The VariableBindings#<<
operator knows how to transform a dotted string to an OID. That's why @picatz suceeded to add this OID. But, the value has no specified type, so #<<
has no transform. It seems this value is an OCTET STRING (type 0x04, with a length od 0x12). So replace last line from picatz's code by:
pkt.snmp.pdu[:varbindlist] << { name: '1.3.6.1.4.1.9.2.1.55.192.168.30.10', value: RASN1::Types::OctetString.new('pwnd-router.config') }
And you will have:
-- PacketGen::Packet -------------------------------------------------
---- PacketGen::Header::IP -------------------------------------------
Int8 u8: 69 (0x45)
version: 4
ihl: 5
Int8 tos: 0 (0x00)
Int16 length: 20 (0x0014)
Int16 id: 37951 (0x943f)
Int16 frag: 0 (0x0000)
flags: none
frag_offset: 0 (0x0000)
Int8 ttl: 64 (0x40)
Int8 protocol: 17 (0x11)
Int16 checksum: 0 (0x0000)
Addr src: 192.168.30.100
Addr dst: 192.168.30.199
Options options:
---- PacketGen::Header::UDP ------------------------------------------
Int16 sport: 162 (0x00a2)
Int16 dport: 162 (0x00a2)
Int16 length: 8 (0x0008)
Int16 checksum: 0 (0x0000)
---- PacketGen::Header::SNMP -----------------------------------------
ENUMERATED version: v2c (0x01)
OCTET STRING community: "private"
PDUs data: SetRequest
---- ASN.1 content ---------------------------------------------------
pdu (SetRequest) pdu SEQUENCE:
id INTEGER: 0
error ENUMERATED: 0
error_index INTEGER: 0
bindings (VariableBindings) SEQUENCE OF:
varbind (VarBind) varbind SEQUENCE:
name OBJECT ID: "1.3.6.1.4.1.9.2.1.55.192.168.30.10"
value (ANY) OCTET STRING: "pwnd-router.config"
---- ASN.1 DER -------------------------------------------------------
00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15
----------------------------------------------------------------------
30 40 02 01 01 04 07 70 72 69 76 61 74 65 a3 32 0@.....private.2
02 01 00 02 01 00 02 01 00 30 27 30 25 06 0f 2b .........0'0%..+
06 01 04 01 09 02 01 37 81 40 81 28 1e 0a 04 12 .......7.@.(....
70 77 6e 64 2d 72 6f 75 74 65 72 2e 63 6f 6e 66 pwnd-router.conf
69 67 ig
----------------------------------------------------------------------
Thank you for the explanation @sdaubert π β€οΈ
Complete example to show how to generate this packet.
pkt = PacketGen.gen('IP', src: '192.168.30.100', dst: '192.168.30.199') pkt.add('UDP', dport: 162, sport: 162) pkt.add('SNMP', community: 'private') pkt.snmp.data.root.chosen = 3 pkt.snmp.pdu[:varbindlist] << { name: '1.3.6.1.4.1.9.2.1.55.192.168.30.10', value: RASN1::Types::OctetString.new('pwnd-router.config') }
@picatz you're crazy fast, touch wood!
@sdaubert I don't know why I got confused from documentation or maybe because accessors were explained in the GetRequest part
Do you think more @example
in code docs would help?
@sdaubert isn't the value
attribute has to be/translated to RASN1::Types::OctetString
by detault?
finally, how is that supposed to be in one line?
@sdaubert isn't the value attribute has to be/translated to RASN1::Types::OctetString by detault?
It can't as its type depends on OID. It may be an integer, a float, a bit string, or even a more complex type (ie one defined by a sequence or a set).
finally, how is that supposed to be in one line?
It is not. For now, chosen value from type cannot be set when adding a SNMP header (but it could). The difficult part is setting the varbindlist.
@KINGSABRI it should be possible to set varbindlist from new, but I have to update RASN1 first.
Fixed in 2.6.0
PacketGen.gen('IP', src: '192.168.30.100', dst: '192.168.30.199').add('UDP', dport: 162, sport: 162).add('SNMP', community: 'private', chosen_pdu: 3, pdu: { id: 1, varbindlist: [{name: "1.3.6.1.4.1.9.2.1.55.192.168.30.10", value: RASN1::Types::OctetString.new("pwnd-router.config")}]})
-- PacketGen::Packet -------------------------------------------------
---- PacketGen::Header::IP -------------------------------------------
Int8 u8: 69 (0x45)
version: 4
ihl: 5
Int8 tos: 0 (0x00)
Int16 length: 20 (0x0014)
Int16 id: 53977 (0xd2d9)
Int16 frag: 0 (0x0000)
flags: none
frag_offset: 0 (0x0000)
Int8 ttl: 64 (0x40)
Int8 protocol: 17 (0x11)
Int16 checksum: 0 (0x0000)
Addr src: 192.168.30.100
Addr dst: 192.168.30.199
Options options:
---- PacketGen::Header::UDP ------------------------------------------
Int16 sport: 162 (0x00a2)
Int16 dport: 162 (0x00a2)
Int16 length: 8 (0x0008)
Int16 checksum: 0 (0x0000)
---- PacketGen::Header::SNMP -----------------------------------------
ENUMERATED version: v2c (0x01)
OCTET STRING community: "private"
PDUs data: SetRequest
---- ASN.1 content ---------------------------------------------------
(SetRequest) pdu SEQUENCE:
id INTEGER: 1
error ENUMERATED: 0
error_index INTEGER: 0
(VariableBindings) bindings SEQUENCE OF:
(VarBind) varbind SEQUENCE:
name OBJECT ID: "1.3.6.1.4.1.9.2.1.55.192.168.30.10"
value (ANY) OCTET STRING: "pwnd-router.config"
---- ASN.1 DER -------------------------------------------------------
00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15
----------------------------------------------------------------------
30 40 02 01 01 04 07 70 72 69 76 61 74 65 a3 32 0@.....private.2
02 01 01 02 01 00 02 01 00 30 27 30 25 06 0f 2b .........0'0%..+
06 01 04 01 09 02 01 37 81 40 81 28 1e 0a 04 12 .......7.@.(....
70 77 6e 64 2d 72 6f 75 74 65 72 2e 63 6f 6e 66 pwnd-router.conf
69 67 ig
----------------------------------------------------------------------
@sdaubert tested and it works, you're awesome!
Hello there, if you have seen this issue. I tried to use packetgen to do so but I could do it using the current documentation
Scapy version
tried
and
I believe my issue that I couldn't understand how to assign the PDU details
SNMPset == SetRequest
from scapy