SonicWall Out Of Bounds Write DoS

We discussed this vulnerability during Episode 204 on 11 April 2023

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.