Lucene search

K
myhack58佚名MYHACK58:62201996250
HistoryNov 07, 2019 - 12:00 a.m.

For libssh2 integer overflow vulnerability (CVE-2019-17498)analysis-vulnerability warning-the black bar safety net

2019-11-0700:00:00
佚名
www.myhack58.com
151

8.8 High

CVSS3

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

REQUIRED

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H

9.3 High

CVSS2

Access Vector

NETWORK

Access Complexity

MEDIUM

Authentication

NONE

Confidentiality Impact

COMPLETE

Integrity Impact

COMPLETE

Availability Impact

COMPLETE

AV:N/AC:M/Au:N/C:C/I:C/A:C

0x01 vulnerability mining
In 2019 3 December 18, Canonical Ltd. Chris Coulson discloses libssh2 nine of vulnerability, CVE-2019-3855 to CVE-2019-3863-in. These vulnerabilities have been in the libssh2 v1. 8. 1 repair. At the time, my colleague Pavel Avgustinov note that fix vulnerabilities reported in the LGTM on the introduction of several new alarm. These alarms were due like the following code:
if((p_len = _libssh2_get_c_string(&buf, &p))
The problem occurs in _libssh2_get_c_string return -1 is an error code, but p_len no symbols, so the error condition will be ignored. libssh2 team has been in the back of the report fixes these problems, but it prompted us to carefully review the code to see that it contains obvious mistakes of vulnerability. We soon discovered this for bounds checking in the function:
int _libssh2_check_length(struct string_buf *buf, size_t len)
{
return ((int)(buf->dataptr - buf->data) len - len)) ? 1 : 0;
}
This function the problem is to cast the int might overflow. On the left side of the cast is safe, because the field buf is a trusted value, but on the right side of the cast is unsafe, because the value of len is not trusted. Create the exploit exp is not difficult, the exploit that the value of len is greater than bypass the overflow check buf->len + 0x80000000。 Available on GitHub to find the PoC.
I later learned that the problem _libssh2_check_length is in 1. 8. 2 version released after the main development branch is introduced, and therefore the vulnerability range check in 1. 8. Version 2 does not exist. Unfortunately, version 1. 8. 2 does not contain any bounds checking, and therefore the PoC is still valid. In 1. 8. Version 2, the vulnerability of the source location is kex. c: 1675。 The problem is that where p_len contains an untrusted value, so subsequent reads s may be out of range. Because _libssh2_check_length in 1. 8. Version 2 does not exist, so do not need the value p_len is larger than 0x80000000 trigger the vulnerability. This means that the smaller the value of len can trigger an out of bounds read, the vulnerability is more likely to be used to achieve remote information disclosure.
0x02 negative error codes is converted to unsigned
When my colleagues and I are to view the vulnerability patch report, we noted that a common error pattern, wherein the negative error return Values Cast to unsigned it. This is a very easy mistake to make, and it is not a compiler warning of the](https://godbolt.org/z/CvqwDm)capture. So I wrote this simple query to find vulnerabilities examples:
import cpp
import semmle. code. cpp. dataflow. DataFlow
import semmle. code. cpp. rangeanalysis. SimpleRangeAnalysis

from the Function f, FunctionCall call, ReturnStmt ret, DataFlow::Node source, DataFlow::Node sink
the where call. getTarget() = f
and ret. getEnclosingFunction() = f
and ret. getExpr(). getValue(). toInt()
The query code is as follows:
r_len = _libssh2_get_c_string(&buf, &r);
if(r_len
The query returns a negative integer constant function. For example, _libssh2_get_c_string in 773 on the line to perform this operation, then it will look for the function calls, these calls return a value and converts it to an unsigned type.
0x03 trigger the vulnerability
The vulnerability of the source location is the packet. c: 480: the
if(message_len
The value of datalen is not trusted because it is by the remote SSH server control. For example, if datalen == 11, the subtraction will overflow and bounds checking message_len invalid. message_len is a 32-bit unsigned integer, it is also by the remote SSH server control, and therefore this may result in the 485 line on the cross-border reads:
language_len =
_libssh2_ntohu32(data + 9 + message_len);
Out of bounds read usually will only lead to a segmentation fault, but LIBSSH2_DISCONNECT in the first 499 lines of the call is also likely to cause other types of problems:
if(session->ssh_msg_disconnect) {
LIBSSH2_DISCONNECT(session, reason, message,
message_len, language, language_len);
}
Depending on the libssh2 library to use, because session->ssh_msg_disconnect is a callback function, the default case of null, but may be made of the library of the user set by calling the libssh2_session_callback_set it.
I wrote a vulnerability PoC, in which a malicious SSH server to use datalen == 11 and returns the disconnect message message_len == 0x41414141, it will lead libssh2 due to segmentation fault and crash.
0x04 libssh2 in an integer overflow variant analysis
I’m in 2019 at the end of 6 before written about libssh2 last blog article. In order to accurately understand the blog articles the technical details, I need to come back to take a look at the libssh2 code. I noticed that many of the careless boundary checking code, for example the above error.
Variant analysis is about the vulnerability of all variants, and where possible, create can be in multiple code bases between the reuse of the query. But my target is concentrated in libssh2 and I found the vulnerability on.
When I asked the vendor to report security vulnerabilities, usually try to include in the report two points:
1. One of the vulnerabilities of the PoC.
2. A QL query, it identifies the I think there is a vulnerability of all of the code position.
QL query and the PoC has several advantages:
1. If the code contains a few very similar error, then I can write a list of all the vulnerabilities in the query.
2. The query so that I can easily check the vulnerability has been fixed in the 90-day deadline is about to expire, it is very easy to.
3. I can be a QL query and its result list as a single URL is included, which for me is very convenient, hope the recipient is also very convenient.
Write the PoC usually requires a lot of work, so if there are a plurality of very similar vulnerabilities, then I usually just for one of the written PoC. My feeling is that a PoC is sufficient to prove the security implications are real. The following query for this use case is adjusted, the query object is not in the libssh2 find all the integer overflow vulnerability, but also due to query coding some libssh2 specific details, it also does not extend to other code libraries.
/**

  • @kind path-problem
    */

import cpp
import semmle. code. cpp. rangeanalysis. SimpleRangeAnalysis
import semmle. code. cpp. dataflow. TaintTracking
import DataFlow::PathGraph

class Config extends DataFlow::Configuration {
Config() { this = “_libssh2_ntohl bounds check overflow” }

the override predicate isSource(DataFlow::Node source) {

[1] [2] next

8.8 High

CVSS3

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

REQUIRED

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H

9.3 High

CVSS2

Access Vector

NETWORK

Access Complexity

MEDIUM

Authentication

NONE

Confidentiality Impact

COMPLETE

Integrity Impact

COMPLETE

Availability Impact

COMPLETE

AV:N/AC:M/Au:N/C:C/I:C/A:C