forked from rapid7/metasploit-framework
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathaddp.rb
218 lines (190 loc) · 6.68 KB
/
addp.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
# -*- coding: binary -*-
module Rex
module Proto
#
# This provides constants, encoding, and decoding routines for Digi International's ADDP protocol
#
class ADDP
require "rex/socket"
#
# See the following URLs for more information:
# - http://qbeukes.blogspot.com/2009/11/advanced-digi-discovery-protocol_21.html
# - http://www.digi.com/wiki/developer/index.php/Advanced_Device_Discovery_Protocol_%28ADDP%29
#
MAGICS = %W{ DIGI DVKT DGDP }
ERRORS = %W{ no_response unknown success authenticaton_failed unit_has_address invalid_value invalid_data unsupported_command }
WLAN_ENC_MODES = %W{ unknown none wep40 wep128 }
WLAN_AUTH_MODES = %W{ unknown open shared_key open_shared_key }
HWTYPES = %W{
unknown ps3_desk8 ps3_desk16 ps3_desk32 ps3_rack16 ps2_desk16 ps2_rack16
lets_desk1 lets_desk2 lets_desk4 dorpia_dinrail1 nubox01 nubox02 nubox04
digione_sp digione_ia digione_em
}
CMD_CONF_REQ = 1
CMD_CONF_REP = 2
CMD_SET_ADDR_REQ = 3
CMD_SET_ADDR_REP = 4
CMD_REBOOT_REQ = 5
CMD_REBOOT_REP = 6
CMD_SET_DHCP_REQ = 7
CMD_SET_DHCP_REP = 8
CMD_SET_WL_REQ = 9
CMD_SET_WL_REP = 10
CMD_SET_WL_COUNTRIES_REQ = 11
CMD_SET_WL_COUNTRIES_REP = 12
CMD_EDP = 13
CMD_CNT = 14
def self.encode_password(pwd="dbps")
[pwd.length].pack("C") + pwd
end
def self.request_config(magic, dmac="\xff\xff\xff\xff\xff\xff")
mac = (dmac.length == 6) ? dmac : Rex::Socket.eth_aton(dmac)
req = magic + [ CMD_CONF_REQ, 6].pack("nn") + mac
return req
end
def self.request_config_all(dmac="\xff\xff\xff\xff\xff\xff")
mac = (dmac.length == 6) ? dmac : Rex::Socket.eth_aton(dmac)
res = []
MAGICS.each { |m| res << self.request_config(m, dmac) }
return res
end
def self.request_static_ip(magic, dmac, ip, mask, gw, pwd="dbps")
mac = (dmac.length == 6) ? dmac : Rex::Socket.eth_aton(dmac)
buf =
Rex::Socket.addr_aton(ip) +
Rex::Socket.addr_aton(mask) +
Rex::Socket.addr_aton(gw) +
mac +
self.encode_password(pwd)
req = magic + [CMD_SET_ADDR_REQ, buf.length].pack("nn") + buf
return req
end
def self.request_dhcp(magic, dmac, enabled, pwd="dbps")
mac = (dmac.length == 6) ? dmac : Rex::Socket.eth_aton(dmac)
buf =
[ enabled ? 1 : 0 ].pack("C") +
mac +
self.encode_password(pwd)
req = magic + [CMD_SET_DHCP_REQ, buf.length].pack("nn") + buf
return req
end
def self.request_reboot(magic, dmac, pwd="dbps")
mac = (dmac.length == 6) ? dmac : Rex::Socket.eth_aton(dmac)
buf =
mac +
self.encode_password(pwd)
req = magic + [CMD_REBOOT_REQ, buf.length].pack("nn") + buf
return req
end
def self.decode_reply(data)
res = {}
r_magic = data[0,4]
r_ptype = data[4,2].unpack("n").first
r_plen = data[6,2].unpack("n").first
buff = data[8, r_plen]
bidx = 0
res[:magic] = data[0,4]
res[:cmd] = r_ptype
while bidx < (buff.length - 2)
i_type, i_len = buff[bidx, 2].unpack("CC")
i_data = buff[bidx + 2, i_len]
break if i_data.length != i_len
case i_type
when 0x01
res[:mac] = Rex::Socket.eth_ntoa(i_data)
when 0x02
res[:ip] = Rex::Socket.addr_ntoa(i_data)
when 0x03
res[:mask] = Rex::Socket.addr_ntoa(i_data)
when 0x04
res[:hostname] = i_data
when 0x05
res[:domain] = i_data
when 0x06
res[:hwtype] = HWTYPES[ i_data.unpack("C").first ] || HWTYPES[ 0 ]
when 0x07
res[:hwrev] = i_data.unpack("C").first
when 0x08
res[:fwrev] = i_data
when 0x09
res[:msg] = i_data
when 0x0a
res[:result] = i_data.unpack("C").first
when 0x0b
res[:gw] = Rex::Socket.addr_ntoa(i_data)
when 0x0c
res[:advisory] = i_data.unpack("n").first
when 0x0d
res[:hwname] = i_data
when 0x0e
res[:realport] = i_data.unpack("N").first
when 0x0f
res[:dns] = Rex::Socket.addr_ntoa(i_data)
when 0x10
res[:dhcp] = (i_data.unpack("C").first == 0) ? false : true
when 0x11
res[:error] = ERRORS[ i_data.unpack("C").first ] || ERRORS[0]
when 0x12
res[:ports] = i_data.unpack("C").first
when 0x13
res[:realport_enc] = (i_data.unpack("C").first == 0) ? false : true
when 0x14
res[:version] = i_data.unpack("n").first
when 0x15
res[:vendor_guid] = i_data.unpack("H*") # GUID
when 0x16
res[:iftype] = i_data.unpack("C").first
when 0x17
res[:challenge] = i_data # Unknown format
when 0x18
res[:cap_port] = i_data.unpack("n").first
when 0x19
res[:edp_devid] = i_data.unpack("H*").first # Unknown format
when 0x1a
res[:edp_enabled] = (i_data.unpack("C").first == 0) ? false : true
when 0x1b
res[:edp_url] = i_data
when 0x1c
res[:wl_ssid] = i_data
when 0x1d
res[:wl_auto_ssid] = (i_data.unpack("n").first == 0) ? false : true
when 0x1e
res[:wl_tx_enh_power] = i_data.unpack("n").first
when 0x1f
res[:wl_auth_mode] = WLAN_AUTH_MODES[ i_data.unpack("n").first ] || WLAN_AUTH_MODES[ 0 ]
when 0x20
res[:wl_enc_mode] = WLAN_ENC_MODES[ i_data.unpack("n").first ] || WLAN_ENC_MODES[ 0 ]
when 0x21
res[:wl_enc_key] = i_data
when 0x22
res[:wl_cur_country] = i_data
when 0x23
res[:wl_country_list] = i_data
else
# Store unknown responses
res["unknown_0x#{"%.2x" % i_type}".to_sym] = i_data
end
bidx = bidx + 2 + i_len
end
return res
end
def self.reply_to_string(res)
str = ""
fields = [
:hwname, :hwtype, :hwrev, :fwrev,
:mac, :ip, :mask, :gw, :hostname, :domain, :dns, :dhcp,
:msg, :result, :error,
:advisory, :ports, :realport, :realport_enc,
:version, :vendor_guid, :iftype, :challenge, :cap_port, :edp_devid, :edp_enabled,
:edp_url, :wl_ssid, :wl_auto_ssid, :wl_tx_enh_power, :wl_auth_mode, :wl_enc_mode,
:wl_enc_key, :wl_cur_country, :wl_country_list, :magic
]
fields.each do |fname|
next unless res.has_key?(fname)
str << "#{fname}:#{res[fname]} "
end
return str
end
end
end
end