You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
After executing my fuzz tests I discovered a remote use-after-free vulnerability in static inline size_t buffer_avail(const buffer_t *pb) at buffer.h, line 25:
Any project that utilizes lotos (including the existing forks of this repo) are potentially vulnerable. Depending on the implementation, this can lead to undefined behavior, denial of service, or authentication bypass.
Makefile Modifications
The following modifications were made to the Makefile to compile lotos with address sanitizer and debug symbols. The purpose of this is to track and verify the location of the use-after-free vulnerability:
CFLAGS=-std=c99 -Wall -O3 -DNDEBUG -DUSE_MEM_POOL=1 -fsanitize=address -g
OPTFLAGS=
OBJS=misc.o ssstr.o dict.o lotos_epoll.o buffer.o request.o response.o \
connection.o http_parser.o server.o mem_pool.o main.o
lotos : $(OBJS)
$(CC) $(CFLAGS) $^ -o $@ $(OPTFLAGS)
test :
make -C ./test
make test -C ./test
format :
find . -iname '*.[ch]' -exec clang-format -i -style="{ColumnLimit: 80}" {} +
clean :
rm -f *.o lotos
.PHONY : test clean format
Compiling Lotos
$ cd lotos/src/
$ make && make test
Proof of Concept Python3 Script
Save the following script to a file named poc.py. The script will send an HTTP request with a malformed URI to lotos and wait for a response. More specifically, the code will send an HTTP request with a URI containing 20,000 bytes:
The following output was produced by address sanitizer:
==415636==ERROR: AddressSanitizer: heap-use-after-free on address 0x625000002904 at pc 0x5585539a14ec bp 0x7ffc148a9370 sp 0x7ffc148a9368
READ of size 4 at 0x625000002904 thread T0
#0 0x5585539a14eb in buffer_avail /home/kali/projects/fuzzing/lotos/src/buffer.h:25
#1 0x5585539a14eb in buffer_cat /home/kali/projects/fuzzing/lotos/src/buffer.c:44
#2 0x5585539a1935 in request_recv /home/kali/projects/fuzzing/lotos/src/request.c:137
#3 0x5585539a34f8 in request_handle /home/kali/projects/fuzzing/lotos/src/request.c:144
#4 0x55855399fc4a in main /home/kali/projects/fuzzing/lotos/src/main.c:81
#5 0x7fc8c68456c9 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
#6 0x7fc8c6845784 in __libc_start_main_impl ../csu/libc-start.c:360
#7 0x55855399fe80 in _start (/home/kali/projects/fuzzing/lotos/src/lotos+0x6e80) (BuildId: f69cadb3b591a9b1911fbc4bf465035606fb00ae)
0x625000002904 is located 4 bytes inside of 8201-byte region [0x625000002900,0x625000004909)
freed by thread T0 here:
#0 0x7fc8c6ad74b5 in __interceptor_realloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:85
#1 0x5585539a13f1 in buffer_cat /home/kali/projects/fuzzing/lotos/src/buffer.c:60
previously allocated by thread T0 here:
#0 0x7fc8c6ad85bf in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69
#1 0x5585539a11bd in buffer_new /home/kali/projects/fuzzing/lotos/src/buffer.c:10
#2 0x5585539a11bd in buffer_init /home/kali/projects/fuzzing/lotos/src/buffer.c:7
SUMMARY: AddressSanitizer: heap-use-after-free /home/kali/projects/fuzzing/lotos/src/buffer.h:25 in buffer_avail
Shadow bytes around the buggy address:
0x625000002680: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x625000002700: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x625000002780: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x625000002800: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x625000002880: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x625000002900:[fd]fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x625000002980: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x625000002a00: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x625000002a80: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x625000002b00: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x625000002b80: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==415636==ABORTING
The error occurs in the buffer_avail function, which is called from buffer_cat in the buffer.c file. The problematic access occurs after a call to realloc in buffer_cat:
When realloc is called, it may move the memory block to a new location if the new size cannot be accommodated in the existing space. This means the pointer to the buffer (buffer_t *pb) could become invalid if realloc moves the memory.
After reallocating, any existing pointers to the old memory location become invalid. If you try to use the old pointer (pb) without updating it to the new memory location returned by realloc it leads to undefined behavior, which is what AddressSanitizer is catching.
Mitigation
There are many moving pieces in this repo, but the following code added to request.c can mitigate this vulnerability. Ultimately to maintain the current functionality and prevent the use-after-free vulnerability, a check is added to line 130 in request.c so all requests greater than 5000 bytes are dropped:
Old Code in request.c, line 130:
if (len == ERROR) {
Updated Code in request.c, line 130:
if (len == ERROR || len>5000) {
The length of 5000 can be modified to meet your specific needs. Keep in mind, the use-after-free occurs at roughly 8154 bytes in the URI.
Hi!
After executing my fuzz tests I discovered a remote use-after-free vulnerability in static inline size_t buffer_avail(const buffer_t *pb) at buffer.h, line 25:
lotos/src/buffer.h
Line 25 in 3eb36cc
Any project that utilizes lotos (including the existing forks of this repo) are potentially vulnerable. Depending on the implementation, this can lead to undefined behavior, denial of service, or authentication bypass.
Makefile Modifications
The following modifications were made to the Makefile to compile lotos with address sanitizer and debug symbols. The purpose of this is to track and verify the location of the use-after-free vulnerability:
Compiling Lotos
Proof of Concept Python3 Script
Save the following script to a file named poc.py. The script will send an HTTP request with a malformed URI to lotos and wait for a response. More specifically, the code will send an HTTP request with a URI containing 20,000 bytes:
Starting Lotos
Executing our Python3 Script
Address Sanitizer Output
The following output was produced by address sanitizer:
The error occurs in the buffer_avail function, which is called from buffer_cat in the buffer.c file. The problematic access occurs after a call to realloc in buffer_cat:
lotos/src/buffer.c
Lines 51 to 60 in 3eb36cc
When realloc is called, it may move the memory block to a new location if the new size cannot be accommodated in the existing space. This means the pointer to the buffer (buffer_t *pb) could become invalid if realloc moves the memory.
After reallocating, any existing pointers to the old memory location become invalid. If you try to use the old pointer (pb) without updating it to the new memory location returned by realloc it leads to undefined behavior, which is what AddressSanitizer is catching.
Mitigation
There are many moving pieces in this repo, but the following code added to request.c can mitigate this vulnerability. Ultimately to maintain the current functionality and prevent the use-after-free vulnerability, a check is added to line 130 in request.c so all requests greater than 5000 bytes are dropped:
Old Code in request.c, line 130:
Updated Code in request.c, line 130:
The length of 5000 can be modified to meet your specific needs. Keep in mind, the use-after-free occurs at roughly 8154 bytes in the URI.
References
The text was updated successfully, but these errors were encountered: