`##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Auxiliary
include Msf::Auxiliary::Report
include Msf::Auxiliary::Scanner
include Msf::Exploit::Capture
def initialize(info = {})
super(update_info(info,
'Name' => 'URGENT/11 Scanner, Based on Detection Tool by Armis',
'Description' => %q{
This module detects VxWorks and the IPnet IP stack, along with devices
vulnerable to CVE-2019-12258.
},
'Author' => [
'Ben Seri', # Upstream tool
'Brent Cook', # Metasploit module
'wvu' # Metasploit module
],
'References' => [
['CVE', '2019-12258'],
['URL', 'https://armis.com/urgent11'],
['URL', 'https://github.com/ArmisSecurity/urgent11-detector']
],
'DisclosureDate' => '2019-08-09', # NVD entry publication
'License' => MSF_LICENSE,
'Notes' => {'Stability' => [CRASH_SAFE]}
))
register_options([
OptString.new('RPORTS', required: true, default: "21 22 23 80 443", desc: 'Target ports for TCP detections')
])
register_advanced_options([
OptInt.new('RetransmissionRate', required: true, default: 3, desc: 'Send n TCP packets')
])
deregister_options('PCAPFILE', 'FILTER')
end
#
# Utility methods
#
def rports
datastore['RPORTS'].split(/[\s,]/).collect{|i| (i.to_i.to_s == i) ? i.to_i : nil}.compact
end
def filter(ip)
"src host #{ip} and dst host #{Rex::Socket.source_address(ip)}"
end
#
# Scanner methods
#
def run_host(ip)
# XXX: Configuring Ethernet and IP headers sends a UDP packet!
@config = PacketFu::Utils.whoami?(target: ip)
open_pcap
capture.setfilter(filter(ip))
port_open = false
rports.each do |rport|
port_open |= run_detections(ip, rport)
end
raise RuntimeError.new("No ports open on #{ip} from #{datastore['RPORTS']}") if !port_open
rescue RuntimeError => e
fail_with(Failure::BadConfig, e.message)
ensure
close_pcap
end
def detections
%w[
tcp_dos_detection
tcp_malformed_options_detection
icmp_code_detection
icmp_timestamp_detection
]
end
def run_detections(ip, port)
print_status("#{ip}:#{port} being checked")
final_ipnet_score = 0
final_vxworks_score = 0
affected_vulnerabilities = []
begin
sock = Rex::Socket::Tcp.create(
'PeerHost' => ip,
'PeerPort' => port
)
rescue
vprint_bad("Could not connect to #{ip}:#{port}, cannot verify vulnerability")
return false
end
detections.each do |detection|
@ipnet_score = 0
@vxworks_score = 0
@vulnerable_cves = []
detection_name = detection.camelize
begin
send(detection, sock, ip, port)
rescue StandardError => e
vprint_error("#{detection_name} failed: #{e.message}")
next
end
vprint_status(
"\t#{detection_name.ljust(30)}" \
"\tVxWorks: #{@vxworks_score}" \
"\tIPnet: #{@ipnet_score}"
)
final_ipnet_score += @ipnet_score
final_vxworks_score += @vxworks_score
affected_vulnerabilities += @vulnerable_cves
end
sock.close
if final_ipnet_score > 0
vprint_good("#{ip}:#{port} detected as IPnet")
elsif final_ipnet_score < 0
vprint_error("#{ip}:#{port} detected as NOT IPnet")
end
if final_vxworks_score > 100
vprint_good("#{ip}:#{port} detected as VxWorks")
elsif final_vxworks_score < 0
vprint_error("#{ip}:#{port} detected as NOT VxWorks")
end
affected_vulnerabilities.each do |vuln|
msg = "#{ip}:#{port} affected by #{vuln}"
print_good(msg)
report_vuln(
host: ip,
name: name,
refs: references,
info: msg
)
end
true
end
#
# TCP detection methods
#
def tcp_malformed_options_detection(sock, ip, port)
pkt = PacketFu::TCPPacket.new(config: @config)
# IP destination address
pkt.ip_daddr = ip
# TCP SYN with malformed options
pkt.tcp_dst = port
pkt.tcp_flags.syn = 1
pkt.tcp_opts = [2, 4, 1460].pack('CCn') + # MSS
[1].pack('C') + # NOP
[3, 2].pack('CC') + # WSCALE with invalid length
[3, 3, 0].pack('CCC') # WSCALE with valid length
pkt.recalc
res = nil
datastore['RetransmissionRate'].times do
pkt.to_w
res = inject_reply(:tcp)
break unless res
end
unless res
return @vxworks_score = 0,
@ipnet_score = 50
end
if res.tcp_flags.rst == 1 &&
res.tcp_dst == pkt.tcp_src && res.tcp_dst == pkt.tcp_src
return @vxworks_score = 100,
@ipnet_score = 100
end
return @vxworks_score = -100,
@ipnet_score = -100
end
def tcp_dos_detection(sock, ip, port)
pkt = PacketFu::TCPPacket.new(config: @config)
# IP destination address
pkt.ip_daddr = ip
# TCP SYN with malformed (truncated) WS option
pkt.tcp_src = sock.getlocalname.last
pkt.tcp_dst = sock.peerport
pkt.tcp_seq = rand(0xffffffff + 1)
pkt.tcp_ack = rand(0xffffffff + 1)
pkt.tcp_flags.syn = 1
pkt.tcp_opts = [3, 2].pack('CC') + # WSCALE with invalid length
[1, 0].pack('CC') # NOP + EOL
pkt.recalc
res = nil
datastore['RetransmissionRate'].times do
pkt.to_w
res = inject_reply(:tcp)
break unless res
end
unless res
return @vxworks_score = 0,
@ipnet_score = 0
end
if res.tcp_flags.rst == 1 &&
res.tcp_dst == pkt.tcp_src && res.tcp_dst == pkt.tcp_src
return @vxworks_score = 100,
@ipnet_score = 100,
@vulnerable_cves = ['CVE-2019-12258']
end
return @vxworks_score = 0,
@ipnet_score = 0
end
#
# ICMP detection methods
#
def icmp_code_detection(sock, ip, _port = nil)
pkt = PacketFu::ICMPPacket.new(config: @config)
# IP destination address
pkt.ip_daddr = ip
# ICMP echo request with non-zero code
pkt.icmp_type = 8
pkt.icmp_code = rand(0x01..0xff)
pkt.payload = capture_icmp_echo_pack
pkt.recalc
pkt.to_w
res = inject_reply(:icmp)
unless res
return @ipnet_score = 0
end
# Echo reply with zeroed code
if res.icmp_type == 0 && res.icmp_code == 0
return @ipnet_score = 20
end
@ipnet_score = -20
end
def icmp_timestamp_detection(sock, ip, _port = nil)
pkt = PacketFu::ICMPPacket.new(config: @config)
# IP destination address
pkt.ip_daddr = ip
# Truncated ICMP timestamp request
pkt.icmp_type = 13
pkt.icmp_code = 0
pkt.payload = "\x00" * 4
pkt.recalc
pkt.to_w
res = inject_reply(:icmp)
unless res
return @ipnet_score = 0
end
# Timestamp reply
if res.icmp_type == 14
return @ipnet_score = 90
end
@ipnet_score = -30
end
end
`
Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation