Vulnerabilities > CVE-2017-2801 - Out-of-bounds Read vulnerability in Botan Project Botan 2.0.1
Attack vector
NETWORK Attack complexity
LOW Privileges required
NONE Confidentiality impact
HIGH Integrity impact
HIGH Availability impact
HIGH Summary
A programming error exists in a way Randombit Botan cryptographic library version 2.0.1 implements x500 string comparisons which could lead to certificate verification issues and abuse. A specially crafted X509 certificate would need to be delivered to the client or server application in order to trigger this vulnerability.
Vulnerable Configurations
Part | Description | Count |
---|---|---|
Application | 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 family Debian Local Security Checks NASL id DEBIAN_DLA-915.NASL description A bug in X509 DN string comparisons could result in out of bound reads. This could result in information leakage, denial of service, or potentially incorrect certificate validation results. For Debian 7 last seen 2020-03-17 modified 2017-04-26 plugin id 99672 published 2017-04-26 reporter This script is Copyright (C) 2017-2020 and is owned by Tenable, Inc. or an Affiliate thereof. source https://www.tenable.com/plugins/nessus/99672 title Debian DLA-915-1 : botan1.10 security update code #%NASL_MIN_LEVEL 80502 # # (C) Tenable Network Security, Inc. # # The descriptive text and package checks in this plugin were # extracted from Debian Security Advisory DLA-915-1. The text # itself is copyright (C) Software in the Public Interest, Inc. # include("compat.inc"); if (description) { script_id(99672); script_version("3.7"); script_set_attribute(attribute:"plugin_modification_date", value:"2020/03/12"); script_cve_id("CVE-2017-2801"); script_name(english:"Debian DLA-915-1 : botan1.10 security update"); script_summary(english:"Checks dpkg output for the updated packages."); script_set_attribute( attribute:"synopsis", value:"The remote Debian host is missing a security update." ); script_set_attribute( attribute:"description", value: "A bug in X509 DN string comparisons could result in out of bound reads. This could result in information leakage, denial of service, or potentially incorrect certificate validation results. For Debian 7 'Wheezy', these problems have been fixed in version 1.10.5-1+deb7u3. We recommend that you upgrade your botan1.10 packages. NOTE: Tenable Network Security has extracted the preceding description block directly from the DLA security advisory. 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://lists.debian.org/debian-lts-announce/2017/04/msg00034.html" ); script_set_attribute( attribute:"see_also", value:"https://packages.debian.org/source/wheezy/botan1.10" ); script_set_attribute(attribute:"solution", value:"Upgrade the affected packages."); script_set_cvss_base_vector("CVSS2#AV:N/AC:L/Au:N/C:P/I:P/A:P"); script_set_cvss_temporal_vector("CVSS2#E:U/RL:OF/RC:C"); script_set_cvss3_base_vector("CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"); script_set_cvss3_temporal_vector("CVSS:3.0/E:U/RL:O/RC:C"); script_set_attribute(attribute:"exploitability_ease", value:"No known exploits are available"); script_set_attribute(attribute:"exploit_available", value:"false"); script_set_attribute(attribute:"plugin_type", value:"local"); script_set_attribute(attribute:"cpe", value:"p-cpe:/a:debian:debian_linux:botan1.10-dbg"); script_set_attribute(attribute:"cpe", value:"p-cpe:/a:debian:debian_linux:libbotan-1.10-0"); script_set_attribute(attribute:"cpe", value:"p-cpe:/a:debian:debian_linux:libbotan1.10-dev"); script_set_attribute(attribute:"cpe", value:"cpe:/o:debian:debian_linux:7.0"); script_set_attribute(attribute:"patch_publication_date", value:"2017/04/25"); script_set_attribute(attribute:"plugin_publication_date", value:"2017/04/26"); script_end_attributes(); script_category(ACT_GATHER_INFO); script_copyright(english:"This script is Copyright (C) 2017-2020 and is owned by Tenable, Inc. or an Affiliate thereof."); script_family(english:"Debian Local Security Checks"); script_dependencies("ssh_get_info.nasl"); script_require_keys("Host/local_checks_enabled", "Host/Debian/release", "Host/Debian/dpkg-l"); exit(0); } include("audit.inc"); include("debian_package.inc"); if (!get_kb_item("Host/local_checks_enabled")) audit(AUDIT_LOCAL_CHECKS_NOT_ENABLED); if (!get_kb_item("Host/Debian/release")) audit(AUDIT_OS_NOT, "Debian"); if (!get_kb_item("Host/Debian/dpkg-l")) audit(AUDIT_PACKAGE_LIST_MISSING); flag = 0; if (deb_check(release:"7.0", prefix:"botan1.10-dbg", reference:"1.10.5-1+deb7u3")) flag++; if (deb_check(release:"7.0", prefix:"libbotan-1.10-0", reference:"1.10.5-1+deb7u3")) flag++; if (deb_check(release:"7.0", prefix:"libbotan1.10-dev", reference:"1.10.5-1+deb7u3")) flag++; if (flag) { if (report_verbosity > 0) security_hole(port:0, extra:deb_report_get()); else security_hole(0); exit(0); } else audit(AUDIT_HOST_NOT, "affected");
NASL family Debian Local Security Checks NASL id DEBIAN_DSA-3939.NASL description Aleksandar Nikolic discovered that an error in the x509 parser of the Botan crypto library could result in an out-of-bounds memory read, resulting in denial of service or an information leak if processing a malformed certificate. last seen 2020-06-01 modified 2020-06-02 plugin id 102446 published 2017-08-14 reporter This script is Copyright (C) 2017-2018 and is owned by Tenable, Inc. or an Affiliate thereof. source https://www.tenable.com/plugins/nessus/102446 title Debian DSA-3939-1 : botan1.10 - security update code # # (C) Tenable Network Security, Inc. # # The descriptive text and package checks in this plugin were # extracted from Debian Security Advisory DSA-3939. The text # itself is copyright (C) Software in the Public Interest, Inc. # include("compat.inc"); if (description) { script_id(102446); script_version("3.6"); script_cvs_date("Date: 2018/11/10 11:49:38"); script_cve_id("CVE-2017-2801"); script_xref(name:"DSA", value:"3939"); script_name(english:"Debian DSA-3939-1 : botan1.10 - security update"); script_summary(english:"Checks dpkg output for the updated package"); script_set_attribute( attribute:"synopsis", value:"The remote Debian host is missing a security-related update." ); script_set_attribute( attribute:"description", value: "Aleksandar Nikolic discovered that an error in the x509 parser of the Botan crypto library could result in an out-of-bounds memory read, resulting in denial of service or an information leak if processing a malformed certificate." ); script_set_attribute( attribute:"see_also", value:"https://packages.debian.org/source/jessie/botan1.10" ); script_set_attribute( attribute:"see_also", value:"https://www.debian.org/security/2017/dsa-3939" ); script_set_attribute( attribute:"solution", value: "Upgrade the botan1.10 packages. For the oldstable distribution (jessie), this problem has been fixed in version 1.10.8-2+deb8u2. For the stable distribution (stretch), this problem has been fixed prior to the initial release." ); script_set_cvss_base_vector("CVSS2#AV:N/AC:L/Au:N/C:P/I:P/A:P"); script_set_cvss_temporal_vector("CVSS2#E:U/RL:OF/RC:C"); script_set_cvss3_base_vector("CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"); script_set_cvss3_temporal_vector("CVSS:3.0/E:U/RL:O/RC:C"); script_set_attribute(attribute:"exploitability_ease", value:"No known exploits are available"); script_set_attribute(attribute:"exploit_available", value:"false"); script_set_attribute(attribute:"plugin_type", value:"local"); script_set_attribute(attribute:"cpe", value:"p-cpe:/a:debian:debian_linux:botan1.10"); script_set_attribute(attribute:"cpe", value:"cpe:/o:debian:debian_linux:8.0"); script_set_attribute(attribute:"patch_publication_date", value:"2017/08/12"); script_set_attribute(attribute:"plugin_publication_date", value:"2017/08/14"); script_end_attributes(); script_category(ACT_GATHER_INFO); script_copyright(english:"This script is Copyright (C) 2017-2018 and is owned by Tenable, Inc. or an Affiliate thereof."); script_family(english:"Debian Local Security Checks"); script_dependencies("ssh_get_info.nasl"); script_require_keys("Host/local_checks_enabled", "Host/Debian/release", "Host/Debian/dpkg-l"); exit(0); } include("audit.inc"); include("debian_package.inc"); if (!get_kb_item("Host/local_checks_enabled")) audit(AUDIT_LOCAL_CHECKS_NOT_ENABLED); if (!get_kb_item("Host/Debian/release")) audit(AUDIT_OS_NOT, "Debian"); if (!get_kb_item("Host/Debian/dpkg-l")) audit(AUDIT_PACKAGE_LIST_MISSING); flag = 0; if (deb_check(release:"8.0", prefix:"botan1.10-dbg", reference:"1.10.8-2+deb8u2")) flag++; if (deb_check(release:"8.0", prefix:"libbotan-1.10-0", reference:"1.10.8-2+deb8u2")) flag++; if (deb_check(release:"8.0", prefix:"libbotan1.10-dev", reference:"1.10.8-2+deb8u2")) flag++; if (flag) { if (report_verbosity > 0) security_hole(port:0, extra:deb_report_get()); else security_hole(0); exit(0); } else audit(AUDIT_HOST_NOT, "affected");
Seebug
bulletinFamily | exploit |
description | ### Summary A programming error exists in a way Randombit Botan cryptographic library version 2.0.1 implements x500 string comparisons which could lead to certificate verification issues and abuse. A specially crafted X509 certificate would need to be delivered to the client or server application in order to trigger this vulnerability. ### Tested Versions Randombit Botan 2.0.1 ### Product URLs https://botan.randombit.net/ ### CVSSv3 Score 6.5 - CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:C/C:L/I:L/A:L ### CWE CWE-125: Out-of-bounds Read ### Details Botan is a C++ cryptographic library that implements the basis for practical systems that require TLS, PKIX certificate handling, password hashing or other cryptographic primitives. There exists a programming error in code related to x509 distinguished name parsing. Namely, an x509 DN comparison function can lead to out of bounds memory access leading to unexpected results, information disclosure or potential denial of service. The vulnerability is located in the overloaded equality comparison function `Botan::x500_name_cmp`: ``` bool x500_name_cmp(const std::string& name1, const std::string& name2) { auto p1 = name1.begin(); auto p2 = name2.begin(); while((p1 != name1.end()) && Charset::is_space(*p1)) ++p1; [1] while((p2 != name2.end()) && Charset::is_space(*p2)) ++p2; while(p1 != name1.end() && p2 != name2.end()) { if(Charset::is_space(*p1)) [2] { if(!Charset::is_space(*p2)) [3] return false; while((p1 != name1.end()) && Charset::is_space(*p1)) ++p1; [4] while((p2 != name2.end()) && Charset::is_space(*p2)) ++p2; [5] if(p1 == name1.end() && p2 == name2.end()) [6] return true; } if(!Charset::caseless_cmp(*p1, *p2)) [7] return false; ++p1; [8] ++p2; } while((p1 != name1.end()) && Charset::is_space(*p1)) ++p1; while((p2 != name2.end()) && Charset::is_space(*p2)) ++p2; if((p1 != name1.end()) || (p2 != name2.end())) return false; return true; } ``` First, at [1], initiall whitespaces are skipped. Then, strings are compared byte by byte in a loop while checking for whitespace at [2]. If a space occurs in the first string [2] and the second too [3], those are again skipped at [4] and [5]. Then, at [6], if both have reached an end, true is returned. If not, another comparison is made at [7] and if it passes, the pointers are increased at [8]. The vulnerability lies in the way whitespaces are handeled. If we are comparing two strings which are initially the same up to a space character, we would enter while loops at [4] and [5]. Now, if one string contains a NULL byte after that space, and the other has spaces until its end, the check at [6] won’t be true, because only the second string would point to its end. However, both are actually pointing at a NULL byte, which means the check at [7] will still hold true, and pointers are once again increased at [8]. Then when the loop rolls around, one of the pointers can point outside its allocated buffer, leading to unexpected behaviour. A specially crafted x509 certificate with specific x509 DN strings for subject and issuer fields can be created. Example strings that satisfy the above conditions are: ``` String 1: AA\x20\x00AAAAAAAAAA String 2: AA\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20 ``` Notice that both are the same length, begin with same characters up until space after which the first is terminated and the second has spaces till the end. Because of the way these pieces of certificate are copied from the x509 file to their memory buffers, the first string’s length won’t be 3, that is, it won’t be terminated at the first NULL. With careful control over X509 distinguished names contents and depending on memory layout in the target application, it could be possible to craft a certificate where equality checks could pass or fail. Also, a discrepancy between a way these malformed strings are handled in Botan and other x509 libraries could lead to other types of abuse, possibly not unlike the famed CVE-2009-2408. The vulnerability can be triggered with the supplied example x509 certificate. ### Crash Information Address sanitizer output: ``` botan/botan cert_info --ber cert1.der 2>&1| asan_symbolize -d ================================================================= ==15015==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60300000dfa3 at pc 0x7f027ec92e85 bp 0x7ffdf452fe60 sp 0x7ffdf452fe58 READ of size 1 at 0x60300000dfa3 thread T0 #0 0x7f027ec92e84 in Botan::x500_name_cmp(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) botan/./src/lib/utils/parsing.cpp:232 #1 0x7f027ec92e84 in ?? ??:0 #2 0x7f027e269f2a in Botan::operator==(Botan::X509_DN const&, Botan::X509_DN const&) botan/./src/lib/asn1/x509_dn.cpp:153 #3 0x7f027e269f2a in ?? ??:0 #4 0x7f027ed8b8f4 in Botan::X509_Certificate::force_decode() botan/./src/lib/x509/x509cert.cpp:149 #5 0x7f027ed8b8f4 in ?? ??:0 #6 0x7f027ed85263 in Botan::X509_Object::do_decode() botan/./src/lib/x509/x509_obj.cpp:235 #7 0x7f027ed85263 in ?? ??:0 #8 0x7f027ed877b1 in X509_Certificate botan/./src/lib/x509/x509cert.cpp:50 #9 0x7f027ed877b1 in ?? ??:0 #10 0x5fcc93 in Botan_CLI::Cert_Info::go() botan/./src/cli/x509.cpp:85 #11 0x5fcc93 in ?? ??:0 #12 0x520ed5 in Botan_CLI::Command::run(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&) botan/./src/cli/cli.h:229 #13 0x520ed5 in ?? ??:0 #14 0x51ca4f in main botan/./src/cli/main.cpp:60 #15 0x51ca4f in ?? ??:0 #16 0x7f027d16982f in __libc_start_main /build/glibc-Qz8a69/glibc-2.23/csu/../csu/libc-start.c:291 #17 0x7f027d16982f in ?? ??:0 #18 0x42e328 in _start ??:? #19 0x42e328 in ?? ??:0 0x60300000dfa3 is located 0 bytes to the right of 19-byte region [0x60300000df90,0x60300000dfa3) allocated by thread T0 here: #0 0x4ce458 in __interceptor_malloc ??:? #1 0x4ce458 in ?? ??:0 #2 0x7f027f296e77 in operator new(unsigned long) ??:? #3 0x7f027f296e77 in ?? ??:0 #4 0x7f027e272283 in std::pair<std::__decay_and_strip<Botan::OID const&>::__type, std::__decay_and_strip<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&>::__type> std::make_pair<Botan::OID const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&>(Botan::OID const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/bits/stl_pair.h:281 (discriminator 4) #5 0x7f027e272283 in void Botan::multimap_insert<Botan::OID, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >(std::multimap<Botan::OID, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<Botan::OID>, std::allocator<std::pair<Botan::OID const, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >&, Botan::OID const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) botan/build/include/botan/internal/stl_util.h:79 (discriminator 4) #6 0x7f027e272283 in ?? ??:0 #7 0x7f027e2671eb in Botan::X509_DN::get_attributes[abi:cxx11]() const botan/./src/lib/asn1/x509_dn.cpp:78 (discriminator 1) #8 0x7f027e2671eb in ?? ??:0 #9 0x7f027e269d49 in Botan::operator==(Botan::X509_DN const&, Botan::X509_DN const&) botan/./src/lib/asn1/x509_dn.cpp:138 (discriminator 1) #10 0x7f027e269d49 in ?? ??:0 #11 0x7f027ed8b8f4 in Botan::X509_Certificate::force_decode() botan/./src/lib/x509/x509cert.cpp:149 #12 0x7f027ed8b8f4 in ?? ??:0 #13 0x7f027ed85263 in Botan::X509_Object::do_decode() botan/./src/lib/x509/x509_obj.cpp:235 #14 0x7f027ed85263 in ?? ??:0 #15 0x7f027ed877b1 in X509_Certificate botan/./src/lib/x509/x509cert.cpp:50 #16 0x7f027ed877b1 in ?? ??:0 #17 0x5fcc93 in Botan_CLI::Cert_Info::go() botan/./src/cli/x509.cpp:85 #18 0x5fcc93 in ?? ??:0 #19 0x520ed5 in Botan_CLI::Command::run(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&) botan/./src/cli/cli.h:229 #20 0x520ed5 in ?? ??:0 #21 0x51ca4f in main botan/./src/cli/main.cpp:60 #22 0x51ca4f in ?? ??:0 #23 0x7f027d16982f in __libc_start_main /build/glibc-Qz8a69/glibc-2.23/csu/../csu/libc-start.c:291 #24 0x7f027d16982f in ?? ??:0 SUMMARY: AddressSanitizer: heap-buffer-overflow (botan/libbotan-2.so.0+0xc38e84) Shadow bytes around the buggy address: 0x0c067fff9ba0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c067fff9bb0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c067fff9bc0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c067fff9bd0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c067fff9be0: fa fa fa fa fa fa 00 00 03 fa fa fa fd fd fd fa =>0x0c067fff9bf0: fa fa 00 00[03]fa fa fa fd fd fd fa fa fa 00 00 0x0c067fff9c00: 00 04 fa fa fd fd fd fd fa fa 00 00 00 03 fa fa 0x0c067fff9c10: fd fd fd fd fa fa 00 00 00 03 fa fa fd fd fd fd 0x0c067fff9c20: fa fa 00 00 05 fa fa fa fd fd fd fa fa fa 00 00 0x0c067fff9c30: 07 fa fa fa fd fd fd fa fa fa 00 00 01 fa fa fa 0x0c067fff9c40: 00 00 00 fa fa fa fd fd fd fa fa fa fd fd fd fa Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Heap right redzone: fb Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack partial redzone: f4 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe Left alloca redzone: ca Right alloca redzone: cb ==15015==ABORTING ``` ### Mitigation Adding another check which tests if either string is at the end while the other is not, which would make them different, is enough to resolve this vulnerability: ``` diff --git a/src/lib/utils/parsing.cpp b/src/lib/utils/parsing.cpp index 8fd2ccc..ce4b02f 100644 --- a/src/lib/utils/parsing.cpp +++ b/src/lib/utils/parsing.cpp @@ -240,6 +240,11 @@ bool x500_name_cmp(const std::string& name1, const std::string& name2) if(p1 == name1.end() && p2 == name2.end()) return true; + if(p1 == name1.end() || p2 == name2.end()) + return false; } if(!Charset::caseless_cmp(*p1, *p2)) return false; ``` ### Timeline * 2017-03-16 - Vendor Disclosure * 2017-04-28 - Public Release ### CREDIT * Discovered by Aleksandar Nikolic of Cisco Talos. |
id | SSV:96525 |
last seen | 2017-11-19 |
modified | 2017-09-19 |
published | 2017-09-19 |
reporter | Root |
title | Randombit Botan Library X509 Certificate Validation Bypass Vulnerability(CVE-2017-2801) |
Talos
id | TALOS-2017-0294 |
last seen | 2019-05-29 |
published | 2017-04-28 |
reporter | Talos Intelligence |
source | http://www.talosintelligence.com/vulnerability_reports/TALOS-2017-0294 |
title | Randombit Botan Library X509 Certificate Validation Bypass Vulnerability |
References
- http://talosintelligence.com/vulnerability_reports/TALOS-2017-0294
- http://talosintelligence.com/vulnerability_reports/TALOS-2017-0294
- http://www.debian.org/security/2017/dsa-3939
- http://www.debian.org/security/2017/dsa-3939
- http://www.securityfocus.com/bid/98106
- http://www.securityfocus.com/bid/98106