Menu

#355 Security vulnerability discovered

v1.0 (example)
closed-fixed
None
9
2023-06-02
2023-05-05
hyper
No

Versions up to 1.3.2 (inclusive) of the MiniDLNA/ReadyMedia package are vulnerable to a heap buffer overflow vulnerability that can be exploited by an attacker to achieve remote code execution. The vulnerability is caused by incorrect validation logic when handling HTTP requests using chunked transport encoding. This results in other code later using attacker-controlled chunk values that exceed the length of the allocated buffer, resulting in out-of-bounds read/write.

The root cause of the bug is found in the ParseHTTPHeaders() function in upnphttp.c around line 428. The second condition of the while statement shown below is intended to parse the chunk size value from the request, save it to h->req_chunklen, and check if the value is greater than 0; due to missing parentheses around the assignment expression, it's actually the result of the comparison to 0 that is assigned to h->req_chunklen.

 while( (line < (h->req_buf + h->req_buflen)) &&
    (h->req_chunklen = strtol(line, &endptr, 16) > 0) &&
    (endptr != line) )

This results in any value greater than 0 being seen as 1 by the validation logic, which causes values that exceed the length of the allocated buffer to get past the check in the first condition of the while loop. Other code in the ParseHttpQuery_upnphttp() function will later parse the same chunk size values and pass them as the size argument in calls to memmove() without further validation, assuming the total length will not exceed the allocated buffer length.

Fix

The bug can be fixed by surround the assignment expression (h->req_chunklen = strtol(line, &endptr, 16) in the code above with an additional set of parentheses to separate it from the comparison.

Testcase to Trigger the Bug

This testcase will trigger the bug by passing a huge value (0xffffff) that is much larger than the
total request length sent, resulting in an OOB read past the end of the request buffer allocation
and into unmapped memory. The application should crash with a segmentation fault.

GET /status HTTP/1.0\r\nTransport-Encoding:chunked\r\n\r\nffffff\r\n\r\n0\r\n\r\n

Exploitability

As this is a heap-based vulnerability, exploitability of this issue will be dependent upon the Glibc version the application is linked against and compiler exploit mitigations, to some extent. Ultimately, because the bug provides for a strong read/write primitive, there are various options for exploitation. I have written a proof-of-concept exploit leading to redirection of code execution to an arbitrary address using a heap tcache poisoning attach to achieve arbitrary read/write on a Debian 11 system with latest patches.

Discussion

  • hyper

    hyper - 2023-05-05

    I have requested a CVE be assigned to this issue and intend to publish the details of the vulnerability and the exploit code when a patched version becomes available or after 60 days, whichever comes first. Please let me know if there any issues with this. Thanks!

     
  • Justin Maggard

    Justin Maggard - 2023-06-02
    • Description has changed:

    Diff:

    --- old
    +++ new
    @@ -1,4 +1,3 @@
    -
     Versions up to 1.3.2 (inclusive) of the MiniDLNA/ReadyMedia package are vulnerable to a heap buffer overflow vulnerability that can be exploited by an attacker to achieve remote code execution. The vulnerability is caused by incorrect validation logic when handling HTTP requests using chunked transport encoding. This results in other code later using attacker-controlled chunk values that exceed the length of the allocated buffer, resulting in out-of-bounds read/write.
    
     The root cause of the bug is found in the `ParseHTTPHeaders()` function in upnphttp.c around line 428. The second condition of the while statement shown below is intended to parse the chunk size value from the request, save it to `h-&gt;req_chunklen`, and check if the value is greater than 0; due to missing parentheses around the assignment expression, it&#39;s actually the result of the comparison to 0 that is assigned to `h-&gt;req_chunklen`.
    
    • status: open --> closed-fixed
    • private: Yes --> No
     

Log in to post a comment.

MongoDB Logo MongoDB