Vulnerabilities > CVE-2016-9036 - Out-of-bounds Read vulnerability in Tarantool Msgpuck 1.0.3

047910
CVSS 7.5 - HIGH
Attack vector
NETWORK
Attack complexity
LOW
Privileges required
NONE
Confidentiality impact
NONE
Integrity impact
NONE
Availability impact
HIGH
network
low complexity
tarantool
CWE-125
nessus

Summary

An exploitable incorrect return value vulnerability exists in the mp_check function of Tarantool's Msgpuck library 1.0.3. A specially crafted packet can cause the mp_check function to incorrectly return success when trying to check if decoding a map16 packet will read outside the bounds of a buffer, resulting in a denial of service vulnerability.

Vulnerable Configurations

Part Description Count
Application
Tarantool
1

Common Weakness Enumeration (CWE)

Common Attack Pattern Enumeration and Classification (CAPEC)

  • Overread Buffers
    An adversary attacks a target by providing input that causes an application to read beyond the boundary of a defined buffer. This typically occurs when a value influencing where to start or stop reading is set to reflect positions outside of the valid memory location of the buffer. This type of attack may result in exposure of sensitive information, a system crash, or arbitrary code execution.

Nessus

  • NASL familyFedora Local Security Checks
    NASL idFEDORA_2016-2D0C8BA781.NASL
    descriptionSecurity fix for CVE-2016-9036, CVE-2016-9037 Note that Tenable Network Security has extracted the preceding description block directly from the Fedora update system website. Tenable has attempted to automatically clean and format it as much as possible without introducing additional issues.
    last seen2020-06-05
    modified2016-12-22
    plugin id96055
    published2016-12-22
    reporterThis script is Copyright (C) 2016-2020 and is owned by Tenable, Inc. or an Affiliate thereof.
    sourcehttps://www.tenable.com/plugins/nessus/96055
    titleFedora 25 : msgpuck / tarantool (2016-2d0c8ba781)
    code
    #%NASL_MIN_LEVEL 80502
    #
    # (C) Tenable Network Security, Inc.
    #
    # The descriptive text and package checks in this plugin were  
    # extracted from Fedora Security Advisory FEDORA-2016-2d0c8ba781.
    #
    
    include("compat.inc");
    
    if (description)
    {
      script_id(96055);
      script_version("3.5");
      script_set_attribute(attribute:"plugin_modification_date", value:"2020/06/04");
    
      script_cve_id("CVE-2016-9036", "CVE-2016-9037");
      script_xref(name:"FEDORA", value:"2016-2d0c8ba781");
    
      script_name(english:"Fedora 25 : msgpuck / tarantool (2016-2d0c8ba781)");
      script_summary(english:"Checks rpm output for the updated packages.");
    
      script_set_attribute(
        attribute:"synopsis", 
        value:"The remote Fedora host is missing one or more security updates."
      );
      script_set_attribute(
        attribute:"description", 
        value:
    "Security fix for CVE-2016-9036, CVE-2016-9037
    
    Note that Tenable Network Security has extracted the preceding
    description block directly from the Fedora update system website.
    Tenable has attempted to automatically clean and format it as much as
    possible without introducing additional issues."
      );
      script_set_attribute(
        attribute:"see_also",
        value:"https://bodhi.fedoraproject.org/updates/FEDORA-2016-2d0c8ba781"
      );
      script_set_attribute(
        attribute:"solution", 
        value:"Update the affected msgpuck and / or tarantool packages."
      );
      script_set_cvss_base_vector("CVSS2#AV:N/AC:L/Au:N/C:N/I:N/A:C");
      script_set_cvss3_base_vector("CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H");
    
      script_set_attribute(attribute:"plugin_type", value:"local");
      script_set_attribute(attribute:"cpe", value:"p-cpe:/a:fedoraproject:fedora:msgpuck");
      script_set_attribute(attribute:"cpe", value:"p-cpe:/a:fedoraproject:fedora:tarantool");
      script_set_attribute(attribute:"cpe", value:"cpe:/o:fedoraproject:fedora:25");
    
      script_set_attribute(attribute:"vuln_publication_date", value:"2016/12/23");
      script_set_attribute(attribute:"patch_publication_date", value:"2016/12/22");
      script_set_attribute(attribute:"plugin_publication_date", value:"2016/12/22");
      script_set_attribute(attribute:"generated_plugin", value:"current");
      script_end_attributes();
    
      script_category(ACT_GATHER_INFO);
      script_copyright(english:"This script is Copyright (C) 2016-2020 and is owned by Tenable, Inc. or an Affiliate thereof.");
      script_family(english:"Fedora Local Security Checks");
    
      script_dependencies("ssh_get_info.nasl");
      script_require_keys("Host/local_checks_enabled", "Host/RedHat/release", "Host/RedHat/rpm-list");
    
      exit(0);
    }
    
    
    include("audit.inc");
    include("global_settings.inc");
    include("rpm.inc");
    
    
    if (!get_kb_item("Host/local_checks_enabled")) audit(AUDIT_LOCAL_CHECKS_NOT_ENABLED);
    release = get_kb_item("Host/RedHat/release");
    if (isnull(release) || "Fedora" >!< release) audit(AUDIT_OS_NOT, "Fedora");
    os_ver = pregmatch(pattern: "Fedora.*release ([0-9]+)", string:release);
    if (isnull(os_ver)) audit(AUDIT_UNKNOWN_APP_VER, "Fedora");
    os_ver = os_ver[1];
    if (! preg(pattern:"^25([^0-9]|$)", string:os_ver)) audit(AUDIT_OS_NOT, "Fedora 25", "Fedora " + os_ver);
    
    if (!get_kb_item("Host/RedHat/rpm-list")) audit(AUDIT_PACKAGE_LIST_MISSING);
    
    
    cpu = get_kb_item("Host/cpu");
    if (isnull(cpu)) audit(AUDIT_UNKNOWN_ARCH);
    if ("x86_64" >!< cpu && cpu !~ "^i[3-6]86$") audit(AUDIT_LOCAL_CHECKS_NOT_IMPLEMENTED, "Fedora", cpu);
    
    
    flag = 0;
    if (rpm_check(release:"FC25", reference:"msgpuck-1.1.3-1.fc25")) flag++;
    if (rpm_check(release:"FC25", reference:"tarantool-1.6.9.52-1.fc25")) flag++;
    
    
    if (flag)
    {
      security_report_v4(
        port       : 0,
        severity   : SECURITY_HOLE,
        extra      : rpm_report_get()
      );
      exit(0);
    }
    else
    {
      tested = pkg_tests_get();
      if (tested) audit(AUDIT_PACKAGE_NOT_AFFECTED, tested);
      else audit(AUDIT_PACKAGE_NOT_INSTALLED, "msgpuck / tarantool");
    }
    
  • NASL familyFedora Local Security Checks
    NASL idFEDORA_2016-BADD014AFE.NASL
    descriptionSecurity fix for CVE-2016-9036, CVE-2016-9037 Note that Tenable Network Security has extracted the preceding description block directly from the Fedora update system website. Tenable has attempted to automatically clean and format it as much as possible without introducing additional issues.
    last seen2020-06-05
    modified2016-12-22
    plugin id96056
    published2016-12-22
    reporterThis script is Copyright (C) 2016-2020 and is owned by Tenable, Inc. or an Affiliate thereof.
    sourcehttps://www.tenable.com/plugins/nessus/96056
    titleFedora 24 : msgpuck / tarantool (2016-badd014afe)
    code
    #%NASL_MIN_LEVEL 80502
    #
    # (C) Tenable Network Security, Inc.
    #
    # The descriptive text and package checks in this plugin were  
    # extracted from Fedora Security Advisory FEDORA-2016-badd014afe.
    #
    
    include("compat.inc");
    
    if (description)
    {
      script_id(96056);
      script_version("3.5");
      script_set_attribute(attribute:"plugin_modification_date", value:"2020/06/04");
    
      script_cve_id("CVE-2016-9036", "CVE-2016-9037");
      script_xref(name:"FEDORA", value:"2016-badd014afe");
    
      script_name(english:"Fedora 24 : msgpuck / tarantool (2016-badd014afe)");
      script_summary(english:"Checks rpm output for the updated packages.");
    
      script_set_attribute(
        attribute:"synopsis", 
        value:"The remote Fedora host is missing one or more security updates."
      );
      script_set_attribute(
        attribute:"description", 
        value:
    "Security fix for CVE-2016-9036, CVE-2016-9037
    
    Note that Tenable Network Security has extracted the preceding
    description block directly from the Fedora update system website.
    Tenable has attempted to automatically clean and format it as much as
    possible without introducing additional issues."
      );
      script_set_attribute(
        attribute:"see_also",
        value:"https://bodhi.fedoraproject.org/updates/FEDORA-2016-badd014afe"
      );
      script_set_attribute(
        attribute:"solution", 
        value:"Update the affected msgpuck and / or tarantool packages."
      );
      script_set_cvss_base_vector("CVSS2#AV:N/AC:L/Au:N/C:N/I:N/A:C");
      script_set_cvss3_base_vector("CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H");
    
      script_set_attribute(attribute:"plugin_type", value:"local");
      script_set_attribute(attribute:"cpe", value:"p-cpe:/a:fedoraproject:fedora:msgpuck");
      script_set_attribute(attribute:"cpe", value:"p-cpe:/a:fedoraproject:fedora:tarantool");
      script_set_attribute(attribute:"cpe", value:"cpe:/o:fedoraproject:fedora:24");
    
      script_set_attribute(attribute:"vuln_publication_date", value:"2016/12/23");
      script_set_attribute(attribute:"patch_publication_date", value:"2016/12/22");
      script_set_attribute(attribute:"plugin_publication_date", value:"2016/12/22");
      script_set_attribute(attribute:"generated_plugin", value:"current");
      script_end_attributes();
    
      script_category(ACT_GATHER_INFO);
      script_copyright(english:"This script is Copyright (C) 2016-2020 and is owned by Tenable, Inc. or an Affiliate thereof.");
      script_family(english:"Fedora Local Security Checks");
    
      script_dependencies("ssh_get_info.nasl");
      script_require_keys("Host/local_checks_enabled", "Host/RedHat/release", "Host/RedHat/rpm-list");
    
      exit(0);
    }
    
    
    include("audit.inc");
    include("global_settings.inc");
    include("rpm.inc");
    
    
    if (!get_kb_item("Host/local_checks_enabled")) audit(AUDIT_LOCAL_CHECKS_NOT_ENABLED);
    release = get_kb_item("Host/RedHat/release");
    if (isnull(release) || "Fedora" >!< release) audit(AUDIT_OS_NOT, "Fedora");
    os_ver = pregmatch(pattern: "Fedora.*release ([0-9]+)", string:release);
    if (isnull(os_ver)) audit(AUDIT_UNKNOWN_APP_VER, "Fedora");
    os_ver = os_ver[1];
    if (! preg(pattern:"^24([^0-9]|$)", string:os_ver)) audit(AUDIT_OS_NOT, "Fedora 24", "Fedora " + os_ver);
    
    if (!get_kb_item("Host/RedHat/rpm-list")) audit(AUDIT_PACKAGE_LIST_MISSING);
    
    
    cpu = get_kb_item("Host/cpu");
    if (isnull(cpu)) audit(AUDIT_UNKNOWN_ARCH);
    if ("x86_64" >!< cpu && cpu !~ "^i[3-6]86$") audit(AUDIT_LOCAL_CHECKS_NOT_IMPLEMENTED, "Fedora", cpu);
    
    
    flag = 0;
    if (rpm_check(release:"FC24", reference:"msgpuck-1.1.3-1.fc24")) flag++;
    if (rpm_check(release:"FC24", reference:"tarantool-1.6.9.52-1.fc24")) flag++;
    
    
    if (flag)
    {
      security_report_v4(
        port       : 0,
        severity   : SECURITY_HOLE,
        extra      : rpm_report_get()
      );
      exit(0);
    }
    else
    {
      tested = pkg_tests_get();
      if (tested) audit(AUDIT_PACKAGE_NOT_AFFECTED, tested);
      else audit(AUDIT_PACKAGE_NOT_INSTALLED, "msgpuck / tarantool");
    }
    

Seebug

bulletinFamilyexploit
description### Summary An exploitable incorrect return value vulnerability exists in the mpcheck function of Tarantool's Msgpuck library 1.0.3. A specially crafted packet can cause the mpcheck function to incorrectly return success when trying to check if decoding a map16 packet will read outside the bounds of a buffer, resulting in a denial of service vulnerability. ### Tested Versions Msgpuck 1.0.3 ### Product URLs https://github.com/tarantool/msgpuck/tree/1.0.3 ### CVSSv3 Score 7.5 - CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H ### CWE CWE-125: Out-of-bounds Read ### Details The Msgpuck library is used to encode and decode data that is serialized with the MsgPack (http://msgpack.org) format. This library was originally implemented to be the default library used for serialization and deserialization for the Tarantool Application Server, but is also distributed as an independent library to provide support for the MsgPack format to other C or C++ applications. When deserializing data that is encoded with the MsgPack format, the Msgpuck library provides a function named mp_check that's used to validate the Msgpack data before it is decoded. This function takes two arguments, one to the beginning of the MsgPack data and another to the end of the data which is used to determine if decoding the packet will read outside the bounds of the data. An example of how this is intended to be used is as follows: ``` // Validate char buf[1024]; const char* b = buf; if (!mp_check(&b, b+sizeof(buf))) return FAILURE; // Decode const char* r = buf; uint32_t count = mp_decode_map(&r); for (int i = 0; i < count; i++) { k = mp_decode_uint(&r); v = mp_decode_uint(&r); } ... ``` For optimization purposes, each of the Msgpuck functions are inlined. When calling mpcheck, the following code will be executed. First the library will read a byte that determines the type. This type will then be used to determine how many more bytes are expected for the encoded type. When the type is a map16 type, the library will check to see if the sum of the current read position and the size of a uint16t seeks past the end pointer. Due to a typo, however, the library will incorrectly return false which is a result that's different from the function's failure result. One can see that the result of a map32 returns a constant 1 when that particular failure occurs. This means that if the 2 bytes determining the map16's length cause the sum to seek past the end pointer, the function will succeed. Later when the library tries to decode this data, the library will read outside the bounds of the source data buffer. ``` msgpuck/msgpuck.h:1819 MP_IMPL int mp_check(const char **data, const char *end) { int k; for (k = 1; k > 0; k--) { if (mp_unlikely(*data >= end)) return 1; uint8_t c = mp_load_u8(data); int l = mp_parser_hint[c]; if (mp_likely(l >= 0)) { *data += l; continue; } else if (mp_likely(l > MP_HINT)) { k -= l; continue; } uint32_t len; switch (l) { ... case MP_HINT_MAP_16: /* MP_MAP (16) */ if (mp_unlikely(*data + sizeof(uint16_t) > end)) return false; // XXX: Should return 1 on failure. k += 2 * mp_load_u16(data); break; case MP_HINT_MAP_32: /* MP_MAP (32) */ if (mp_unlikely(*data + sizeof(uint32_t) > end)) return 1; k += 2 * mp_load_u32(data); break; ... default: mp_unreachable(); } } if (mp_unlikely(*data > end)) return 1; return 0; } ``` ### Crash Information ``` $ gdb --quiet --args ./poc-server.out 0.0.0.0:57005 ... $ python poc 127.0.0.1:57005 ... Catchpoint 4 (signal SIGSEGV), 0x0000000000402bdc in mp_load_u16 () (gdb) x/i $pc => 0x402bdc <mp_load_u16+15>: movzwl (%rax),%eax (gdb) i r rax rax 0x7ffff7ff6fff 0x7ffff7ff6fff ``` ### Exploit Proof-of-Concept In order to demonstrate the out-of-bounds read, a server that reads a MsgPack decoded map type is provided. This server allocates space for the source buffer followed by a guard-page to show the exact instruction that reads outside the allocated buffer. To compile this, simply copy the `poc-server.cc` file to the root of the Tarantool directory and type in the following. This will create a binary named `poc-server.out` which will run the MsgPack server. The arguments to this binary control which interface and port the server will bind to. ``` $ g++ -Wall -Isrc/lib/msgpuck src/lib/msgpuck/msgpuck.c -std=c++11 -o poc-server.out poc-server.cc $ ./poc-server.out Usage: ./poc-server.out host:port $ ./poc-server.out 0.0.0.0:57005 Listening on 0.0.0.0:57005 ... ``` Once the server is running, the proof-of-concept can be executed against the server using python. This is done using a similar syntax. The proof-of-concept will send 5 packets. The first 3 packets that are sent will exercise the fixmap, map16, and map32 encoded types. The 4th packet will send a malformed map16 type. The 5th and last packet will trigger the vulnerability causing the out-of-bounds read. ``` $ python poc host:port Sending a valid fixmap {1:1, 2:2, 3:3, 4:4, 5:5} Sending a valid map16 {1:1, 2:2, 3:3, 4:4, 5:5} Sending a valid map32 {1:1, 2:2, 3:3, 4:4, 5:5} Sending a invalid map16 {1:1, 2:2, 3:3, 4:4, 5:5} Sending a vulnerable map16 {1:1, 2:2, 3:3, 4:4, 5:5} ``` ### Timeline * 2016-12-14 - Vendor Disclosure * 2016-12-16 - Public Release ### CREDIT * Discovered by the Cisco Talos Team
idSSV:96590
last seen2017-11-19
modified2017-09-26
published2017-09-26
reporterRoot
titleTarantool Msgpuck mp_check Denial Of Service Vulnerability(CVE-2016-9036)

Talos

idTALOS-2016-0254
last seen2019-05-29
published2016-12-16
reporterTalos Intelligence
sourcehttp://www.talosintelligence.com/vulnerability_reports/TALOS-2016-0254
titleTarantool Msgpuck mp_check Denial Of Service Vulnerability