CVE-2019-12527: Code Execution on Squid Proxy Through a Buffer OverflowAugust 22, 2019 | Trend Micro Research Team
In this excerpt of a Trend Micro Vulnerability Research Service report, Saran Neti and Sivathmican Sivakumaran of the Trend Micro Research Team detail a recent buffer overflow vulnerability in the Squid web proxy. A remote, unauthenticated attacker could exploit this vulnerability by sending a crafted request to the target server, resulting in code execution in the context of the Squid process. The following is a portion of their write-up covering CVE-2019-12527, with a few minimal modifications.
Squid is a popular open source Internet proxy and web caching application. It can be used to reduce bandwidth usage and demand on web servers, filter network traffic, and speed up web access by locally caching frequently-used resources. Squid supports a variety of network protocols including HTTP, FTP, and Gopher. Squid supports forward proxying where clients on an internal network connect to a server on an external network via Squid, reverse proxying where clients on an external network connect via Squid to a server on the internal network, and intercept or transparent proxying where Squid mediates connections between clients and servers transparently.
Background and Fundamentals
Within Squid, the cache manager interface,
cachemgr.cgi, is provided to display statistics about the Squid proxy process over the web. In addition to displaying statistics, the cache manager can also be used to manage the cache without the need to log in to the Squid server.
HTTP is a request/response protocol described in RFCs 7230-7237 and many other RFCs. A request is sent from a client to a server, which in turn sends a response back to the client. An HTTP request consists of a request line, various headers, an empty line, and an optional message body:
CRLF represents the new line sequence Carriage Return (CR) followed by Line Feed (LF). SP represents a space character. Parameters can be passed from the client to the server as name-value pairs in either the Request-URI, or in the message body, depending on the Method used and the Content-Type header. For example, a simple HTTP request passing a parameter named
param with value
1, using the GET method might look like:
HTTP supports several authentication schemes, many of which involve the use of the
Authorization header. It has the following format:
Common values for <type> include “Basic”, “Digest”, “OAuth”, and “Negotiate”.
A buffer overflow vulnerability exists in Squid. When Squid receives an incoming request for
cachemgr, the CacheManager::ParseHeaders() function is called to parse the headers of the request. An example of this would be an HTTP request for a
REQUEST-URI that starts with “
cache_object”. If the header contains a “Authorization” header that starts with a value
Basic, the vulnerable function HttpHeader::getAuth() is called.
Similarly, when Squid is used as an FTP proxy and a request is sent with a
REQUEST-URI that begins with “ftp”, the HttpHeader::getAuth() function is called.
The HttpHeader::getAuth() function uses an 8192-byte buffer, decodedAuthToken, into which it performs base64-decoding of
<credentials> using base64_decode_update(). If the decoded version is over 8192 bytes, a buffer overflow occurs.
A remote attacker can exploit this vulnerability by sending a crafted HTTP request to the target server. Successful exploitation will result in the attacker being able to execute arbitrary code with the privileges of the server process while an unsuccessful attack will cause the server process to abnormally terminate.
Source Code Walkthrough
The following code snippet was taken from Squid version 4.7. Some comments have been added by Trend Micro.
And finally, in
Triggering the Vulnerability
The following packet decode illustrates a fragment of an attack request from a client to a target Squid proxy:
As previously mentioned, the standard Authorization header has a format of:
Following "Authorization: Basic", there is a string of characters, only a portion of which are visible in this fragment. When the entire string is base64 decoded, the result overflows the 8192-byte buffer. Note that the process of base64 decoding produces output that is 3/4 of the input length, so the transmitted string must actually be considerably longer than 8192 bytes for a successful attack.
This vulnerability was corrected by the Squid maintainers with a recent commit. In the notes for the commit, they note the bug was fixed by replacing the fixed-size buffer for decoding base64 tokens with an SBuf to avoid decoder issues on large inputs. They also updated callers to SBuf API operations for more efficient memory management.
Special thanks to Saran Neti and Sivathmican Sivakumaran of the Trend Micro Research Team for providing such a thorough analysis of this vulnerability. For an overview of Trend Micro Research services please visit http://go.trendmicro.com/tis/.
The threat research team will be back with other great vulnerability analysis reports in the future. Until then, follow the ZDI team for the latest in exploit techniques and security patches.
Edit: This vulnerability was initially described as a heap buffer overflow. This has been corrected to reflect this is a static buffer overflow instead.