MASARYK U N I V E R S I T Y FACULTY O F INFORMATICS Data Loss Prevention in Linux Workstation Environment Master's Thesis BC. ADAM POVAŽAN EC Brno, Fall 2022 MAS ARY K U N I V E R S I T Y FACULTY O F INFORMATICS Data Loss Prevention in Linux Workstation Environment Master's Thesis BC. ADAM POVAŽAN EC Advisor: RNDr. Lukáš Daubner Department of Computer Systems and Communications Brno, Fall 2022 Declaration Hereby I declare that this paper is my original authorial work, which I have worked out on my own. A l l sources, references, and literature used or excerpted during elaboration of this work are properly cited and listed in complete reference to the due source. Be. Adam Považanec Advisor: RNDr. Lukáš Daubner iii Acknowledgements I want to express my sincere gratitude to my thesis supervisor RNDr. Lukáš Daubner for his guidance, useful advice and invaluable feedback during the time I worked on this thesis. I would also like to thank Mikuláš Patočka and Ing. Ján Richter for their consultations on the Linux kernel. Finally, I would like to thank my family, friends, colleagues and everyone else who supported me during the course of my master's studies. iv Abstract Endpoint data loss prevention (DLP) software monitors and protects data stored on the endpoint against leakage. This thesis analyses the possibility of implementing endpoint D L P in a Linux environment. Namely, the analysis focuses on file system operations and external USB devices audit and control. Based on the analysis, suitable technologies for implementing D L P are selected, and a prototype of a DLP system for Linux is developed. The prototype serves as a proofof-concept demonstrating the viability of the selected methods. The architecture and implementation of the resulting prototype are thoroughly described to showcase a general approach to implementing endpoint DLP. Finally, functionality and performance tests of the prototype are conducted and evaluated. Keywords Linux, Ubuntu, Data Loss Prevention, DLP, kernel module, ftrace, udev, Safetica v Contents Introduction 1 1 Data Loss Prevention 3 1.1 DLP and States of Data 3 1.1.1 Data in Use 3 1.1.2 Data in Motion 4 1.1.3 Data at Rest 4 1.2 Endpoint DLP Channels 5 1.3 DLP Policies 6 1.4 DLP Deployment Architecture 7 1.4.1 Management Server 7 1.4.2 Endpoint Agent 7 1.4.3 Network Agent 8 1.4.4 Cloud Agent 9 1.5 Overview of Existing Solutions 9 1.5.1 CoSoSys Endpoint Protector 10 1.5.2 Digital Guardian 11 2 Audit and Control of the File System Operations 13 2.1 File system monitoring and interception API 13 2.1.1 Evaluation 16 2.2 Linux Security Modules 16 2.2.1 Evaluation 18 2.3 File System Functions Hooking 19 2.3.1 Standard Library Preloading 19 2.3.2 System Call Table Hijacking 21 2.3.3 Ftrace 21 2.3.4 Evaluation 23 2.4 Selection of Approach for DLP 25 3 Audit and Control of External Devices 27 3.1 Discovering USB Devices and Receiving Events 27 3.1.1 Enumeration and Monitoring API 29 3.2 USB Device Attributes and Authorization 30 3.2.1 Sysfs 30 vi 3.2.2 USB Device Attributes 32 3.2.3 USB Device Authorization 32 3.3 Summary 33 4 DLP System Design and Implementation 35 4.1 Architecture 35 4.1.1 Modules 35 4.1.2 Shared Components 37 4.2 Used Technologies 38 4.3 Data Loss Prevention Module 39 4.3.1 Filtering of File System Operations 39 4.3.2 Path Type Resolution 41 4.3.3 Processing of File System Operations 43 4.3.4 File System Hooking Library 46 4.4 Device Control Module 50 4.4.1 Initialization Stage 50 4.4.2 Monitoring Stage 50 4.4.3 USB Control Library 52 4.5 Policy Provider 54 4.5.1 Policy File Specification 55 4.6 Incident Logger 57 4.6.1 Database Schema 58 5 Testing and Evaluation 61 5.1 Unit Tests 61 5.2 End-to-end Tests 61 5.3 Performance Evaluation 62 5.3.1 File Copy 63 5.3.2 File Move 65 5.3.3 File Delete 67 6 Conclusion and Future Work 69 A Benchmark Data 72 B Test Cases 79 B.l Upload 79 B.2 Instant Messaging 80 vii B.3 File Transfer 8 1 B.4 File Deletion 8 5 B.5 USB Devices 8 6 C Electronic Attachments 8 9 Bibliography 9 0 viii Introduction Data is typically one of the most valuable resources a company has. With more data becoming digitalized, more data is being handled with computers and transferred through e-mails, portable devices or even stored on the cloud. Naturally, the probability of data being transferred to an unauthorized party also grows. Cost of a Data Breach Report from IBM [1] studied 550 organizations from 17 different countries and 17 different industries. It states that 83% of the studied companies have experienced a data breach in the year 2022. Of that, just 17% stated that it was their first one. The average cost of a single data breach was calculated to be 4.35 million USD. This drives private companies, as well as governments, to look for ways to mitigate the risk of data breaches. Data loss prevention (DLP) solutions offer a way to protect critical data and reduce the risk of its leakage. Specifically, endpoint D L P is a type of D L P system with an agent running directly on the endpoint device, such as a workstation. With Windows and macOS dominating the market with a market share of 91% [2], few D L P vendors are offering an endpoint D L P for Linux. However, the market share of Linux workstations has had a steadily increasing trend over the past years. The goal of this thesis is to explore the possibilities of implementing an endpoint DLP solution for the Linux operating system. Namely, approaches for audit and control of file system operations and external USB devices are explored, and their viability for implementing endpoint D L P is evaluated. Consequently, a proof-of-concept D L P system is designed and implemented to demonstrate the viability of selected technologies. The thesis is composed of six chapters. In Chapter 1, the D L P solutions are described in a general setting. The main focus is placed on the deployment architecture, types of D L P agents and security policies. O n top of that, an overview of existing endpoint D L P solutions for Linux is provided. Chapter 2 explores possible ways to audit and control file system operations on the Linux operating system. The viability of each approach is evaluated according to defined criteria. The approach to audit and control external USB devices is 1 INTRODUCTION discussed in Chapter 3. Following that, Chapter 4 presents the D L P system implemented as a proof-of-concept. Its capabilities, limitations, architectural structure and implementation details are discussed in depth. Chapter 5 describes the testing and performance evaluation of the implemented D L P system. The impact of the D L P system on the general OS performance is thoroughly evaluated and discussed. Lastly, Chapter 6 formulates a conclusion and defines the possibility of future work. 2 1 Data Loss Prevention Data loss prevention (DLP) solutions are systems which are intended to detect and possibly prevent attempts to copy or send sensitive, confidential or business-critical data. These attempts can be intentional or unintentional, but mainly by persons who are authorized to access the sensitive information - insider threat [3,4]. They do not directly protect against outsider threats. In general, D L P solutions need to monitor actions performed by the user and look out for two main things - if the attempted action puts the data at risk and if the data is sensitive. Once both components are identified, D L P must remedy the action either by preventing it from happening, logging the incident or alerting the administrators. DLP solutions also often provide auditing capabilities in order to monitor the flow of data in the system. The data can be later analyzed to provide insight into how it is used in the company. Moreover, in case of a security incident, forensic analysis can be performed on the stored data [5,6]. In this chapter, I describe the data states recognized by the D L P and the data transport channels. Following that, I also discuss the DLP security policies, the general architecture of D L P solutions and three main deployment points of D L P software. Finally, I provide an overview of existing endpoint D L P solutions for the Linux operating system. 1.1 DLP and States of Data For data loss prevention, three states of data are generally recognised: data in use, data in motion, and data at rest [3]. Different techniques need to be employed in order to protect data in each state. 1.1.1 Data in Use Data in use is defined as all the data the user actively interacts with on his device - reading, modifying or accessing in any other way [3]. Naturally, this data state is protected by a D L P agent running on the endpoint. The main idea of protecting data in use is to monitor all the 3 l . DATA LOSS PREVENTION Data in Use -Send< ReceiveData in Motion Access S a v e 1 Data at Rest -Send- Receive Figure 1.1: States of the data user interactions with the data and its movement through data transfer channels of the device [5]. The transfer channels are covered in depth in Chapter 1.2. When an attempt to transport data through an output channel is made, it must be immediately detected and inspected. If the attempt violates the security policy, it must be blocked to prevent data leakage. 1.1.2 Data in Motion Data in motion are defined as data flowing through the network [3]. This can include common protocols such as HTTP, FTP, SMB or various email protocols. Usually, D L P agents deployed at the network level monitor the contents of the packets and detect if any sensitive data may be present. If sensitive data is being transmitted to a location, which is not declared safe by the security policy, the agent blocks the transmission. 1.1.3 Data at Rest Data at rest is the data stored on the persistent storage of the endpoint device [3]. Since the data is static and not in use, it is not directly at risk of being leaked. It can be protected against unauthorized access by using means of access control and encryption. Endpoint D L P agents crawl this data in order to discover files containing sensitive content. Discovered sensitive data can be marked as sensitive and processed later without inspecting its content. They 4 l . DATA LOSS PREVENTION can also log information about the location of sensitive data and inform the administrator if they are stored on an unauthorized device [5]. 1.2 Endpoint DLP Channels For endpoints to share data with other devices, so-called data transport channels must be used. Generally, when data leave the workstation, they travel through one of these channels. Data leaks typically happen as the data are leaving the workstation. To mitigate the risk of data leaks, the transport of data through these channels must be managed. Examples of such channels on the endpoint as defined by [7, 3] are: • Removable media (USB drives, CD/DVD, etc.) • Printers, fax machines • Email, Webmail • Upload to web • Network sharing protocols (SMB, FTP, etc.) • Bluetooth • Cloud • Instant Messaging In most cases, data transport channels cannot be disabled completely since the users use them to perform day-to-day operations. DLP systems generally monitor data going through these channels and enforce security policies on them. The data transport channels monitored by the DLP system are called DLP channels [7]. Figure 1.2 visualises the most common D L P channels. Generally, some of the channels are harder to secure, while others can be easier. Channels such as removable media, Bluetooth or printing need to be addressed at the workstation level. On the contrary, other channels, such as network sharing protocols, upload, email or instant messaging, can be secured both on the workstation and at the network level. 5 l . DATA LOSS PREVENTION Network share Figure 1.2: Common workstation D L P channels 1.3 DLP Policies DLP policies are rules which define how data can be shared outside the company. The data owner must analyze what data is to be protected according to company policies [7]. Commonly, the company policies follow some regulatory compliance a company needs to meet. Examples of regulatory compliance can include General Data Protection Regulation1 (GDPR), California Consumer Privacy Act2 (CCPA) or Health Insurance Portability and Accountability Act3 (HIPAA). The DLP policies are then modelled based on the analysis. Policies need to define two main things - what data can be shared outside of the company (content) and how the data can be shared (context). For instance, a policy can define that text files containing 1. https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX70 3A32016R0679 2. https://oag.ca.gov/privacy/ccpa 3. https://www.nhs.gov/hipaa 6 l . DATA LOSS PREVENTION credit card numbers cannot be copied to USB drives. Consequently, the DLP solution enforces the policy by preventing the user from copying such a file to any USB drive. 1.4 DLP Deployment Architecture DLP solution is usually composed of multiple components deployed on different logical layers. Different components cover different security scenarios and protect different states of data. Not every component is essential in order for a D L P solution to function properly; however, its effectiveness and functionality are diminished by any missing part. A typical D L P deployment scheme is visualised in Figure 1.3. 1.4.1 Management Server A management server is a centralized service which manages all deployed DLP agents. Generally, it collects data provided by agents, such as audit logs and information about security incidents [3]. It also distributes settings to agents, such as defined policies. It usually also provides an interface which allows administrators to view all collected information and analyze it. The server can be running on the company's on-premise hardware. It is usually the more expensive solution, as the company needs to keep the hardware up-to-date or provide maintenance and the required infrastructure. However, it gives the company control over all the stored data. The other option, which is nowadays becoming more employed, is deploying the management server to the cloud. 1.4.2 Endpoint Agent A DLP agent deployed on an endpoint is software which runs directly on the endpoint device - most commonly a workstation or a laptop, less commonly, a server or a mobile device. This thesis mainly focuses on this layer of protection - endpoint DLP, namely deployment on the endpoints running Linux-based systems. The D L P agent has two primary responsibilities. Firstly, the agent monitors how the user interacts with the data [5]. Every action is inspected and classified according to policy settings. 7 l . DATA LOSS PREVENTION Company Network Workstation Workstation Workstation NAS Laptop Figure 1.3: Typical D L P deployment scheme If the action violates the security policy, the agent blocks it, effectively preventing potential leakage of data. It also reports the incident to the management server. Secondly, the agent inspects the data stored on the device and, possibly, connected network drives. It tries to discover sensitive files, as defined by D L P policy, mark them and report where they are stored. 1.4.3 Network Agent A D L P agent deployed on a network analyzes the network traffic and, according to defined policies, blocks the action which may result in 8 l . DATA LOSS PREVENTION a data leak by dropping the packets. At this level, data which is being transferred from one point in the network to another one is protected. Network deployed solution only protects data, which flows through the company network. Therefore after a device is disconnected from the company network, it is no longer protected. Another limitation is that data flowing through the network is commonly protected by encryption. Encrypted data cannot be inspected for sensitive content without a decryption key, which limits the D L P solution's ability to protect it. In general, any use of network tunnelling protocols can limit the inspection of packets. 1.4.4 Cloud Agent A cloud access security broker (CASB) is software that acts as an intermediary between users and cloud service providers [8]. D L P solution can implement a CASB in order to act as an agent in the cloud and enforce the organization's security policies. It does not include only cloud storage, but an entire suite of cloud applications, which specific provider (such as Microsoft Office 3654 ) provides, such as email, storage, etc. This way, DLP solutions can protect sensitive data even when it is stored and moving on the cloud and outside of the company's hardware. 1.5 Overview of Existing Solutions To review existing D L P solutions, I focused on the top 25 DLP products, as named by G2's 2022 review of DLP software [9]. Out of these 25 products, I was able to identify 9 products which provide endpoint DLP functionality. The most common operating support was for Windows, followed by macOS. Linux support was quite rare. I was able to identify only two products implementing support for Linux endpoint DLP: CoSoSys Endpoint Protector5 and Digital Guardian6 . In this section, I provide a more detailed description of both mentioned products, which support Linux-based platforms. I focus on the 4. https://www.office.com/ 5. https://www.endpointprotector.com/ 6. https://digitalguardian.com/products/endpoint-dlp 9 l . DATA LOSS PREVENTION functionality, which is deemed as most important in endpoint D L P product by [3]: • Protection of endpoint data transport channels • Content inspection capabilities • Sensitive data discovery • USB drive management • Management server features Note that I was not able to install the D L P products, as they are commercial products focused on the enterprise. Therefore I could not have evaluated them hands-on. Most of the information in this section is based on publicly available materials and my interpretation of them. Some of the information may be, therefore, inaccurate. Moreover, I was also unable to determine from the public materials how the inner workings of both products may be implemented. 1.5.1 CoSoSys Endpoint Protector Endpoint Protector is an endpoint DLP product from CoSoSys, which supports all three major platforms - Windows, macOS and Linux. All the information about Endpoint Protector is based on the publicly available user manual [10]. Its main feature is the Content-Aware D L P module. It is able to monitor data transfer channels and enforce D L P policies on them. Namely, supported channels are file transfers through web browsers, email clients, instant messaging, cloud sync clients, USB and network drives, printers and clipboard (a detailed list is available in Section 4.3.2. of the manual). Content inspection is based on dictionaries and regular expressions. Administrators can define custom templates of sensitive content for their business. Predefined templates for different regulations such as GDPR, HIPAA or PCI-DSS are available. Endpoint Protector's module, called eDiscovery, scans and identifies sensitive data at rest on the company's workstations. Administrators can define remediation actions, for example, encryption or deletion of the data stored at unauthorized locations. 10 l . DATA LOSS PREVENTION The Device Control module can monitor and control not only USB drives but also other peripherals such as C D or D V D drives, printers or mobile phones (a complete list is available in Section 3.6.1. of the manual). It is possible to define D L P policies to block the use of blacklisted devices. Devices can be blocked completely (i.e. full lockdown) or selectively based on various information, such as device type, vendor ID, product ID or serial number. Every interaction with the device, for example, connection or removal, is logged. The management server is provided in three different versions on-premise virtual appliance, cloud service or software-as-a-service (SaaS) option. It provides GUI, which allows the administrator to see, filter, visualize and export data collected by endpoint agents. The administrator can also define comprehensive D L P policies there and perform the entire management of the endpoint agent settings. 1.5.2 Digital Guardian Digital Guardian (DG) provides an endpoint DLP product supporting Windows, macOS and Linux platforms. Their other products include a network DLP appliance or cloud protection services. Information in this section is based on publicly available white papers [11,12,13,14]. Digital Guardian endpoint DLP can monitor data sent and attached to emails, moved to USB drives, cloud storage or uploaded to the web. The actions can be logged, blocked or require justification if they violate any D L P policy. For content inspection, fingerprinting technology is used. Predefined rules include templates for the identification of personally identifiable information (PII), personal health information (PHI) and payment card industry (PCI) data. Customized templates can be created to meet regulations such as GDPR or HIPAA. Digital Guardian does not implement management of the USB drives directly. D L P policies can be set up to restrict data movement to USB drives based on their brand, model or serial number. It is also possible to enforce encryption of data on external devices. It is possible to configure data discovery, which scans local and network drives. It can also be extended to integrate with cloud storage. When sensitive data is located, it is tagged, and remedial action can be applied, such as encryption or deletion. 11 l . DATA LOSS PREVENTION The remote server managing the agents is deployed as a cloud service. It allows the administrator to define D L P policies and manage deployed agents. It also provides visualization of logs, alerts and reported incidents across all endpoints. 12 2 Audit and Control of the File System Operations The endpoint D L P agent needs to perform two tasks regarding file system operations - audit and control. Audit of security-related events is a common security control on all systems. It is even required by the information security standard ISO/IEC 27001 [15]. On Linux-based systems, the Linux Audit system (more commonly known as AuditD) is a native service responsible for collecting information about security events. This includes system calls, file access, network access or login attempts. A complete list of security events is available in [16]. On the other hand, control of file operations is not a common task. D L P agent needs to be able to intercept an operation, inspect the context and the content of the file in question and take proper action (i.e. authorize or block the operation). The interception process is visualized in Figure 2.1. In this chapter, I present and discuss five possible approaches to watching and intercepting file system operations. Naturally, interception of the file system is very platform-specific, so the presented approaches are only applicable to the Linux OS. The focus is put on advantages, disadvantages and the technical details of implementation. The main criteria to evaluate are: • Granularity of interceptable file system operations • Available context information about the operation • Invasivity of the method • Technical difficulty of the implementation 2.1 File system monitoring and interception API A n API called fanotify [17], used for monitoring and interception of file system operations, was introduced in Linux kernel version 2.6.37. Its sibling and more widespread API is called inotify [18], which is commonly used for monitoring single file or directory changes. In contrast, fanotify provides the functionality to intercept file system operations and the ability to monitor the whole file system instead 13 2. AUDIT A N D CONTROL OF THE FILE SYSTEM OPERATIONS Process requests file operation DLP check Not OK- Deny request -Not O K - OK _ i _ Perform file operation Figure 2.1: Interception of the file system operations by DLP of only specified paths. It is meant to be used by software, such as anti-viruses, to intercept file access, scan files for malicious content and possibly, prevent access to possibly malicious objects. A n API consumer can register with fanotify to receive events about file system operations. The set of supported events comprises two subsets - notification and permission events. Notification events are only informative, and the recipient cannot prevent them from happening. Supported notification events include file access (i.e. read), open, creation, deletion, move, modification and close. Permission events, on the other hand, can be intercepted, and the recipient decides whether they are authorized to happen or not. The set of permission events is rather small and includes only open and access events. Any other file system operations, such as metadata change or memory mapping, do not generate any events. Function f anotif y _ i n i t (2) returns a virtual file descriptor, which contains a continuous stream of file system events. The stream includes 14 2. AUDIT A N D CONTROL OF THE FILE SYSTEM OPERATIONS only events which fired after the call of the function. Each event in the stream is defined by the following structure: s t r u c t f a n o t i f y _ e v e n t _ m e t a d a t a { __u32 e v e n t _ l e n ; __u8 v e r s ; __u8 r e s e r v e d ; _ _ u l 6 m e t a d a t a _ l e n ; _ _ a l i g n e d _ u 6 4 mask; __s32 f d ; __s32 p i d ; } ; The most important fields for DLP are: • mask - the type of the event • f d - open file descriptor to object being accessed, FAN_N0FD is supplied when no descriptor can be delivered • pid - identifier (PID) of the process which caused the event Each event can contain additional data. If it does, the event structure is followed by one or more additional structures containing the information. It is defined as: s t r u c t f a n o t i f y _ e v e n t _ i n f o _ f i d { s t r u c t f a n o t i f y _ e v e n t _ i n f o _ h e a d e r h d r ; _ _ k e r n e l _ f s i d _ t f s i d ; u n s i g n e d char f i l e _ h a n d l e [0] ; } ; Where the fields contain: • hdr - a generic header containing information about what is contained in the additional record • f s i d - unique identifier of the file system in which the event fired • f ile_handle - unique identifier the object as returned by standard function name to handle at(2) 15 2. AUDIT A N D CONTROL OF THE FILE SYSTEM OPERATIONS 2.1.1 Evaluation As mentioned previously, the main purpose of the fanotify API is to provide on-access scanners (e.g. anti-virus software) with a way to be notified when a file should be scanned and possibly block access to a malicious file. The main advantage of fanotify is its mature interface, which, in contrast to other monitoring APIs, is quite straightforward to use. It is also well-documented, and its manual page contains a few code examples. Another advantage is that the entire monitoring and interception can be implemented from user space without any need for kernel modification, which naturally enhances the product's security. On the other hand, the set of file system operations which can be intercepted is very limited. As of the time of writing of this thesis, only open and access events have permission variants. D L P solution may need a much broader set of interceptable events in order to control the flow of the data. For instance, a file move event may need to be blocked to prevent the user from moving a sensitive file to a cloudsynchronized folder. Another example may be a delete operation, which might be needed to be blocked to prevent the user from deleting sensitive data. Memory mapping events are also not supported. Lastly, there is very limited information associated with an event. For instance, there is no way to inspect flags associated with the file opening, which may carry a lot of information about what a process is trying to do with a file. As for information about the process, only process id (PID) is supplied, which may not be enough for audit logging. It is possible to retrieve more information about the process, having only PID, from proc file system. However, with notification events, which are not blocking the operation, the process performing the operation may have already been terminated, and the PID would be unusable. This imposes an inherent race condition between the delivery of the event and the termination of the process. 2.2 Linux Security Modules Linux Security Modules (LSM) [19] is a framework integrated into the Linux kernel, first introduced in version 2.6. The framework in- 16 2. AUDIT A N D CONTROL OF THE FILE SYSTEM OPERATIONS serts security calls in various places in the kernel. Generally, security calls are inserted before actions, which may affect the security of the operating system. The security call is basically an interception point. The kernel cannot perform the action without the security call resulting in approval. When the action is approved, the kernel normally executes the action in question. Figure 2.2 visualizes the architecture of LSM. Security modules leveraging the L S M framework can perform arbitrary security checks at these interception points. The modules can possibly deny access if the performed action would violate the security policy. L S M can control access to kernel objects such as files, task structures, security credentials or inter-process communication structures [20]. Process requests file operation system call ± inode lookup O K Return error - N o t O K - DAC check O K - N o t O K - LSM framework event > Specific LSM LSM framework <-approve/ deny-- modules<-approve/ deny-- modules O K ± Perform operation Figure 2.2: The architecture of L S M file system security calls For the purposes of file system audit and control, the most interesting part of L S M is the security calls in the file system. The security calls are inserted in places where the kernel would access internal virtual file system (VFS) structures. Namely, the structures include super_block, inode and f i l e [19]. 17 2. AUDIT A N D CONTROL OF THE FILE SYSTEM OPERATIONS The security calls are present in a vast number of actions, including operations over inodes (open, read,...), operations over file descriptors (f cntl, i o c t l , statf s...) and mounting. Each call can inspect the VFS structure on which the relevant action wants to operate. For example, a security call on an open operation can inspect the f i l e structure of the object which is being opened. Additionally, the security calls are executed in the context of the calling process. This means that the context of the calling process can be fully inspected - its PID, executable, thread, effective UID etc. 2.2.1 Evaluation LSM framework may seem like an ideal solution for implementing DLP software since its interface was designed for this particular purpose. In fact, it can be seen that its architecture (Figure 2.2) directly resembles the architecture I defined for D L P interception in Figure 2.1. The main advantage of the LSM approach is its broad set of security calls and very rich amount of information available to inspect. The set of interceptable operations practically contains everything that can happen in the file system. The kernel VFS structure can be inspected in the security call, and therefore, L S M provides access to the full context of the file operation. Moreover, the context of executing process can be inspected as well. On the other hand, the documentation and publicly available information on the L S M is very limited. Most of the information in this chapter was derived from the Linux kernel source code. This fact makes this approach possibly hard to implement, maintain and extend. As a security feature, modules levering L S M Framework must be directly compiled into the kernel source code. They cannot be loaded dynamically in a kernel module. This basically means that for use in any mainstream distribution, they have to be merged into the upstream Linux kernel source tree. The other problem is that it is difficult to use multiple L S M modules alongside each other. This is called L S M stacking [21]. L S M module can be marked with LSM_FLAG_EXCLUSIVE. Only a single module with this flag set can be active at a certain time. A n example of an exclusive module is SELinux [22], which is a very widespread module used 18 2. AUDIT A N D CONTROL OF THE FILE SYSTEM OPERATIONS in almost all distributions. Non-exclusive are only so-called "minor" modules, which mostly implement some hard-coded static checks. 2.3 File System Functions Hooking Processors based on Intel x86 architecture work with four different protection levels (called rings, visualized by Figure 2.3). Ring 0 is the most privileged level, and ring 3 is the least privileged. On Linux systems, the kernel and all loaded Linux kernel modules (LKM) operate in ring 0. They have direct access to all the hardware and important system objects. O n the other hand, all user space applications run in ring 3 and have limited privileges. Direct access to file system objects is only available from the kernel. For user space applications to use the file system, they must ask the kernel to provide access for them. System calls are used to interface with the kernel to require its services. System calls on x86 32-bit Linux can be called by raising software interrupt number 0x80 or on x86 64-bit Linux by using syscall instruction. Most user space processes do not use system calls directly but use high-level wrappers provided by l i b c [23]. This way, they do not need to worry about a specific system call interface on the underlying system. Function hooking is a programming technique in which a function call is intercepted and redirected to another function (called hook), effectively changing the behaviour of the called function [24]. In this section, two methods of hooking system calls and one method of hooking almost any function in the kernel is be presented and discussed. 2.3.1 Standard Library Preloading Normally, l i b c implementation comes as a shared library and all its symbols are resolved before execution of the program using Linux's dynamic linker Id.so [25]. Dynamic linker loads shared libraries in whatever order it needs them. LD_PREL0AD is an environment variable containing a list of additional libraries that the dynamic linker should load before any others. This feature can be used to override functions in other shared ob- 19 2. AUDIT A N D CONTROL OF THE FILE SYSTEM OPERATIONS Figure 2.3: Intel x86 ring architecture jects selectively. As a result, the behaviour of programs can be altered non-invasively - without rewriting their source code. The LD_PRELOAD must be specified for every process specifically. To preload a library system-wide, a file /etc/Id. so .preload exists. The file specifies a list of libraries which should be preloaded for every process. Libraries are loaded before those listed in LDPRELOAD and are non-overridable [25]. To implement interception of the file system operations, a custom shared library can be preloaded for every process. The library would contain custom implementation of file operation system calls such as open(2), unlink(2), etc. This way, every process launched after the modification would use this implementation of the system calls. The custom implementation would be able to inspect the function arguments it was called with. Additionally, it would be able to inspect the process context it is called in. This information would be reported to the D L P agent for evaluation. Following that, if the D L P agent does not authorize the operation, the custom function can fail and not perform any file system change. In the other case, original implementation can be called. 20 2. AUDIT A N D CONTROL OF THE FILE SYSTEM OPERATIONS 2.3.2 System Call Table Hijacking On Linux, every system call has assigned its unique number. A system call table maps each system call number to an address of its handling routine. The most obvious and classic way to hook system calls is by rewriting entries in the system call table. By changing the address of the handling routine, the system can be effectively made to handle hooked system calls by a custom implementation. Kernel stores system call table in a structure called sys_call_table. Since it is not an exported symbol, L K M s need to find its address in kernel memory space to access it. This can be achieved in multiple ways, for example, by using kallsyms_lookup_name, by brute-force search through memory locations where the table could reside or by using kprobes [26]. Another problem is that s y s c a l l t a b l e resides in a read-only part of the memory. A register crO in processors based on x86 architecture holds flag WP. This flag controls if the C P U may write into read-only sections of memory. To disable memory protection, WP must be overwritten. After finding the location of the system call table and disabling the memory protection, the module can overwrite the addresses of selected system call handling routines. For interception of file system operations, handling routines of the system calls handling file operations (open(2), unlink(2), etc.) would be replaced. The custom handling routines could function similarly as described previously in Section 2.3.1. 2.3.3 Ftrace Ftrace is a framework composed of several tracing utilities integrated into the Linux kernel. It can, for instance, display function call graphs, length of function calls or track function call frequencies [27]. It provides the necessary infrastructure to attach hooks at the beginning of almost any kernel symbol to record what is happening outside the user space. It is implemented by inserting a call to a special tracing symbol called f entry () or mcount to the beginning of every function. Since calling an external symbol at the start of every function can be 21 2. AUDIT A N D CONTROL OF THE FILE SYSTEM OPERATIONS very costly an optimization called dynamic f trace [28] is commonly employed. With optimization in place, every call to f entry () or mcount is replaced by NOP instruction if ftrace is disabled. When it is enabled for a specific function, calls are added back to necessary functions. The primary use case for these hooks is the already mentioned function tracing. However, they can also be leveraged to redirect the kernel's flow for other use cases - e. g., live kernel patching or security monitoring. In this section, I describe a way to hook arbitrary kernel symbols using ftrace as described in official Linux kernel documentation [29]. To register a hook, the following structure needs to be defined: s t r u c t f t r a c e _ o p s { f t r a c e _ f u n c _ t f u n c ; u n s i g n e d l o n g f l a g s ; v o i d * p r i v a t e ; }; Parameter f unc is a function pointer specifying the callback, which will be called at the hook point. Field flags specifies if the framework should employ any additional behaviour when installing or calling the hook. Namely, flag FTRACE_OPS_FL_R.ECUR.SION protects the callback from infinite recursive calls to itself. Linux kernel source file include/linux/f trace. h contains an exhaustive list of the possible flags. Pointer to arbitrary data can be stored in private, which can be later accessed from the callback. The callback function is of type: v o i d ( * f t r a c e _ f u n c _ t ) ( u n s i g n e d l o n g i p , u n s i g n e d l o n g p a r e n t _ i p , s t r u c t f t r a c e _ o p s * o p , s t r u c t p t _ r e g s * r e g s ) ; Arguments ip is an instruction pointer to the hooked function. Similarly, p a r e n t i p is an instruction pointer to the function, which called the hooked function. Argument op contains the previously stored private data. The state of registers during the call to the function is stored in regs. 22 2. AUDIT A N D CONTROL OF THE FILE SYSTEM OPERATIONS Functions can be hooked based only on their name. This also allows the hooking of functions which are not exported by the kernel for LKMs. If the hook needs to call the original function, its address must be resolved beforehand and can only be called through it. To enable the hooks, the f t r a c e s e t f i l t e r has to be called to. Following that, calling register_ftrace_f unction registers the defined f traceops structure. The registered callback will start being called at an unspecified time instant during the call of the register function. For completeness, function unregister_ftrace_f unction is used for removing the hooks. It is guaranteed that there will not be any calls of the installed callback after this function is finished executing. The interception of file system operations could be done by hooking system call handling routines, as described in Subsection 2.3.2. Alternatively, any accessing the VFS structures could be intercepted in a similar way. 2.3.4 Evaluation Standard library preloading The standard library preloading is a simple approach which is already implemented in Linux OS. It is thoroughly documented, simple to use and available entirely through user space. Every file system operation provided by the standard library can be intercepted, and their arguments can be inspected. Additionally, the process calling the function can be inspected as well. On the other hand, it has numerous limitations for the analysed use cases. Firstly, it works only with shared libraries. If the program is statically linked with l i b c , functions will not be overridden. Secondly, there is no way to hook functions of already running processes. Lastly, the main limitation of LD PRELOAD and, generally, any user space-level hooking solutions is the fact that they can hook only functions wrapping actual system calls. If the process called system call directly through software interrupt or through any other library implementation, the hook would not be called. This greatly limits the usability of standard library preloading. 23 2. AUDIT A N D CONTROL OF THE FILE SYSTEM OPERATIONS System call table hijacking System call table hijacking has a minimal performance impact. The system call table is updated only once, and there is no extra overhead in calling the custom handler. Another advantage is that there is no specific kernel feature required for this method to work, so it is achievable on nearly any Linux distribution. Every system call handler, which performs a file operation, can be intercepted. The information about the operation is available in the C P U registers, which contain the system call parameters. The handler runs in a process context; therefore, a calling process can also be inspected. The main disadvantage is the technical complexity. Complex procedures are required to locate the system call table and bypass write protection of the read-only memory region. Also, measures need to be taken to ensure the safe replacement of the table entries so no handler is invoked during the modification of the system call table. The entire process happens in kernel space, so if the custom handler is not vulnerability-free, the entire system may become compromised. Ftrace hooking Ftrace is a modern framework with a simple and mature API. Hooking kernel functions requires only creating a single structure and a few API calls. The set of interceptable operations and information is broader than in the system call table hijacking method. It is able to hook not only system call handlers but any other function in the kernel only by specifying its name, which may prove useful in future development. It has a higher overhead than a system call table hijacking, but with dynamicftrace optimization, a lot of overhead is neglected [28]. Another concern may be that ftrace may not be compiled into the kernel and, therefore, disabled. I have experimentally found out that the most popular distributions1 have this feature enabled. From the security point of view, the entire hooking needs to be implemented in the kernel module. This means that extra care needs to be taken to write secure code. A n error in kernel code is more likely to compromise the security and general stability of the machine than an error in user space code. 1. Ubuntu, Fedora, RHEL 24 2. AUDIT A N D CONTROL OF THE FILE SYSTEM OPERATIONS 2.4 Selection of Approach for DLP At first, L S M seemed like an ideal candidate designed for this use case. However, after deeper study, I have found it has many limitations, which make it unusable for DLP. The main reason was the requirement that LSM needs to be compiled into the kernel. This is a huge limitation, as it would require the usage of a custom kernel for the DLP agent to work. Another limitation is the described exclusivity of the modules. If the DLP module would require the usage of any exclusive features, other popular LSMs (such as SELinux) would have to be disabled. Lastly, the documentation is very lacking, making the implementation and extensibility technically challenging. The fanotify API has a very limited set of file system operations which can be intercepted. It also does not supply enough context information about the operation. For example, there is no way to inspect arguments of the file operation, such as flags of the file open. This context information is crucial for DLP implementation as described in Subsection 4.3.3. The standard library hooking in user space has numerous limitations. It can intercept only file system operations performed by the library functions. Directly invoking a system call would evade the interception. Moreover, this approach only works with shared libraries. Statically linked binaries would evade interception as well. Finally, the hooks cannot be installed on already running processes. Hijacking of the system call table is an old practice used mostly by malware and is commonly checked and controlled by anti-virus software. In order to implement it, multiple technical and security challenges must be overcome. Moreover, it is mostly disregarded by the Linux kernel community. Finally, ftrace is the most modern of the three presented hooking approaches. It has extended official documentation [29], several protections in place and a very mature interface. It is able to hook any function in the kernel, which makes it able to intercept an even bigger set of operations than LSM. The operation arguments, as well as information about the requesting process, can be retrieved. After inspecting and evaluating all the mentioned approaches, I have found kernel function hooking using ftrace as the most viable approach for implementing interception of file system operations in 25 2. AUDIT A N D CONTROL OF THE FILE SYSTEM OPERATIONS a D L P system. It matches the defined criteria the most. It provides a broad set of interceptable operations with granularity at the level of kernel functions and complete context information. The only limitation is its technical difficulty, as it requires a kernel module to be written. However, this limitation is partially redeemed by its publicly available documentation and code examples. Specifics of the design decisions and implementation are described in Section 4. 26 3 Audit and Control of External Devices Multiple D L P solutions implement the so-called device control feature (Section 1.5), which allows administrators to audit the usage of external devices within the company. Additionally, specific devices can be blocked from use on the endpoint based on various attributes like the type of device, product ID, serial number etc. In this section, I focus only on storage devices connected through Universal Serial Bus (USB), as nowadays it is the most common type of portable storage device used [30]. In order for this feature to work, the D L P agent needs to perform various tasks regarding USB devices. Namely, it needs to be able to: • Enumerate USB devices connected to the endpoint • Monitor changes of the connected USB devices • Inspect attributes of the USB devices • Block the USB device from use in the operating system I consider this set as the necessary functionality requirements, which the final approach needs to be able to address. I have discovered only one viable approach to audit and control the usage of USB devices on the Linux OS. It uses a conjunction of two subsystems. The first one is the udev subsystem, which fulfils the need to enumerate the connected devices and monitor USB device changes. Following that, sysf s virtual file system provides the required functionality of inspecting their attributes and blocking them from being used in the system. In this chapter, I describe how udev works and how to subscribe to device events. On top of that, I present the sysf s file system, what information it exports about devices and how it can be used to block or remove devices from the system. 3.1 Discovering USB Devices and Receiving Events Linux subsystem called udev is responsible for managing devices. It distributes device events from the kernel throughout the user space. 27 3. AUDIT A N D CONTROL OF EXTERNAL DEVICES USB is inserted physically Ienumerate usb bus kernel Discover new device Create directory in Discover new device sysfs Read and fill device details send uevent udevd Read device details Execute defined rules Notify event subscribers udisksd Mount the USB device storage partition Figure 3.1: Simplified USB device discovery flow in Ubuntu Linux Moreover, it also manages device node permissions and creates symbolic links in \dev directory with meaningful names so that devices can be identified reliably [31]. The system daemon udevd runs entirely in the user space. Section udevd in Figure 3.1 visualizes its part in the USB discovery process. It continuously reads device events (called uevents) directly from the kernel through a dedicated Netlink socket. However, Events from the kernel can come out of order, with cryptic kernel names etc. Due to this fact, they must be processed by the udevd to be easily readable. After processing these events, udevd executes specific user-defined actions, which are specified in so-called rule files. Finally, udevd notifies all user space subscribers about the event. One of the subscribers is usually udisksd, which automatically mounts the USB device storage partition. 28 3- AUDIT A N D CONTROL OF EXTERNAL DEVICES Rule files Rule files contain conditions and actions, which are executed when a device event matching the specified condition of the rule is received. Rule files are files with . rules extension located in the following directories: • /usr/lib/udev/rules.d/ • /usr/local/lib/udev/rules.d/ • /run/udev/rules.d/ • /etc/udev/rules.d/ Rules are typically used to rename a network interface, add symbolic links pointing to the device node, or run an arbitrary script as a consequence of a device event. They could also be used to block the device in exactly the same way as described in Section 3.2. Specific rule syntax and examples of rules are described in [31]. 3.1.1 Enumeration and Monitoring API A library libudev provides an API to enumerate and inspect devices connected to the workstation [32]. It also provides a way to register as a device event subscriber and receive events from udevd after they are processed. It interfaces with udevd, so it functions entirely in the user space. Enumeration To enumerate devices connected to the system, an enumeration object can be created by udev_enumerate_new(3). This function returns a pointer to an enumeration. Various filters (i.e. on device attributes, subsystem, parent device) can be applied to limit the results of the enumeration. These filters can be applied by the family of functions named udev_enumerate_add_match_* (3). Calling a function udev_enumerate_scan_devices (3) with the specified enumeration object applies the filters and scans the system for matching devices. The list of devices can be accessed by udev_enumerate_get_list_entry (3). 29 3- AUDIT A N D CONTROL OF EXTERNAL DEVICES Monitoring To monitor device events such as connect and disconnect, a monitor object can be created by udev_monitor_new_from_netlink(3). The second argument specifies if the monitor should receive events from udevd or uevents directly from the kernel. Filters can be applied by a family of functions udev_monitor_f ilter_add_* ( 3 ) . Calling udev_monitor_enable_receiving(3) applies the filter and activates the monitor object. A file descriptor, which will contain device event data when an event is available, is returned by function udev_monitor_get_f d(3). This file descriptor can be monitored for available data by standard functions select (2) or p o l l (2). When the event data is available, it can be retrieved to udevdevice object by udev_monitor_receive_device(3). 3.2 USB Device Attributes and Authorization Every USB device exposes a number of standard attributes. These attributes can indicate the device's type, manufacturer and product identifiers or its serial number. Naturally, the attributes can be used to identify the USB device. The sysf s file system exports attributes of each of the USB devices connected to the workstation. In this section, I discuss and describe which attributes are exported, with the main focus on attributes which can be used for USB device identification. 3.2.1 Sysfs The sysfs file system [33] is a virtual file system which provides access to inspect kernel data structures. These data structures include information about devices, file systems, kernel modules etc. The sysfs file system is typically automatically mounted by the kernel at /sys. It contains a directory structure with virtual files acting as an interface for the kernel. It contains two kinds of files: • Read-only files, exporting information about kernel objects to the user space • Writable files, allowing change of variables inside the kernel from the user space 30 3. AUDIT A N D CONTROL OF EXTERNAL DEVICES / 1_ sys _devices _bus _usb _dev _ b l o c k _ 8 : 0 _ char Figure 3.2: Example of device hierarchy in the sysfs There is heavy use of symbolic links across the file system to avoid redundancies. After the kernel discovers a new device, it creates a corresponding file hierarchy in /sys/devices/ subdirectory. The created file hierarchy directly represents the hierarchy of struct device structures inside the kernel [33]. The folders are named by the internal names derived by the kernel from the device tree. These names are usually unpredictable and based on the order of discovery [31]. Following that, there are other directories which provide easier access to device structures using symbolic links to the /sys/devices/ subdirectory. For instance, the /sys/bus/ contains one subdirectory for each bus type in the kernel. The subdirectory then contains symbolic links to entries corresponding to devices discovered on this bus. Another example can be the /sys/dev/, which contains two directories block/ and char/. As the names may suggest, these directories contain block and character devices on the system. Inside these subdirectories, symbolic links with names in the form of $Maj orlD: $MinorID are located. Naturally, it provides an easy way to locate device entries by their IDs. 31 3. AUDIT A N D CONTROL OF EXTERNAL DEVICES 3.2.2 USB Device Attributes The sysf s file system creates a virtual read-only file for each attribute of the USB device. These files are located in the directory of the corresponding device. The attributes which I identified as relevant to uniquely identify a USB device are: • bDeviceClass, bDeviceSubClass, bDeviceProtocol -Class code information defined by the USB protocol, which is used to identify the type and functionality of the device. This information is encoded in three bytes named device class, device subclass and device protocol. A complete list is specified by the USB implementers forum [34]. • idVendor, idProduct - 16-bit numbers used to identify the manufacturer and the specific product of the vendor. Both are assigned by the USB implementers forum. • configuration - The file contains the USB device serial number if it is specified. This number can be used in conjunction with vendor I D and product I D to identify the USB device uniquely. • manufacturer - String representation of the manufacturer. • product - String representation of the product. A complete list of exported attributes can be found in [35]. Naturally, the firmware of the USB device can be tampered with, and the attributes could be modified [36]. This way, a malicious user could effectively forge the identifiers of the device. I consider the scenario as out of the scope of this thesis; however, advanced techniques of firmware inspection [37] could be used to remedy this. 3.2.3 USB Device Authorization Linux kernel implements a feature which allows the superuser to control if a USB device can be used in the system [38]. This feature is fully available from user space and can be controlled through sysf s file system. USB device authorization is controlled through a virtual file at /sys/bus/usb/devices/$DEVICE/authorized where $DEVICE is the 32 3- AUDIT A N D CONTROL OF EXTERNAL DEVICES identifier of the corresponding device. By writing 1 or 0 to the file, a device can be authorized or unauthorized from use in the system, respectively. When the device is not authorized, it stays connected to the system but cannot be accessed by any device drivers. It can be reauthorized later without physically reconnecting it. By default, wired USB devices are authorized to be used. This behaviour can be changed by a virtual file located at /sys/bus/usb/devices/usb$X/authorized_def ault where $X is the number of the USB host of which default behaviour will be changed. Moreover, the device can be forced to be disconnected from the system through the virtual file at path: /sys/bus/usb/devices/usb$X/removed where $X is again the number of the USB host. After writing 1 to this file, the device gets completely disconnected from the system. In order for the system to access it again, the device needs to be physically reconnected to the USB port. 3.3 Summary Summing up, the udev subsystem in conjunction with the sysf s seems a viable method for implementing the device control feature of the DLP system. The libudev library provides an API to enumerate USB devices and subscribe to their events. These features can be used to implement the first two of the defined requirements - enumeration and monitoring of USB devices. Moreover, it does not support only USB devices, so the functionality could be extended to support other kinds of devices, such as SD cards. The sysf s file system can be used to read the attributes of the USB devices and (un)authorize the use of USB devices from the system, fulfilling the rest of the previously defined requirements. The available attributes are limited to generic attributes of the USB devices, such as vendor ID and product ID. However, the contents of the USB storage cannot be inspected without authorizing its use in the entire system. Furthermore, the authorization feature is limited only to USB devices [35]. Finally, the authorization status of the device can be changed by anyone with superuser privileges; however, it is not deemed a limitation because it follows the general Linux philosophy. 33 3- AUDIT A N D CONTROL OF EXTERNAL DEVICES Both technologies are available in all the major Linux distributions. They feature an extensive set of documented and available code samples. Moreover, they function entirely from user space, which makes them less technologically challenging and more secure than any kernel-based approach. While having its limitations, the described approach to monitoring and controlling USB devices provides the required functionality for the D L P system I defined at the start of this section. It provides a way to monitor USB devices in the system, read their attributes and (un)authorize them from use. This functionality can be used to monitor and control one of the endpoint DLP channels - removable media, namely USB drives. It can also be used as access control for data at rest. Access control on the USB device level can have many forms. For example, serial numbers of USB drives with sensitive data can be identified and allowed to be used only by authorized workstations. Another form of protection may be restricting the use of USB drives only to known and identified devices. This ensures that no other USB drives (i.e. personal) are used to store data throughout the company. 34 4 DLP System Design and Implementation One of the goals of this thesis was to develop a prototype D L P system. I developed a proof-of-concept D L P system named Failsafe. It demonstrates the usability of selected audit and control approaches in Chapters 2 and 3. On top of that, it also serves as an example of an endpoint DLP implementation. Both file system operation control and external USB device control are implemented as standalone libraries, named libFSHook and libUSBControl. Failsafe uses these libraries to demonstrate how they can be used to tackle DLP scenarios. In this chapter, I present in detail the functionality, architecture and implementation details of Failsafe and the associated libraries. I also discuss the used technologies, developed DLP policy system and incident logging. 4.1 Architecture Figure 4.1 visualizes the high-level architecture of Failsafe. From a high-level point of view, the architecture is modular and consists of modules and shared components. Each module is independent of the others and provides some specific functionality. The shared components implement a common functionality, which is shared by all modules. 4.1.1 Modules A module is an independent unit in the system. It has a concrete set of responsibilities and functionality it provides. The modules do not have any public interface and do not interact with each other. This separation allows any of the modules to be disabled for arbitrary reasons (i.e. its functionality is not required, it causes problems etc.) without impacting the others. Failsafe features two modules: • DLP module • Device control (DC) module 35 4- D L P SYSTEM DESIGN A N D IMPLEMENTATION U s e r s p a c e Policy Provider Incident Logger DLP Prototype Evaluate DC policies Log DLP i n c i d e n t i f y Evaluate D L P ^ i o ^ DC incidents File system events Event authorization J ±_ libFSHook USB device events Event authorization j ±_ libUSBControl Device events Read device info + authorization File system events Event authorization sysfs K e r n F S H o o k Kernel Figure 4.1: High-level overview of the architecture The D L P module is responsible for monitoring and protecting data in use on multiple D L P channels. It functions by intercepting file system operations on the workstation. The details of functionality architecture and implementation of the DLP module are discussed in Section 4.3. On the other hand, the D C module is responsible for USB device management. It is able to monitor and protect the USB device D L P channel as a whole. Additionally, it is able to protect data at rest by providing access control to USB drives containing sensitive data. It functions by controlling USB devices connected to the workstation. 36 4- D L P SYSTEM DESIGN A N D IMPLEMENTATION The details of functionality, architecture and implementation of the DC module are discussed in Section 4.4. A new module can be added without modifying the existing ones or implementing any specific interface. The new module needs to function entirely in its own thread. If needed, the new module can use the services provided by the shared components. A n example of a new module may be a network monitoring module. 4.1.2 Shared Components The shared components implement a single functionality which is required by all of the modules. Consequently, they provide their services to the modules. The modules are not dependent on the concrete implementation of the shared component's functionality. They use the public interface of the corresponding component. This separation allows changing the implementation of the component's functionality without impacting any of the modules. The shared components present in Failsafe are: • Policy Provider • Incident Logger The policy provider is a shared component which implements a system of DLP policies. It is responsible for evaluating if any operation should be classified as a security incident. In other terms, the module can provide details about an operation it monitors (i.e. file is being uploaded). In response, the policy provider tells the module what action it should take (i.e. block the upload). The concrete implementation of the DLP policy system is discussed in Section 4.5. Similarly, the incident logger is responsible for logging of security incidents. If a module identifies a security incident, it can pass necessary details about the incident to the incident logger. The incident logger then processes the information and creates an incident log. The concrete implementation of the incident logging system is discussed in Section 4.6. A new shared component can be added by defining its public interface, implementing the functionality and passing its reference to all of the modules. On the other hand, if a new module needs to use the 37 4- D L P SYSTEM DESIGN A N D IMPLEMENTATION currently implemented shared components, their functionality must be adjusted to accommodate the requirements of the new module. For example, the policy provider would need to be adjusted to have the ability to process new types of operations, which are monitored by the new module. 4.2 Used Technologies Failsafe was developed and tested on Ubuntu 22.04.1, codename Jammy Jellyfish, running Linux kernel version 5.15.0-53-generic. This is the latest version featuring long-term support as of the time of working on this thesis. The chosen programming languages for the implementation were C + + and C , specifically C + + 1 7 and C 9 9 standards. Furthermore, CMake version 3.2.11 was used as a build system generator. The following third-party libraries were used: • Catch2 [39] - A unit testing framework for C + + . Used to implement unit tests for both Failsafe and the associated static libraries. • spdlog [40] - A C + + logging library. This library is used for the implementation of verbose debug logs in a very convenient and readable format. • nlohmann_j son [41] - A C + + library for parsing JSON format. This library is used for parsing files containing DLP policies. • cxxopts [40] - A C + + library for parsing command line arguments. This library is used for parsing command-line arguments passed to Failsafe. • libudev - A library providing an interface to the udev subsystem. This library is explained in detail in Section 3.1. It is used as a backend in USBControl library developed as a part of this thesis. • l i b n l suite [42] - A collection of libraries implementing functionality to communicate with Linux kernel interfaces based on the Netlink protocol. From this suite, a core library l i b n l - 3 , implementing core Netlink functionality, is used. Furthermore, a 38 4- D L P SYSTEM DESIGN A N D IMPLEMENTATION l i b n l - g e n l - 3 library is used, implementing the Generic Netlink protocol, which is an extension of the classical Netlink protocol. • SQLiteCpp [43] - A C++ library encapsulating the native C sqlite API. This library was is to implement security incident logging. 4.3 Data Loss Prevention Module The main responsibility of the D L P module is to monitor and protect data in use. It accomplishes it by monitoring and intercepting the file system operations. From the point of view of the endpoint D L P channels, it monitors and protects the following channels: • Upload of files to web • Instant messaging • File transfer to USB storage, network shares and cloud drives The module uses the libFSHook library to receive events about file system operations from the kernel and processes them accordingly. A flow diagram of this process is visualized in Figure 4.2. Firstly, the events are filtered, and their path type is determined. Following that, the events are processed by so-called handlers. The DLP module features two types of handlers: application-specific and generic. If events caused by a specific application require special processing logic, then they are handled by an application-specific handler. Otherwise, they are handled by a generic handler with non-specific logic. This section discusses each part of the module's functionality in detail. 4.3.1 Filtering of File System Operations Naturally, a lot of operations are happening on the file system. Many of them are not interesting from the DLP point of view, as they do not pose a risk of a data leak. These can include: • Operations with configuration files, shared libraries, fonts or other application resources... 39 4- D L P SYSTEM DESIGN A N D IMPLEMENTATION Figure 4.2: Flow diagram of the D L P module functionality • Operations with temporary files • Operations with non-regular files (sockets, symbolic links etc.) Generally, this is a hard problem, as not filtering enough events may cause a lot of stress on the D L P system and possibly generate false-positive incidents. O n the other hand, filtering a lot of events may cause a D L P system to miss a data leak. Failsafe employs a filtering system which works by filtering operations according to the following conditions: 40 4- D L P SYSTEM DESIGN A N D IMPLEMENTATION 1. A file system operation is filtered out if it is caused by any of the default system daemons1 2. A file operation is filtered if it is outside of the user's /home directory and outside of any external storage mount points 3. A file operation is filtered out if it is happening inside a hidden directory The idea behind this filtering is that the user typically works in his home directory or some mounted storage. Overall, this is a very strict filtering strategy, which definitely does not cover all scenarios which may result in a data leak; however, I have deemed it adequate for the demonstration purposes of this DLP system. For completeness, the filtering system could be improved by introducing various filtering heuristics. I consider these heuristics as out of the scope of this thesis. To name a few examples: • Do not filter operations performed by the currently active G U I application • Do not filter the operation if the path to the file was recently used as a command line argument • Filtering specific paths based on application, which performed the operation 4.3.2 Path Type Resolution The D L P system needs to be able to recognize if a file is being transferred through a D L P channel. To accomplish this, it needs a way to determine if a file path resides outside the workstation's local hard drive. Knowing that, the system can recognise a file transfer to a nonlocal path. Failsafe is able to recognize four path types - local drive, U S B drive, network share and cloud-synchronized directory. To perform the resolution, the D L P module maintains a list of resolved mount points with their assigned type. The resolution of a path type then happens in steps. Firstly, the path is converted to 1. systemd-* 41 4- D L P SYSTEM DESIGN A N D IMPLEMENTATION canonical form (absolute, no symbolic links etc.). Secondly, the list is searched for a prefix of the path. If found, the corresponding path type is returned. Otherwise, the path is considered as a path on a local drive. USB and Network Storage The recognition of USB storage and network share mount points is achieved by monitoring the /proc/mounts virtual file. The file contains a list of mounted file systems. It is exported and updated by the kernel; therefore, it is always up to date [44]. Every time the file changes, the DLP system reads every entry and updates a list of mount points. Note that it contains information about all the mount points in the system. This includes virtual file systems, partitions of the hard drive etc., so the entries are filtered in the following way: • If a file system type of a mount point is a network file system type, then consider it as a network drive. • If a name of a device from which a file system is located in a /dev directory, then it is a physical drive. Consequently, if a device name can be resolved to a device object using libUSBControl library, then the mount point is on a USB device. Cloud Maintaining a list of cloud-synchronized directories is specific for each cloud storage provider. Each cloud client stores its configuration somewhere. Usually, it is stored in a configuration file somewhere on a disk. To determine a set of cloud-synchronized directories, these configuration files must be found and parsed according to their specific format. The configuration files are monitored for changes and parsed when needed. Naturally, this approach can break with an update of the cloud client featuring a breaking change in its configuration format. To demonstrate this general principle, I have implemented support for Dropbox2 . Nevertheless, the support for other cloud storage could be implemented similarly. Dropbox client stores its configuration in -/. dropbox/inf o. j son. The file is a JSON dictionary, which stores a path to the synchronized directory in the value of a path key. 2. https://www.dropbox.com/ 42 4- D L P SYSTEM DESIGN A N D IMPLEMENTATION 4.3.3 Processing of File System Operations The operations happening on the file system are quite low-level. For instance, the system calls exported by the Linux kernel include file open, create, rename or unlink (delete). The DLP system needs to recognize a sequence of low-level operations and map it to a higher-level operation that may result in a data leak. When such an operation is recognized, the system checks if it violates any D L P policy and performs a remediation action. In this subsection, I describe the heuristics that Failsafe's D L P module uses to recognize such operations, their limitations and possible improvements. Upload to web On an endpoint-level DLP without a network layer, uploading a file to the web can be recognized by monitoring the file operations of a web browser application. Obviously, to upload a file, the browser must open the file with a reading flag to read its contents. However, just an opening of the file for reading by a web browser can't be immediately considered a web upload. Browsers open many files for reading libraries, configuration files, cache files etc. However, these files usually reside in known paths and can be easily filtered out. Therefore, if the web browser opens a file in some standard location, it can be classified as a file upload. With high probability, this classification is correct. This is a general principle and should apply to every browser. The detection can be further improved by recognizing the specific behaviour of each browser. Failsafe demonstratively implements this heuristic based on this observation for Google Chrome3 . It is hard-coded in its applicationspecific handler. Additionally, by manually inspecting the file operations performed by Google Chrome, I have found out that opening a file for upload is always performed by the main thread of the application. This is a key observation, which serves as a browser-specific enhancement to improve the reliability of the upload detection. Since Google Chrome has a common core with other browsers (Chromium), it can be determined that this behaviour applies to every Chromiumbased web browser. 3. https://www.google.com/chrome/ 43 4- D L P SYSTEM DESIGN A N D IMPLEMENTATION I have discovered one scenario when this approach fails and produces a false-positive incident. Google Chrome browser can also act as a PDF reader. Opening a PDF file is recognized by this heuristic as an upload. This scenario could be handled by implementing an inspection of the current U R L and incorporating it into the heuristic. Send through an instant messaging application The sending of a file through an instant messaging (IM) application can be recognized similarly to the web upload. When an I M application sends a file, it opens it for reading. This is a general principle which can be applied to every I M application. In Failsafe, this principle is implemented for demonstration purposes. One of the application-specific handlers is a handler for Slack4 IM. It features the logic of detecting sending through this I M applica- tion. File transfer There are multiple ways how files are transferred. Files can be copied or moved, and both of these operations can happen within a single file system or even between two different file systems. Linux kernel does not provide any system call for copying files. For a file to be copied, a process must perform a sequence of operations. Firstly, it must open a file it wants to copy for reading (source). Secondly, it must open a file where it wants to copy for writing (destination). Finally, it reads data from the source file and writes them to the destination file. In the case of file move, two scenarios must be distinguished moving within a single file system and between two different file systems. Moving a file within a single file system partition is just a single rename operation. This is because the data is already present in the file system; only the file's path needs to be changed. This can be reliably detected as it is just a single file system operation. On the other hand, to move files between two different file systems, the actual data needs to be moved as well. To do this, the process must perform the same sequence of events as during the file copying and delete the source file afterwards. 4. https://slack.com/ 44 4- D L P SYSTEM DESIGN A N D IMPLEMENTATION These are general sequences of operations which can be used to recognize a file copying and moving. The sequence recognition needs to be application-specific since the application can perform the operations in an arbitrary order - i.e. open destination file first, then source file or vice-versa. On the other hand, the moving of files within a single file system is not application specific as it is just a single operation. Therefore it does not need to be processed by the application-specific logic and can be recognized generically. In Failsafe's DLP module, I demonstratively implement a heuristic based on this observation for detecting file transfer using Ubuntu's default file manager - Nautilus. I experimentally inspected the sequence of the file system events produced by Nautilus when copying and moving a file. As expected, the sequence matches the previously described general observation. Firstly, Nautilus opens the source file with only a read flag. Following this opening, it opens a destination file with a write flag. When the system recognizes this sequence, it treats it as a file transfer from the source path to the destination path. If the operation violates any policies and needs to be blocked, the opening of the destination file is blocked. This causes to entire operation to fail. Copying multiple files simultaneously follows the same behaviour, repeated for each file. Detection of file moving is implemented similarly. File delete The deletion of a file does not need special logic to be detected. The Linux kernel provides an unlink(2) system call, which is a single file system operation. Therefore it can be processed generically. One case, which may need an application-specific heuristic, is trashing a file through a file manager. Generally, file managers do not delete a file but move it to a special trash location. By doing this, files can be later easily recovered. This case can be easily recognized by detecting a movement of the file into the trash location by the file manager. Even though this sequence consists only of a single operation, it needs to have application-specific logic. This is caused by the possibility of every file manager using a different location for storing trashed files. For instance, Nautilus uses -/. local/share/Trash/. 45 4- D L P SYSTEM DESIGN A N D IMPLEMENTATION 4.3.4 File System Hooking Library A library for file system hooking, called libFSHook, was implemented to provide the functionality of file system interception. Both the kernel module and the library are written in C using the C99 standard. C language was chosen instead of C++ because most higher-level languages provide the functionality to interface with C libraries. This allows the library to be used even in projects which use other languages. The library depends on the C standard library, POSIX threading library and l i b n l . Every public function is thoroughly documented in its header file. The kernel module is responsible for the interception of the file system operations, retrieval of the operation and process context and generation of events. On the other hand, the client library is responsible for providing functions to interface with the kernel module. The kernel module, along with the client library, functions in the following way (Figure 4.3): 1. The kernel module intercepts a file operation and sends an event to the user space client for authorization 2. The user space client can inspect the event and authorize the kernel to perform the operation or not 3. The kernel performs the operation based on the reply from the client Interception of file operations The interception is implemented using the ftracefunction hooking approach as it is deemed the most suitable solution for D L P in Section 2.3.3. Three file system operations are intercepted - open, rename and removal (unlink) of a file. Interception of only these three operations is sufficient based on the analysis performed in Subsection 4.3.3. However, to intercept other operations, it would be sufficient to define their hook functions and information structures containing their context. For the interception to work, corresponding kernel functions must be hooked. The Linux kernel provides multiple system calls for performing a single file operation. For instance, opening a file can be 46 4- D L P SYSTEM DESIGN A N D IMPLEMENTATION Kernel module File operation is intercepted Retrieve information about the process Retrieve information about the operation Create event and send to client \AM for reply for 5 seconds Return error