1 00:00:20,700 --> 00:00:25,560 Quick announcement, I'm gonna use laser pointer and 2 00:00:33,170 --> 00:00:34,870 I'm gonna use this screen. 3 00:00:35,250 --> 00:00:43,050 So those people sitting here, please move either to the center of the room or to the right side. 4 00:01:05,620 --> 00:01:07,440 You prefer to stay there? 5 00:01:15,370 --> 00:01:19,950 Well I think it depends on how close I am to the mic rather than... 6 00:01:36,690 --> 00:01:38,430 Okay, so let's start. 7 00:01:38,530 --> 00:01:40,130 Thank you for coming for my talk. 8 00:01:40,130 --> 00:01:48,830 It's the first talk in the morning, so it might be pretty difficult for you to get up early and come here, so thank you for showing up. 9 00:01:50,310 --> 00:01:58,750 The title of my talk is JIRA, which is a tool for automatic detection, identification and repair of control hijacking attacks. 10 00:01:58,990 --> 00:02:03,490 I am Alexey Smirnov and this is a joint work with Tricker Chair, who is my advisor. 11 00:02:03,550 --> 00:02:05,630 We are from Stony Brook University. 12 00:02:07,510 --> 00:02:09,390 Here is the outline of my talk. 13 00:02:09,390 --> 00:02:14,250 First I'm gonna give a brief introduction on control hijacking attacks. 14 00:02:14,450 --> 00:02:20,170 Then I'm gonna talk about the related work in the areas of attack detection, identification and repair. 15 00:02:20,230 --> 00:02:25,970 Then I'll present our architecture, JIRA, which has these three components. 16 00:02:25,970 --> 00:02:31,250 The attack detection component, the attack identification and attack repair component. 17 00:02:31,250 --> 00:02:36,230 The purpose of attack detection component is to detect a buffer overflow or control hijacking attack. 18 00:02:36,230 --> 00:02:43,150 So it's similar to the goal of the tools like StackGuard and Propolis. 19 00:02:43,470 --> 00:02:52,370 The attack identification component builds up the signature that can be supplied to intrusion detection system so that these attack packets can be filtered out in the future. 20 00:02:52,590 --> 00:03:00,050 The attack repair component repairs the program and allows it to continue its execution as if the attack never happened. 21 00:03:00,050 --> 00: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. 22 00:03:08,230 --> 00:03:12,630 And we'll conclude with a summary of research contributions and with the direction of future work. 23 00:03:14,290 --> 00:03:18,150 Buffer overflow attacks are the most common type of attacks. 24 00:03:18,870 --> 00:03:24,370 Computer warms use buffer overflow attacks as a basic building block for the propagation. 25 00:03:24,690 --> 00:03:38,310 So as soon as they arrive to a new host, they perform a buffer overflow attack, hijack control of the underlying program or of the host, and then scan for more vulnerable machines by performing random IP scanning. 26 00:03:38,550 --> 00: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. 27 00:03:47,410 --> 00:03:51,670 A comprehensive protection strategy should include the following three components. 28 00:03:51,670 --> 00:03:58,870 The attack detection component, which will detect the control hijacking attack when it happens. 29 00:03:58,870 --> 00:04:02,810 That is, when the worm tries to get control of the underlying computer. 30 00:04:02,890 --> 00:04:08,150 The attack identification component is responsible for building the signature of the attack. 31 00:04:08,150 --> 00:04:20,670 That is, for identifying malicious packets and representing them in the most general form so that polymorphic worms or polymorphic attacks can be detected by the same signature. 32 00:04:20,990 --> 00:04:28,510 The attack repair component allows the compromised program to continue its execution as if the attack never happened. 33 00:04:28,510 --> 00:04:43,130 That is, it should restore the memory image or the environment of the program as it was in the pre-attack time so that the program will think that it has never received any attack packets. 34 00:04:43,330 --> 00:04:58,130 We propose a compiler, Jira is a compiler, that instruments programs, source code of a program so that the instrumented program can identify, detect, and repair itself after a control hijacking attack. 35 00:04:58,870 --> 00:05:01,010 What is a buffer overflow attack? 36 00:05:01,170 --> 00:05:14,730 Well, the idea behind control hijacking attacks is to operate a control sensitive data structure such as a return address, function pointer, or any other control sensitive data structure. 37 00:05:14,730 --> 00:05:23,750 By the way, I've got some t-shirts here and books and I'm going to give them away and I'm going to ask you questions and who answers first gets a t-shirt or a book. 38 00:05:23,750 --> 00:05:25,510 So here's the first question. 39 00:05:26,150 --> 00:05:31,330 The return address and the function pointer are two possible types of control sensitive data structure. 40 00:05:31,330 --> 00:05:36,530 What are other data structures that a worm or a virus can override? 41 00:05:39,560 --> 00:05:41,440 That's what I said, function pointer. 42 00:05:43,320 --> 00:05:44,600 What else? 43 00:05:45,220 --> 00:05:46,020 Okay. 44 00:05:47,340 --> 00:05:48,480 What about HIP? 45 00:05:49,860 --> 00:05:51,200 What do you mean by HIP? 46 00:05:53,500 --> 00:05:55,040 Well, okay, I got a t-shirt. 47 00:06:01,260 --> 00:06:02,240 What else? 48 00:06:05,600 --> 00:06:07,460 That's what he said probably, HIP. 49 00:06:07,580 --> 00:06:09,100 Okay , that was what I... 50 00:06:19,100 --> 00:06:24,260 So the name of the control sensitive data structure is... 51 00:06:24,940 --> 00:06:26,080 just word. 52 00:06:28,000 --> 00:06:29,860 Okay, any other ideas? 53 00:06:30,360 --> 00:06:31,200 Okay. 54 00:06:35,160 --> 00:06:38,840 Well, for example, GOT, which is global offsets table. 55 00:06:40,380 --> 00: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. 56 00:06:47,680 --> 00: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. 57 00:06:55,100 --> 00:06:57,520 And that's when the buffer overflow happens. 58 00:06:57,520 --> 00:07:04,760 Standard libc functions, such as stringcpy or sprintf, are responsible for most buffer overflow attacks. 59 00:07:05,820 --> 00:07:10,240 So we're going to review related work in the areas of attack detection, identification, and repair. 60 00:07:10,240 --> 00:07:13,800 StackGuard is the first tool for buffer overflow attack detection. 61 00:07:13,800 --> 00: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. 62 00:07:21,000 --> 00:07:26,500 If the values are different, then the attack has happened, and the application is terminated. 63 00:07:26,500 --> 00:07:31,960 RADint is another tool that protects programs from buffer overflow attacks. 64 00:07:31,960 --> 00:07:42,260 It works by saving the original return address in a special well-protected buffer at function prologue, and compares it with the values stored in the stack at function epilogue. 65 00:07:42,260 --> 00: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. 66 00:07:52,700 --> 00:07:58,040 Can anyone think of any other tools for attack detection? 67 00:07:59,800 --> 00:08:02,340 Nah, Snore is content filter engine. 68 00:08:05,000 --> 00:08:06,720 Okay, I got it. 69 00:08:07,380 --> 00:08:08,720 You got a T-shirt? 70 00:08:08,720 --> 00:08:09,800 Who was that? 71 00:08:18,280 --> 00:08:21,300 So, let's move to attack identification. 72 00:08:23,120 --> 00:08:30,620 We need automatic ways for attack identification, because it's very important to generate signatures fast. 73 00:08:30,620 --> 00:08:34,780 Computer warms infect vulnerable machines very fast. 74 00:08:34,780 --> 00:08:38,620 It's a rate of thousands per minute, or maybe tens of thousands per minute. 75 00:08:38,660 --> 00:08:48,500 Therefore, if we wait for a human expert to come up with a signature, which is going to take a few hours, then the warm is going to hijack the most vulnerable host on the Internet. 76 00:08:48,680 --> 00: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. 77 00:08:59,620 --> 00:09:13,360 Previous systems for automatic signature generation either produced signatures that consisted of only one packet, or required a large pool of malicious network data to come up with a comprehensive signature. 78 00:09:13,360 --> 00:09:29,160 Signature that consists of one packet is sometimes insufficient, because a complex attack can involve multiple packets, such as, let's say, FTP server attack, it involves sending out authentication packets, and only then sending out the final attack packet. 79 00:09:29,160 --> 00:09:34,140 A comprehensive signature should include all attack packets, not just the last one. 80 00:09:34,140 --> 00:09:36,400 So here are some relevant projects. 81 00:09:36,460 --> 00:09:40,020 TaintCheck is a tool for... 82 00:09:40,020 --> 00:09:53,860 It uses the taint analysis to generate attack signature, and it reports the value of the return address, the form used to hijack control as a signature. 83 00:09:53,860 --> 00:09:55,940 So it's only a four-byte signature. 84 00:09:55,940 --> 00:10:08,000 Autograph uses so-called Rabin fingerprints to find common subsequences in a large pool of malicious network data. 85 00:10:08,000 --> 00:10:15,120 Polygraph and naming also use a large pool of malicious data, and to use machine learning algorithms to construct a multi-packet signature. 86 00:10:18,700 --> 00:10:22,600 AttackRepair relies on checkpointing. 87 00:10:22,600 --> 00:10:31,280 That is, one first checkpoints the program state, and then jumps to a previous point in the past to restore program's execution. 88 00:10:32,460 --> 00:10:38,860 So two approaches here are either keeping complete execution history, or do periodic stack checkpointing. 89 00:10:38,860 --> 00:10:45,020 That is, to take a snapshot of the memory image of the program. 90 00:10:45,140 --> 00:10:51,440 And the second approach relies on a fork system call, which is available under Linux, but might not be available under other operating systems. 91 00:10:51,440 --> 00:11:02,240 And Shadow Honeypot project runs two versions of the application, instrumented, that is protected and non-protected, and switches between them dynamically when it detects an attack. 92 00:11:02,240 --> 00:11:04,580 Now we move on to DIRA architecture. 93 00:11:04,580 --> 00:11:07,660 DIRA is a compiler that provides all these three components. 94 00:11:07,960 --> 00:11:11,840 AttackDetectionComponent, AttackIdentification, and AttackRepairComponent. 95 00:11:14,930 --> 00:11:24,310 As I said, DIRA is an extension to GCC, version 3.4.1 currently, but it can be used with other versions as well. 96 00:11:24,310 --> 00:11:32,730 The idea behind DIRA is memory updates logging, and this approach solves all these three problems at the same time. 97 00:11:32,770 --> 00:11:38,730 So the idea is to maintain a run-time log of all changes that the program performs. 98 00:11:40,110 --> 00:11:49,130 Assignments such as A equals B, or ellipsis functions call, such as memcpy, change memory state of the program, and therefore their effects should be saved. 99 00:11:49,130 --> 00:11:51,150 For example... 100 00:11:51,150 --> 00:11:53,570 Okay, we will see some examples later. 101 00:11:53,570 --> 00:12:00,010 For each memory update, DIRA stores its source address, its destination address, its length, and the preimage. 102 00:12:00,290 --> 00:12:05,790 So in the case of the assignment A equals B... 103 00:12:05,790 --> 00:12:07,150 Where's my pointer? 104 00:12:09,270 --> 00:12:10,030 Here. 105 00:12:10,550 --> 00:12:18,150 The source is the address of variable B, because that's where the new data comes from. 106 00:12:18,150 --> 00:12:23,410 The right address is the address of A, because that's the address that has been written into. 107 00:12:23,410 --> 00:12:27,290 The length of the data is the size of type of variable B. 108 00:12:27,290 --> 00:12:29,270 So if it's integer, it's 4-byte. 109 00:12:29,270 --> 00:12:35,050 The preimage is the old value of A, and it's used to restore memory image to the program. 110 00:12:35,410 --> 00:12:43,250 So the DIRA compiler instruments the source code of the program in compile-time. 111 00:12:43,250 --> 00:12:48,490 It adds the log-in code for variable assignments and for standard library functions. 112 00:12:48,530 --> 00:12:58,950 At run-time, this log-in code, this memory update log, is generated, and it's used at repair time to detect, to identify, and to repair the attack. 113 00:12:59,450 --> 00:13:03,510 So how can we detect, identify, and repair an attack if we have this memory update log? 114 00:13:03,510 --> 00:13:12,210 To detect an attack, we need to compare the current value of the return pointer, or the return address, saved in the stack frame with the value saved in the memory update log. 115 00:13:12,210 --> 00:13:29,770 When we invoke a function, we lay out a new stack frame, we save the old return address, we save any registers that are used in this function, and therefore, this is a changed memory state of the program, which should be saved in the memory update log according to our concept. 116 00:13:30,050 --> 00:13:35,530 Therefore, the old value of the return address will be saved in the memory update log when the function is invoked. 117 00:13:35,530 --> 00:13:42,230 When the function is returning, this saved value should be compared with the value that is currently on the stack. 118 00:13:42,230 --> 00:13:44,750 If these two values are different, then there is an attack. 119 00:13:44,890 --> 00:13:56,910 To identify an attack using the memory update log, we can trace back the data that overrode the control-sensitive data structure to the point where it was first received in the program. 120 00:13:57,770 --> 00:14:00,330 For example, through a receive call. 121 00:14:01,390 --> 00:14:09,270 To repair an attack, we need to restore the memory image of the program by using the pre-images that are also saved in the memory update log. 122 00:14:09,270 --> 00:14:17,810 This idea of keeping the memory update log of program memory state changes is the essential idea behind our tool. 123 00:14:17,890 --> 00:14:24,010 It allows us to solve all these three problems of attack detection, identification, and repair in the same uniform way. 124 00:14:25,450 --> 00:14:27,850 Memory update log is a circle buffer. 125 00:14:27,910 --> 00:14:30,470 Each record of this buffer has four fields. 126 00:14:30,470 --> 00:14:32,670 Read address, write address, length, and data. 127 00:14:33,150 --> 00:14:46,210 Dero saves the effect of each assignment operation, such as x equals y, where x and y are either directly referenced variables, array references, or dereferenced variables. 128 00:14:46,430 --> 00:15:02,690 As I said previously, the read address is set to the address of the right-hand side, the write address is set to the address of the left-hand side, the length is set to the size of the memory update, and the data is set to the pre-image that stores the data that they're going to overwrite, 129 00:15:02,690 --> 00:15:04,690 that is, the old value of x. 130 00:15:05,770 --> 00:15:13,170 If the right-hand side is a complex expression, then a log record is created for each variable in the right-hand side. 131 00:15:13,170 --> 00:15:26,210 To handle memory change performed by standard library functions, Dero proxies a few of them, such as string manipulation functions, format string functions, file network IO functions, and other functions that change memory state of the program. 132 00:15:27,490 --> 00:15:40,450 So the proxy function constructs a new memory update log record that summarizes the changes performed by the corresponding ellipsis function. 133 00:15:40,830 --> 00:15:47,310 And the memory update log is also used to store tags, which are special records that indicate change to memory to the state of the program. 134 00:15:47,310 --> 00:15:53,090 For example, when the function is invoked, function enter tag is inserted, and when the function returns, function exit tag is inserted. 135 00:15:53,090 --> 00:15:59,970 These tags are used at repair and identification time to build up signature and to repair program after an attack. 136 00:16:01,870 --> 00:16:03,730 So here are a few examples. 137 00:16:03,730 --> 00:16:09,830 At compile time, let's say there is a statement x equals y plus z. 138 00:16:10,690 --> 00:16:15,230 So the compiler adds two logging codes. 139 00:16:15,310 --> 00:16:23,130 The first code logs the effect of variable y, sorry, of variable z. 140 00:16:23,170 --> 00:16:25,870 The other of the variable y. 141 00:16:26,150 --> 00:16:28,390 And finally, there is this original statement. 142 00:16:28,510 --> 00:16:37,470 At run time, these two logging codes produce these two log records with the read and write addresses set as I described previously. 143 00:16:38,250 --> 00:16:42,590 Suppose there is the string CPY code in the source code of the program. 144 00:16:43,210 --> 00:16:46,950 The debug compiler replaces this code with a proxy function. 145 00:16:47,530 --> 00:16:59,710 And at run time, this proxy function inserts a log record with the read address of b, because that's where the data is coming from, with the write address of a, because that's where the write data enter. 146 00:16:59,750 --> 00:17:09,250 With the length, strlen of b plus one, because they're going to write strlen of b bytes plus non-terminating character. 147 00:17:09,430 --> 00:17:19,010 And with the preimage is a, which is the old value of a, Now let's talk about attack detection. 148 00:17:19,270 --> 00:17:20,810 Jira uses a RAD-like approach. 149 00:17:20,810 --> 00:17:29,810 That is, it saves the original return address when the function is invoked and compares the saved value with the value that is currently on stack at function epilogue. 150 00:17:29,810 --> 00:17:32,830 If these two values are different, then an attack is detected. 151 00:17:33,490 --> 00:17:40,770 Jira can protect other control-sensitive data structures, such as function pointers, GOT, signal-handling variables, and a similar function, but it's not implemented yet. 152 00:17:46,380 --> 00:17:48,600 Now let's talk about attack identification. 153 00:17:48,600 --> 00:17:52,060 So here are the desired properties of an ideal signature. 154 00:17:52,200 --> 00:17:58,460 A signature should be context-aware, which means that it should include all the attack packets that participate in a given attack. 155 00:17:58,880 --> 00:18:01,360 And this allows to reduce the rate of false positives. 156 00:18:01,600 --> 00:18:06,160 It should be also semantics-aware, that it ideally should incorporate the knowledge about the protocol. 157 00:18:06,160 --> 00:18:22,320 For example, if this is an HTTP attack, and the attack request is a GET request, then the signature should specify that this is GET, so that the intrusion detection system can filter out, keep all the requests of other types, of other protocols, and even if it's HTTP, 158 00:18:22,320 --> 00:18:25,740 but not GET, it should also discard those packets. 159 00:18:25,740 --> 00:18:31,940 It should check the signature only against packets that are HTTP GET kind of packets. 160 00:18:32,780 --> 00:18:35,340 And this also allows to reduce the rate of false positives. 161 00:18:35,640 --> 00:18:45,540 And the signature should provide a certain degree of flexibility within each packet, so that polymorphic warnings that change their body as they propagate can be matched using the same signature. 162 00:18:46,820 --> 00:18:55,380 The attack packets should be represented as regular expressions, and that's the desired flexibility that a signature should have. 163 00:18:56,760 --> 00:19:05,480 So, as I said, these three properties are the desired properties, and now let's see how JIRA satisfies all those properties. 164 00:19:05,480 --> 00:19:09,780 JIRA signatures are kind of severe, because they consist of multiple packets. 165 00:19:10,100 --> 00:19:15,420 They consist of all packets that an attack consists of. 166 00:19:15,420 --> 00:19:19,060 And each of those packets is represented as a regular expression. 167 00:19:19,780 --> 00:19:26,380 And there's a feature called length constraint that allows to limit the attack in part of the packet. 168 00:19:26,640 --> 00:19:36,720 That is, it allows to specify that a terminating character, such as null character, should occur between offset A and offset B. 169 00:19:36,820 --> 00:19:41,320 If the terminating sequence occurs within this offset, this is not an attack packet. 170 00:19:41,320 --> 00:19:47,460 If there is no such a terminating character in the packet, then this is an attack packet. 171 00:19:48,140 --> 00:20:00,080 So, in some sense, this is equivalent to semantics awareness, because it allows to narrow down the part of the packet that the intrusion detection system searches. 172 00:20:00,080 --> 00:20:07,320 So it doesn't search the specified sequence in the whole packet, but rather this length constraint allows to limit the... 173 00:20:07,320 --> 00:20:10,380 or narrow down the scope where we search for the... 174 00:20:12,720 --> 00:20:14,420 required terminating constraint. 175 00:20:14,420 --> 00:20:15,880 For example, if this is a... 176 00:20:15,880 --> 00:20:31,160 same example, if this is a GET attack, and there's an overly long URL, which is terminated by a null character, here it allows to specify that this null character should occur between the fourth and, let's say, twentieth-bit byte of the packet. 177 00:20:31,180 --> 00:20:37,620 Because the first three characters are GET characters, and then the remaining part of the packet is the URL. 178 00:20:37,720 --> 00:20:44,720 If the terminating character is found in the first twenty-four bytes of the packet, then this is not an attacking packet. 179 00:20:44,780 --> 00:20:51,700 If the null terminating character is not found in the first twenty-four bytes, then this is an attack packet, because the URL is too long. 180 00:20:52,740 --> 00:21:02,440 Memory update slog allows us to construct signatures that consist of multiple packets, to represent each packet as a regular expression, and to generate a length constraint. 181 00:21:02,440 --> 00:21:10,260 And we're going to give an example, and we will show how all this functionality is implemented. 182 00:21:11,920 --> 00:21:16,920 Two types of dependencies exist in the program, data and control dependency. 183 00:21:20,740 --> 00:21:26,040 Data dependency is created when one variable is assigned to another, for example, A equals B, same example. 184 00:21:26,040 --> 00:21:28,960 In this case, A depends on B. 185 00:21:29,180 --> 00:21:37,700 A control dependency is created whenever variable X and variable Y is used... 186 00:21:39,600 --> 00:21:46,160 I'm sorry, variable X is used in conditional expressions, such as if, and Y is in this conditional body. 187 00:21:46,220 --> 00:21:47,400 So here's an example. 188 00:21:47,980 --> 00:21:58,800 In this case, even though there is no direct assignment between X and Y, Y depends on X, because the value that Y will take depends on the value of X. 189 00:21:58,920 --> 00:22:01,340 This type of dependency is called control dependency. 190 00:22:01,340 --> 00:22:07,380 No direct assignment, but dependency is there, because value of Y depends on value of X. 191 00:22:08,700 --> 00:22:10,320 Why do we need control dependencies? 192 00:22:10,740 --> 00:22:11,780 So here's an example. 193 00:22:11,780 --> 00:22:14,240 FTP server attack involvement authentication. 194 00:22:15,000 --> 00:22:17,700 Here's an example of vulnerable FTP server. 195 00:22:18,180 --> 00:22:20,120 Here's the vulnerable buffer. 196 00:22:20,300 --> 00:22:23,900 The program has two state variables, isAuthentication, isUser. 197 00:22:25,540 --> 00:22:28,640 And here is the main loop of this server. 198 00:22:28,640 --> 00:22:31,140 First, it receives a packet. 199 00:22:31,140 --> 00:22:34,360 Then it compares the four bytes of the packet. 200 00:22:34,400 --> 00:22:36,300 If it's QuickCommand, the loop breaks. 201 00:22:36,400 --> 00:22:40,100 If it's UserCommand, then isUser variable is set to 1. 202 00:22:40,100 --> 00:22:44,160 If it's PasswordCommand, then isUser and isUser has been set. 203 00:22:44,160 --> 00:22:50,220 Then authentication has been completed, and isAuthenticated variable is set to 1. 204 00:22:50,480 --> 00:22:54,740 If authentication was not performed previously, then the program continues. 205 00:22:55,180 --> 00:23:01,660 The client requests are handled only in the case if the authentication has been completed previously. 206 00:23:01,740 --> 00:23:10,060 So if the user is authenticated, then the program checks the first three bytes of the packet. 207 00:23:10,060 --> 00:23:15,320 If it's a GET packet, then there's a GET request, and it returns the file that the user requested. 208 00:23:15,540 --> 00:23:19,040 But this request is only processed if the user has previously authenticated. 209 00:23:21,120 --> 00:23:23,960 So these are the three packets used in the attack. 210 00:23:26,820 --> 00:23:40,120 There is a file name that is too long and that overrides the buffer, that overrides this buffer, which is only 16 characters bytes long. 211 00:23:41,020 --> 00:23:43,720 Let's look at lock records generated at run time. 212 00:23:44,020 --> 00:23:49,660 First, there is a lock record here at receive for the receive function. 213 00:23:49,820 --> 00:23:55,800 For the proxy function, proxy is standard receive call, and it has this tag. 214 00:23:55,800 --> 00:23:57,100 Here's the tag. 215 00:23:57,100 --> 00:23:58,380 This is the write address. 216 00:23:58,660 --> 00:24:05,280 That's the destination, where the network data is written into 11 different things. 217 00:24:05,280 --> 00:24:10,140 And here's also the image of the data that varies from network. 218 00:24:10,340 --> 00:24:18,760 Then there is a proxy function for SDR and CMP, which also has the write address... 219 00:24:18,760 --> 00:24:22,740 I'm sorry, it's read address of the variable. 220 00:24:22,740 --> 00:24:24,560 4 is the length of the argument. 221 00:24:24,560 --> 00:24:27,400 This record specifies... 222 00:24:27,400 --> 00:24:34,560 indicates that we search buffer P and we look at first four bytes of this buffer. 223 00:24:34,720 --> 00:24:40,940 Then this record is created for conditional expression and it means that variable P participates in the if expression. 224 00:24:40,940 --> 00:24:45,560 So for every variable in the if expression, we save this variable into memory and this log. 225 00:24:46,060 --> 00:24:47,840 And this is also... 226 00:24:47,840 --> 00:24:53,920 this is the record for the statement that updates each user variable. 227 00:24:53,920 --> 00:25:01,320 So in this case, the read address is set now because we don't know where the data that is written into isUser comes from. 228 00:25:01,320 --> 00:25:03,340 And it's just a constant. 229 00:25:03,720 --> 00:25:05,240 So the write address is isUser. 230 00:25:05,240 --> 00:25:07,980 The length is 4 and isUser is preimage. 231 00:25:07,980 --> 00:25:12,380 Similarly, for the second packet, we have the receive record here. 232 00:25:12,380 --> 00:25:18,880 We have the string comparison record that checks the first four bytes of the packet. 233 00:25:18,880 --> 00:25:24,520 We have two conditional variables now because two variables are checked, P and isUser. 234 00:25:24,560 --> 00:25:31,380 And finally, this is the record that updates the isAuthentication variable. 235 00:25:32,660 --> 00:25:35,520 So finally, let's look at the third packet. 236 00:25:35,760 --> 00:25:42,040 So we also have a record when the packet is received. 237 00:25:42,060 --> 00:25:46,600 Then we also have the conditional record for variable isAuthenticated. 238 00:25:46,600 --> 00:25:52,820 Then there is the record for string comparison that checks the first three bytes of the packet. 239 00:25:52,820 --> 00:25:56,860 Then there is the conditional record for P. 240 00:25:56,860 --> 00:26:02,240 And finally, this is the record that was created by string.cpyProxy function. 241 00:26:02,420 --> 00:26:12,420 And it describes the fact that the data from buffer here, I'm sorry, the data from buffer P plus 4 was written into buffer. 242 00:26:13,180 --> 00:26:23,920 And the length of the update is the length of P minus 4 plus 1 because all bytes of P except the first four bytes were copied into buffer buff. 243 00:26:24,280 --> 00:26:27,040 And we also save the preimage of P. 244 00:26:32,060 --> 00:26:34,000 So this is the summary. 245 00:26:34,000 --> 00:26:39,200 These are all log records that are generated at runtime when this server attack is executed. 246 00:26:39,740 --> 00:26:46,380 And suppose that the return address is located after the buff variable. 247 00:26:46,380 --> 00:26:50,880 That is, the return address is saved at the offset buff plus 17. 248 00:26:50,920 --> 00:26:53,400 Buffer is a buffer of 16 bytes. 249 00:26:53,660 --> 00:26:56,320 So the return address is saved at the offset 17. 250 00:26:57,180 --> 00:27:02,400 Now let's see how we can detect the control hijacking attack using this memory on this log. 251 00:27:07,160 --> 00:27:12,520 So we start with log record, with the last log record that overrode this buffer. 252 00:27:14,100 --> 00:27:16,360 And here is its write address. 253 00:27:16,360 --> 00:27:19,460 So we look for the source of this data. 254 00:27:19,720 --> 00:27:22,480 That is, we try to find out where the data came from. 255 00:27:22,840 --> 00:27:26,660 And this log record allows us to conclude that this data came from P. 256 00:27:27,660 --> 00:27:30,540 Return address was saved at the offset buff plus 17. 257 00:27:30,540 --> 00:27:37,240 Therefore, the data was read from the offset P plus 4 plus 17, which is P plus 21. 258 00:27:37,340 --> 00:27:44,320 That is, the return address value came from memory address P plus 4 plus 17, which is P plus 21. 259 00:27:44,340 --> 00:27:46,600 So this is the new address that we look for. 260 00:27:46,600 --> 00:27:50,580 Now we search memory on this log for the address P plus 21. 261 00:27:50,900 --> 00:28:05,120 And if we traverse this log record, this memory on this log upward, we can find that there is this receive record that read data from network into buffer P and the length was 62. 262 00:28:05,120 --> 00:28:08,000 And we look for memory... 263 00:28:09,320 --> 00:28:12,260 memory location with the address P plus 21. 264 00:28:12,600 --> 00:28:21,060 And this is the record that has written data from network into that memory location. 265 00:28:21,140 --> 00:28:30,520 So we conclude that here is the read operation that read data from network and wrote it into address P plus 21. 266 00:28:31,040 --> 00:28:38,800 And because this is the operation that reads data from network, we conclude that this is the attack in packet. 267 00:28:39,040 --> 00:28:42,460 So this way we identify the first attack in packet. 268 00:28:42,720 --> 00:28:45,320 Is it the only packet in the attack in packet? 269 00:28:45,700 --> 00:28:51,400 Probably not, because the user is only processed if the user has authenticated. 270 00:28:51,400 --> 00:28:54,780 So we need to continue our search and try to find more attack in packets. 271 00:28:56,080 --> 00:28:56,820 Sure. 272 00:29:23,870 --> 00:29:25,350 Well, debugging is not automatic. 273 00:29:25,350 --> 00:29:26,570 Our tool is completely automatic. 274 00:29:26,570 --> 00:29:28,690 It doesn't require any user involvement at all. 275 00:29:28,830 --> 00:29:32,430 So the process that I described here is completely automatic. 276 00:29:32,430 --> 00:29:34,590 It's performed by our program, not by a user. 277 00:29:34,590 --> 00:29:35,690 Not manually. 278 00:29:35,830 --> 00:29:38,190 It's not log analysis performed by a human expert. 279 00:29:38,190 --> 00:29:40,230 It's log analysis performed automatically. 280 00:29:51,700 --> 00:29:55,800 Well, you are right. 281 00:30:06,410 --> 00:30:09,370 Well, that's the question of our performance evaluation. 282 00:30:09,370 --> 00:30:11,410 We will get to this question later. 283 00:30:11,890 --> 00:30:15,450 And if I don't give a clear answer, I'd like to talk to you offline. 284 00:30:17,010 --> 00:30:20,850 So as I said previously, we were able to identify the first attack in packet. 285 00:30:20,850 --> 00:30:22,830 And now we look for more attack in packets. 286 00:30:22,830 --> 00:30:25,390 And here's where we use conditional dependencies. 287 00:30:25,390 --> 00:30:28,850 Let's look at the first memory update statement. 288 00:30:28,850 --> 00:30:34,150 If we go upward, we can see that this statement depends on two conditions. 289 00:30:34,150 --> 00:30:38,170 That is, it's inside two outer if statements. 290 00:30:38,170 --> 00:30:44,850 The first if statement checks p variable, and the second checks is authenticate variable. 291 00:30:45,290 --> 00:30:51,750 Therefore, this memory update was only possible because of these two checks that involve these two variables. 292 00:30:52,130 --> 00:30:55,670 Variable p is, has been found before. 293 00:30:55,910 --> 00:30:58,570 So, this record should be discarded. 294 00:30:58,870 --> 00:31:03,470 Whereas, this variable is authenticated should be used for later search. 295 00:31:04,730 --> 00:31:07,270 So we continue with variable is authenticated. 296 00:31:07,270 --> 00:31:11,350 And we try to find out whether this variable depends on network packet or not. 297 00:31:11,530 --> 00:31:16,690 So, if we continue traversing the block upward, we can see this memory update block operation. 298 00:31:16,950 --> 00:31:22,130 And the read address of this operation is unknown because this variable was assigned to a constant. 299 00:31:22,230 --> 00:31:31,570 Therefore, we should again use condition dependencies to find out what our variable is authenticated depends on. 300 00:31:31,830 --> 00:31:36,350 And we can see two conditional lock records isUser and p here. 301 00:31:37,070 --> 00:31:42,810 Which means that variable is authenticated depends conditionally on isUser and p. 302 00:31:43,610 --> 00:31:46,330 So, we now look for p and isUser. 303 00:31:46,330 --> 00:31:48,070 We can find p here. 304 00:31:49,030 --> 00:31:54,830 Therefore, we conclude that variable isUser depends on network packet that contains password. 305 00:31:54,830 --> 00:32:04,570 And this turns out to be true because variable p is set only if the attacker sends password packet. 306 00:32:05,110 --> 00:32:10,510 That variable isUser also depends sorry, variable isAuthenticated also depends on isUser. 307 00:32:10,510 --> 00:32:14,170 So, we continue with this variable isUser and we can find it here. 308 00:32:14,690 --> 00:32:18,210 This is the memory update long operation that sets variable isUser. 309 00:32:18,210 --> 00:32:21,630 Its readers is also unknown because it's set to constant. 310 00:32:21,630 --> 00:32:29,170 Therefore, we should use control dependencies to find out whether variable isUser depends on any network packets. 311 00:32:30,370 --> 00:32:35,590 And once again, we can see this conditional string expression that uses variable P. 312 00:32:35,830 --> 00:32:41,390 Therefore, we now search for variable P and try to find out whether it depends on any network data. 313 00:32:41,690 --> 00:32:43,650 And it turns out to be true. 314 00:32:43,650 --> 00:32:47,790 Variable P contains the packet payload of the user command. 315 00:32:47,790 --> 00:32:51,390 So what we can see now, we have found three attack packets. 316 00:32:52,570 --> 00:32:56,450 And so the get packet, the pass packet, the user packet. 317 00:32:56,990 --> 00:32:59,730 The first packet was found using direct dependencies. 318 00:32:59,730 --> 00:33:03,090 The remaining two packets were found using control dependencies. 319 00:33:03,610 --> 00:33:11,370 So the control dependencies are really important to link the first attack packet to all the remaining attack packets. 320 00:33:12,110 --> 00:33:16,250 Because of this state variables that are used in network daemons. 321 00:33:27,160 --> 00:33:29,220 Well, this is just our assumption. 322 00:33:29,460 --> 00:33:35,540 Well, the real value of the return errors is returned by the attack detection component. 323 00:33:39,300 --> 00:33:44,820 Well, this attack detection component tells you which data structure was damaged. 324 00:33:45,060 --> 00:33:51,740 So it tells you the return address of the compromised data structure, which in our case is the return address. 325 00:33:51,900 --> 00:33:54,480 So this assumption I just made it up. 326 00:33:54,840 --> 00:33:57,300 But this address is always known at runtime. 327 00:34:00,580 --> 00:34:03,360 Let's now give a precise definition of control dependencies . 328 00:34:04,880 --> 00:34:12,120 We say that whenever a variable x can prevent control flow from reaching variable y , a control dependency is created between x and y . 329 00:34:27,040 --> 00:34:29,620 Let's look at the value of variable cond is. 330 00:34:29,620 --> 00:34:37,940 However, if you look at the right-hand side, then one of these branches here, this branch, has a return . 331 00:34:38,900 --> 00:34:42,100 And therefore , if condition is takes such 332 00:34:51,820 --> 00:34:59,780 a value from x to then value 333 00:35:04,040 --> 00:35:04,980 is returned y. 334 00:35:10,180 --> 00:35:10,860 And 335 00:35:16,980 --> 00:35:22,860 therefore, the value of condition is returned from x to y. 336 00:35:25,600 --> 00:35:28,940 So this the value 337 00:35:38,280 --> 00:35:40,360 of condition. 338 00:35:40,660 --> 00:35:51,080 therefore, the value of condition is returned from x to y. 339 00:35:54,240 --> 00:35:59,340 And therefore, the value of condition is returned from x to y. 340 00:36:03,840 --> 00:36:08,040 therefore, the of condition is returned from x y. 341 00:36:08,300 --> 00:36:15,440 And therefore, value of condition is returned from x to y. 342 00:36:25,120 --> 00:36:27,980 And therefore, the value of condition 343 00:36:31,080 --> 00:36:31,860 returned from y . 344 00:36:38,900 --> 00:36:47,360 And therefore, the 345 00:36:52,760 --> 00:36:54,080 value is returned from y. 346 00:36:54,080 --> 00:36:57,300 And therefore, the value of is returned from x 347 00:37:07,220 --> 00:37:09,620 And therefore, the 348 00:37:13,380 --> 00:37:25,420 value of condition is returned from x to y. 349 00:37:25,420 --> 00:37:32,540 And therefore, the value of condition is from x to y . 350 00:37:45,960 --> 00:37:53,200 And therefore, the value of condition is returned from x y. 351 00:37:53,340 --> 00:37:56,380 And therefore, the value condition is 352 00:38:05,040 --> 00:38:24,780 returned from And therefore, the is returned from x to y. 353 00:38:24,780 --> 00:38:25,640 And 354 00:38:39,540 --> 00:38:45,420 therefore, value of condition is returned from y . 355 00:38:45,420 --> 00:38:54,900 And therefore, the value of condition is returned from x to y. 356 00:38:55,340 --> 00:38:55,620 And 357 00:39:07,140 --> 00:39:13,960 therefore, the value of condition from y . 358 00:39:13,960 --> 00:39:30,260 And therefore, of condition is returned from x therefore, the value of condition is from x to 359 00:39:37,720 --> 00:39:40,580 And therefore, the value of 360 00:39:44,100 --> 00:39:45,980 condition is y. 361 00:39:46,580 --> 00:39:48,460 And therefore, condition is returned from 362 00:39:56,920 --> 00:40:00,320 x to y. 363 00:40:08,440 --> 00:40:10,800 therefore, the value of condition 364 00:40:16,860 --> 00:40:18,380 is returned from y . 365 00:40:18,740 --> 00:40:23,700 And therefore, the value of condition is returned from x to y. 366 00:40:23,700 --> 00:40:33,200 And therefore, the value of condition is returned x And therefore, the value 367 00:40:37,920 --> 00:40:39,060 of condition 368 00:40:44,120 --> 00:40:46,420 returned from x to y. 369 00:40:46,580 --> 00:40:54,220 And therefore, the of condition is returned from x 370 00:41:00,160 --> 00:41:01,720 to y. 371 00:41:01,840 --> 00:41:08,300 And therefore, value of is returned x to y . 372 00:41:09,620 --> 00:41:11,000 And therefore, the value of is returned 373 00:41:15,540 --> 00:41:16,620 from x to y. 374 00:41:20,380 --> 00:41:24,840 And therefore, the value of from 375 00:41:41,900 --> 00:41:45,300 And therefore, 376 00:41:48,680 --> 00:41:53,240 value of condition is returned from x to y. 377 00:42:00,940 --> 00:42:03,280 And therefore, the value of condition is 378 00:42:07,940 --> 00:42:14,960 returned from x to y . 379 00:42:14,960 --> 00:42:16,220 And therefore , value of 380 00:42:20,980 --> 00:42:23,540 condition is returned from x y. 381 00:42:25,700 --> 00:42:26,720 And therefore , the value 382 00:42:31,940 --> 00:42:35,140 condition is returned from x to y. 383 00:42:38,360 --> 00:42:46,040 And therefore, the value of condition is x 384 00:42:51,020 --> 00:42:55,120 to y. 385 00:42:55,120 --> 00:42:59,600 And therefore, the value of condition is returned from x to y. 386 00:42:59,600 --> 00:43:03,580 And therefore, the value returned from to y . 387 00:43:03,580 --> 00:43:04,120 And 388 00:43:08,400 --> 00:43:10,980 therefore, the 389 00:43:21,000 --> 00:43:22,300 value of condition is returned from x y . 390 00:43:22,360 --> 00:43:29,060 And therefore, the value of condition is returned from 391 00:43:36,840 --> 00:43:38,300 x to y. 392 00:43:38,300 --> 00:43:41,320 And therefore , the value condition is 393 00:43:44,960 --> 00:43:47,080 returned from x to y. 394 00:43:47,380 --> 00:43:54,060 And therefore, the value of is returned from x to y. 395 00:43:54,360 --> 00:43:55,040 And 396 00:44:21,740 --> 00:44:24,080 therefore, condition is y. 397 00:44:24,080 --> 00:44:25,700 And therefore, is returned from x y. 398 00:44:25,700 --> 00:44:30,880 And therefore, the value of condition is 399 00:44:35,960 --> 00:44:44,640 returned x to And therefore, of is returned from x to y. 400 00:44:58,040 --> 00:44:59,860 And therefore, condition 401 00:45:06,460 --> 00:45:08,110 x to 402 00:45:16,430 --> 00:45:17,310 y is 403 00:45:22,190 --> 00:45:23,530 returned to y. 404 00:45:24,810 --> 00:45:25,310 And 405 00:45:29,650 --> 00:45:35,410 therefore, value of condition is returned from x to y. 406 00:45:35,410 --> 00:45:45,310 And therefore, value of condition is returned from x 407 00:46:04,150 --> 00:46:06,850 to y. 408 00:46:06,850 --> 00:46:06,990 And value 409 00:46:10,230 --> 00:46:34,700 of condition returned from x y . 410 00:46:34,700 --> 00:46:37,320 And therefore, returned x to y. 411 00:46:37,320 --> 00:46:37,580 And 412 00:46:46,930 --> 00:46:48,830 therefore, condition is returned from x 413 00:47:11,320 --> 00:47:37,180 to y. 414 00:47:37,180 --> 00:47:37,840 And therefore, value 415 00:47:44,540 --> 00:47:47,580 of condition is returned from y . 416 00:47:47,580 --> 00:47:54,500 And therefore, condition is returned to y. 417 00:47:57,620 --> 00:48:01,340 And therefore, value condition is returned from 418 00:48:06,660 --> 00:48:08,900 x to 419 00:48:19,840 --> 00:48:21,600 y. 420 00:48:22,080 --> 00:48:29,600 And therefore, value is returned x to y. 421 00:48:29,600 --> 00:48:34,460 And therefore, is returned x to y. 422 00:48:34,640 --> 00:48:38,980 And therefore, condition is returned from x 423 00:48:55,460 --> 00:49:09,220 And therefore, value of condition is returned y. 424 00:49:09,220 --> 00:49:10,240 And y. 425 00:49:10,240 --> 00:49:11,120 And 426 00:49:44,210 --> 00:49:48,770 therefore, condition is returned x to y . 427 00:49:49,450 --> 00:49:53,670 And therefore, value returned This is the length of packet, this is the packet that represents the regular expression, this is the length constraint. 428 00:49:53,670 --> 00:49:57,110 This is pretty much the same as the signature that we constructed in our example. 429 00:49:57,610 --> 00:50:01,650 This is the bind signature, signature for DNS daemon. 430 00:50:01,910 --> 00:50:05,550 So one packet, this is the length, this is the length constraint. 431 00:50:06,610 --> 00:50:15,850 Remote cat daemon has a signature that consists of three packets because this cat daemon requires user authentication. 432 00:50:16,150 --> 00:50:27,190 So here we can see user packet, password packet, the length constraint and the, yes, and the last packet. 433 00:50:27,850 --> 00:50:31,730 All the signatures will generate automatically from a single attack instance. 434 00:50:33,350 --> 00:50:35,330 Now let's talk about the recovery. 435 00:50:35,330 --> 00:50:36,550 Is it really useful? 436 00:50:36,550 --> 00:50:38,230 The overhead is pretty high at 70%. 437 00:50:38,230 --> 00:50:41,330 Maybe we can do well without recovery. 438 00:50:41,830 --> 00:50:48,770 And we think that recovery is really useful because many programs are single-thread and they are, like, event-driven. 439 00:50:48,770 --> 00:50:52,790 And if you just terminate the program, then you disconnect all the clients. 440 00:50:52,850 --> 00:50:55,910 So you have only one bad client, you have, let's say, a dozen of good clients. 441 00:50:55,910 --> 00:51:00,830 You disconnect one bad and disconnect a dozen of good, which is very bad for good clients. 442 00:51:00,990 --> 00:51:10,050 And the same attack can be reviewed in the future, and therefore the attacker can implement the denial of service attack if you simply terminate the program instead of recovering. 443 00:51:10,050 --> 00:51:16,030 If you recover it, then repair the effect of the bad guy, but you allow good guys to continue their execution. 444 00:51:17,070 --> 00:51:20,130 And the same trade-off exists in the case of source code analysis tools. 445 00:51:20,890 --> 00:51:34,690 Whenever you have a bug, if you use static code analysis tool, then you first need to find out this bug, and these tools are prone to false positives, so we need to determine whether this is a false positive or a real bug. 446 00:51:34,810 --> 00:51:37,850 If it turns out to be a real bug, then you have to come up with a fix. 447 00:51:37,850 --> 00:51:41,610 You have to upload this patch to the developer's side. 448 00:51:41,610 --> 00:51:43,430 The developer has to verify this patch. 449 00:51:43,430 --> 00:51:47,330 So it's also a lengthy process, and it involves a lot of human experience. 450 00:51:48,270 --> 00:51:49,550 So there is the same trade-off. 451 00:51:49,550 --> 00:51:56,230 You either invest the same amount of runtime as we do, or you invest the same amount of developers' time, which is probably more expensive. 452 00:51:57,790 --> 00:51:59,470 Now we arrive at the conclusion. 453 00:52:00,150 --> 00:52:06,950 DIRA is the first system that solves the problems of attack detection and identification in a unified way using memory on this log. 454 00:52:07,070 --> 00:52:21,630 It can produce accurate multi-packet signatures from a single attack instance, which we believe is a big achievement, because all the previous systems either reported less attack packets, or they required a large pool of network data to generate an accurate multi-packet signature. 455 00:52:21,950 --> 00:52:27,810 Dynamic slicing of the memory on this log is the underlying technique behind our tool. 456 00:52:27,810 --> 00:52:35,370 And this is a well-known technique from programming languages, but I think we just found some cool applications for this programming languages technique. 457 00:52:35,870 --> 00:52:41,890 And we plan to apply the same technique in the future to generate patches for buffer overflow attacks. 458 00:52:42,570 --> 00:52:43,790 This is what we're working on. 459 00:52:43,790 --> 00:52:45,870 We plan to work in the next few months. 460 00:52:46,590 --> 00:52:48,150 Our tool is available for download. 461 00:52:48,150 --> 00:52:52,130 Please visit our website and download it and play with it. 462 00:52:52,130 --> 00:52:59,810 So if you find bugs or if you have any experiences to share, please mail me and I'll be happy to answer you. 463 00:52:59,810 --> 00:53:00,890 Thank you. 464 00:53:08,450 --> 00:53:11,230 I have one book, one question. 465 00:53:12,950 --> 00:53:13,850 Yes. 466 00:53:40,770 --> 00:53:42,110 I'm sorry. 467 00:53:51,160 --> 00:53:55,540 Well, our program generates a signature whenever an attack happens. 468 00:53:55,540 --> 00:53:58,120 It doesn't use history. 469 00:53:58,120 --> 00:54:00,820 It doesn't look for previous packets. 470 00:54:00,820 --> 00:54:02,280 It doesn't analyze them. 471 00:54:02,280 --> 00:54:04,740 So whenever you perform an attack, a signature will be generated. 472 00:54:04,740 --> 00:54:08,460 So the question is whether the signature will be different from previously generated signatures or not. 473 00:54:08,660 --> 00:54:16,220 And I think the answer is yes, because if the length is different, then the regular expressions will also be different. 474 00:54:43,590 --> 00:54:57,850 Yes, this is the kind of denial-of-service attack that we think is like more lightweight than complete program restart, because a complete program restart disconnects all clients, all benign clients, and recovery doesn't disconnect anybody except attacker. 475 00:54:57,950 --> 00:55:08,770 And therefore, the benign clients will be able to perform their requests slower than when the program runs normally, but at least they won't be disconnected, which we believe is pretty good. 476 00:55:16,770 --> 00:55:18,230 Remember, AtlasLocker is a circular buffer. 477 00:55:18,230 --> 00:55:26,050 Yes, the log records are used constantly and previous records are freed up when the record is about to be used. 478 00:55:28,870 --> 00:55:29,750 Yes. 479 00:55:31,130 --> 00:55:32,850 Okay, thank you very much.