WEBVTT 0:00:03.120000 --> 0:00:09.060000 Welcome to this video lesson on OS Query Fundamentals and Endpoint Analysis. 0:00:09.060000 --> 0:00:13.740000 In this video, we are going to cover OS Query Fundamentals, how to interrogate 0:00:13.740000 --> 0:00:18.340000 an endpoint through OS Query, how to scale OS Query, and finally, some 0:00:18.340000 --> 0:00:25.560000 of OS Query's advanced functionalities and applications. 0:00:25.560000 --> 0:00:30.660000 Over the last few years, network visibility has become especially difficult, 0:00:30.660000 --> 0:00:34.320000 mainly due to heavy utilization of encryption and bring your own device 0:00:34.320000 --> 0:00:38.820000 policies. This is why every organization should work on maximizing its 0:00:38.820000 --> 0:00:40.920000 endpoint visibility. 0:00:40.920000 --> 0:00:45.140000 Endpoint visibility can be achieved to a certain degree by deploying SISMUN, 0:00:45.140000 --> 0:00:48.640000 but the addition of a specialized agent that can efficiently interrogate 0:00:48.640000 --> 0:00:52.180000 endpoints can prove useful during incident response activities. 0:00:52.180000 --> 0:00:55.840000 In addition, a specialized agent is great for gaining visibility into 0:00:55.840000 --> 0:00:59.660000 Linux endpoints, where SISMUN is not applicable. 0:00:59.660000 --> 0:01:03.580000 A solution that can offer extended endpoint visibility efficiently and 0:01:03.580000 --> 0:01:06.340000 at scale is OS Query. 0:01:06.340000 --> 0:01:09.720000 OS Query is an open source software. 0:01:09.720000 --> 0:01:14.340000 Its query language resembles SQL, and it is thus easy to learn. 0:01:14.340000 --> 0:01:19.160000 OS Query works in all major operating systems, and finally, it was designed 0:01:19.160000 --> 0:01:21.520000 with performance and security in mind. 0:01:21.520000 --> 0:01:25.260000 Note that OS Query cannot perform system changes, it only reads aspects 0:01:25.260000 --> 0:01:29.720000 of the system. Let's start with some OS Query Fundamentals. 0:01:29.720000 --> 0:01:33.480000 Suppose we are analyzing a Windows 8.1 endpoint for traces of malware 0:01:33.480000 --> 0:01:38.260000 infection. Luckily, this endpoint has OS Query installed. 0:01:38.260000 --> 0:01:43.140000 To start OS Query, we first navigate to the backwards slash program data 0:01:43.140000 --> 0:01:49.120000 backwards slash OS Query Directory, and then execute OS Query I.exe. 0:01:49.120000 --> 0:01:55.300000 OS Query I is the interactive shell of OS Query, whereas OS Query D is 0:01:55.300000 --> 0:01:57.060000 OS Query's daemon. 0:01:57.060000 --> 0:02:01.500000 Throughout this video lesson, we are going to use OS Query version 3.3 0:02:01.500000 --> 0:02:09.440000 .2. By typing .help, we are presented with some helpful OS Query commands. 0:02:09.440000 --> 0:02:15.620000 We can exit OS Query's interactive shell by executing .exit or .quit. 0:02:15.620000 --> 0:02:21.940000 What we usually do when analyzing an endpoint for traces of malware infection 0:02:21.940000 --> 0:02:24.400000 is list running processes. 0:02:24.400000 --> 0:02:34.880000 We can do that through OS Query as follows. 0:02:34.880000 --> 0:02:38.740000 Through this query, we are looking into the processes table and we are 0:02:38.740000 --> 0:02:43.640000 selecting the process name, process path, parent process name, and the 0:02:43.640000 --> 0:02:45.720000 parent process path. 0:02:45.720000 --> 0:02:49.400000 Left outer join performs a join starting with the first table and then 0:02:49.400000 --> 0:02:57.280000 any matching second table records. 0:02:57.280000 --> 0:03:01.940000 That service underscore KMS executable looks suspicious if we take into 0:03:01.940000 --> 0:03:04.540000 consideration that this is a corporate endpoint. 0:03:04.540000 --> 0:03:08.880000 In addition, we notice services .exe as the parent process. 0:03:08.880000 --> 0:03:12.680000 This means that this executable has been registered as a system service. 0:03:12.680000 --> 0:03:18.220000 Another way to identify curious looking services through OS Query is the 0:03:18.220000 --> 0:03:28.120000 following. Through this query, we are looking into the services table 0:03:28.120000 --> 0:03:34.000000 and we are selecting the service name, process ID, path, and display name. 0:03:34.000000 --> 0:03:37.280000 We are also specifying that we are interested in services that have a 0:03:37.280000 --> 0:03:41.720000 start type of auto underscore start and a path different than c colon 0:03:41.720000 --> 0:03:51.640000 backwards slash windows, backwards slash xe minus k, since this path usually 0:03:51.640000 --> 0:03:54.280000 accommodates legitimate services. 0:03:54.280000 --> 0:04:13.140000 Let's upload this executable to a cloud antivirus service. 0:04:13.140000 --> 0:04:18.100000 Service underscore KMS.exe was indeed malicious. 0:04:18.100000 --> 0:04:24.000000 Note that stopped services can also be of interest since they can be indicators 0:04:24.000000 --> 0:04:28.240000 of malicious activity. 0:04:28.240000 --> 0:04:31.400000 Through this query, we are checking the status of the service responsible 0:04:31.400000 --> 0:04:33.420000 for collecting logs. 0:04:33.420000 --> 0:04:37.660000 It looks like attackers have disabled it. 0:04:37.660000 --> 0:04:45.300000 The go to resource for studying OS Query tables is osquery.io forward 0:04:45.300000 --> 0:04:49.620000 slash schema. It is recommended that you spend some time in going through 0:04:49.620000 --> 0:04:51.820000 all the available tables and their columns. 0:04:51.820000 --> 0:04:59.520000 You can also filter by OS Query version. 0:04:59.520000 --> 0:05:03.100000 Let's see some additional queries and OS Query commands to get more familiar 0:05:03.100000 --> 0:05:16.860000 with the agent. In this query, we are looking into the system underscore 0:05:16.860000 --> 0:05:21.700000 info table and we are selecting the host name and UUID columns. 0:05:21.700000 --> 0:05:24.400000 The semicolon at the very end is important. 0:05:24.400000 --> 0:05:28.320000 Always place it there since it states that your query is complete and 0:05:28.320000 --> 0:05:30.280000 ready to be executed. 0:05:30.280000 --> 0:05:34.860000 .tables presents us with all the available tables that we can query based 0:05:34.860000 --> 0:05:38.200000 on our OS Query version and our operating system. 0:05:38.200000 --> 0:05:43.900000 For example, if we are interested in tables related to WMI, we can execute 0:05:43.900000 --> 0:06:08.740000 .tables WMI. We can also change the output mode by specifying the preferred 0:06:08.740000 --> 0:06:28.800000 output type before entering the interactive shell. 0:06:28.800000 --> 0:06:32.980000 We can also do the same from inside the interactive shell by typing .mode 0:06:32.980000 --> 0:06:58.740000 and depending the preferred output type. 0:06:58.740000 --> 0:07:03.900000 Remember that whenever you see where on a query, it is used for filtering. 0:07:03.900000 --> 0:07:13.100000 Let's also see how the join operator works. 0:07:13.100000 --> 0:07:16.880000 The default join operation is the inner join one and inner join operation 0:07:16.880000 --> 0:07:21.520000 only combines rows from each table that have matches in a similar column. 0:07:21.520000 --> 0:07:25.380000 Through this query, we identify all running processes that are listening 0:07:25.380000 --> 0:07:27.240000 for an incoming connection. 0:07:27.240000 --> 0:07:31.260000 The join operation uses the shared process ID column. 0:07:31.260000 --> 0:07:38.140000 If we perform a left join operation, what we are presented with is all 0:07:38.140000 --> 0:07:41.320000 the running processes regardless of them listening for an incoming connection 0:07:41.320000 --> 0:07:45.420000 or not. If the process is listening for an incoming connection, the port 0:07:45.420000 --> 0:07:50.760000 is also included otherwise, a null is used. 0:07:50.760000 --> 0:07:54.420000 Suppose now that you were required to identify all installed applications 0:07:54.420000 --> 0:07:56.980000 so that a baseline can be created. 0:07:56.980000 --> 0:08:23.360000 This can be done through OS Query as follows. 0:08:23.360000 --> 0:08:27.640000 We can also look at suspicious installed applications by using where and 0:08:27.640000 --> 0:08:47.700000 like in our queries. 0:08:47.700000 --> 0:08:51.620000 If we wanted to add the system host name to each result, we could do so 0:08:51.620000 --> 0:09:18.660000 as follows. Let's now cover how we can perform endpoint analysis with 0:09:18.660000 --> 0:09:21.280000 OS Query through detection oriented examples. 0:09:21.280000 --> 0:09:25.540000 We will focus on process interrogation and checking system areas that 0:09:25.540000 --> 0:09:28.420000 can be abused for persistence purposes. 0:09:28.420000 --> 0:09:36.700000 A good indicator of malicious activity is excessive resource usage. 0:09:36.700000 --> 0:09:41.860000 User underscore time and system underscore time contain how much CPU time 0:09:41.860000 --> 0:09:46.540000 is spent in user space and the kernel while resident underscore size contains 0:09:46.540000 --> 0:09:50.580000 the total memory size of a process. 0:09:50.580000 --> 0:09:55.320000 We notice nothing suspicious on the most CPU consuming processes. 0:09:55.320000 --> 0:10:06.340000 Let's try ordering by memory size. 0:10:06.340000 --> 0:10:11.060000 We notice a curious looking and memory consuming process that tries to 0:10:11.060000 --> 0:10:15.260000 blend in by misspelling the legitimate conhost.exe process. 0:10:15.260000 --> 0:10:22.340000 This process is conhosts.exe. 0:10:22.340000 --> 0:10:26.400000 We could have also identified it by looking for variations of legitimate 0:10:26.400000 --> 0:10:28.920000 processed names as follows. 0:10:28.920000 --> 0:10:32.000000 Underscore means any character. 0:10:32.000000 --> 0:10:36.260000 In this query, we have also specified that we wanted information about 0:10:36.260000 --> 0:10:42.200000 the process path and command line arguments if any. 0:10:42.200000 --> 0:10:45.460000 Something important in such cases is to add the parent process to the 0:10:45.460000 --> 0:10:57.680000 mix. We could do that as follows. 0:10:57.680000 --> 0:11:01.540000 We see that explore.exe was the parent process. 0:11:01.540000 --> 0:11:04.760000 This most probably means that the user himself executed the malicious 0:11:04.760000 --> 0:11:09.000000 executable. He was either tricked into doing so or we are dealing with 0:11:09.000000 --> 0:11:10.200000 a malicious insider. 0:11:10.200000 --> 0:11:21.920000 If you saw CMD.exe as the parent process, that would be even more concerning. 0:11:21.920000 --> 0:11:27.500000 In addition, if we wanted to detect suspicious outbound network activity, 0:11:27.500000 --> 0:11:31.700000 we could have done so by executing the following. 0:11:31.700000 --> 0:11:36.020000 In this query, we are leveraging the process underscore open underscore 0:11:36.020000 --> 0:11:40.060000 sockets table and we have filtered the results so that only outbound traffic 0:11:40.060000 --> 0:11:42.620000 to uncommon ports is included. 0:11:42.620000 --> 0:11:49.320000 It is no surprise to see conhosts.exe communicating with a remote machine 0:11:49.320000 --> 0:11:54.740000 over an uncommon port. 0:11:54.740000 --> 0:11:58.680000 Let's continue with using OS Query to check Windows aspects that are commonly 0:11:58.680000 --> 0:12:00.700000 used for persistence. 0:12:00.700000 --> 0:12:04.960000 One of the most common persistence techniques used by attackers is the 0:12:04.960000 --> 0:12:06.880000 addition of a malicious user. 0:12:06.880000 --> 0:12:14.240000 We can use OS Query to identify any abnormal users as follows. 0:12:14.240000 --> 0:12:18.800000 If we wanted to identify which users have administrative privileges, we 0:12:18.800000 --> 0:12:31.940000 could have done so as follows. 0:12:31.940000 --> 0:12:35.720000 This query joins the users table and the user underscore groups table 0:12:35.720000 --> 0:12:39.820000 using the UserID column and filters things so that only administrator 0:12:39.820000 --> 0:12:42.120000 level users are returned. 0:12:42.120000 --> 0:12:47.660000 If this was a Linux machine, you should have specified GID27 for users 0:12:47.660000 --> 0:12:53.020000 having pseudo level access and GID0 for users having root level access. 0:12:53.020000 --> 0:12:57.820000 Another persistence technique used by attackers is the introduction of 0:12:57.820000 --> 0:13:11.000000 a malicious service, but we have already covered that. 0:13:11.000000 --> 0:13:13.300000 We can use the user to get a desktop .ini entry whenever a user logs in. 0:13:13.300000 --> 0:13:21.980000 For every user profile, we are going to get a desktop.ini entry so we 0:13:21.980000 --> 0:13:36.380000 filter those out. 0:13:36.380000 --> 0:13:48.580000 Let's take a closer look at the registry location as follows. 0:13:48.580000 --> 0:13:53.840000 First of all, the usage of PowerShell version 1 is suspicious since anything 0:13:53.840000 --> 0:13:57.700000 executed through PowerShell version 1 cannot be logged. 0:13:57.700000 --> 0:14:01.260000 Secondly, we see the PowerShell is instructed to load an encoded script 0:14:01.260000 --> 0:14:05.660000 that is stored inside another registry key. 0:14:05.660000 --> 0:14:15.000000 Let's check this other key through OS query. 0:14:15.000000 --> 0:14:20.180000 There is no doubt we are dealing with the persistence mechanism. 0:14:20.180000 --> 0:14:24.020000 This overly long base 64 string contains a PowerShell script that will 0:14:24.020000 --> 0:14:29.820000 be executed on user login. 0:14:29.820000 --> 0:14:34.220000 Browser extensions can be extremely dangerous from a persistence perspective. 0:14:34.220000 --> 0:14:36.740000 It is like having someone right behind your shoulder while using your 0:14:36.740000 --> 0:14:41.440000 computer. Luckily, OS query can provide us with visibility into all installed 0:14:41.440000 --> 0:15:06.160000 browser extensions as follows. 0:15:06.160000 --> 0:15:09.640000 Not only does this extension look curious looking, but the permissions 0:15:09.640000 --> 0:15:24.800000 it requested are quite excessive. 0:15:24.800000 --> 0:15:28.520000 Attackers can also persist on the system through app shimming. 0:15:28.520000 --> 0:15:32.040000 When legacy apps need to run on newer Windows versions and a deprecated 0:15:32.040000 --> 0:15:36.220000 call is made, a shim can be registered that can pass back to the application 0:15:36.220000 --> 0:15:38.780000 whatever is needed for it to function properly. 0:15:38.780000 --> 0:15:42.540000 Unfortunately, this mechanism can be used for persistence. 0:15:42.540000 --> 0:15:47.200000 OS query can provide us with visibility into executables being shimmed, 0:15:47.200000 --> 0:15:51.640000 including the shim's path and its SDB ID. 0:15:51.640000 --> 0:15:56.820000 By Googling the SDB ID, you can conclude if the shim is ill-intended or 0:15:56.820000 --> 0:16:01.740000 not. Legitimate shims will have a SDB ID that can be found through search 0:16:01.740000 --> 0:16:13.380000 engines. In this case, the system was free of shim-based persistence. 0:16:13.380000 --> 0:16:16.920000 Suppose that we are informed about an internet-facing web server being 0:16:16.920000 --> 0:16:20.220000 compromised and we are responding to this incident. 0:16:20.220000 --> 0:16:25.320000 First, let's list all running processes through OS query. 0:16:25.320000 --> 0:16:43.380000 At first glance, we see nothing suspicious. 0:16:43.380000 --> 0:16:46.680000 We notice two running Python processes. 0:16:46.680000 --> 0:16:51.420000 Let's analyze them further. 0:16:51.420000 --> 0:17:05.260000 We are leveraging the processes table once again. 0:17:05.260000 --> 0:17:09.520000 Another useful OS query table is the Process underscore Open underscore 0:17:09.520000 --> 0:17:26.660000 files one that includes file descriptors for each process. 0:17:26.660000 --> 0:17:30.980000 The Process ID, File Descriptor and Path Table related to the first Python 0:17:30.980000 --> 0:17:37.100000 process indicates that File Descriptors for STD out, STD in, and STD error 0:17:37.100000 --> 0:17:39.880000 are tied to a teletype writer. 0:17:39.880000 --> 0:17:43.360000 For the second Python process, such information is not available, which 0:17:43.360000 --> 0:17:48.120000 is suspicious. We should be able to see a tied teletype writer as well. 0:17:48.120000 --> 0:17:51.060000 Let's investigate further by adding the command line arguments to the 0:17:51.060000 --> 0:18:15.040000 mix. As expected, the second Python process was launched with bad intentions. 0:18:15.040000 --> 0:18:18.340000 The command line arguments indicate that the second Python process was 0:18:18.340000 --> 0:18:30.080000 launched to establish a reverse shell with a remote machine. 0:18:30.080000 --> 0:18:33.900000 Suppose that we are informed about an Internet facing web server suffering 0:18:33.900000 --> 0:18:36.460000 from excessive CPU usage. 0:18:36.460000 --> 0:18:42.640000 Let's list running processes ordered by CPU usage, as we did in a previous 0:18:42.640000 --> 0:18:51.300000 example. The majority of the entries look like legitimate Linux processes. 0:18:51.300000 --> 0:19:11.460000 The last entry though, looks uncommon. 0:19:11.460000 --> 0:19:28.600000 Let's see what OS query can tell us about this process. 0:19:28.600000 --> 0:19:33.020000 This process runs from inside the temp directory, which is suspicious. 0:19:33.020000 --> 0:19:44.340000 Let's also identify the parent process as follows. 0:19:44.340000 --> 0:19:48.860000 It looks like the suspicious process was spawned by a bash script residing 0:19:48.860000 --> 0:19:53.940000 in the forward slash var, forward slash www directory. 0:19:53.940000 --> 0:20:19.000000 Let's continue identifying parent processes recursively. 0:20:19.000000 --> 0:20:21.900000 We see the cron process being mentioned. 0:20:21.900000 --> 0:20:34.780000 This means that some kind of persistence is also involved. 0:20:34.780000 --> 0:20:36.640000 Indeed, that is the case. 0:20:36.640000 --> 0:20:40.260000 By listing all cron jobs, we notice a malicious job that launches the 0:20:40.260000 --> 0:20:51.740000 malicious script that in turn launches the malicious binary called consumer. 0:20:51.740000 --> 0:20:55.740000 Imagine being able to execute the same query across all your endpoints, 0:20:55.740000 --> 0:20:59.500000 and not only that, but also being able to receive an alert in case of 0:20:59.500000 --> 0:21:01.820000 deviation from the normal endpoint state. 0:21:01.820000 --> 0:21:07.100000 Well, you can actually do that by enrolling every OS query agent to a 0:21:07.100000 --> 0:21:11.020000 collide fleet. Collide fleet is essentially an open source OS query manager 0:21:11.020000 --> 0:21:15.320000 that enables you to track, manage and monitor your entire infrastructure 0:21:15.320000 --> 0:21:17.560000 from a single screen. 0:21:17.560000 --> 0:21:22.000000 On your screen, you can see collide fleets main screen showing that two 0:21:22.000000 --> 0:21:24.000000 endpoints have been enrolled. 0:21:24.000000 --> 0:21:27.280000 System information as well as OS queries version are shown in each endpoint 0:21:27.280000 --> 0:21:40.280000 window. Now, let's see how we can execute the same query across our fleet. 0:21:40.280000 --> 0:21:45.080000 To do so, we should navigate to the query tab, specify the query, and 0:21:45.080000 --> 0:21:57.980000 also specify the endpoints where we want the query to be executed. 0:21:57.980000 --> 0:22:01.860000 Then, all we have to do is press the run button. 0:22:01.860000 --> 0:22:06.780000 At the bottom of this window, we will find the results of the query we 0:22:06.780000 --> 0:22:32.740000 specified. By the way, this is the command we executed to enroll this 0:22:32.740000 --> 0:22:35.120000 endpoint to the collide fleet server. 0:22:35.120000 --> 0:22:42.240000 Notice that we used OS query D to do so, not OS query I. 0:22:42.240000 --> 0:22:46.420000 If we wanted to schedule a query's execution across specific endpoints, 0:22:46.420000 --> 0:22:48.900000 we should first save the query to be executed. 0:22:48.900000 --> 0:22:53.040000 We can do that by specifying the query, filling the query title and description, 0:22:53.040000 --> 0:23:06.240000 and finally, pressing the save button. 0:23:06.240000 --> 0:23:09.820000 Next thing we should do is create a query pack, which means specify the 0:23:09.820000 --> 0:23:12.780000 endpoints where we want the query to be scheduled, as well as the query 0:23:12.780000 --> 0:23:17.420000 itself. We can do that by navigating to the packs tab, pressing create 0:23:17.420000 --> 0:23:21.060000 new pack, choosing the endpoints to be included in the pack, filling the 0:23:21.060000 --> 0:23:24.480000 query pack title and description, and finally, pressing the save query 0:23:24.480000 --> 0:23:35.700000 pack button. The only thing left is specifying the query we want to be 0:23:35.700000 --> 0:23:50.900000 scheduled and pressing the save button. 0:23:50.900000 --> 0:23:54.600000 When it comes to the query results, we can choose snapshot if we want 0:23:54.600000 --> 0:23:58.520000 an exact point in time set of results or differential. 0:23:58.520000 --> 0:24:01.640000 If we want to see differential changes between the most recent query execution 0:24:01.640000 --> 0:24:05.660000 and the current execution, ignore removals means that the results will 0:24:05.660000 --> 0:24:07.420000 show only what's been added, since the query is not set. 0:24:07.420000 --> 0:24:43.060000 Since the last run. 0:24:43.060000 --> 0:24:47.040000 Most of OS queries virtual tables are generated when an SQL statement 0:24:47.040000 --> 0:24:52.160000 requests data. From an operating systems perspective, query time synchronous 0:24:52.160000 --> 0:24:54.140000 data retrieval is lossy. 0:24:54.140000 --> 0:24:56.460000 Consider the processes table. 0:24:56.460000 --> 0:25:00.840000 If a process like PS runs for a fraction of a moment, there's no way select 0:25:00.840000 --> 0:25:04.520000 asterisk from processes will ever include the details. 0:25:04.520000 --> 0:25:09.520000 To solve this, OS Query exposes a published subscribed framework for aggregating 0:25:09.520000 --> 0:25:13.080000 operating system information asynchronously at event time. 0:25:13.080000 --> 0:25:17.260000 Storing related event details in the OS Query backing store and performing 0:25:17.260000 --> 0:25:20.540000 a lookup to report stored rows at query time. 0:25:20.540000 --> 0:25:25.840000 Let's witness this advanced OS Query functionality through another detection 0:25:25.840000 --> 0:25:30.460000 example. Specifically, we're going to leverage the file underscore events 0:25:30.460000 --> 0:25:34.960000 event table that tracks time or action changes to file specified in configuration 0:25:34.960000 --> 0:25:39.960000 data. Suppose that we want to monitor the forward slash var forward slash 0:25:39.960000 --> 0:25:44.500000 www forward slash html directory for changes. 0:25:44.500000 --> 0:26:04.600000 We can do that by starting OS Query D and specifying a configuration file. 0:26:04.600000 --> 0:26:08.700000 The configuration files contents instruct OS Query to enable the file 0:26:08.700000 --> 0:26:10.900000 system monitoring functionality. 0:26:10.900000 --> 0:26:14.300000 The configuration file also includes the query to be executed against 0:26:14.300000 --> 0:26:18.260000 the file underscore events event table and of course the directory we 0:26:18.260000 --> 0:26:31.360000 want to monitor. 0:26:31.360000 --> 0:26:40.320000 Let's run OS queries daemon. 0:26:40.320000 --> 0:26:44.220000 Let's also view the specified queries results that are stored on the forward 0:26:44.220000 --> 0:26:48.740000 slash var forward slash org forward slash OS query forward slash OS query 0:26:48.740000 --> 0:26:55.800000 D dot results dot log file. 0:26:55.800000 --> 0:27:00.440000 Let's try to edit a file within the forward slash var forward slash www 0:27:00.440000 --> 0:27:33.120000 forward slash html directory and see if OS Query will detect the change. 0:27:33.120000 --> 0:27:37.300000 The specified query was able to detect the change to the file by identifying 0:27:37.300000 --> 0:27:42.140000 the existence of a dot SWP file within the forward slash var forward slash 0:27:42.140000 --> 0:27:52.900000 www forward slash html directory. 0:27:52.900000 --> 0:27:56.760000 Let's now see how we can have detected PowerShell based malware through 0:27:56.760000 --> 0:28:00.900000 OS Query and this advanced publish subscribe framework. 0:28:00.900000 --> 0:28:05.660000 This time we will start OS Query i dot exe with the Windows underscore 0:28:05.660000 --> 0:28:09.500000 event underscore channel option that subscribes to the specified Windows 0:28:09.500000 --> 0:28:13.760000 event channel. In this example we are subscribing to the channel containing 0:28:13.760000 --> 0:28:16.520000 PowerShell script block logging events log. 0:28:16.520000 --> 0:28:21.460000 Of course PowerShell script block logging has been enabled on the system. 0:28:21.460000 --> 0:28:27.360000 If we issue a query to see event PowerShell script block logging log the 0:28:27.360000 --> 0:28:30.840000 results will be empty since no PowerShell code has been executed from 0:28:30.840000 --> 0:28:35.900000 the time we started OS Query. 0:28:35.900000 --> 0:28:40.920000 Now if we execute any PowerShell code the PowerShell underscore events 0:28:40.920000 --> 0:28:44.740000 event table will be filled with PowerShell script block logging logs containing 0:28:44.740000 --> 0:28:55.420000 the code that has been executed in memory. 0:28:55.420000 --> 0:29:00.020000 In this case we are dealing with malicious PowerShell code performing 0:29:00.020000 --> 0:29:02.120000 reflective dll injection. 0:29:02.120000 --> 0:29:07.620000 Notice the usage of base 64 encoding and most importantly the usage of 0:29:07.620000 --> 0:29:12.080000 Virtual Alec which is a function related to reserving committing or changing 0:29:12.080000 --> 0:29:15.680000 the state of a region of pages in the virtual address space of the calling 0:29:15.680000 --> 0:29:25.020000 process. Finally let's see how OS Query can be used in conjunction with 0:29:25.020000 --> 0:29:28.460000 the attack matrix to practice detecting attacker techniques tactics and 0:29:28.460000 --> 0:29:44.980000 procedures. Since knowing how to replicate every known TTP is difficult 0:29:44.980000 --> 0:29:49.340000 organization should leverage Red Canary's atomic red team project that 0:29:49.340000 --> 0:29:56.720000 contains information about how to replicate numerous attacker TTPs. 0:29:56.720000 --> 0:30:01.100000 The procedure and organization should follow is first identify the TTP 0:30:01.100000 --> 0:30:04.500000 against which it wants to test its defenses. 0:30:04.500000 --> 0:30:08.820000 Then replicated inside an isolated environment and finally inform the 0:30:08.820000 --> 0:30:16.500000 blue team that they can try to detect it. 0:30:16.500000 --> 0:30:21.880000 In this case we will try to detect a TTP for which atomic red team doesn't 0:30:21.880000 --> 0:30:24.420000 include information about how to replicate it. 0:30:24.420000 --> 0:30:30.600000 This TTP is the loading of malicious kernel modules. 0:30:30.600000 --> 0:30:34.820000 On the left terminal we will create and load a benign kernel module. 0:30:34.820000 --> 0:30:36.960000 The actual code is irrelevant. 0:30:36.960000 --> 0:30:40.000000 You could ask the development team to develop a simple kernel module for 0:30:40.000000 --> 0:30:54.560000 you. Let's create the kernel module using the make file. 0:30:54.560000 --> 0:30:58.660000 Luckily OS Query contains the kernel underscore modules table that includes 0:30:58.660000 --> 0:31:13.080000 both loaded and within the load search path kernel modules. 0:31:13.080000 --> 0:31:31.180000 As you can see there is no kernel module called hello in the results. 0:31:31.180000 --> 0:31:44.340000 Let's now load the kernel module we created. 0:31:44.340000 --> 0:31:47.940000 Let's see if the loaded hello kernel module will be listed in OS Query's 0:31:47.940000 --> 0:32:04.400000 results. We were able to identify the recently loaded kernel module. 0:32:04.400000 --> 0:32:07.720000 As I already mentioned one could schedule this query at regular intervals 0:32:07.720000 --> 0:32:17.220000 and be informed of newly loaded kernel modules on the system. 0:32:17.220000 --> 0:32:22.080000 And this concludes our video lesson on OS Query Fundamentals and Endpoint 0:32:22.080000 --> 0:32:25.320000 Analysis. Thank you for joining us.