PrBoom-plus is a Doom source port based on PrBoom (which itself is based on other projects). It supports Windows, Mac, Linux and BSD systems. As I’m a Doom fan by myself I decided to get PrBoom-plus and analyze it from security perspective.
Compilation with ASAN
I started with downloading the project from repository and preparing for compilation with ASAN.
According to INSTALL file I installed required packages.
Also, I added useful compilator flags, because it appeared that CFLAGS environment variable placed additional parameters in invalid order, making them useless.
After such preparation I was able to compile the project with ASAN.
Game data
After compilation, there was the last step required before running the game. PrBoom-Plus is just an engine, so it requires game data to run. I was mostly interested in multiplayer part, so I chose FreeDM, the multiplayer part of Freedoom project.
First run and crash
When everything was ready, it was possible to run the server and the client.
The first crash occured immediately, just by running the client.
Analyzing first crash
The client crashes on reading outisde a buffer in ChecksumPacket function in src/SDL/i_network.c:221.
It seemed that len variable has greater values than size of p buffer. This function was called from I_GetPacket in src/SDL/i_network.c:243.
Here the problem starts to become visible. Value from udp_packet->len is assigned to a len variable. Then, there’s a check (line 234) to ensure les is not greater than buflen (buffer’s size). If it is, les is reduced to value of buflen. Invocation of memcpy properly uses len variable, so no data will be written outside the buffer. However, invocation of ChecksumPacket uses udp_packet->len which may be greater than buffer’s size, finally leading to reading outside it.
To fix this bug, I passed len variable, the same way as it is done with memcpy.
After recompilation, the game started to work (the game requires two players to start, the client’s command should be ran twice)
Fuzzing
I wanted to fuzz network part of the project. The idea was very simple - collect some network data samples, modify and send. Implementation was even more simplier and naive. I began with collecting data. I ran Wireshark, played the game for a while (2 player game by myself, it was quite strange) and saved the traffic. Then downloaded and built radamsa and installed scapy.
Scapy script responsible for parsing data, modifying with radamsa (I know it’s inefficient) and resend. To fuzz the client instead of the server, UDP port should be changed from 5030 to 1024. The first line in s function calculates a checksum which validated after being received.
Note: for some reason packets sent between the client and the server from the same machine didn’t reach their destination. A workaround was to clone my virtual machine and run fuzzing from it.
Crashes
After a while two crashes were found, the first one in the server, and the second one in the client. However, they are related and share similar bug.
Server crash 1
Minimal payload to crash \xb6\x05\x01\x01\x56\x33\x27\xff\x00.
results in:
The program tried to write 10991 bytes to a buffer with 10000 bytes on a heap in I_SendPacketTo in src/SDL/i_network.c:261.
From this I assummed that len variable was greater than length of udp_packet->data, so I started digging.
UDP packet has fixed size of 10000 bytes. A packet from which data was copied is allocated in main function in src/d_server.c:688.
tics variable was the only variable partially controlled from network input, so I followed how it was set.
remoteticto is set here:
This array is signed int type,
but a packet received over network is parsed to packet_header_t structure with unsigned tic (0xff273356 from the payload). When tic is assigned to the array (line 565), integer overflow occurs and it becomes a negative value (-14208170). In the result, in line 684, this whole value is zeroed. lowtic is the only variable on which tics depends (line 685).
lowtic is taken from remoteticfrom which grows itself as the game is started and players connected. In practice waiting for less than 20 seconds was enough to get lowtic greater than 525, which resulted in the allocated buffer bigger than 10000 bytes and finally in heap buffer overflow.
Client crash 1
Minimal payload to crash: \xb4\x05\x00\x00\x56\x33\x27\xff
and the result:
A function I_SendPacket in src/SDL/i_network.c:254 copies more bytes than allocated fixed 10000 bytes in UDP packet.
I looked how size_t len is calculated in src/d_client.c and this problem looked similar to the previous one.
remotesend is a signed integer, but tic in packet is unsigned, so integer overflow occurs and 0xff273356 from the payload becomes a negative value. In line 353 remotesend is zeroed, so sendtics depends only on maketic. This variable grows itself as the game is on, and when it reaches 1249 (in practice it was less than a minute) the allocated buffer is bigger than fixed 10000 bytes and heap buffer overflow occurs.
Summary
The first crash was found just after starting the game, the next two after very quick and naive fuzzing. I don’t consider this topic as closed, but I reported my findings and I’m moving to looking for another vulnerabilities using various approaches.
According to art. 13 of the General Regulation on the Protection of Personal Data of 27 April 2016 (Official Journal EU L 119 of 04.05.2016) I inform that:
Data Administrator: The administrator of your personal data is Logicaltrust sp. z o.o. sp. k., with its registered office at ul. Stanisławowska 47, 54-611 Wrocław, Tax Identification Number (NIP): 8952177980, National Business Registry Number (REGON): 369271084, National Court Register Number (KRS): 0000713515.
Contact with the Data Administrator: You can contact the data administrator via email at: ado@logicaltrust.net or by traditional mail by sending a letter to the administrator's registered office address.
Purpose and Legal Basis for Processing Personal Data: Your personal data will be processed by the data administrator for the purpose of responding to your inquiries, executing requested contact, taking actions prior to entering into a contract, performing the contract, establishing business relationships, presenting offers upon potential client's request (based on Art. 6(1)(a), (b), and (f) of the General Data Protection Regulation).
Data Processing Period: Your personal data will be processed for the time necessary to clarify your matter and provide a comprehensive response. They will also be processed for the duration of cooperation and the contract (in this case, the data is processed as client data). In the event of non-cooperation, the data will be promptly deleted unless there is a need for further retention for the purpose of defense and protection against claims. In cases where the processing of personal data is based on voluntarily given consent according to Art. 6(1)(a) of the General Data Protection Regulation, you have the right to withdraw your consent at any time. The withdrawal of consent does not affect the lawfulness of processing based on consent before its withdrawal, in accordance with the applicable law.
Scope of Processed Data: The scope of processed data includes: first name, last name, email, and phone number.
Recipients of Personal Data: In specific situations, your personal data may be disclosed, for example, to fulfill a legal obligation or to exercise legally justified interests pursued by the data administrator or by a third party. The categories of recipients to whom the data administrator may disclose your personal data are entities or authorities authorized by law and service providers processing personal data on behalf of the data administrator based on data processing agreements (e.g., hosting company).
Data Transfers: Your personal data will not be transferred outside the European Economic Area.
Rights and Entitlements: You have the right to request access to your personal data, their correction, deletion, or processing limitations, as well as the right to object to data processing. You also have the right to file a complaint with the President of the Personal Data Protection Office (ul. Stawki 2, 00-193 Warsaw) if you believe that the processing of personal data violates data protection regulations.
Additional Information: Providing data is voluntary, but failure to provide data necessary for correspondence may hinder the execution and maintenance of contact.
Cookie policy
1. About cookies - Cookies are small data files, especially text files, which are stored by a server on your computer. With these files, your device will be recognized and, in consequence, the way a given website is presented will be adjusted to your personal preferences. Cookies usually contain the name of the website from which they originate, information on how long they have been stored on the device and a unique number.
2. Which type of cookies do we use - Session cookies – temporary files which are stored on your device until you log out from a given website or close the Internet browser. Persistent cookies – permanent files that remain on your device for a fixed period (specified in the parameters of the file) or until they are deleted manually. Third-party cookies – files that adjust the way a given website is presented to your personal preferences.
3. Why do we use cookies? - Cookies are used for the purpose of statistics, marketing and in order to adjust the contents of websites to the user's personal preferences. Cookies store information about geolocation, the visitor's language and random data about session identifiers. With the collected data, we are able to understand how exactly the visitor uses websites and, consequently, to improve their structure and content. The information received helps us to prepare statistics related to the number of new and regular users as well as enables us to analyze which pages are visited.
4. How to use and how to disable cookies - You can change the settings of your Internet browser at any time, so that it would block cookies or inform you when they are being sent. However, please note that if you do not accept the cookie policy, you may encounter some problems while using the website. The software used for searching websites accepts the cookies by default. The settings of an Internet browser can be changed, so that it would block cookies or inform the user each time when cookies are being sent onto his/her device. For more information on how to disable automatic saving of cookies, please check the settings of your Internet browser (the software used for searching Internet websites).