Security
Headlines
HeadlinesLatestCVEs

Headline

URGENT/11 Scanner, Based On Detection Tool By Armis

This Metasploit module detects VxWorks and the IPnet IP stack, along with devices vulnerable to CVE-2019-12258.

Packet Storm
#vulnerability#git#auth
### 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  endend

Related news

CVE-2019-12258

Wind River VxWorks 6.6 through vx7 has Session Fixation in the TCP component. This is a IPNET security vulnerability: DoS of TCP connection via malformed TCP options.

Packet Storm: Latest News

ABB Cylon Aspect 3.08.01 vstatConfigurationDownload.php Configuration Download