168 lines
6.2 KiB
Ruby
168 lines
6.2 KiB
Ruby
# -*- coding: binary -*-
|
|
|
|
module Msf
|
|
###
|
|
#
|
|
# This module provides methods for working with Arista equipment
|
|
#
|
|
###
|
|
module Auxiliary::Arista
|
|
include Msf::Auxiliary::Report
|
|
|
|
def arista_eos_config_eater(thost, tport, config)
|
|
|
|
if framework.db.active
|
|
credential_data = {
|
|
address: thost,
|
|
port: tport,
|
|
protocol: 'tcp',
|
|
workspace_id: myworkspace_id,
|
|
origin_type: :service,
|
|
private_type: :nonreplayable_hash,
|
|
jtr_format: 'sha512,crypt', # default on the devices
|
|
service_name: '',
|
|
module_fullname: fullname,
|
|
status: Metasploit::Model::Login::Status::UNTRIED
|
|
}
|
|
end
|
|
|
|
# Default SNMP to UDP
|
|
if tport == 161
|
|
credential_data[:protocol] = 'udp'
|
|
end
|
|
|
|
store_loot('arista.eos.config', 'text/plain', thost, config.strip, 'config.txt', 'Arista EOS Configuration')
|
|
|
|
host_info = {
|
|
host: thost,
|
|
os_name: 'Arista EOS'
|
|
}
|
|
report_host(host_info)
|
|
|
|
config.each_line do |line|
|
|
case line
|
|
|
|
# one of the first lines
|
|
# ! device: aristaveos (vEOS, EOS-4.19.10M)
|
|
# ! device: switch (DCS-7150S-64-CL, EOS-4.13.2F)
|
|
when /^\s*! device: (.+) \((.+),\s*(.+)-(.+)\)/i
|
|
hostname = Regexp.last_match(1).to_s
|
|
device = Regexp.last_match(2).to_s
|
|
os = Regexp.last_match(3).to_s
|
|
os_ver = Regexp.last_match(4).to_s
|
|
host_info[:os_name] = os
|
|
host_info[:os_flavor] = os_ver
|
|
host_info[:name] = hostname
|
|
report_host(host_info)
|
|
print_good("#{thost}:#{tport} Hostname: #{hostname}, Device: #{device}, OS: #{os}, Version: #{os_ver}")
|
|
# https://www.arista.com/en/um-eos/eos-section-6-1-managing-the-switch-name
|
|
# hostname aristaveos
|
|
when /^\s*hostname (\S+)/i
|
|
host_info[:name] = Regexp.last_match(1).to_s
|
|
report_host(host_info)
|
|
print_good("#{thost}:#{tport} Hostname: #{Regexp.last_match(1)}")
|
|
# https://www.arista.com/en/um-eos/eos-section-4-7-aaa-commands#ww1349127
|
|
# enable secret sha512 $6$jemN09cUdoLRim6i$Mvl2Fog/VZ7ktxyLSVDR1KnTTTPSMHU3WD.G/kxwgODdsc3d7S1aSNJX/DJmQI3nyrYnEw4lsmoKPGClFJ9hH1
|
|
when /^\s*enable secret sha512 (.*)$/i
|
|
if framework.db.active
|
|
cred = credential_data.dup
|
|
cred[:username] = 'enable'
|
|
cred[:private_data] = Regexp.last_match(1).to_s
|
|
create_credential_and_login(cred)
|
|
end
|
|
print_good("#{thost}:#{tport} Enable hash: #{Regexp.last_match(1)}")
|
|
# https://www.arista.com/en/um-eos/eos-section-43-3-configuring-snmp?searchword=snmp
|
|
# snmp-server community read ro
|
|
# snmp-server community write rw
|
|
when /^\s*snmp-server community ([^\s]+) (RO|RW)/i
|
|
stype = Regexp.last_match(2).strip
|
|
scomm = Regexp.last_match(1).strip
|
|
print_good("#{thost}:#{tport} SNMP Community (#{stype}): #{scomm}")
|
|
|
|
if framework.db.active
|
|
cred = credential_data.dup
|
|
cred[:access_level] = stype.upcase
|
|
cred[:protocol] = 'udp'
|
|
cred[:service_name] = 'snmp'
|
|
cred[:private_type] = :password
|
|
cred[:jtr_format] = ''
|
|
cred[:port] = 161
|
|
cred[:private_data] = scomm
|
|
create_credential_and_login(cred)
|
|
end
|
|
# https://www.arista.com/en/um-eos/eos-section-4-7-aaa-commands#ww1349963
|
|
# username admin privilege 15 role network-admin secret sha512 $6$Ei2bjrcTCGPOjSkk$7S.XSTZqdRVXILbUUDcRPCxzyfqEFYzg6HfL0BHXvriETX330MT.KObHLkGx7n9XZRVWBr68ZsKfvzvxYCvj61
|
|
# username bob privilege 15 secret 5 $1$EGQJlod0$CdkMmW1FoiRgMfbLFD/kB/
|
|
# username rlaney role network-admin secret 0 ralrox
|
|
when /^\s*username ([^\s]+) (?:privilege (\d+) )?(?:role (.+) )?secret (.+) ([^\s]+)/i
|
|
name = Regexp.last_match(1).to_s
|
|
privilege = Regexp.last_match(2).to_s
|
|
role = Regexp.last_match(3).to_s
|
|
# for secret, 0=plaintext, 5=md5sum, sha512=sha512
|
|
secret = Regexp.last_match(4).to_s
|
|
hash = Regexp.last_match(5).to_s
|
|
output = "#{thost}:#{tport} Username '#{name}'"
|
|
unless privilege.empty?
|
|
output << " with privilege #{privilege},"
|
|
end
|
|
unless role.empty?
|
|
output << " Role #{role},"
|
|
end
|
|
|
|
if framework.db.active
|
|
cred = credential_data.dup
|
|
else
|
|
cred = {} # throw away, but much less code than constant if statements
|
|
end
|
|
|
|
if secret == '0'
|
|
output << " and Password: #{hash}"
|
|
cred[:private_type] = :password
|
|
cred[:jtr_format] = ''
|
|
else
|
|
output << " and Hash: #{hash}"
|
|
cred[:jtr_format] = Metasploit::Framework::Hashes.identify_hash(hash)
|
|
end
|
|
|
|
cred[:username] = name
|
|
cred[:private_data] = hash
|
|
|
|
if framework.db.active
|
|
create_credential_and_login(cred)
|
|
end
|
|
print_good(output)
|
|
# aaa root secret sha512 $6$Rnanb2dQsVy2H3QL$DEYDZMy6j6KK4XK62Uh.3U3WXxK5XJvn8Zd5sm36T7BVKHS5EmIcQV.EN1X1P1ZO099S0lkxpvEGzA9yK5PQF.
|
|
when /^\s*aaa (root) secret (.+) ([^\s]+)/i
|
|
name = Regexp.last_match(1).to_s
|
|
# for secret, 0=plaintext, 5=md5sum, sha512=sha512
|
|
secret = Regexp.last_match(2).to_s
|
|
hash = Regexp.last_match(3).to_s
|
|
output = "#{thost}:#{tport} AAA Username '#{name}'"
|
|
if framework.db.active
|
|
cred = credential_data.dup
|
|
else
|
|
cred = {} # throw away, but much less code than constant if statements
|
|
end
|
|
|
|
cred[:username] = name.to_s
|
|
|
|
if secret == '0'
|
|
output << " and Password: #{hash}"
|
|
cred[:private_type] = :password
|
|
cred[:jtr_format] = ''
|
|
else
|
|
output << " with Hash: #{hash}"
|
|
cred[:jtr_format] = Metasploit::Framework::Hashes.identify_hash(hash)
|
|
end
|
|
|
|
cred[:private_data] = hash.to_s
|
|
if framework.db.active
|
|
create_credential_and_login(cred)
|
|
end
|
|
print_good(output)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|