Project

General

Profile

Bug #2945

Security - SIGABRT during GET request handling with url-path-2f-decode enabled

Added by stze 3 months ago. Updated 2 months ago.

Status:
Fixed
Priority:
Normal
Assignee:
-
Category:
core
Target version:
Start date:
2019-04-09
Due date:
% Done:

100%

Estimated time:
Missing in 1.5.x:

Description

Dear lighttpd team —

I have detected a SIGABRT during handling a malicious GET request with option url-path-2f-decode from server.http-parseopts enabled.

Version: lighttpd-1.4.53

How to reproduce:

$ ./configure --prefix=/tmp/lighttpd
$ mkdir -p /tmp/lighttpd/lib/
$ make
$ cp src/.libs/* /tmp/lighttpd/lib/
$ ./src/lighttpd -f <attached lighttpd.conf> -D

The server is started on localhost:8090

$ nc 127.0.0.1 8090 < crash.light

Aborted (core dumped)

Stacktrace:

STACK:
 <0x00007ffff7baf895> [[UNKNOWN]():0 at /usr/lib64/libc-2.28.so]
 <0x0000000000567f32> [log_failed_assert():1027 at /home/stze/Downloads/lighttpd-1.4.53/src/lighttpd]
 <0x0000000000568957> [buffer_realloc():83 at /home/stze/Downloads/lighttpd-1.4.53/src/lighttpd]
 <0x000000000056856b> [buffer_string_prepare_copy():102 at /home/stze/Downloads/lighttpd-1.4.53/src/lighttpd]
 <0x0000000000568daf> [buffer_copy_string_len():166 at /home/stze/Downloads/lighttpd-1.4.53/src/lighttpd]
 <0x000000000056f3f8> [burl_normalize_path():300 at /home/stze/Downloads/lighttpd-1.4.53/src/lighttpd]
 <0x000000000056dd5a> [burl_normalize():349 at /home/stze/Downloads/lighttpd-1.4.53/src/lighttpd]
 <0x000000000053e1b4> [http_response_prepare():342 at /home/stze/Downloads/lighttpd-1.4.53/src/lighttpd]
 <0x0000000000544bb2> [connection_state_machine():1157 at /home/stze/Downloads/lighttpd-1.4.53/src/lighttpd]
 <0x000000000054e550> [network_server_handle_fdevent():64 at /home/stze/Downloads/lighttpd-1.4.53/src/lighttpd]
 <0x00000000005370d5> [server_main():2031 at /home/stze/Downloads/lighttpd-1.4.53/src/lighttpd]
 <0x0000000000530c63> [HonggfuzzNetDriver_main():2102 at /home/stze/Downloads/lighttpd-1.4.53/src/lighttpd]
 <0x00000000005d4407> [netDriver_mainProgram():0 at /home/stze/Downloads/lighttpd-1.4.53/src/lighttpd]
 <0x00007ffff7f0c58e> [[UNKNOWN]():0 at /usr/lib64/libpthread-2.28.so]
 <0x00007ffff7c8a683> [[UNKNOWN]():0 at /usr/lib64/libc-2.28.so]
=====================================================================

gdb:

(gdb) bt
#0  0x00007f0f2220e57f in raise () from /lib64/libc.so.6
#1  0x00007f0f221f8895 in abort () from /lib64/libc.so.6
#2  0x0000000000416d81 in log_failed_assert (filename=<optimized out>, line=<optimized out>, msg=<optimized out>) at buffer.c:1027
#3  0x00000000004171e5 in buffer_realloc (b=<optimized out>, len=0) at buffer.c:81
#4  0x0000000000417346 in buffer_string_prepare_copy (b=<optimized out>, size=<optimized out>) at buffer.c:102
#5  buffer_copy_string_len (b=0x1deb920, s=0x1e2c701 "601", s_len=18446744073709551613) at buffer.c:164
#6  0x000000000040cbaf in http_response_prepare (srv=0x1dd9260, con=0x1deb4e0) at response.c:387
#7  0x000000000040e541 in connection_state_machine (srv=0x1dd9260, con=0x1deb4e0) at connections.c:1157
#8  0x000000000040b905 in server_main (srv=0x1dd9260, argc=<optimized out>, argv=<optimized out>) at server.c:2044
#9  0x0000000000408ed9 in main (argc=4, argv=0x7fffa2c75b38) at server.c:2102

Please let me know what additional information I can provide to successfully reproduce the issue.

Cheers

-Stephan Zeisberg
lighttpd.conf (2.02 KB) lighttpd.conf stze, 2019-04-09 14:01
crash.light (250 Bytes) crash.light stze, 2019-04-09 14:01
fix-2f-to-slash-crash.patch (471 Bytes) fix-2f-to-slash-crash.patch stbuehler, 2019-04-09 18:49

Associated revisions

Revision 32120d5b (diff)
Added by gstrauss 3 months ago

[core] fix abort in http-parseopts (fixes #2945)

fix abort in server.http-parseopts with url-path-2f-decode enabled

(thx stze)

x-ref:
"Security - SIGABRT during GET request handling with url-path-2f-decode enabled"
https://redmine.lighttpd.net/issues/2945

History

#1

Updated by stze 3 months ago

One more information. The issue looks like it's an int overflow in buffer_copy_string_len:

buffer_copy_string_len(con->uri.query, qstr + 1, rlen - plen - 1); <-- overflow

in the provided crash example rlen = 206 and plen = 208. The subtraction of both values results in an overflow.

#2

Updated by stbuehler 3 months ago

Nice catch. Simple reproducer:

curl http://0.0.0.0:8090/%2F?
#3

Updated by gstrauss 3 months ago

  • Category set to core
  • Status changed from New to Patch Pending
  • Target version changed from 1.4.x to 1.4.54

Thanks for the analysis. We've reproduced the issue and I hope to push the tested patch this coming weekend, along with some additional test cases.

#4

Updated by gstrauss 3 months ago

  • Status changed from Patch Pending to Fixed
  • % Done changed from 0 to 100
#5

Updated by stze 3 months ago

tracked as CVE-2019-11072

#6

Updated by gstrauss 3 months ago

Please note that url-path-2f-decode => "enable" is not yet default behavior in lighttpd

#7

Updated by gstrauss 3 months ago

stze: please correct the CVE. "Base Score: 9.8 CRITICAL" is entirely inappropriate for a feature that is both optional and must be explicitly enabled -- it is not enabled by default.

#8

Updated by stze 3 months ago

@gstrauss. The score is set by Mitre, not by me. I just issued the cve request and also mentioned that it is only exploitable with url-path-2f-decode enabled.

#9

Updated by gstrauss 2 months ago

The feature which can be abused to cause the crash is a new feature in lighttpd 1.4.50, and is not enabled by default. It must be explicitly configured in the config file (e.g. lighttpd.conf) with:
server.http-parseopts = ( "url-path-2f-decode" => "enable" )
and can be disabled in the config file (or commented out) with:
server.http-parseopts = ( "url-path-2f-decode" => "disable" )
losing only the functionality of that feature.

Certain input will trigger an abort() in lighttpd when that feature is enabled. However, unlike the original text in the CVE, there is no unspecified impact. The impact is fully specified.

lighttpd detects the underflow or realloc() will fail (in both 32-bit and 64-bit executables), also detected in lighttpd. Either triggers an explicit abort() by lighttpd. This is not exploitable beyond triggering the explicit abort() with subsequent application exit.

Also available in: Atom