SonicWall Out Of Bounds Write DoS
A fun bug, likely stemming from misunderstanding the return value from an snprintf
call. Unfortunately (for us, good for security) only seems to be useful for a denial of service attack.
The httpServer
function has a few cases where it seems to work as a sort of reverse proxy, reading in part of the request and crafting a new request that it’ll presumable send on. This happens when a request path becimes with /stats/
or /Security_Services/
.
In these cases, it has a 1024 byte buffer, calls snprintf
to write the HTTP verb (method) and request path to the buffer. It takes note of the return value and subtracts it from 1024 to track how many more bytes it can still write to the buffer. Then calls snprintf
again to write the HTTP version string. This may have worked when using sprintf
and sized format specifiers like %1024s
because sprintf
returns the number of bytes written to the buffer. However, snprintf
is a bit more tricky, it’ll return the number of bytes written assuming it had space to write everything. So if it didn’t have space, it still returns the number of bytes it would have written. This might seem a bit weird but using snprintf
with a 0
byte buffer is a common trick to find out how much space you need to allocate for a dynamic string.
Because snprintf
isn’t necessarily returning how many bytes were written it can actually return a value larger than the given limit of the buffer, so after the first snprintf
call when it adjusts the reamining buffer size, by subtracting what was written, that value can wrap negative resulting in the second snprintf
call being calls with overly permissive bounds and an attacker can write well out of bounds on the stack. With canaries in play, and no other interesting data it seems most likely that this can only cause a crash.