Bug #3064


Server Aborted due to Malicious Data sent to lighty.stat

Added by axe34 about 3 years ago. Updated about 3 years ago.

Target version:


My configuration file is as follows.

server.modules += ("mod_magnet","mod_accesslog")
server.port = 3000
server.document-root = "/var/www/" 
etag.use-inode = "disable" 
etag.use-mtime = "disable" 
etag.use-size = "disable" 
static-file.etags = "disable" 
mimetype.assign = (
  ".html" => "text/html", 
magnet.attract-physical-path-to = ( "/home/***/magnet.lua"  )

Here is my lua script.


My script basically takes input from the uri.query and passes it to lighty.stat.

If the parameter is empty, it will cause the server to abort.
The abort is a security mechanism of lighttpd.

Actions #1

Updated by axe34 about 3 years ago

I forgot to add the stack trace my bad.

stat_cache.c.1257: assertion failed: 0 != len

Thread 1 "lighttpd" received signal SIGABRT, Aborted.
__GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
50      ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) bt
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#1  0x00007ffff7d05859 in __GI_abort () at abort.c:79
#2  0x0000000000266487 in log_failed_assert (filename=<optimized out>, line=<optimized out>, msg=<optimized out>) at buffer.c:1016
#3  0x000000000029e2df in stat_cache_get_entry (name=<optimized out>) at stat_cache.c:1257
#4  0x00007ffff7c513d6 in magnet_stat (L=0x362ee8) at mod_magnet.c:293
#5  0x00007ffff7c1a4d5 in ?? () from /lib/x86_64-linux-gnu/
#6  0x00007ffff7c27225 in ?? () from /lib/x86_64-linux-gnu/
#7  0x00007ffff7c1a8c8 in ?? () from /lib/x86_64-linux-gnu/
#8  0x00007ffff7c1a8f5 in ?? () from /lib/x86_64-linux-gnu/
#9  0x00007ffff7c19cf7 in ?? () from /lib/x86_64-linux-gnu/
#10 0x00007ffff7c1ab9f in ?? () from /lib/x86_64-linux-gnu/
#11 0x00007ffff7c1643e in lua_pcallk () from /lib/x86_64-linux-gnu/
#12 0x00007ffff7c4fa60 in magnet_attract (r=0x338840, p=0x32d570, name=<optimized out>) at mod_magnet.c:997
#13 0x00007ffff7c4f347 in magnet_attract_array (r=<optimized out>, p=<optimized out>, stage=<optimized out>) at mod_magnet.c:1099
#14 0x0000000000231a2b in http_response_handler (r=0x338840) at plugin.c:276
#15 0x000000000023a6b5 in connection_state_machine_loop (r=0x338840, con=0x338840) at connections.c:1097
#16 0x000000000023a1ea in connection_state_machine_h1 (r=0x338840, con=0x338840) at connections.c:1416
#17 0x000000000024d505 in network_server_handle_fdevent (context=0x32d940, revents=<optimized out>) at connections.c:1434
#18 0x00000000002aa6a4 in fdevent_linux_sysepoll_poll (ev=0x32e470, timeout_ms=<optimized out>) at fdevent_linux_sysepoll.c:43
#19 0x0000000000285ca1 in fdevent_poll (ev=0x32e470, timeout_ms=-28304) at fdevent.c:436
#20 0x000000000022ad27 in server_main_loop (srv=0x3131b0) at server.c:1902
#21 0x000000000022710f in main (argc=6, argv=<optimized out>) at server.c:2037

Actions #2

Updated by gstrauss about 3 years ago

My script basically takes input from the uri.query and passes it to lighty.stat

If you are running lua code inside the lighttpd server, then you can do anything and everything that lua allows you to do, as the same user, running in the same process as the lighttpd web server. You can read all the files that the lighttpd server can read and can shell out and can execute arbitrary commands, including kill.

If you are passing user-supplied data without validating it, then you have failed to validate user-supplied data.

If you should not have admin privileges over the lighttpd server, then you should not have privileges to run lua code inside the lighttpd server.

Actions #3

Updated by axe34 about 3 years ago

Ok makes sense

Actions #4

Updated by gstrauss about 3 years ago

I do appreciate that you're looking for ways to break lighttpd, and, within reason, I will try to provide an explanation and may add patches to lighttpd to more gracefully handle some of the errors or bugs.

(still to-be-tested patch follows:)

--- a/src/mod_magnet.c
+++ b/src/mod_magnet.c
@@ -290,7 +290,9 @@ static int magnet_print(lua_State *L) {

 static int magnet_stat(lua_State *L) {
        buffer * const sb = magnet_checkbuffer(L, 1);
-       stat_cache_entry * const sce = stat_cache_get_entry(sb);
+       stat_cache_entry * const sce = (!buffer_string_is_empty(sb))
+         ? stat_cache_get_entry(sb)
+         : NULL;
        if (NULL == sce) {

Actions #5

Updated by gstrauss about 3 years ago

  • Status changed from New to Patch Pending
  • Target version changed from 1.4.x to 1.4.60
Actions #6

Updated by gstrauss about 3 years ago

  • Status changed from Patch Pending to Fixed

Also available in: Atom