[00:20.700 --> 00:34.870] Quick announcement, I'm gonna use laser pointer and I'm gonna use this screen. [00:35.250 --> 00:43.050] So those people sitting here, please move either to the center of the room or to the right side. [01:05.620 --> 01:07.440] You prefer to stay there? [01:15.370 --> 01:19.950] Well I think it depends on how close I am to the mic rather than... [01:36.690 --> 01:38.430] Okay, so let's start. [01:38.530 --> 01:40.130] Thank you for coming for my talk. [01:40.130 --> 01:46.110] It's the first talk in the morning, so it might be pretty difficult for you to get up early and [01:46.110 --> 01:48.830] come here, so thank you for showing up. [01:50.310 --> 01:55.610] The title of my talk is JIRA, which is a tool for automatic detection, identification and [01:55.610 --> 01:58.750] repair of control hijacking attacks. [01:58.990 --> 02:03.490] I am Alexey Smirnov and this is a joint work with Tricker Chair, who is my advisor. [02:03.550 --> 02:05.630] We are from Stony Brook University. [02:07.510 --> 02:09.390] Here is the outline of my talk. [02:09.390 --> 02:14.250] First I'm gonna give a brief introduction on control hijacking attacks. [02:14.450 --> 02:20.170] Then I'm gonna talk about the related work in the areas of attack detection, identification and repair. [02:20.230 --> 02:25.970] Then I'll present our architecture, JIRA, which has these three components. [02:25.970 --> 02:31.250] The attack detection component, the attack identification and attack repair component. [02:31.250 --> 02:36.230] The purpose of attack detection component is to detect a buffer overflow or control hijacking attack. [02:36.230 --> 02:43.150] So it's similar to the goal of the tools like StackGuard and Propolis. [02:43.470 --> 02:49.390] The attack identification component builds up the signature that can be supplied to intrusion detection system [02:49.390 --> 02:52.370] so that these attack packets can be filtered out in the future. [02:52.590 --> 03:00.050] The attack repair component repairs the program and allows it to continue its execution as if the attack never happened. [03:00.050 --> 03:08.050] In the performance evaluation part we're gonna talk about the overheads, the runtime overhead and the compile time overheads of our compiler. [03:08.230 --> 03:12.630] And we'll conclude with a summary of research contributions and with the direction of future work. [03:14.290 --> 03:18.150] Buffer overflow attacks are the most common type of attacks. [03:18.870 --> 03:24.370] Computer warms use buffer overflow attacks as a basic building block for the propagation. [03:24.690 --> 03:29.170] So as soon as they arrive to a new host, they perform a buffer overflow attack, [03:29.170 --> 03:32.390] hijack control of the underlying program or of the host, [03:32.810 --> 03:38.310] and then scan for more vulnerable machines by performing random IP scanning. [03:38.550 --> 03:46.790] Once they find a new vulnerable machine, they send their body to the new machine and perform the control hijacking attack on that new host. [03:47.410 --> 03:51.670] A comprehensive protection strategy should include the following three components. [03:51.670 --> 03:58.870] The attack detection component, which will detect the control hijacking attack when it happens. [03:58.870 --> 04:02.810] That is, when the worm tries to get control of the underlying computer. [04:02.890 --> 04:08.150] The attack identification component is responsible for building the signature of the attack. [04:08.150 --> 04:14.010] That is, for identifying malicious packets and representing them in the most general form [04:14.010 --> 04:20.670] so that polymorphic worms or polymorphic attacks can be detected by the same signature. [04:20.990 --> 04:28.510] The attack repair component allows the compromised program to continue its execution as if the attack never happened. [04:28.510 --> 04:37.490] That is, it should restore the memory image or the environment of the program as it was in the pre-attack time [04:38.230 --> 04:43.130] so that the program will think that it has never received any attack packets. [04:43.330 --> 04:50.370] We propose a compiler, Jira is a compiler, that instruments programs, source code of a program [04:50.370 --> 04:58.130] so that the instrumented program can identify, detect, and repair itself after a control hijacking attack. [04:58.870 --> 05:01.010] What is a buffer overflow attack? [05:01.170 --> 05:09.590] Well, the idea behind control hijacking attacks is to operate a control sensitive data structure [05:09.590 --> 05:14.730] such as a return address, function pointer, or any other control sensitive data structure. [05:14.730 --> 05:17.930] By the way, I've got some t-shirts here and books and I'm going to give them away [05:17.930 --> 05:23.750] and I'm going to ask you questions and who answers first gets a t-shirt or a book. [05:23.750 --> 05:25.510] So here's the first question. [05:26.150 --> 05:31.330] The return address and the function pointer are two possible types of control sensitive data structure. [05:31.330 --> 05:36.530] What are other data structures that a worm or a virus can override? [05:39.560 --> 05:41.440] That's what I said, function pointer. [05:43.320 --> 05:44.600] What else? [05:45.220 --> 05:46.020] Okay. [05:47.340 --> 05:48.480] What about HIP? [05:49.860 --> 05:51.200] What do you mean by HIP? [05:53.500 --> 05:55.040] Well, okay, I got a t-shirt. [06:01.260 --> 06:02.240] What else? [06:05.600 --> 06:07.460] That's what he said probably, HIP. [06:07.580 --> 06:09.100] Okay, that was what I... [06:19.100 --> 06:24.260] So the name of the control sensitive data structure is... [06:24.940 --> 06:26.080] just word. [06:28.000 --> 06:29.860] Okay, any other ideas? [06:30.360 --> 06:31.200] Okay. [06:35.160 --> 06:38.840] Well, for example, GOT, which is global offsets table. [06:40.380 --> 06:47.640] Anyway, buffer overflows are possible when the length of the destination buffer is shorter than the length of the data that's been written into it. [06:47.680 --> 06:55.100] So whenever you write something that is longer, it can override something that is behind this buffer, such as a return address. [06:55.100 --> 06:57.520] And that's when the buffer overflow happens. [06:57.520 --> 07:04.760] Standard libc functions, such as stringcpy or sprintf, are responsible for most buffer overflow attacks. [07:05.820 --> 07:10.240] So we're going to review related work in the areas of attack detection, identification, and repair. [07:10.240 --> 07:13.800] StackGuard is the first tool for buffer overflow attack detection. [07:13.800 --> 07:21.000] It works by placing a canRevert in the stack frame in the function prologue, and it checks this canRevert at function epilogue. [07:21.000 --> 07:26.500] If the values are different, then the attack has happened, and the application is terminated. [07:26.500 --> 07:31.960] RADint is another tool that protects programs from buffer overflow attacks. [07:31.960 --> 07:37.420] It works by saving the original return address in a special well-protected buffer at function prologue, [07:37.420 --> 07:42.260] and compares it with the values stored in the stack at function epilogue. [07:42.260 --> 07:52.700] If the values stored in the protected buffer end in the function frame when the function returns are different, then an attack is dejected. [07:52.700 --> 07:58.040] Can anyone think of any other tools for attack detection? [07:59.800 --> 08:02.340] Nah, Snore is content filter engine. [08:05.000 --> 08:06.720] Okay, I got it. [08:07.380 --> 08:09.800] You got a T-shirt? Who was that? [08:18.280 --> 08:21.300] So, let's move to attack identification. [08:23.120 --> 08:30.620] We need automatic ways for attack identification, because it's very important to generate signatures fast. [08:30.620 --> 08:34.780] Computer warms infect vulnerable machines very fast. [08:34.780 --> 08:38.620] It's a rate of thousands per minute, or maybe tens of thousands per minute. [08:38.660 --> 08:44.120] Therefore, if we wait for a human expert to come up with a signature, which is going to take a few hours, [08:44.120 --> 08:48.500] then the warm is going to hijack the most vulnerable host on the Internet. [08:48.680 --> 08:59.620] Recent epidemics propagate at a very, very high speed, so it's very difficult for a human expert to come up with a signature quickly. [08:59.620 --> 09:08.500] Previous systems for automatic signature generation either produced signatures that consisted of only one packet, [09:08.500 --> 09:13.360] or required a large pool of malicious network data to come up with a comprehensive signature. [09:13.360 --> 09:17.200] Signature that consists of one packet is sometimes insufficient, [09:17.200 --> 09:23.080] because a complex attack can involve multiple packets, such as, let's say, FTP server attack, [09:23.080 --> 09:29.160] it involves sending out authentication packets, and only then sending out the final attack packet. [09:29.160 --> 09:34.140] A comprehensive signature should include all attack packets, not just the last one. [09:34.140 --> 09:36.400] So here are some relevant projects. [09:36.460 --> 09:40.020] TaintCheck is a tool for... [09:40.020 --> 09:46.420] It uses the taint analysis to generate attack signature, [09:46.420 --> 09:53.860] and it reports the value of the return address, the form used to hijack control as a signature. [09:53.860 --> 09:55.940] So it's only a four-byte signature. [09:55.940 --> 10:08.000] Autograph uses so-called Rabin fingerprints to find common subsequences in a large pool of malicious network data. [10:08.000 --> 10:11.320] Polygraph and naming also use a large pool of malicious data, [10:11.320 --> 10:15.120] and to use machine learning algorithms to construct a multi-packet signature. [10:18.700 --> 10:22.600] AttackRepair relies on checkpointing. [10:22.600 --> 10:25.540] That is, one first checkpoints the program state, [10:25.540 --> 10:31.280] and then jumps to a previous point in the past to restore program's execution. [10:32.460 --> 10:36.440] So two approaches here are either keeping complete execution history, [10:36.440 --> 10:38.860] or do periodic stack checkpointing. [10:38.860 --> 10:45.020] That is, to take a snapshot of the memory image of the program. [10:45.140 --> 10:47.300] And the second approach relies on a fork system call, [10:47.300 --> 10:51.440] which is available under Linux, but might not be available under other operating systems. [10:51.440 --> 10:55.600] And Shadow Honeypot project runs two versions of the application, [10:55.600 --> 10:58.500] instrumented, that is protected and non-protected, [10:58.500 --> 11:02.240] and switches between them dynamically when it detects an attack. [11:02.240 --> 11:04.580] Now we move on to DIRA architecture. [11:04.580 --> 11:07.660] DIRA is a compiler that provides all these three components. [11:07.960 --> 11:11.840] AttackDetectionComponent, AttackIdentification, and AttackRepairComponent. [11:14.930 --> 11:22.090] As I said, DIRA is an extension to GCC, version 3.4.1 currently, [11:22.090 --> 11:24.310] but it can be used with other versions as well. [11:24.310 --> 11:28.310] The idea behind DIRA is memory updates logging, [11:28.310 --> 11:32.730] and this approach solves all these three problems at the same time. [11:32.770 --> 11:38.730] So the idea is to maintain a run-time log of all changes that the program performs. [11:40.110 --> 11:44.030] Assignments such as A equals B, or ellipsis functions call, [11:44.030 --> 11:46.730] such as memcpy, change memory state of the program, [11:46.730 --> 11:49.130] and therefore their effects should be saved. [11:49.130 --> 11:51.150] For example... [11:51.150 --> 11:53.570] Okay, we will see some examples later. [11:53.570 --> 11:56.590] For each memory update, DIRA stores its source address, [11:56.590 --> 12:00.010] its destination address, its length, and the preimage. [12:00.290 --> 12:05.790] So in the case of the assignment A equals B... [12:05.790 --> 12:07.150] Where's my pointer? [12:09.270 --> 12:10.030] Here. [12:10.550 --> 12:14.970] The source is the address of variable B, [12:14.970 --> 12:18.150] because that's where the new data comes from. [12:18.150 --> 12:20.870] The right address is the address of A, [12:20.870 --> 12:23.410] because that's the address that has been written into. [12:23.410 --> 12:27.290] The length of the data is the size of type of variable B. [12:27.290 --> 12:29.270] So if it's integer, it's 4-byte. [12:29.270 --> 12:32.530] The preimage is the old value of A, [12:32.530 --> 12:35.050] and it's used to restore memory image to the program. [12:35.410 --> 12:43.250] So the DIRA compiler instruments the source code of the program in compile-time. [12:43.250 --> 12:48.490] It adds the log-in code for variable assignments and for standard library functions. [12:48.530 --> 12:52.170] At run-time, this log-in code, this memory update log, is generated, [12:52.170 --> 12:58.950] and it's used at repair time to detect, to identify, and to repair the attack. [12:59.450 --> 13:03.510] So how can we detect, identify, and repair an attack if we have this memory update log? [13:03.510 --> 13:07.350] To detect an attack, we need to compare the current value of the return pointer, [13:07.350 --> 13:12.210] or the return address, saved in the stack frame with the value saved in the memory update log. [13:12.210 --> 13:15.810] When we invoke a function, we lay out a new stack frame, [13:15.810 --> 13:21.350] we save the old return address, we save any registers that are used in this function, [13:21.910 --> 13:26.330] and therefore, this is a changed memory state of the program, [13:26.330 --> 13:29.770] which should be saved in the memory update log according to our concept. [13:30.050 --> 13:35.530] Therefore, the old value of the return address will be saved in the memory update log when the function is invoked. [13:35.530 --> 13:40.590] When the function is returning, this saved value should be compared with the value [13:40.590 --> 13:44.750] that is currently on the stack. If these two values are different, then there is an attack. [13:44.890 --> 13:47.970] To identify an attack using the memory update log, [13:47.970 --> 13:53.830] we can trace back the data that overrode the control-sensitive data structure [13:53.830 --> 13:56.910] to the point where it was first received in the program. [13:57.770 --> 14:00.330] For example, through a receive call. [14:01.390 --> 14:05.390] To repair an attack, we need to restore the memory image of the program [14:05.390 --> 14:09.270] by using the pre-images that are also saved in the memory update log. [14:09.270 --> 14:14.950] This idea of keeping the memory update log of program memory state changes [14:14.950 --> 14:17.810] is the essential idea behind our tool. [14:17.890 --> 14:21.910] It allows us to solve all these three problems of attack detection, identification, and repair [14:21.910 --> 14:24.010] in the same uniform way. [14:25.450 --> 14:27.850] Memory update log is a circle buffer. [14:27.910 --> 14:30.470] Each record of this buffer has four fields. [14:30.470 --> 14:32.670] Read address, write address, length, and data. [14:33.150 --> 14:36.670] Dero saves the effect of each assignment operation, [14:38.130 --> 14:39.870] such as x equals y, [14:39.870 --> 14:43.110] where x and y are either directly referenced variables, [14:43.110 --> 14:46.210] array references, or dereferenced variables. [14:46.430 --> 14:49.390] As I said previously, the read address is set to the address of the right-hand side, [14:49.390 --> 14:52.810] the write address is set to the address of the left-hand side, [14:52.810 --> 14:58.010] the length is set to the size of the memory update, [14:58.010 --> 14:59.330] and the data is set to the pre-image [15:00.210 --> 15:02.690] that stores the data that they're going to overwrite, [15:02.690 --> 15:04.690] that is, the old value of x. [15:05.770 --> 15:08.270] If the right-hand side is a complex expression, [15:08.270 --> 15:13.170] then a log record is created for each variable in the right-hand side. [15:13.170 --> 15:17.530] To handle memory change performed by standard library functions, [15:17.530 --> 15:19.390] Dero proxies a few of them, [15:19.390 --> 15:22.970] such as string manipulation functions, format string functions, file network IO functions, [15:22.970 --> 15:26.210] and other functions that change memory state of the program. [15:27.490 --> 15:34.270] So the proxy function constructs a new memory update log record [15:35.650 --> 15:40.450] that summarizes the changes performed by the corresponding ellipsis function. [15:40.830 --> 15:43.330] And the memory update log is also used to store tags, [15:43.330 --> 15:47.310] which are special records that indicate change to memory to the state of the program. [15:47.310 --> 15:50.550] For example, when the function is invoked, function enter tag is inserted, [15:50.550 --> 15:53.090] and when the function returns, function exit tag is inserted. [15:53.090 --> 15:55.670] These tags are used at repair and identification time [15:55.670 --> 15:59.970] to build up signature and to repair program after an attack. [16:01.870 --> 16:03.730] So here are a few examples. [16:03.730 --> 16:09.830] At compile time, let's say there is a statement x equals y plus z. [16:10.690 --> 16:15.230] So the compiler adds two logging codes. [16:15.310 --> 16:20.030] The first code logs the effect of variable y, [16:20.810 --> 16:23.130] sorry, of variable z. [16:23.170 --> 16:25.870] The other of the variable y. [16:26.150 --> 16:28.390] And finally, there is this original statement. [16:28.510 --> 16:32.770] At run time, these two logging codes produce these two log records [16:33.570 --> 16:37.470] with the read and write addresses set as I described previously. [16:38.250 --> 16:42.590] Suppose there is the string CPY code in the source code of the program. [16:43.210 --> 16:46.950] The debug compiler replaces this code with a proxy function. [16:47.530 --> 16:50.770] And at run time, this proxy function inserts a log record [16:50.770 --> 16:56.190] with the read address of b, because that's where the data is coming from, [16:56.190 --> 16:59.710] with the write address of a, because that's where the write data enter. [16:59.750 --> 17:02.830] With the length, strlen of b plus one, [17:02.830 --> 17:09.250] because they're going to write strlen of b bytes plus non-terminating character. [17:09.430 --> 17:16.030] And with the preimage is a, which is the old value of a, [17:16.750 --> 17:19.010] Now let's talk about attack detection. [17:19.270 --> 17:20.810] Jira uses a RAD-like approach. [17:20.810 --> 17:24.410] That is, it saves the original return address when the function is invoked [17:24.410 --> 17:28.310] and compares the saved value with the value that is currently on stack [17:28.310 --> 17:29.810] at function epilogue. [17:29.810 --> 17:32.830] If these two values are different, then an attack is detected. [17:33.490 --> 17:35.790] Jira can protect other control-sensitive data structures, [17:35.790 --> 17:39.210] such as function pointers, GOT, signal-handling variables, and a similar function, [17:39.210 --> 17:40.770] but it's not implemented yet. [17:46.380 --> 17:48.600] Now let's talk about attack identification. [17:48.600 --> 17:52.060] So here are the desired properties of an ideal signature. [17:52.200 --> 17:53.700] A signature should be context-aware, [17:53.700 --> 17:56.500] which means that it should include all the attack packets [17:56.500 --> 17:58.460] that participate in a given attack. [17:58.880 --> 18:01.360] And this allows to reduce the rate of false positives. [18:01.600 --> 18:02.980] It should be also semantics-aware, [18:02.980 --> 18:06.160] that it ideally should incorporate the knowledge about the protocol. [18:06.160 --> 18:09.060] For example, if this is an HTTP attack, [18:09.060 --> 18:11.920] and the attack request is a GET request, [18:11.920 --> 18:14.160] then the signature should specify that this is GET, [18:14.160 --> 18:16.400] so that the intrusion detection system can filter out, [18:16.400 --> 18:20.520] keep all the requests of other types, of other protocols, [18:20.520 --> 18:23.840] and even if it's HTTP, but not GET, [18:23.840 --> 18:25.740] it should also discard those packets. [18:25.740 --> 18:28.300] It should check the signature only against packets [18:28.300 --> 18:31.940] that are HTTP GET kind of packets. [18:32.780 --> 18:35.340] And this also allows to reduce the rate of false positives. [18:35.640 --> 18:37.620] And the signature should provide a certain degree of flexibility [18:37.620 --> 18:39.360] within each packet, [18:39.360 --> 18:42.600] so that polymorphic warnings that change their body as they propagate [18:42.600 --> 18:45.540] can be matched using the same signature. [18:46.820 --> 18:50.720] The attack packets should be represented as regular expressions, [18:50.720 --> 18:55.380] and that's the desired flexibility that a signature should have. [18:56.760 --> 19:01.280] So, as I said, these three properties are the desired properties, [19:01.280 --> 19:05.480] and now let's see how JIRA satisfies all those properties. [19:05.480 --> 19:08.080] JIRA signatures are kind of severe, [19:08.080 --> 19:09.780] because they consist of multiple packets. [19:10.100 --> 19:15.420] They consist of all packets that an attack consists of. [19:15.420 --> 19:19.060] And each of those packets is represented as a regular expression. [19:19.780 --> 19:21.900] And there's a feature called length constraint [19:22.420 --> 19:26.380] that allows to limit the attack in part of the packet. [19:26.640 --> 19:30.100] That is, it allows to specify that a terminating character, [19:30.100 --> 19:31.320] such as null character, [19:31.320 --> 19:36.720] should occur between offset A and offset B. [19:36.820 --> 19:39.720] If the terminating sequence occurs within this offset, [19:39.720 --> 19:41.320] this is not an attack packet. [19:41.320 --> 19:45.880] If there is no such a terminating character in the packet, [19:45.880 --> 19:47.460] then this is an attack packet. [19:48.140 --> 19:52.220] So, in some sense, this is equivalent to semantics awareness, [19:52.220 --> 19:55.900] because it allows to narrow down the part of the packet [19:57.420 --> 20:00.080] that the intrusion detection system searches. [20:00.080 --> 20:03.960] So it doesn't search the specified sequence in the whole packet, [20:03.960 --> 20:07.320] but rather this length constraint allows to limit the... [20:07.320 --> 20:10.380] or narrow down the scope where we search for the... [20:12.720 --> 20:14.420] required terminating constraint. [20:14.420 --> 20:15.880] For example, if this is a... [20:15.880 --> 20:18.660] same example, if this is a GET attack, [20:18.660 --> 20:21.080] and there's an overly long URL, [20:21.080 --> 20:23.180] which is terminated by a null character, [20:23.180 --> 20:25.260] here it allows to specify that this null character [20:25.260 --> 20:28.820] should occur between the fourth and, let's say, [20:28.820 --> 20:31.160] twentieth-bit byte of the packet. [20:31.180 --> 20:34.400] Because the first three characters are GET characters, [20:34.400 --> 20:37.620] and then the remaining part of the packet is the URL. [20:37.720 --> 20:39.120] If the terminating character is found [20:39.120 --> 20:42.640] in the first twenty-four bytes of the packet, [20:42.640 --> 20:44.720] then this is not an attacking packet. [20:44.780 --> 20:47.020] If the null terminating character is not found [20:47.020 --> 20:48.780] in the first twenty-four bytes, [20:48.780 --> 20:51.700] then this is an attack packet, because the URL is too long. [20:52.740 --> 20:56.260] Memory update slog allows us to construct signatures [20:56.260 --> 20:58.160] that consist of multiple packets, [20:58.160 --> 21:00.660] to represent each packet as a regular expression, [21:00.660 --> 21:02.440] and to generate a length constraint. [21:02.440 --> 21:04.440] And we're going to give an example, [21:05.160 --> 21:10.260] and we will show how all this functionality is implemented. [21:11.920 --> 21:15.340] Two types of dependencies exist in the program, [21:15.340 --> 21:16.920] data and control dependency. [21:20.740 --> 21:23.940] Data dependency is created when one variable is assigned to another, [21:23.940 --> 21:26.040] for example, A equals B, same example. [21:26.040 --> 21:28.960] In this case, A depends on B. [21:29.180 --> 21:31.700] A control dependency is created whenever variable X [21:31.700 --> 21:37.700] and variable Y is used... [21:39.600 --> 21:43.000] I'm sorry, variable X is used in conditional expressions, [21:43.000 --> 21:46.160] such as if, and Y is in this conditional body. [21:46.220 --> 21:47.400] So here's an example. [21:47.980 --> 21:50.740] In this case, even though there is no direct assignment [21:50.740 --> 21:54.260] between X and Y, Y depends on X, [21:54.260 --> 21:58.800] because the value that Y will take depends on the value of X. [21:58.920 --> 22:01.340] This type of dependency is called control dependency. [22:01.340 --> 22:03.960] No direct assignment, but dependency is there, [22:03.960 --> 22:07.380] because value of Y depends on value of X. [22:08.700 --> 22:10.320] Why do we need control dependencies? [22:10.740 --> 22:11.780] So here's an example. [22:11.780 --> 22:14.240] FTP server attack involvement authentication. [22:15.000 --> 22:17.700] Here's an example of vulnerable FTP server. [22:18.180 --> 22:20.120] Here's the vulnerable buffer. [22:20.300 --> 22:22.180] The program has two state variables, [22:22.180 --> 22:23.900] isAuthentication, isUser. [22:25.540 --> 22:28.640] And here is the main loop of this server. [22:28.640 --> 22:31.140] First, it receives a packet. [22:31.140 --> 22:34.360] Then it compares the four bytes of the packet. [22:34.400 --> 22:36.300] If it's QuickCommand, the loop breaks. [22:36.400 --> 22:40.100] If it's UserCommand, then isUser variable is set to 1. [22:40.100 --> 22:44.160] If it's PasswordCommand, then isUser and isUser has been set. [22:44.160 --> 22:47.100] Then authentication has been completed, [22:47.100 --> 22:50.220] and isAuthenticated variable is set to 1. [22:50.480 --> 22:53.440] If authentication was not performed previously, [22:53.440 --> 22:54.740] then the program continues. [22:55.180 --> 22:57.900] The client requests are handled only in the case [22:57.900 --> 23:01.660] if the authentication has been completed previously. [23:01.740 --> 23:04.160] So if the user is authenticated, [23:04.160 --> 23:10.060] then the program checks the first three bytes of the packet. [23:10.060 --> 23:12.460] If it's a GET packet, then there's a GET request, [23:12.460 --> 23:15.320] and it returns the file that the user requested. [23:15.540 --> 23:16.940] But this request is only processed [23:16.940 --> 23:19.040] if the user has previously authenticated. [23:21.120 --> 23:23.960] So these are the three packets used in the attack. [23:26.820 --> 23:31.140] There is a file name that is too long [23:31.140 --> 23:33.920] and that overrides the buffer, [23:35.480 --> 23:37.640] that overrides this buffer, [23:37.640 --> 23:40.120] which is only 16 characters bytes long. [23:41.020 --> 23:43.720] Let's look at lock records generated at run time. [23:44.020 --> 23:46.200] First, there is a lock record here at receive [23:46.200 --> 23:49.660] for the receive function. [23:49.820 --> 23:53.880] For the proxy function, proxy is standard receive call, [23:53.880 --> 23:55.800] and it has this tag. [23:55.800 --> 23:57.100] Here's the tag. [23:57.100 --> 23:58.380] This is the write address. [23:58.660 --> 24:01.240] That's the destination, [24:01.240 --> 24:05.280] where the network data is written into 11 different things. [24:05.280 --> 24:08.680] And here's also the image of the data [24:08.680 --> 24:10.140] that varies from network. [24:10.340 --> 24:14.800] Then there is a proxy function for SDR and CMP, [24:15.720 --> 24:18.760] which also has the write address... [24:18.760 --> 24:22.740] I'm sorry, it's read address of the variable. [24:22.740 --> 24:24.560] 4 is the length of the argument. [24:24.560 --> 24:27.400] This record specifies... [24:27.400 --> 24:30.840] indicates that we search buffer P [24:30.840 --> 24:34.560] and we look at first four bytes of this buffer. [24:34.720 --> 24:37.280] Then this record is created for conditional expression [24:37.280 --> 24:40.940] and it means that variable P participates in the if expression. [24:40.940 --> 24:42.640] So for every variable in the if expression, [24:42.640 --> 24:45.560] we save this variable into memory and this log. [24:46.060 --> 24:47.840] And this is also... [24:47.840 --> 24:51.680] this is the record for the statement [24:51.680 --> 24:53.920] that updates each user variable. [24:53.920 --> 24:56.340] So in this case, the read address is set now [24:56.340 --> 24:57.720] because we don't know where the data [24:57.720 --> 25:01.320] that is written into isUser comes from. [25:01.320 --> 25:03.340] And it's just a constant. [25:03.720 --> 25:05.240] So the write address is isUser. [25:05.240 --> 25:07.980] The length is 4 and isUser is preimage. [25:07.980 --> 25:10.260] Similarly, for the second packet, [25:10.260 --> 25:12.380] we have the receive record here. [25:12.380 --> 25:13.940] We have the string comparison record [25:13.940 --> 25:18.880] that checks the first four bytes of the packet. [25:18.880 --> 25:20.540] We have two conditional variables now [25:20.540 --> 25:22.860] because two variables are checked, [25:22.860 --> 25:24.520] P and isUser. [25:24.560 --> 25:26.300] And finally, this is the record [25:27.060 --> 25:31.380] that updates the isAuthentication variable. [25:32.660 --> 25:35.520] So finally, let's look at the third packet. [25:35.760 --> 25:37.320] So we also have a record [25:40.040 --> 25:42.040] when the packet is received. [25:42.060 --> 25:44.900] Then we also have the conditional record [25:44.900 --> 25:46.600] for variable isAuthenticated. [25:46.600 --> 25:49.180] Then there is the record for string comparison [25:49.180 --> 25:52.820] that checks the first three bytes of the packet. [25:52.820 --> 25:56.860] Then there is the conditional record for P. [25:56.860 --> 25:58.540] And finally, this is the record [25:58.540 --> 26:02.240] that was created by string.cpyProxy function. [26:02.420 --> 26:06.180] And it describes the fact that the data from buffer [26:06.960 --> 26:08.660] here, I'm sorry, [26:08.660 --> 26:10.580] the data from buffer P plus 4 [26:10.580 --> 26:12.420] was written into buffer. [26:13.180 --> 26:15.660] And the length of the update is [26:15.660 --> 26:18.500] the length of P minus 4 plus 1 [26:18.500 --> 26:20.620] because all bytes of P [26:20.620 --> 26:21.840] except the first four bytes [26:21.840 --> 26:23.920] were copied into buffer buff. [26:24.280 --> 26:27.040] And we also save the preimage of P. [26:32.060 --> 26:34.000] So this is the summary. [26:34.000 --> 26:35.520] These are all log records [26:35.520 --> 26:36.460] that are generated at runtime [26:36.460 --> 26:39.200] when this server attack is executed. [26:39.740 --> 26:42.500] And suppose that the return address [26:42.500 --> 26:46.380] is located after the buff variable. [26:46.380 --> 26:48.260] That is, the return address is saved [26:48.260 --> 26:50.880] at the offset buff plus 17. [26:50.920 --> 26:53.400] Buffer is a buffer of 16 bytes. [26:53.660 --> 26:54.840] So the return address is saved [26:54.840 --> 26:56.320] at the offset 17. [26:57.180 --> 26:58.800] Now let's see how we can detect [26:58.800 --> 27:00.400] the control hijacking attack [27:00.400 --> 27:02.400] using this memory on this log. [27:07.160 --> 27:08.900] So we start with log record, [27:08.900 --> 27:09.820] with the last log record [27:09.820 --> 27:12.520] that overrode this buffer. [27:14.100 --> 27:16.360] And here is its write address. [27:16.360 --> 27:19.460] So we look for the source of this data. [27:19.720 --> 27:20.880] That is, we try to find out [27:20.880 --> 27:22.480] where the data came from. [27:22.840 --> 27:24.460] And this log record allows us to conclude [27:24.460 --> 27:26.660] that this data came from P. [27:27.660 --> 27:28.760] Return address was saved [27:28.760 --> 27:30.540] at the offset buff plus 17. [27:30.540 --> 27:32.280] Therefore, the data was read [27:32.280 --> 27:35.740] from the offset P plus 4 plus 17, [27:35.740 --> 27:37.240] which is P plus 21. [27:37.340 --> 27:38.820] That is, the return address value [27:38.820 --> 27:42.960] came from memory address P plus 4 plus 17, [27:42.960 --> 27:44.320] which is P plus 21. [27:44.340 --> 27:45.680] So this is the new address [27:45.680 --> 27:46.600] that we look for. [27:46.600 --> 27:48.100] Now we search memory on this log [27:48.100 --> 27:50.580] for the address P plus 21. [27:50.900 --> 27:53.440] And if we traverse this log record, [27:53.440 --> 27:55.420] this memory on this log upward, [27:55.420 --> 27:56.340] we can find that there is [27:56.340 --> 27:57.800] this receive record [27:58.500 --> 28:01.880] that read data from network [28:01.880 --> 28:03.040] into buffer P [28:03.040 --> 28:05.120] and the length was 62. [28:05.120 --> 28:08.000] And we look for memory... [28:09.320 --> 28:10.380] memory location [28:10.380 --> 28:12.260] with the address P plus 21. [28:12.600 --> 28:15.140] And this is the record [28:15.140 --> 28:19.340] that has written data from network [28:19.340 --> 28:21.060] into that memory location. [28:21.140 --> 28:22.280] So we conclude that [28:22.280 --> 28:26.020] here is the read operation [28:26.020 --> 28:27.600] that read data from network [28:27.600 --> 28:30.520] and wrote it into address P plus 21. [28:31.040 --> 28:33.400] And because this is the operation [28:33.400 --> 28:34.860] that reads data from network, [28:34.860 --> 28:35.720] we conclude that [28:35.720 --> 28:38.800] this is the attack in packet. [28:39.040 --> 28:40.340] So this way we identify [28:40.720 --> 28:42.460] the first attack in packet. [28:42.720 --> 28:45.080] Is it the only packet in the attack [28:45.080 --> 28:45.320] in packet? [28:45.700 --> 28:46.600] Probably not, [28:46.600 --> 28:48.720] because the user is only processed [28:48.720 --> 28:51.400] if the user has authenticated. [28:51.400 --> 28:52.640] So we need to continue our search [28:52.640 --> 28:54.780] and try to find more attack in packets. [28:56.080 --> 28:56.820] Sure. [29:23.870 --> 29:25.350] Well, debugging is not automatic. [29:25.350 --> 29:26.570] Our tool is completely automatic. [29:26.570 --> 29:28.690] It doesn't require any user involvement at all. [29:28.830 --> 29:30.250] So the process that I described here [29:30.250 --> 29:32.430] is completely automatic. [29:32.430 --> 29:33.670] It's performed by our program, [29:33.670 --> 29:34.590] not by a user. [29:34.590 --> 29:35.690] Not manually. [29:35.830 --> 29:36.790] It's not log analysis [29:36.790 --> 29:38.190] performed by a human expert. [29:38.190 --> 29:38.870] It's log analysis [29:38.870 --> 29:40.230] performed automatically. [29:51.700 --> 29:52.580] Well, [29:54.400 --> 29:55.800] you are right. [30:06.410 --> 30:08.230] Well, that's the question [30:08.230 --> 30:09.370] of our performance evaluation. [30:09.370 --> 30:11.410] We will get to this question later. [30:11.890 --> 30:13.730] And if I don't give a clear answer, [30:13.730 --> 30:15.450] I'd like to talk to you offline. [30:17.010 --> 30:18.490] So as I said previously, [30:18.490 --> 30:19.470] we were able to identify [30:19.470 --> 30:20.850] the first attack in packet. [30:20.850 --> 30:22.830] And now we look for more attack in packets. [30:22.830 --> 30:23.830] And here's where we use [30:23.830 --> 30:25.390] conditional dependencies. [30:25.390 --> 30:28.850] Let's look at the first memory update statement. [30:28.850 --> 30:30.710] If we go upward, [30:30.710 --> 30:31.950] we can see that this statement [30:31.950 --> 30:34.150] depends on two conditions. [30:34.150 --> 30:34.670] That is, [30:34.670 --> 30:38.170] it's inside two outer if statements. [30:38.170 --> 30:39.750] The first if statement checks [30:39.750 --> 30:41.710] p variable, [30:41.710 --> 30:42.870] and the second checks [30:42.870 --> 30:44.850] is authenticate variable. [30:45.290 --> 30:46.250] Therefore, [30:46.250 --> 30:47.010] this memory update [30:47.010 --> 30:47.950] was only possible [30:47.950 --> 30:49.970] because of these two checks [30:49.970 --> 30:51.750] that involve these two variables. [30:52.130 --> 30:53.710] Variable p is, [30:54.310 --> 30:54.970] has been found [30:54.970 --> 30:55.670] before. [30:55.910 --> 30:56.610] So, [30:56.610 --> 30:58.570] this record should be discarded. [30:58.870 --> 30:59.710] Whereas, [30:59.710 --> 31:00.770] this variable [31:00.770 --> 31:01.650] is authenticated [31:01.650 --> 31:02.150] should be used [31:02.150 --> 31:03.470] for later search. [31:04.730 --> 31:05.710] So we continue [31:05.710 --> 31:07.270] with variable is authenticated. [31:07.270 --> 31:08.130] And we try to find out [31:08.130 --> 31:08.930] whether this variable [31:08.930 --> 31:10.130] depends on network packet [31:10.130 --> 31:11.350] or not. [31:11.530 --> 31:11.910] So, [31:11.910 --> 31:12.830] if we continue traversing [31:12.830 --> 31:13.970] the block upward, [31:13.970 --> 31:15.130] we can see this memory update [31:15.130 --> 31:16.690] block operation. [31:16.950 --> 31:17.850] And the read address [31:17.850 --> 31:18.610] of this operation [31:18.610 --> 31:19.230] is unknown [31:19.230 --> 31:20.650] because this variable [31:20.650 --> 31:22.130] was assigned to a constant. [31:22.230 --> 31:22.770] Therefore, [31:22.770 --> 31:23.450] we should again use [31:23.450 --> 31:24.550] condition dependencies [31:24.550 --> 31:24.990] to [31:24.990 --> 31:26.450] find out [31:27.090 --> 31:28.010] what our [31:28.010 --> 31:28.950] variable [31:28.950 --> 31:29.650] is authenticated [31:29.650 --> 31:29.950] depends [31:29.950 --> 31:31.570] on. [31:31.830 --> 31:32.590] And we can see [31:32.590 --> 31:33.310] two conditional [31:33.310 --> 31:34.370] lock records [31:34.370 --> 31:35.410] isUser and p [31:35.410 --> 31:36.350] here. [31:37.070 --> 31:37.930] Which means [31:37.930 --> 31:38.650] that variable [31:38.650 --> 31:39.450] is authenticated [31:40.370 --> 31:40.710] depends [31:40.710 --> 31:41.130] conditionally [31:41.130 --> 31:42.810] on isUser and p. [31:43.610 --> 31:44.310] So, [31:44.310 --> 31:44.930] we now look for [31:44.930 --> 31:46.330] p and isUser. [31:46.330 --> 31:46.890] We can find [31:46.890 --> 31:48.070] p here. [31:49.030 --> 31:49.410] Therefore, [31:49.410 --> 31:49.830] we conclude [31:49.830 --> 31:50.410] that variable [31:50.410 --> 31:51.550] isUser depends [31:51.550 --> 31:52.470] on network packet [31:52.470 --> 31:53.810] that contains [31:53.810 --> 31:54.830] password. [31:54.830 --> 31:55.990] And this turns out [31:55.990 --> 31:56.410] to be true [31:56.410 --> 31:56.850] because [31:58.650 --> 31:59.250] variable [31:59.250 --> 31:59.650] p [32:00.390 --> 32:01.230] is set [32:01.230 --> 32:01.550] only [32:01.550 --> 32:02.730] if the [32:02.730 --> 32:03.350] attacker sends [32:03.350 --> 32:04.570] password packet. [32:05.110 --> 32:05.630] That variable [32:05.630 --> 32:06.270] isUser also [32:06.270 --> 32:06.730] depends [32:07.690 --> 32:08.390] sorry, [32:08.390 --> 32:08.590] variable [32:08.590 --> 32:09.190] isAuthenticated [32:09.190 --> 32:09.790] also depends [32:09.790 --> 32:10.510] on isUser. [32:10.510 --> 32:11.090] So, we continue [32:11.090 --> 32:11.390] with this [32:11.390 --> 32:11.630] variable [32:11.630 --> 32:12.070] isUser [32:12.070 --> 32:13.050] and we can [32:13.050 --> 32:13.330] find it [32:13.330 --> 32:14.170] here. [32:14.690 --> 32:15.070] This is the [32:15.070 --> 32:15.670] memory update [32:15.670 --> 32:16.570] long operation [32:16.570 --> 32:17.110] that sets [32:17.110 --> 32:17.450] variable [32:17.450 --> 32:18.210] isUser. [32:18.210 --> 32:18.830] Its readers [32:18.830 --> 32:19.410] is also [32:19.410 --> 32:19.710] unknown [32:19.710 --> 32:20.510] because it's [32:20.510 --> 32:20.790] set to [32:20.790 --> 32:21.630] constant. [32:21.630 --> 32:22.010] Therefore, [32:22.010 --> 32:22.170] we should [32:22.170 --> 32:22.630] use [32:22.630 --> 32:23.110] control [32:23.110 --> 32:24.050] dependencies [32:24.050 --> 32:25.310] to find [32:25.310 --> 32:25.530] out [32:25.530 --> 32:25.770] whether [32:25.770 --> 32:26.130] variable [32:26.130 --> 32:26.550] isUser [32:26.550 --> 32:26.970] depends [32:26.970 --> 32:27.830] on any [32:27.830 --> 32:28.130] network [32:28.130 --> 32:29.170] packets. [32:30.370 --> 32:31.650] And once [32:31.650 --> 32:31.930] again, [32:31.930 --> 32:32.070] we can [32:32.070 --> 32:32.550] see this [32:32.550 --> 32:33.050] conditional [32:33.050 --> 32:33.850] string expression [32:33.850 --> 32:34.410] that uses [32:34.410 --> 32:34.730] variable [32:34.730 --> 32:35.590] P. [32:35.830 --> 32:36.390] Therefore, [32:36.390 --> 32:36.750] we now [32:36.750 --> 32:37.730] search for [32:37.730 --> 32:38.010] variable [32:38.010 --> 32:38.750] P and [32:38.750 --> 32:38.970] try to [32:38.970 --> 32:39.350] find out [32:39.350 --> 32:39.570] whether [32:39.570 --> 32:39.950] it depends [32:39.950 --> 32:40.250] on any [32:40.250 --> 32:40.530] network [32:40.530 --> 32:41.390] data. [32:41.690 --> 32:42.550] And it [32:42.550 --> 32:42.870] turns out [32:42.870 --> 32:43.050] to be [32:43.050 --> 32:43.650] true. [32:43.650 --> 32:43.910] Variable [32:43.910 --> 32:44.230] P [32:44.230 --> 32:44.790] contains [32:44.790 --> 32:45.230] the [32:45.230 --> 32:45.670] packet [32:45.670 --> 32:46.090] payload [32:46.090 --> 32:46.750] of the [32:46.750 --> 32:46.910] user [32:46.910 --> 32:47.790] command. [32:47.790 --> 32:48.630] So what we can [32:48.630 --> 32:49.110] see now, [32:49.110 --> 32:49.350] we have [32:49.350 --> 32:49.630] found [32:49.630 --> 32:50.090] three [32:50.090 --> 32:50.470] attack [32:50.470 --> 32:51.390] packets. [32:52.570 --> 32:53.590] And so [32:53.590 --> 32:54.010] the get [32:54.010 --> 32:54.790] packet, [32:54.790 --> 32:55.150] the pass [32:55.150 --> 32:55.450] packet, [32:55.450 --> 32:55.650] the user [32:55.650 --> 32:56.450] packet. [32:56.990 --> 32:57.610] The first [32:57.610 --> 32:58.010] packet was [32:58.010 --> 32:58.670] found using [32:58.670 --> 32:59.070] direct [32:59.070 --> 32:59.730] dependencies. [32:59.730 --> 33:00.130] The remaining [33:00.130 --> 33:00.590] two packets [33:00.590 --> 33:01.350] were found [33:01.350 --> 33:01.750] using [33:01.750 --> 33:02.130] control [33:02.130 --> 33:03.090] dependencies. [33:03.610 --> 33:04.090] So the [33:04.090 --> 33:04.350] control [33:04.350 --> 33:04.650] dependencies [33:04.650 --> 33:05.430] are really [33:05.430 --> 33:06.430] important to [33:06.430 --> 33:07.470] link the [33:07.470 --> 33:07.970] first attack [33:07.970 --> 33:08.930] packet to [33:08.930 --> 33:09.670] all the [33:09.670 --> 33:09.990] remaining [33:09.990 --> 33:10.330] attack [33:10.330 --> 33:11.370] packets. [33:12.110 --> 33:13.070] Because of [33:13.070 --> 33:13.570] this state [33:13.570 --> 33:13.970] variables [33:13.970 --> 33:14.210] that are [33:14.210 --> 33:14.930] used in [33:14.930 --> 33:15.210] network [33:15.210 --> 33:16.250] daemons. [33:27.160 --> 33:27.880] Well, this is [33:27.880 --> 33:28.200] just our [33:28.200 --> 33:29.220] assumption. [33:29.460 --> 33:30.140] Well, the [33:30.140 --> 33:30.800] real value [33:30.800 --> 33:31.420] of the [33:31.420 --> 33:31.820] return [33:31.820 --> 33:33.160] errors is [33:33.160 --> 33:33.860] returned by [33:33.860 --> 33:34.160] the attack [33:34.160 --> 33:34.460] detection [33:34.460 --> 33:35.540] component. [33:39.300 --> 33:40.120] Well, this [33:40.120 --> 33:40.380] attack [33:40.380 --> 33:40.860] detection [33:41.440 --> 33:41.960] component [33:41.960 --> 33:42.560] tells you [33:42.560 --> 33:43.120] which [33:43.120 --> 33:43.480] data [33:43.480 --> 33:43.760] structure [33:43.760 --> 33:43.940] was [33:43.940 --> 33:44.820] damaged. [33:45.060 --> 33:45.860] So it [33:45.860 --> 33:46.220] tells you [33:46.220 --> 33:46.980] the return [33:46.980 --> 33:48.060] address of [33:48.060 --> 33:48.280] the [33:48.280 --> 33:48.640] compromised [33:48.640 --> 33:48.900] data [33:48.900 --> 33:49.640] structure, [33:49.640 --> 33:49.880] which in [33:49.880 --> 33:50.000] our [33:50.000 --> 33:50.600] case is [33:50.600 --> 33:50.740] the [33:50.740 --> 33:50.960] return [33:50.960 --> 33:51.740] address. [33:51.900 --> 33:52.400] So this [33:52.400 --> 33:52.700] assumption [33:52.700 --> 33:53.500] I just [33:53.500 --> 33:53.780] made it [33:53.780 --> 33:54.480] up. [33:54.840 --> 33:55.220] But this [33:55.220 --> 33:55.580] address is [33:55.580 --> 33:55.740] always [33:55.740 --> 33:56.600] known at [33:56.600 --> 33:57.300] runtime. [34:00.580 --> 34:01.260] Let's now [34:01.260 --> 34:01.880] give a [34:01.880 --> 34:02.280] precise [34:02.280 --> 34:02.440] definition [34:02.440 --> 34:02.620] of [34:02.620 --> 34:02.880] control [34:02.880 --> 34:05.360] dependencies. [34:05.360 --> 34:06.220] We say [34:06.220 --> 34:07.080] that [34:07.240 --> 34:07.440] whenever a [34:07.440 --> 34:07.720] variable [34:07.720 --> 34:08.100] x can [34:08.100 --> 34:08.380] prevent [34:08.380 --> 34:08.600] control [34:08.600 --> 34:08.840] flow [34:08.840 --> 34:09.020] from [34:09.020 --> 34:09.300] reaching [34:09.300 --> 34:09.680] variable [34:09.680 --> 34:10.080] y, a [34:10.080 --> 34:10.320] control [34:10.320 --> 34:10.500] dependency [34:10.500 --> 34:11.060] is created [34:11.060 --> 34:11.300] between [34:11.300 --> 34:11.640] x and [34:11.640 --> 34:27.520] y. [34:25.620 --> 34:26.620] Let's [34:27.520 --> 34:27.920] look at [34:27.920 --> 34:28.040] the [34:28.040 --> 34:28.400] value of [34:28.400 --> 34:28.640] variable [34:28.640 --> 34:28.960] cond [34:28.960 --> 34:29.620] is. [34:29.620 --> 34:30.220] However, [34:30.220 --> 34:30.500] if you [34:30.500 --> 34:30.720] look at [34:30.720 --> 34:30.820] the [34:30.820 --> 34:31.060] right-hand [34:31.060 --> 34:32.900] side, [34:32.900 --> 34:33.780] then one [34:33.780 --> 34:33.980] of these [34:33.980 --> 34:34.300] branches [34:34.300 --> 34:34.960] here, [34:34.960 --> 34:35.180] this [34:35.180 --> 34:36.780] branch, [34:36.780 --> 34:37.420] has a [34:37.420 --> 34:39.060] return. [34:39.060 --> 34:39.400] And [34:39.400 --> 34:39.780] therefore, [34:39.780 --> 34:40.220] if [34:40.220 --> 34:41.240] condition [34:41.240 --> 34:41.900] is [34:41.900 --> 34:42.100] takes [34:51.820 --> 34:52.340] such [34:55.520 --> 34:56.520] a [34:53.620 --> 34:54.300] value [34:54.300 --> 34:54.640] from [34:55.280 --> 34:55.440] x [34:57.960 --> 34:58.640] to [34:58.640 --> 34:59.580] then [34:59.580 --> 34:59.780] value [35:04.040 --> 35:04.720] is [35:04.720 --> 35:04.820] returned [35:04.820 --> 35:04.980] y. [35:10.180 --> 35:10.860] And [35:16.980 --> 35:17.660] therefore, [35:17.660 --> 35:17.680] the [35:17.680 --> 35:17.900] value [35:17.900 --> 35:18.000] of [35:18.000 --> 35:18.340] condition [35:20.060 --> 35:20.740] is [35:20.740 --> 35:20.760] returned [35:20.760 --> 35:20.780] from [35:21.240 --> 35:21.580] x [35:22.300 --> 35:22.820] to [35:22.820 --> 35:22.860] y. [35:25.600 --> 35:26.280] So [35:26.960 --> 35:27.620] this [35:27.620 --> 35:27.820] the [35:27.820 --> 35:28.940] value [35:38.280 --> 35:38.940] of [35:38.940 --> 35:40.360] condition. [35:40.660 --> 35:42.600] therefore, [35:43.900 --> 35:44.560] the [35:44.560 --> 35:45.160] value [35:45.160 --> 35:45.260] of [35:45.260 --> 35:45.280] condition [35:45.280 --> 35:45.560] is [35:45.560 --> 35:45.940] returned [35:47.720 --> 35:48.380] from [35:48.380 --> 35:48.880] x [35:50.400 --> 35:51.060] to [35:51.060 --> 35:51.080] y. [35:54.240 --> 35:54.900] And [35:54.900 --> 35:54.940] therefore, [35:54.940 --> 35:54.960] the [35:54.960 --> 35:54.980] value [35:54.980 --> 35:55.000] of [35:55.000 --> 35:55.020] condition [35:55.020 --> 35:55.040] is [35:55.040 --> 35:55.060] returned [35:55.060 --> 35:55.080] from [35:55.080 --> 35:56.240] x [35:56.240 --> 35:56.260] to [35:58.220 --> 35:59.340] y. [36:03.840 --> 36:04.400] therefore, [36:04.400 --> 36:04.720] the [36:04.720 --> 36:05.280] of [36:06.160 --> 36:06.720] condition [36:06.720 --> 36:07.000] is [36:07.000 --> 36:07.420] returned [36:07.420 --> 36:07.560] from [36:07.560 --> 36:07.580] x [36:07.580 --> 36:08.040] y. [36:08.300 --> 36:08.860] And [36:08.860 --> 36:09.440] therefore, [36:09.440 --> 36:09.560] value [36:09.560 --> 36:09.640] of [36:09.640 --> 36:09.840] condition [36:09.840 --> 36:10.020] is [36:10.020 --> 36:10.200] returned [36:12.080 --> 36:12.640] from [36:12.640 --> 36:13.080] x [36:13.080 --> 36:13.220] to [36:14.580 --> 36:15.440] y. [36:25.120 --> 36:25.680] And [36:25.680 --> 36:25.980] therefore, [36:25.980 --> 36:26.140] the [36:26.140 --> 36:26.160] value [36:26.160 --> 36:26.780] of [36:27.480 --> 36:27.980] condition [36:31.080 --> 36:31.580] returned [36:31.580 --> 36:31.620] from [36:31.620 --> 36:31.860] y. [36:38.900 --> 36:39.400] And [36:39.400 --> 36:45.760] therefore, [36:46.860 --> 36:47.360] the [36:52.760 --> 36:53.260] value [36:53.260 --> 36:53.280] is [36:53.280 --> 36:53.740] returned [36:53.740 --> 36:53.880] from [36:53.880 --> 36:54.080] y. [36:54.080 --> 36:54.580] And [36:54.580 --> 36:55.060] therefore, [36:55.060 --> 36:55.160] the [36:55.160 --> 36:55.340] value [36:55.340 --> 36:55.780] of [36:55.780 --> 36:55.800] is [36:55.800 --> 36:56.580] returned [36:56.580 --> 36:56.860] from [36:56.860 --> 36:57.300] x [37:07.220 --> 37:08.020] And [37:08.020 --> 37:08.660] therefore, [37:08.660 --> 37:09.620] the [37:13.380 --> 37:14.180] value [37:21.000 --> 37:21.800] of [37:21.800 --> 37:22.060] condition [37:23.600 --> 37:24.400] is [37:24.400 --> 37:24.860] returned [37:24.860 --> 37:24.880] from [37:24.880 --> 37:25.100] x [37:25.100 --> 37:25.120] to [37:25.120 --> 37:25.420] y. [37:25.420 --> 37:25.780] And [37:25.780 --> 37:26.180] therefore, [37:26.180 --> 37:26.320] the [37:26.320 --> 37:26.560] value [37:28.620 --> 37:29.140] of [37:29.140 --> 37:29.540] condition [37:29.540 --> 37:29.880] is [37:29.880 --> 37:30.800] from [37:30.800 --> 37:31.020] x [37:31.920 --> 37:32.440] to [37:32.440 --> 37:32.540] y. [37:45.960 --> 37:46.480] And [37:46.480 --> 37:47.020] therefore, [37:47.020 --> 37:47.040] the [37:47.040 --> 37:47.300] value [37:47.300 --> 37:47.540] of [37:48.260 --> 37:48.780] condition [37:48.780 --> 37:48.940] is [37:48.940 --> 37:49.300] returned [37:49.300 --> 37:49.560] from [37:52.120 --> 37:52.640] x [37:52.640 --> 37:53.200] y. [37:53.340 --> 37:53.380] And [37:53.380 --> 37:53.880] therefore, [37:53.880 --> 37:53.900] the [37:53.900 --> 37:53.960] value [37:55.140 --> 37:55.660] condition [37:55.660 --> 37:56.380] is [38:05.040 --> 38:06.240] returned [38:17.780 --> 38:18.980] from [38:20.260 --> 38:21.460] And [38:21.460 --> 38:22.340] therefore, [38:22.340 --> 38:22.820] the [38:22.820 --> 38:22.840] is [38:22.840 --> 38:24.400] returned [38:24.400 --> 38:24.700] from [38:24.700 --> 38:24.720] x [38:24.720 --> 38:24.740] to [38:24.740 --> 38:24.780] y. [38:24.780 --> 38:25.640] And [38:39.540 --> 38:41.260] therefore, [38:41.260 --> 38:41.500] value [38:41.500 --> 38:41.600] of [38:41.600 --> 38:42.180] condition [38:42.180 --> 38:42.400] is [38:42.400 --> 38:42.860] returned [38:44.420 --> 38:45.280] from [38:45.280 --> 38:45.420] y. [38:45.420 --> 38:45.840] And [38:45.840 --> 38:46.500] therefore, [38:46.500 --> 38:46.600] the [38:46.600 --> 38:46.900] value [38:46.900 --> 38:46.920] of [38:46.920 --> 38:48.640] condition [38:48.640 --> 38:49.100] is [38:49.100 --> 38:49.500] returned [38:49.500 --> 38:50.600] from [38:52.720 --> 38:53.580] x [38:53.580 --> 38:54.020] to [38:54.020 --> 38:54.900] y. [38:55.340 --> 38:55.620] And [39:07.140 --> 39:08.660] therefore, [39:08.660 --> 39:09.180] the [39:09.180 --> 39:09.440] value [39:09.440 --> 39:09.620] of [39:09.620 --> 39:09.860] condition [39:12.300 --> 39:13.340] from [39:13.340 --> 39:13.960] y. [39:13.960 --> 39:13.980] And [39:13.980 --> 39:15.900] therefore, [39:15.900 --> 39:15.920] of [39:15.920 --> 39:17.240] condition [39:17.240 --> 39:18.920] is [39:18.920 --> 39:19.060] returned [39:19.060 --> 39:19.140] from [39:20.740 --> 39:21.780] x [39:24.680 --> 39:26.760] therefore, [39:26.760 --> 39:26.780] the [39:26.780 --> 39:27.380] value [39:27.380 --> 39:27.420] of [39:27.420 --> 39:27.520] condition [39:27.520 --> 39:27.680] is [39:27.680 --> 39:28.460] from [39:29.640 --> 39:30.200] x [39:30.200 --> 39:30.260] to [39:37.720 --> 39:38.280] And [39:38.280 --> 39:38.540] therefore, [39:38.540 --> 39:38.560] the [39:38.560 --> 39:39.640] value [39:39.640 --> 39:40.580] of [39:44.100 --> 39:44.660] condition [39:44.660 --> 39:45.380] is [39:45.380 --> 39:45.980] y. [39:46.580 --> 39:47.140] And [39:47.140 --> 39:47.480] therefore, [39:47.480 --> 39:47.760] condition [39:47.760 --> 39:47.920] is [39:47.920 --> 39:48.280] returned [39:48.280 --> 39:48.460] from [39:56.920 --> 39:57.480] x [39:57.480 --> 39:57.500] to [39:59.600 --> 40:00.320] y. [40:08.440 --> 40:09.060] therefore, [40:09.060 --> 40:09.100] the [40:09.100 --> 40:09.360] value [40:09.360 --> 40:09.540] of [40:10.440 --> 40:10.800] condition [40:16.860 --> 40:17.220] is [40:17.940 --> 40:18.300] returned [40:18.300 --> 40:18.340] from [40:18.340 --> 40:18.380] y. [40:18.740 --> 40:19.100] And [40:19.100 --> 40:19.220] therefore, [40:19.220 --> 40:19.680] the [40:19.680 --> 40:19.700] value [40:19.700 --> 40:19.880] of [40:19.880 --> 40:20.060] condition [40:20.060 --> 40:20.140] is [40:20.140 --> 40:20.160] returned [40:20.160 --> 40:20.240] from [40:21.900 --> 40:22.260] x [40:22.260 --> 40:22.780] to [40:23.240 --> 40:23.700] y. [40:23.700 --> 40:23.880] And [40:24.860 --> 40:25.240] therefore, [40:25.240 --> 40:25.260] the [40:25.260 --> 40:25.420] value [40:25.420 --> 40:26.000] of [40:26.000 --> 40:26.460] condition [40:26.460 --> 40:26.620] is [40:26.620 --> 40:26.860] returned [40:26.860 --> 40:27.780] x [40:28.220 --> 40:29.000] And [40:29.000 --> 40:29.580] therefore, [40:32.220 --> 40:33.000] the [40:33.000 --> 40:33.200] value [40:37.920 --> 40:38.700] of [40:38.700 --> 40:39.060] condition [40:44.120 --> 40:44.900] returned [40:44.900 --> 40:45.540] from [40:45.540 --> 40:45.780] x [40:45.780 --> 40:45.960] to [40:45.960 --> 40:46.420] y. [40:46.580 --> 40:47.360] And [40:47.360 --> 40:47.500] therefore, [40:47.500 --> 40:47.520] the [40:49.160 --> 40:49.940] of [40:50.960 --> 40:51.740] condition [40:51.740 --> 40:51.840] is [40:51.840 --> 40:51.860] returned [40:51.860 --> 40:51.880] from [40:53.660 --> 40:54.220] x [41:00.160 --> 41:00.720] to [41:00.720 --> 41:01.720] y. [41:01.840 --> 41:02.400] And [41:02.400 --> 41:02.420] therefore, [41:02.420 --> 41:02.640] value [41:02.640 --> 41:02.680] of [41:02.680 --> 41:03.480] is [41:03.480 --> 41:04.040] returned [41:05.480 --> 41:06.040] x [41:07.180 --> 41:07.740] to [41:07.740 --> 41:08.300] y. [41:09.620 --> 41:09.900] And [41:09.900 --> 41:10.060] therefore, [41:10.060 --> 41:10.080] the [41:10.080 --> 41:10.380] value [41:10.380 --> 41:10.660] of [41:10.660 --> 41:10.760] is [41:10.760 --> 41:11.000] returned [41:15.540 --> 41:16.100] from [41:16.100 --> 41:16.340] x [41:16.340 --> 41:16.460] to [41:16.460 --> 41:16.620] y. [41:20.380 --> 41:20.940] And [41:20.940 --> 41:21.660] therefore, [41:21.660 --> 41:22.020] the [41:23.540 --> 41:23.980] value [41:23.980 --> 41:24.620] of [41:24.620 --> 41:24.840] from [41:41.900 --> 41:42.340] And [41:42.340 --> 41:45.300] therefore, [41:48.680 --> 41:48.820] value [41:48.820 --> 41:48.980] of [41:48.980 --> 41:49.200] condition [41:50.360 --> 41:50.800] is [41:50.800 --> 41:50.820] returned [41:50.820 --> 41:51.040] from [41:51.640 --> 41:52.080] x [41:52.080 --> 41:52.180] to [41:52.180 --> 41:53.240] y. [42:00.940 --> 42:01.380] And [42:01.380 --> 42:01.580] therefore, [42:01.580 --> 42:02.100] the [42:02.780 --> 42:03.220] value [42:03.220 --> 42:03.240] of [42:03.240 --> 42:03.260] condition [42:03.260 --> 42:03.280] is [42:07.940 --> 42:08.420] returned [42:12.580 --> 42:13.060] from [42:14.120 --> 42:14.600] x [42:14.600 --> 42:14.820] to [42:14.820 --> 42:14.960] y. [42:14.960 --> 42:15.140] And [42:15.140 --> 42:15.200] therefore, [42:15.200 --> 42:15.540] value [42:15.540 --> 42:16.220] of [42:20.980 --> 42:21.460] condition [42:21.460 --> 42:21.640] is [42:21.640 --> 42:22.060] returned [42:22.060 --> 42:22.180] from [42:22.180 --> 42:22.920] x [42:22.920 --> 42:23.540] y. [42:25.700 --> 42:26.180] And [42:26.180 --> 42:26.460] therefore, [42:26.460 --> 42:26.520] the [42:26.520 --> 42:26.720] value [42:31.940 --> 42:32.420] condition [42:32.420 --> 42:32.660] is [42:32.660 --> 42:32.860] returned [42:32.860 --> 42:33.040] from [42:33.040 --> 42:33.260] x [42:33.980 --> 42:34.540] to [42:34.540 --> 42:35.140] y. [42:38.360 --> 42:38.920] And [42:38.920 --> 42:39.080] therefore, [42:39.080 --> 42:39.100] the [42:39.100 --> 42:39.380] value [42:42.300 --> 42:42.860] of [42:42.860 --> 42:43.000] condition [42:44.360 --> 42:44.920] is [42:45.480 --> 42:46.040] x [42:51.020 --> 42:51.580] to [42:54.360 --> 42:55.120] y. [42:55.120 --> 42:55.640] And [42:55.640 --> 42:56.580] therefore, [42:56.580 --> 42:57.100] the [42:57.100 --> 42:57.120] value [42:57.120 --> 42:57.140] of [42:57.140 --> 42:57.160] condition [42:57.160 --> 42:57.340] is [42:57.340 --> 42:57.780] returned [42:57.780 --> 42:57.920] from [42:57.920 --> 42:58.200] x [42:58.200 --> 42:58.480] to [42:58.940 --> 42:59.600] y. [42:59.600 --> 43:00.140] And [43:00.140 --> 43:00.460] therefore, [43:00.460 --> 43:00.600] the [43:00.600 --> 43:01.000] value [43:02.260 --> 43:02.860] returned [43:02.860 --> 43:03.260] from [43:03.260 --> 43:03.540] to [43:03.540 --> 43:03.580] y. [43:03.580 --> 43:04.120] And [43:08.400 --> 43:09.600] therefore, [43:10.380 --> 43:10.980] the [43:21.000 --> 43:21.600] value [43:21.600 --> 43:21.620] of [43:21.620 --> 43:21.640] condition [43:21.640 --> 43:21.660] is [43:21.660 --> 43:21.880] returned [43:21.880 --> 43:21.900] from [43:21.900 --> 43:22.000] x [43:22.000 --> 43:22.300] y. [43:22.360 --> 43:22.960] And [43:22.960 --> 43:23.600] therefore, [43:24.740 --> 43:24.760] the [43:24.760 --> 43:25.560] value [43:25.560 --> 43:25.820] of [43:25.820 --> 43:26.000] condition [43:26.920 --> 43:27.520] is [43:27.520 --> 43:27.660] returned [43:28.380 --> 43:29.060] from [43:36.840 --> 43:37.520] x [43:37.520 --> 43:37.680] to [43:37.680 --> 43:38.300] y. [43:38.300 --> 43:38.620] And [43:38.620 --> 43:39.460] therefore, [43:39.460 --> 43:39.580] the [43:39.580 --> 43:40.160] value [43:40.160 --> 43:41.300] condition [43:41.300 --> 43:41.320] is [43:44.960 --> 43:45.640] returned [43:45.640 --> 43:45.720] from [43:45.720 --> 43:46.240] x [43:46.240 --> 43:46.360] to [43:46.360 --> 43:47.080] y. [43:47.380 --> 43:48.060] And [43:48.060 --> 43:48.220] therefore, [43:48.220 --> 43:48.240] the [43:48.240 --> 43:48.740] value [43:48.740 --> 43:49.060] of [43:49.060 --> 43:49.120] is [43:49.120 --> 43:49.280] returned [43:49.280 --> 43:49.820] from [43:52.500 --> 43:53.180] x [43:53.180 --> 43:53.520] to [43:53.520 --> 43:54.060] y. [43:54.360 --> 43:55.040] And [44:21.740 --> 44:22.620] therefore, [44:22.620 --> 44:23.020] condition [44:23.020 --> 44:23.800] is [44:23.800 --> 44:24.080] y. [44:24.080 --> 44:24.300] And [44:24.300 --> 44:24.840] therefore, [44:24.840 --> 44:24.880] is [44:24.880 --> 44:25.040] returned [44:25.040 --> 44:25.260] from [44:25.260 --> 44:25.680] x [44:25.680 --> 44:25.700] y. [44:25.700 --> 44:25.960] And [44:25.960 --> 44:26.000] therefore, [44:26.000 --> 44:26.020] the [44:26.020 --> 44:26.240] value [44:26.240 --> 44:26.380] of [44:26.380 --> 44:27.020] condition [44:29.740 --> 44:30.880] is [44:35.960 --> 44:37.100] returned [44:37.100 --> 44:37.560] x [44:37.560 --> 44:38.540] to [44:38.540 --> 44:39.120] And [44:39.120 --> 44:39.360] therefore, [44:39.360 --> 44:39.600] of [44:39.600 --> 44:40.380] is [44:41.440 --> 44:41.840] returned [44:41.840 --> 44:41.860] from [44:42.380 --> 44:43.200] x [44:43.200 --> 44:43.760] to [44:43.760 --> 44:44.640] y. [44:58.040 --> 44:59.180] And [44:59.180 --> 44:59.640] therefore, [44:59.640 --> 44:59.860] condition [45:06.460 --> 45:07.030] x [45:07.610 --> 45:08.110] to [45:16.430 --> 45:16.930] y [45:16.930 --> 45:17.310] is [45:22.190 --> 45:22.690] returned [45:22.690 --> 45:23.330] to [45:23.330 --> 45:23.530] y. [45:24.810 --> 45:25.310] And [45:29.650 --> 45:30.150] therefore, [45:30.150 --> 45:30.410] value [45:30.410 --> 45:30.570] of [45:30.570 --> 45:31.090] condition [45:31.090 --> 45:31.110] is [45:33.810 --> 45:34.310] returned [45:34.310 --> 45:34.410] from [45:34.410 --> 45:34.910] x [45:34.910 --> 45:35.090] to [45:35.090 --> 45:35.410] y. [45:35.410 --> 45:35.710] And [45:35.710 --> 45:35.910] therefore, [45:35.910 --> 45:36.150] value [45:36.150 --> 45:36.170] of [45:36.170 --> 45:36.390] condition [45:36.390 --> 45:36.910] is [45:36.910 --> 45:37.010] returned [45:39.770 --> 45:41.170] from [45:43.910 --> 45:45.310] x [46:04.150 --> 46:05.550] to [46:05.550 --> 46:06.850] y. [46:06.850 --> 46:06.970] And [46:06.970 --> 46:06.990] value [46:10.230 --> 46:10.730] of [46:33.220 --> 46:33.720] condition [46:33.720 --> 46:34.640] returned [46:34.640 --> 46:34.660] from [46:34.660 --> 46:34.680] x [46:34.680 --> 46:34.700] y. [46:34.700 --> 46:34.720] And [46:34.720 --> 46:34.740] therefore, [46:34.740 --> 46:35.440] returned [46:35.440 --> 46:35.920] x [46:35.920 --> 46:36.160] to [46:36.800 --> 46:37.320] y. [46:37.320 --> 46:37.580] And [46:46.930 --> 46:47.430] therefore, [46:47.430 --> 46:47.610] condition [46:47.610 --> 46:47.670] is [46:47.670 --> 46:47.690] returned [46:47.690 --> 46:48.130] from [46:48.130 --> 46:48.830] x [47:11.320 --> 47:12.720] to [47:35.780 --> 47:37.180] y. [47:37.180 --> 47:37.260] And [47:37.260 --> 47:37.480] therefore, [47:37.480 --> 47:37.840] value [47:44.540 --> 47:45.340] of [47:45.340 --> 47:45.600] condition [47:45.600 --> 47:47.140] is [47:47.140 --> 47:47.500] returned [47:47.500 --> 47:47.540] from [47:47.540 --> 47:47.580] y. [47:47.580 --> 47:48.360] And [47:48.360 --> 47:52.220] therefore, [47:52.220 --> 47:53.040] condition [47:53.040 --> 47:53.240] is [47:53.240 --> 47:53.500] returned [47:53.500 --> 47:53.920] to [47:53.920 --> 47:54.500] y. [47:57.620 --> 47:58.420] And [47:58.420 --> 47:59.140] therefore, [47:59.140 --> 47:59.800] value [47:59.800 --> 48:00.040] condition [48:00.040 --> 48:00.580] is [48:00.580 --> 48:00.780] returned [48:00.780 --> 48:01.340] from [48:06.660 --> 48:07.460] x [48:07.460 --> 48:08.900] to [48:19.840 --> 48:21.600] y. [48:22.080 --> 48:22.260] And [48:22.260 --> 48:23.880] therefore, [48:26.500 --> 48:27.380] value [48:27.380 --> 48:27.820] is [48:27.820 --> 48:28.580] returned [48:28.580 --> 48:28.780] x [48:28.780 --> 48:29.260] to [48:29.260 --> 48:29.600] y. [48:29.600 --> 48:29.980] And [48:29.980 --> 48:30.280] therefore, [48:30.280 --> 48:30.680] is [48:30.680 --> 48:30.880] returned [48:30.880 --> 48:32.620] x [48:32.620 --> 48:33.320] to [48:33.320 --> 48:34.460] y. [48:34.640 --> 48:34.960] And [48:34.960 --> 48:35.660] therefore, [48:35.660 --> 48:36.220] condition [48:36.220 --> 48:36.480] is [48:37.000 --> 48:37.620] returned [48:37.880 --> 48:38.500] from [48:38.500 --> 48:38.980] x [48:55.460 --> 48:56.700] And [48:56.700 --> 49:05.300] therefore, [49:05.300 --> 49:06.680] value [49:06.680 --> 49:06.920] of [49:06.920 --> 49:07.920] condition [49:07.920 --> 49:08.160] is [49:08.160 --> 49:08.780] returned [49:08.780 --> 49:09.220] y. [49:09.220 --> 49:10.180] And [49:10.180 --> 49:10.240] y. [49:10.240 --> 49:11.120] And [49:44.210 --> 49:45.370] therefore, [49:45.370 --> 49:45.670] condition [49:47.170 --> 49:47.750] is [49:47.750 --> 49:48.030] returned [49:48.030 --> 49:48.270] x [49:48.270 --> 49:48.670] to [49:48.670 --> 49:48.770] y. [49:49.450 --> 49:50.030] And [49:50.030 --> 49:50.090] therefore, [49:50.090 --> 49:50.130] value [49:50.130 --> 49:50.170] returned [49:50.170 --> 49:52.690] This is the length of packet, this is the packet that represents the regular expression, [49:52.690 --> 49:56.070] this is the length constraint. This is pretty much the same as the signature that we constructed [49:56.070 --> 50:03.450] in our example. This is the bind signature, signature for DNS daemon. So one packet, this [50:03.450 --> 50:10.450] is the length, this is the length constraint. Remote cat daemon has a signature that consists [50:11.370 --> 50:17.250] of three packets because this cat daemon requires user authentication. So here we can see user [50:17.250 --> 50:28.510] packet, password packet, the length constraint and the, yes, and the last packet. All the [50:28.510 --> 50:31.730] signatures will generate automatically from a single attack instance. [50:33.350 --> 50:38.230] Now let's talk about the recovery. Is it really useful? The overhead is pretty high at 70%. [50:38.230 --> 50:44.270] Maybe we can do well without recovery. And we think that recovery is really useful because [50:44.270 --> 50:49.490] many programs are single-thread and they are, like, event-driven. And if you just terminate [50:49.490 --> 50:54.710] the program, then you disconnect all the clients. So you have only one bad client, you have, [50:54.710 --> 50:58.650] let's say, a dozen of good clients. You disconnect one bad and disconnect a dozen of good, which [50:58.650 --> 51:04.010] is very bad for good clients. And the same attack can be reviewed in the future, and [51:04.010 --> 51:08.150] therefore the attacker can implement the denial of service attack if you simply terminate [51:08.150 --> 51:12.130] the program instead of recovering. If you recover it, then repair the effect of the [51:12.130 --> 51:16.030] bad guy, but you allow good guys to continue their execution. [51:17.070 --> 51:21.450] And the same trade-off exists in the case of source code analysis tools. Whenever you [51:22.590 --> 51:28.990] have a bug, if you use static code analysis tool, then you first need to find out this [51:28.990 --> 51:33.630] bug, and these tools are prone to false positives, so we need to determine whether this is a [51:33.630 --> 51:36.990] false positive or a real bug. If it turns out to be a real bug, then you have to come [51:36.990 --> 51:42.250] up with a fix. You have to upload this patch to the developer's side. The developer has [51:42.250 --> 51:47.330] to verify this patch. So it's also a lengthy process, and it involves a lot of human experience. [51:48.270 --> 51:52.510] So there is the same trade-off. You either invest the same amount of runtime as we do, [51:52.510 --> 51:56.230] or you invest the same amount of developers' time, which is probably more expensive. [51:57.790 --> 52:02.350] Now we arrive at the conclusion. DIRA is the first system that solves the problems of attack [52:02.350 --> 52:07.610] detection and identification in a unified way using memory on this log. It can produce [52:07.610 --> 52:11.430] accurate multi-packet signatures from a single attack instance, which we believe is a big [52:11.430 --> 52:17.050] achievement, because all the previous systems either reported less attack packets, or they [52:17.050 --> 52:21.630] required a large pool of network data to generate an accurate multi-packet signature. [52:21.950 --> 52:27.810] Dynamic slicing of the memory on this log is the underlying technique behind our tool. [52:27.810 --> 52:32.710] And this is a well-known technique from programming languages, but I think we just found some [52:32.710 --> 52:37.370] cool applications for this programming languages technique. And we plan to apply the same [52:37.370 --> 52:43.270] technique in the future to generate patches for buffer overflow attacks. This is what we're [52:43.270 --> 52:48.150] working on. We plan to work in the next few months. Our tool is available for download. [52:48.150 --> 52:54.730] Please visit our website and download it and play with it. So if you find bugs or if you [52:54.730 --> 53:00.890] have any experiences to share, please mail me and I'll be happy to answer you. Thank you. [53:08.450 --> 53:42.110] I have one book, one question. Yes. I'm sorry. [53:51.160 --> 53:58.120] Well, our program generates a signature whenever an attack happens. It doesn't use history. [53:58.120 --> 54:03.380] It doesn't look for previous packets. It doesn't analyze them. So whenever you perform an [54:03.380 --> 54:06.160] attack, a signature will be generated. So the question is whether the signature will be [54:06.160 --> 54:11.200] different from previously generated signatures or not. And I think the answer is yes, because [54:11.200 --> 54:16.220] if the length is different, then the regular expressions will also be different. [54:43.590 --> 54:49.310] Yes, this is the kind of denial-of-service attack that we think is like more lightweight [54:49.310 --> 54:54.050] than complete program restart, because a complete program restart disconnects all clients, all [54:54.050 --> 54:58.890] benign clients, and recovery doesn't disconnect anybody except attacker. And therefore, the [54:58.890 --> 55:03.610] benign clients will be able to perform their requests slower than when the program runs [55:03.610 --> 55:08.770] normally, but at least they won't be disconnected, which we believe is pretty good. [55:16.770 --> 55:21.390] Remember, AtlasLocker is a circular buffer. Yes, the log records are used constantly and [55:21.890 --> 55:29.750] previous records are freed up when the record is about to be used. Yes. [55:31.130 --> 55:32.850] Okay, thank you very much.