Lucene search

K
hackeroneHxdH1:227344
HistoryMay 09, 2017 - 9:29 p.m.

Internet Bug Bounty: CVE-2017-8798 - miniupnp getHTTPResponse chunked encoding integer signedness error

2017-05-0921:29:06
hxd
hackerone.com
39

0.058 Low

EPSS

Percentile

93.4%

Integer signedness error in miniupnpc [1] allows remote attackers to cause a denial of service condition (access violation and heap corruption) via specially crafted HTTP response

An integer signedness error was found in miniupnpā€™s miniwget allowing
an unauthenticated remote entity typically located on the
local network segment to trigger a heap corruption or an access violation
in miniupnpā€™s http response parser when processing a specially crafted
chunked-encoded response to a request for the xml root description url.

  • affects
  • all versions >= v1.4.20101221 (released 21/12/2010; ~6 years ago)
  • all configurations as its a core part of the library
  • impact
  • DoS (access violation due to buffer overread memcpy)
  • Heap Overwrite (pot. race RCE in multithreaded envs)
  • requirements
    • no user interaction, unauth, low complexity
  • how widespread is this software?
  • miniupnpc is compiled into a wide range of network applications and embedded device firmware.
  • blockchain clients: bitcoind and almost all forks, CPP ethereum, ā€¦
  • p2p filesharing applications: qBittorrent, Transmission, ā€¦
  • network device firmware: dlink, linksys, probably synology or anything that allows IGD management / portforwarding
  • numerous hits for miniwget on google or github. closed source obviously not included but its likely to find this lib packed with embedded devices.
  • disclosure
  • provided detailed description, PoC and patch
  • status: fixed; within 8 days.

The vulnerable component is a HTTP file download method called
miniwget (precisely getHTTPResponse) that fails to properly handle
invalid chunked-encoded HTTP responses. The root cause is a bounds check
that mistakenly casts an unsigned attacker-provided chunksize to signed
int leading to an incorrect decision on the destination heap buffer size
when copying data from the server response to an internal buffer. The
attacker controls both the size of the internal buffer as well as the
number of bytes to copy. In order for this attack to succeed, the number
of bytes to copy must be negative.

attacker controls:

  • int content_length
  • unsigned int chunksize
  • bytestocopy if (int) chunksize is negative (or at least < n-i ~ 1900 bytes)
  • length of content_buf if bytestocopy is negative

In the end, the attacker has almost full control of the following two methods

  • realloc(content_buf, content_length)
  • memcpy(content_buf+x, http_response, chunksize)

affected methods (almost all exposed API):

    basically all `miniwget*` and `UPNP_*` methods.
    * getHTTPResponse (vulnerable)
      * miniwget3
       * miniwget2
        * miniwget
        * miniwget_getaddr
         * UPNP_GetIGDFromUrl
         * UPNP_GetValidIGD
          * UPnP_selectigd
      * UPNP_Get*
      * UPNP_Check*
      * UPNP_Delete*
      * UPNP_Update*
      * UPNP_Add*

This vulnerability is easily exploitable with an attacker being on the same network segment/multicast domain by answering SSDP discovery requests (1) (or sending notification requests) providing an URL to the attacker controlled webserver. Answering this request (2) makes upnp clients download a description file from that webserver (3)(4) in order to learn more about the capabilities of the Internet Gateway Device (IGD). By providing a negative chunk length in the chunked-encoded answer (4) to this request the malicious webserver triggers the vulnerability. This way one malicous client could exploit all other clients in the same multicast domain. (Funny sidenote: I had to implement a target ip filter otherwise the PoC would attract devices like a magnet and crash all of them)

      client (miniupnpc)                         server (poc.py)
          |                                         |
          |                                         |
          | SSDP:  Discovery - M-SEARCH             |
      1.  | --------------------------------------&gt; |
          |                                         |
          | SSDP:  Reply - Location Header          |
      2.  | &lt;-------------------------------------- |
          |                                         |
          | SCPD:  GET (Location Header/xxxx.xml)   |
      3.  | --------------------------------------&gt; |
          |                                         |
          | SCPD:  HTTP chunked-encoded reply       |
      4.  | &lt;-------------------------------------- |
          |                                         |

Note: the vulnerability is basically not bound to the adjacent network since miniwget could also be used to download arbitrary files on the internet. This is just the most common/typical vector, otherwise the CVSS score would be higher.

Disclosure

coordinated disclosure and reported to the miniupnp project owner, provided detailed vulnerability analysis, a one-click exploit all PoC and a minimal patch. The patch was accepted with minor changes. Fixed within a few days of first contact (May 1st ->May 9th).

details and the actual research material that was securely shared with the miniupnp project is going to be be pushed to the following github repository once vendors picked up the changes: https://github.com/tintinweb/pub/tree/master/pocs/cve-2017-8798

Vendor response [2] and Patch [3]

ā¤ Thanks to miniupnp for treating this with priority.

[1] http://miniupnp.free.fr
[2] http://miniupnp.free.fr/files/changelog.php?file=miniupnpc-2.0.20170509.tar.gz
[3] https://github.com/miniupnp/miniupnp/commit/f0f1f4b22d6a98536377a1bb07e7c20e4703d229