nemasu/asmttpd

Multiple crashes on long request paths

Closed this issue · 2 comments

The server crashes if a request of more than 0xFF bytes length is issued. I've identified three independent bugs causing such problems. They might be exploitable to execute arbitrary code.


First, RAX holds the length of the request path and is not explicitly zeroed out before the worker_thread_append_directory_path loop. Since LODSB only overwrites AL, the RAX=0 condition is never met and the loop will never terminate the request path is longer than 0xFF bytes and therefore a bit of AH is set.

Zeroing out RAX before worker_thread_append_directory_path (e.g. xor rax,rax) fixes this issue.

Test case: $ curl -v http://192.168.0.21/m$(perl -e'print "/"x300' )


Second, an off-by-two bug when leads to a crash if the request is more than 8192 bytes long. The sys_recv call fills the buffer with 8192 bytes in this case, and returns 8192 in RAX. However, RAX is then copied to r11, incremented and used as an array index to write the 0x00 byte to (mov BYTE [rdi], 0x00). This will overwrite buffer[8193], while the last allocated buffer byte was buffer[8191].

Test case: $ curl -v http://192.168.0.21/m$(perl -e'print "/"x9999' )


Third, the remaining space of the receive buffer is reused to build the file system path from the request path without any boundary checking. This leads to an out-of-boundary write and possible heap corruption if the space remaining in the receive buffer is less than the length of the request path (i.e. if the request path is longer than ~4096 bytes) but the request as a whole still fits into the receive buffer (so it ends with \r\n\r\n and is still considered a valid request).

Test case: $ curl -v http://192.168.0.21/m$(perl -e'print "/"x4242' )

Awesome, thanks. I knew there would be problems in the corner cases with that buffer. I used to reserve part of it, but it got changed in a recent commit of mine.

Fixed in 0.09. Thanks again for your help.