78%
18%
98%
Sudo before 1.9.5p2 has a Heap-based Buffer Overflow, allowing privilege escalation to root via "sudoedit -s" and a command-line argument that ends with a single backslash character:
Sudo before 1.9.5p2 has a Heap-based Buffer Overflow, allowing privilege escalation to root via "sudoedit -s" and a command-line argument that ends with a single backslash character.
Sudo before 1.9.5p2 contains an off-by-one error that can result in a heap-based buffer overflow, which allows privilege escalation to root via "sudoedit -s" and a command-line argument that ends with a single backslash character.
CVSS 3.1 Base Score 7.8. CVSS Attack Vector: local. CVSS Attack Complexity: low. CVSS Vector: (CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H).
CVSS 2.0 Base Score 7.2. CVSS Attack Vector: local. CVSS Attack Complexity: low. CVSS Vector: (AV:L/AC:L/Au:N/C:C/I:C/A:C).
The following code attempts to save four different identification numbers into an array.
id_sequence[3] = 456;
In the following example, it is possible to request that memcpy move a much larger segment of memory than assumed:
}
.../* if chunk info is valid, return the size of usable memory,* else, return -1 to indicate an error*/...
If returnChunkSize() happens to encounter an error it will return -1. Notice that the return value is not checked before the memcpy operation (CWE-252), so -1 can be passed as the size argument to memcpy() (CWE-805). Because memcpy() assumes that the value is unsigned, it will be interpreted as MAXINT-1 (CWE-195), and therefore will copy far more memory than is likely available to the destination buffer (CWE-787, CWE-788).
This example takes an IP address from a user, verifies that it is well formed and then looks up the hostname and copies it into a buffer.
}
strcpy(hostname, hp->h_name);/*routine that ensures user_supplied_addr is in the right format for conversion */
This function allocates a buffer of 64 bytes to store the hostname, however there is no guarantee that the hostname will not be larger than 64 bytes. If an attacker specifies an address which resolves to a very large hostname, then we may overwrite sensitive data or even relinquish control flow to the attacker.
Note that this example also contains an unchecked return value (CWE-252) that can lead to a NULL pointer dereference (CWE-476).
This example applies an encoding procedure to an input string and stores it into a buffer.
}
return dst_buf;die("user string too long, die evil hacker!");
else dst_buf[dst_index++] = user_supplied_string[i];dst_buf[dst_index++] = ';';
/* encode to < */
The programmer attempts to encode the ampersand character in the user-controlled string, however the length of the string is validated before the encoding procedure is applied. Furthermore, the programmer assumes encoding expansion will only expand a given character by a factor of 4, while the encoding of the ampersand expands by 5. As a result, when the encoding procedure expands the string it is possible to overflow the destination buffer if the attacker provides a string of many ampersands.
In the following C/C++ example, a utility function is used to trim trailing whitespace from a character string. The function copies the input string to a local character string and uses a while statement to remove the trailing whitespace by moving backward through the string and overwriting whitespace with a NUL character.
}
return retMessage;// copy input string to a temporary stringmessage[index] = strMessage[index];// trim trailing whitespacelen--;// return string without trailing whitespace
However, this function can cause a buffer underwrite if the input character string contains all whitespace. On some systems the while statement will move backwards past the beginning of a character string and will call the isspace() function on an address outside of the bounds of the local buffer.
The following is an example of code that may result in a buffer underwrite, if find() returns a negative value to indicate that ch is not found in srcBuf:
}...
If the index to srcBuf is somehow under user control, this is an arbitrary write-what-where condition.
The following code allocates memory for a maximum number of widgets. It then gets a user-specified number of widgets, making sure that the user does not request too many. It then initializes the elements of the array using InitializeWidget(). Because the number of widgets can vary for each request, the code inserts a NULL pointer to signify the location of the last widget.
showWidgets(WidgetList);ExitError("Incorrect number of widgets requested!");WidgetList[i] = InitializeWidget();
However, this code contains an off-by-one calculation error. It allocates exactly enough space to contain the specified number of widgets, but it does not include the space for the NULL pointer. As a result, the allocated buffer is smaller than it is supposed to be (CWE-131). So if the user ever requests MAX_NUM_WIDGETS, there is an off-by-one buffer overflow when the NULL is assigned. Depending on the environment and compilation settings, this could cause memory corruption.
In this example, the code does not account for the terminating null character, and it writes one byte beyond the end of the buffer.
The first call to strncat() appends up to 20 characters plus a terminating null character to fullname[]. There is plenty of allocated space for this, and there is no weakness associated with this first call. However, the second call to strncat() potentially appends another 20 characters. The code does not account for the terminating null character that is automatically added by strncat(). This terminating null character would be written one byte beyond the end of the fullname[] buffer. Therefore an off-by-one error exists with the second strncat() call, as the third argument should be 19.
strncat(fullname, lastname, 20);
When using a function like strncat() one must leave a free byte at the end of the buffer for a terminating null character, thus avoiding the off-by-one weakness. Additionally, the last argument to strncat() is the number of characters to append, which must be less than the remaining space in the buffer. Be careful not to just use the total size of the buffer.
strncat(fullname, lastname, sizeof(fullname)-strlen(fullname)-1);
The Off-by-one error can also be manifested when reading characters from a character array within a for loop that has an incorrect continuation condition.
}
filename[i] = getc();filename[i] = '\0';
In this case, the correct continuation condition is shown below.
...
As another example the Off-by-one error can occur when using the sprintf library function to copy a string variable to a formatted string variable and the original string variable comes from an untrusted source. As in the following example where a local function, setFilename is used to store the value of a filename to a database but first uses sprintf to format the filename. The setFilename function includes an input parameter with the name of the file that is used as the copy source in the sprintf function. The sprintf function will copy the file name to a char array of size 20 and specifies the format of the new variable as 16 characters followed by the file extension .dat.
}return success;
However this will cause an Off-by-one error if the original filename is exactly 16 characters or larger because the format of 16 characters with the file extension is exactly 20 characters and does not take into account the required null terminator that will be placed at the end of the string.
ExploitPedia is constantly evolving. Sign up to receive a notification when we release additional functionality.
If you'd like to report a bug or have any suggestions for improvements then please do get in touch with us using this form. We will get back to you as soon as we can.