1 00:00:00,870 --> 00:00:01,703 - So, yeah. 2 00:00:01,703 --> 00:00:02,880 This is Internal Server Error: 3 00:00:02,880 --> 00:00:04,470 Exploiting Inter-Process Communication 4 00:00:04,470 --> 00:00:06,660 With New Desynchronization Primitives. 5 00:00:06,660 --> 00:00:09,603 Please welcome Martin Doyhenard. 6 00:00:09,603 --> 00:00:12,603 (audience applauds) 7 00:00:17,070 --> 00:00:18,000 - Hello everyone. 8 00:00:18,000 --> 00:00:19,440 Welcome to Internal Server Error: 9 00:00:19,440 --> 00:00:21,330 Exploiting Inter-Process Communication 10 00:00:21,330 --> 00:00:24,570 With New Desynchronization Primitives. 11 00:00:24,570 --> 00:00:26,130 My name is Martin Doyhenard. 12 00:00:26,130 --> 00:00:28,230 I'm a security researcher at Onapsis, 13 00:00:28,230 --> 00:00:32,730 which is a company focused on enterprise software security, 14 00:00:32,730 --> 00:00:36,210 and among the different enterprise software developers, 15 00:00:36,210 --> 00:00:38,580 SAP is probably the most popular one 16 00:00:38,580 --> 00:00:40,890 with over 400,000 customers, 17 00:00:40,890 --> 00:00:44,343 and this includes 90% of Fortune 500 companies. 18 00:00:45,840 --> 00:00:48,420 Most of the services that SAP provides 19 00:00:48,420 --> 00:00:51,120 are for managing business processes, 20 00:00:51,120 --> 00:00:53,670 such as financials, operations, 21 00:00:53,670 --> 00:00:57,026 human capital, customer relationships, supply chain, 22 00:00:57,026 --> 00:00:59,670 and manage many other software 23 00:00:59,670 --> 00:01:02,790 that manage the critical assets of a company. 24 00:01:02,790 --> 00:01:05,160 And to do so, they provide a lot of modules 25 00:01:05,160 --> 00:01:07,950 that are based on web services that are accessible 26 00:01:07,950 --> 00:01:09,450 through HTTP. 27 00:01:09,450 --> 00:01:12,240 And this is true for both Java and ABAP, 28 00:01:12,240 --> 00:01:14,283 and also for S400 and the cloud. 29 00:01:15,420 --> 00:01:17,400 To expose these kind of services, 30 00:01:17,400 --> 00:01:19,980 they use the same proprietary HTTP server 31 00:01:19,980 --> 00:01:21,240 in all their products, 32 00:01:21,240 --> 00:01:23,790 which is called the internet communication manager. 33 00:01:25,170 --> 00:01:28,710 And so, what is this internet communication manager, or ICM? 34 00:01:28,710 --> 00:01:30,870 Well, it's a component that is used to handle 35 00:01:30,870 --> 00:01:33,300 all the communication with the outside world 36 00:01:33,300 --> 00:01:34,590 and with the SAP system, 37 00:01:34,590 --> 00:01:37,380 and this includes all communication with clients, 38 00:01:37,380 --> 00:01:41,220 such as different employees or customers, 39 00:01:41,220 --> 00:01:44,163 also with other systems and with other SAP systems. 40 00:01:45,000 --> 00:01:47,580 Among the different protocols that can be used, 41 00:01:47,580 --> 00:01:51,030 there is a P4, which is a proprietary protocol 42 00:01:51,030 --> 00:01:52,950 similar to RMA. 43 00:01:52,950 --> 00:01:56,310 Also, IOP, SMTP, but the main purpose 44 00:01:56,310 --> 00:01:59,160 of the internet communication manager 45 00:01:59,160 --> 00:02:03,033 is to handle the HTTP and HTTPS communications. 46 00:02:04,560 --> 00:02:06,090 This is really important. 47 00:02:06,090 --> 00:02:08,160 This is the component that will be exposed, 48 00:02:08,160 --> 00:02:09,540 and it will be present by default 49 00:02:09,540 --> 00:02:11,730 in all SAP installations in the world. 50 00:02:11,730 --> 00:02:14,610 Therefore, we will find it in all SAP products, 51 00:02:14,610 --> 00:02:16,200 and it is quite important, 52 00:02:16,200 --> 00:02:18,840 and that's why I decided to make that research on this, 53 00:02:18,840 --> 00:02:20,793 because anytime we find an SAP, 54 00:02:21,801 --> 00:02:24,360 the HTTP service will be exposed, 55 00:02:24,360 --> 00:02:27,510 and we will find many SAP systems exposing this 56 00:02:27,510 --> 00:02:28,353 to the internet. 57 00:02:29,940 --> 00:02:33,150 But before I can find any vulnerability, 58 00:02:33,150 --> 00:02:34,110 I needed to understand 59 00:02:34,110 --> 00:02:37,380 how this internet communication manager worked. 60 00:02:37,380 --> 00:02:39,780 And of course we don't have the source code. 61 00:02:39,780 --> 00:02:44,280 That is not because SAP does not like open source. 62 00:02:44,280 --> 00:02:46,650 They know that would kill the fans, 63 00:02:46,650 --> 00:02:50,583 so I had to reverse engineer the entire component. 64 00:02:52,230 --> 00:02:55,500 You can see that SAP provide us with a small diagram, 65 00:02:55,500 --> 00:02:59,820 which says not too much about the architecture. 66 00:02:59,820 --> 00:03:02,400 We can see some components, but it's not really descripted, 67 00:03:02,400 --> 00:03:06,090 so I had to make a small abstraction of this diagram, 68 00:03:06,090 --> 00:03:08,610 so that you understand how this work. 69 00:03:08,610 --> 00:03:10,530 Also, I will abstract a lot of internals. 70 00:03:10,530 --> 00:03:13,650 If you want to learn more or want to know more about this, 71 00:03:13,650 --> 00:03:15,210 you can ask me later, 72 00:03:15,210 --> 00:03:17,190 or you can write me through my Twitter 73 00:03:17,190 --> 00:03:18,603 or see the white paper. 74 00:03:20,130 --> 00:03:23,550 First, we will say that the ICM is the HTTP server 75 00:03:23,550 --> 00:03:26,550 that will receive connections from clients. 76 00:03:26,550 --> 00:03:28,623 When a client starts a TCP connection, 77 00:03:30,630 --> 00:03:32,820 a worker thread, which is an internal thread 78 00:03:32,820 --> 00:03:36,123 from the process, will be assigned to this TCP connection. 79 00:03:37,020 --> 00:03:38,970 And the idea is that this worker thread 80 00:03:38,970 --> 00:03:41,250 handlers all the request and responses 81 00:03:41,250 --> 00:03:43,830 for this specific client, 82 00:03:43,830 --> 00:03:46,650 so when a client sends a request, 83 00:03:46,650 --> 00:03:49,170 it will be received by the worker thread, 84 00:03:49,170 --> 00:03:52,890 which will use the HTTP parser to understand the request. 85 00:03:52,890 --> 00:03:55,170 Then, it will use some internal HTTP handlers, 86 00:03:55,170 --> 00:03:56,870 which I will talk later about them 87 00:03:57,810 --> 00:04:00,030 to try to resolve this request internally, 88 00:04:00,030 --> 00:04:01,500 and if it's not possible to do it, 89 00:04:01,500 --> 00:04:04,953 which most cases, that will be the case, 90 00:04:06,060 --> 00:04:08,850 it will send the request to another process. 91 00:04:08,850 --> 00:04:10,260 This is because the business logic 92 00:04:10,260 --> 00:04:14,190 of the SAP is not inside the ICM. 93 00:04:14,190 --> 00:04:17,310 It's actually programmed in Java or ABAP. 94 00:04:17,310 --> 00:04:20,280 Therefore, it will be sent to another process. 95 00:04:20,280 --> 00:04:21,960 And to do so, it will use something 96 00:04:21,960 --> 00:04:23,310 that is called memory pipes, 97 00:04:23,310 --> 00:04:25,860 which I will also explain in a minute, 98 00:04:25,860 --> 00:04:29,250 to officially send this data to the other process, 99 00:04:29,250 --> 00:04:31,320 which is called the worker process, 100 00:04:31,320 --> 00:04:32,640 which will generate a response, 101 00:04:32,640 --> 00:04:36,000 send it back through these memory pipes to the ICM, 102 00:04:36,000 --> 00:04:38,373 and the ICM will forward it to the client. 103 00:04:40,410 --> 00:04:42,690 Again, what are these memory pipes? 104 00:04:42,690 --> 00:04:44,090 Well MPI is how SAP call it. 105 00:04:45,930 --> 00:04:48,750 It's a framework that supports the exchange of data 106 00:04:48,750 --> 00:04:52,890 between the SAP and the worker process, 107 00:04:52,890 --> 00:04:54,393 which can be Java or ABAP. 108 00:04:55,230 --> 00:04:58,950 The idea is this framework will be used to send the data, 109 00:04:58,950 --> 00:05:01,260 but not to copy all the requests and responses, 110 00:05:01,260 --> 00:05:03,210 because that will be inefficient. 111 00:05:03,210 --> 00:05:08,210 So, the MPI uses the share memory to do so. 112 00:05:08,220 --> 00:05:10,320 It will use MPI buffers, 113 00:05:10,320 --> 00:05:14,730 which are just fixed size buffers of 65 kilobytes, 114 00:05:14,730 --> 00:05:17,130 and they will be storing the shared memory. 115 00:05:17,130 --> 00:05:19,320 Instead of sending the entire request and response 116 00:05:19,320 --> 00:05:21,570 and copying from one process to another, 117 00:05:21,570 --> 00:05:23,130 it will just send a pointer, 118 00:05:23,130 --> 00:05:25,013 which is called an MPI pointer, 119 00:05:25,013 --> 00:05:27,990 to these MPI buffers. 120 00:05:27,990 --> 00:05:29,280 It will use the MPI handler, 121 00:05:29,280 --> 00:05:33,123 which is a class that will manage all these communications. 122 00:05:34,410 --> 00:05:35,460 Let's see an example. 123 00:05:36,540 --> 00:05:40,800 First, when a request arrives to the worker thread, 124 00:05:40,800 --> 00:05:43,140 the input output handler will receive this. 125 00:05:43,140 --> 00:05:46,110 This is just a TCP socket that will have an internal buffer 126 00:05:46,110 --> 00:05:49,590 to store everything that comes from the internet. 127 00:05:49,590 --> 00:05:51,420 When the ICM worker thread is ready 128 00:05:51,420 --> 00:05:54,270 to receive and handle that request, 129 00:05:54,270 --> 00:05:57,513 it will first reserve an MPI buffer. 130 00:05:59,190 --> 00:06:01,470 Then, it will store the request there. 131 00:06:01,470 --> 00:06:04,233 This is all going to be done using the MPI handler. 132 00:06:05,130 --> 00:06:08,190 And now, when it will use the HTTP parser, 133 00:06:08,190 --> 00:06:10,500 then it will try to resolve the request 134 00:06:10,500 --> 00:06:11,760 using internal handlers, 135 00:06:11,760 --> 00:06:13,470 and if it fails, 136 00:06:13,470 --> 00:06:16,260 it will send the request to the worker process. 137 00:06:16,260 --> 00:06:19,533 This is going to be done by sending just the MPI pointer. 138 00:06:20,430 --> 00:06:23,160 And now, the Java or ABAP process will have that reference 139 00:06:23,160 --> 00:06:24,870 to this request. 140 00:06:24,870 --> 00:06:27,180 Then it will generate a response, 141 00:06:27,180 --> 00:06:29,730 and it will also reserve a new MPI buffer, 142 00:06:29,730 --> 00:06:31,263 which will store the response. 143 00:06:32,100 --> 00:06:35,080 Then it will send the MPI pointer back to the worker thread 144 00:06:36,210 --> 00:06:38,310 and the worker thread will forward this response 145 00:06:38,310 --> 00:06:39,393 back to the clients. 146 00:06:40,350 --> 00:06:44,340 Then both MPI buffers will be freed, one by one, 147 00:06:44,340 --> 00:06:46,503 and then the references will be lost. 148 00:06:48,810 --> 00:06:51,090 I also said that there are some internal handlers 149 00:06:51,090 --> 00:06:53,430 that are going to be used to try to resolve the request, 150 00:06:53,430 --> 00:06:55,560 and they are inside the ICM. 151 00:06:55,560 --> 00:06:57,060 They're actually functions that will try 152 00:06:57,060 --> 00:07:00,153 to generate a response out of a request. 153 00:07:02,610 --> 00:07:03,870 When a request arrives, 154 00:07:03,870 --> 00:07:07,533 there will be a list of handlers that will be used. 155 00:07:08,640 --> 00:07:11,040 The component that will decide which handlers 156 00:07:11,040 --> 00:07:12,930 should be included is the HTTP parser. 157 00:07:12,930 --> 00:07:16,890 It will see at the URL, and depending on the URL, 158 00:07:16,890 --> 00:07:20,070 it will know which handlers should be included in the list. 159 00:07:20,070 --> 00:07:22,853 And then, those handlers will try to resolve the request. 160 00:07:23,700 --> 00:07:26,340 When an internal handler is able to resolve a request, 161 00:07:26,340 --> 00:07:28,980 actually, when any handler is able to resolve a request, 162 00:07:28,980 --> 00:07:32,250 the other handlers will be deleted from this list, 163 00:07:32,250 --> 00:07:34,953 and the response will be sent back to the client. 164 00:07:36,780 --> 00:07:38,910 First, we have the cache handler. 165 00:07:38,910 --> 00:07:41,760 I'm going to show the handlers in order 166 00:07:41,760 --> 00:07:44,850 as they are being called when they are included in the list. 167 00:07:44,850 --> 00:07:46,800 First, we have the cache handler. 168 00:07:46,800 --> 00:07:48,690 This is present by default, 169 00:07:48,690 --> 00:07:50,100 and it's always included in the list, 170 00:07:50,100 --> 00:07:51,870 no matter what the URL is. 171 00:07:51,870 --> 00:07:54,153 It's always included in the handlers list. 172 00:07:55,170 --> 00:07:57,360 The cache handler will do what we all expect: 173 00:07:57,360 --> 00:07:59,550 It will try to resolve the request by looking at the cache, 174 00:07:59,550 --> 00:08:02,310 and if it has a stored object for that URL, 175 00:08:02,310 --> 00:08:05,613 then it will return the response back to the client. 176 00:08:06,720 --> 00:08:08,040 Then, we have the admin handler 177 00:08:08,040 --> 00:08:09,603 and the authentication handler. 178 00:08:11,850 --> 00:08:13,920 They are both present by default, sorry. 179 00:08:13,920 --> 00:08:16,740 But they are only going to be called depending on the URL, 180 00:08:16,740 --> 00:08:18,960 and if the pattern is correct. 181 00:08:18,960 --> 00:08:20,310 So, for the admin handler, 182 00:08:20,310 --> 00:08:23,490 that is a prefix being /SAP/admin. 183 00:08:23,490 --> 00:08:24,810 And for the authentication handler, 184 00:08:24,810 --> 00:08:26,940 we will have some hard coded values in the ICM 185 00:08:26,940 --> 00:08:29,280 that will be used to know if the handler 186 00:08:29,280 --> 00:08:30,580 should be included or not. 187 00:08:32,130 --> 00:08:34,260 Then we have the modification handler, 188 00:08:34,260 --> 00:08:37,020 the file access handler and the redirect handler. 189 00:08:37,020 --> 00:08:38,430 They are not present by default. 190 00:08:38,430 --> 00:08:41,760 They need to be set in a configuration file 191 00:08:41,760 --> 00:08:42,900 before the SAP starts, 192 00:08:42,900 --> 00:08:45,273 so we are not going to see more about them. 193 00:08:46,290 --> 00:08:48,720 And finally, we'll have the Java and the ABAP handler. 194 00:08:48,720 --> 00:08:51,570 That depends on how the system is configured. 195 00:08:51,570 --> 00:08:54,960 And they also are going to be always included by default, 196 00:08:54,960 --> 00:08:55,950 but they are not going to try 197 00:08:55,950 --> 00:08:57,330 to resolve the request internally. 198 00:08:57,330 --> 00:09:01,230 They will just send the request to the worker process. 199 00:09:01,230 --> 00:09:02,790 As you can see, there is a specific function 200 00:09:02,790 --> 00:09:04,620 for each of these handlers. 201 00:09:04,620 --> 00:09:07,470 We also have other handlers, like the log handler, 202 00:09:07,470 --> 00:09:09,630 but that's not really interesting for us, 203 00:09:09,630 --> 00:09:12,663 because it cannot generate a response out of our request. 204 00:09:14,310 --> 00:09:16,590 Let's see an example of how a request is resolved 205 00:09:16,590 --> 00:09:17,793 using internal handlers. 206 00:09:19,110 --> 00:09:20,310 Again, when a request arrive, 207 00:09:20,310 --> 00:09:23,130 it will be stored in the input output handler, 208 00:09:23,130 --> 00:09:24,543 and in this case, we see that the request 209 00:09:24,543 --> 00:09:27,333 is a gate to /SAP/admin. 210 00:09:28,800 --> 00:09:31,950 Again, the worker thread will try to resolve 211 00:09:31,950 --> 00:09:33,570 a new MPI buffer. 212 00:09:33,570 --> 00:09:36,060 It will place there request there. 213 00:09:36,060 --> 00:09:39,480 And now, the HTTP parser will start 214 00:09:39,480 --> 00:09:40,530 calling different handlers, 215 00:09:40,530 --> 00:09:42,720 will actually include these handlers in the list. 216 00:09:42,720 --> 00:09:44,160 First, the cache handler, 217 00:09:44,160 --> 00:09:46,980 because it's always included. 218 00:09:46,980 --> 00:09:48,480 Then in this case, the admin handler, 219 00:09:48,480 --> 00:09:51,963 because of the /SAP/admin prefix. 220 00:09:53,160 --> 00:09:55,320 And then, the Java or ABAP handler, 221 00:09:55,320 --> 00:09:58,170 depending on the worker process that is going to be used. 222 00:09:59,850 --> 00:10:02,940 Now, the cache handler is going to be called. 223 00:10:02,940 --> 00:10:04,290 In this case, let's say it fails. 224 00:10:04,290 --> 00:10:06,330 It cannot resolve the request. 225 00:10:06,330 --> 00:10:08,370 So, in this case, the admin handler is also going 226 00:10:08,370 --> 00:10:11,400 to be called after this, and in this case, 227 00:10:11,400 --> 00:10:15,210 we see that we obtain a response out of the cache handler. 228 00:10:15,210 --> 00:10:17,220 This is not going to be placed in the shared memory, 229 00:10:17,220 --> 00:10:18,180 because it's not necessary. 230 00:10:18,180 --> 00:10:20,460 We will not send it to the worker process. 231 00:10:20,460 --> 00:10:24,450 The response is going to be placed in the hip, 232 00:10:24,450 --> 00:10:26,820 and then this will be forwarded. 233 00:10:26,820 --> 00:10:28,890 All the other handlers will be deleted, 234 00:10:28,890 --> 00:10:31,713 and this will be forwarded to the client. 235 00:10:32,610 --> 00:10:34,770 Again, the MPI buffer will be freed, 236 00:10:34,770 --> 00:10:36,320 and the reference will be lost. 237 00:10:37,860 --> 00:10:39,990 As I said, MPI buffers are fixed size. 238 00:10:39,990 --> 00:10:44,990 This means that they can only hold 65 kilobytes of data. 239 00:10:45,030 --> 00:10:48,210 So, what if we send a longer request? 240 00:10:48,210 --> 00:10:49,980 I'm going to call this a long request, 241 00:10:49,980 --> 00:10:51,240 even though it's not that long. 242 00:10:51,240 --> 00:10:52,950 It's just 65 kilobytes. 243 00:10:52,950 --> 00:10:56,280 But what if we send something that cannot be freed 244 00:10:56,280 --> 00:10:58,443 inside the MPI buffer? 245 00:11:00,330 --> 00:11:01,260 Let's see an example. 246 00:11:01,260 --> 00:11:05,613 We send a request with a content length of 66,000 bytes. 247 00:11:07,206 --> 00:11:10,440 And the ICM will first reserve an MPI buffer, as always, 248 00:11:10,440 --> 00:11:13,770 and it will only place this first 65 kilobytes 249 00:11:13,770 --> 00:11:17,850 of the request that has arrived from the client. 250 00:11:17,850 --> 00:11:19,587 And this is because the internal handlers 251 00:11:19,587 --> 00:11:22,020 are supposed to resolve request 252 00:11:22,020 --> 00:11:23,520 that does not contain body, 253 00:11:23,520 --> 00:11:28,410 that are just simple requests with some special headers. 254 00:11:28,410 --> 00:11:32,460 And so, the ICM is not expecting to use the rest of the body 255 00:11:32,460 --> 00:11:33,780 or the rest of the request 256 00:11:33,780 --> 00:11:36,333 until the worker process is required. 257 00:11:37,500 --> 00:11:40,590 Again, the HTTP parser will read the request, 258 00:11:40,590 --> 00:11:42,570 will call some handlers. 259 00:11:42,570 --> 00:11:44,040 In this case, the cache handler is not able 260 00:11:44,040 --> 00:11:45,270 to resolve the request. 261 00:11:45,270 --> 00:11:49,200 And so when the Java or ABAP process is called, 262 00:11:49,200 --> 00:11:52,650 so when we send this request to the worker process, 263 00:11:52,650 --> 00:11:54,840 then in this case, we will need the rest of the request, 264 00:11:54,840 --> 00:11:57,390 because of course, the Java or ABAP process 265 00:11:57,390 --> 00:11:58,950 will use the body of our request, 266 00:11:58,950 --> 00:12:02,550 and the business logic needs this kind of data. 267 00:12:02,550 --> 00:12:06,900 So, the ICM will reserve as many MPI buffers as required. 268 00:12:06,900 --> 00:12:09,270 It will store the rest of the request there, 269 00:12:09,270 --> 00:12:13,770 and it will send all the MPI pointers to the worker process. 270 00:12:13,770 --> 00:12:14,987 Now, the worker process will have a reference, 271 00:12:14,987 --> 00:12:17,583 and it will use them to generate a response. 272 00:12:18,810 --> 00:12:23,010 And again, the worker process will reserve an MPI buffer, 273 00:12:23,010 --> 00:12:26,193 store the response, send it to the worker thread, 274 00:12:27,150 --> 00:12:30,450 and the worker thread will forward this response 275 00:12:30,450 --> 00:12:31,890 back to the client. 276 00:12:31,890 --> 00:12:34,860 And now, as I said, previously, 277 00:12:34,860 --> 00:12:37,500 these MPI buffers are going to be freed one by one 278 00:12:37,500 --> 00:12:39,330 when we have a simple request. 279 00:12:39,330 --> 00:12:42,300 However, when we have a multi-buffer request, 280 00:12:42,300 --> 00:12:45,180 the MPI free all buffer function is going to be called, 281 00:12:45,180 --> 00:12:48,930 which will delete or will free all the MPI buffers 282 00:12:48,930 --> 00:12:51,130 that are associated with this worker thread. 283 00:12:52,140 --> 00:12:54,040 And then, the references will be lost. 284 00:12:56,975 --> 00:12:59,808 Let's see the first vulnerability. 285 00:13:00,750 --> 00:13:05,400 As I said, the worker thread is not expecting to use 286 00:13:05,400 --> 00:13:07,173 or to resolve a request. 287 00:13:08,250 --> 00:13:09,390 We using the body, 288 00:13:09,390 --> 00:13:14,370 because internal handlers shouldn't use that information. 289 00:13:14,370 --> 00:13:16,410 But what if we send a long request 290 00:13:16,410 --> 00:13:19,020 that is not handled by the worker process, 291 00:13:19,020 --> 00:13:21,420 but instead it's handled by an internal handler? 292 00:13:22,710 --> 00:13:25,980 Again, as I already explained, we will see. 293 00:13:25,980 --> 00:13:30,900 In this case, we have our gate request to /SAP/admin. 294 00:13:30,900 --> 00:13:35,310 And it's a long request containing 66,000 bytes. 295 00:13:35,310 --> 00:13:37,740 Therefore, only the first 65 kilobytes 296 00:13:37,740 --> 00:13:39,510 will be stored in an MPI buffer. 297 00:13:39,510 --> 00:13:43,590 And then, the parser will include these different handlers. 298 00:13:43,590 --> 00:13:45,960 The cache handler, again, will fail. 299 00:13:45,960 --> 00:13:47,520 But in this case, the admin handler 300 00:13:47,520 --> 00:13:49,220 was able to generate the response. 301 00:13:50,610 --> 00:13:54,060 This response will again be sent to the client. 302 00:13:54,060 --> 00:13:56,910 Then, all the handlers will be removed. 303 00:13:56,910 --> 00:13:59,343 the MPI buffer will be freed, 304 00:14:00,480 --> 00:14:03,060 and the request response cycle will be completed. 305 00:14:03,060 --> 00:14:03,990 But as you can see, 306 00:14:03,990 --> 00:14:05,880 we have more data from the previous request 307 00:14:05,880 --> 00:14:07,260 in the input output handler. 308 00:14:07,260 --> 00:14:10,710 So now, when the worker thread tries to read a new request, 309 00:14:10,710 --> 00:14:14,733 it will consider this as, of course, a new isolated request. 310 00:14:15,870 --> 00:14:18,990 So, if you know something about the HTTP synchronization, 311 00:14:18,990 --> 00:14:21,290 which I hope you do, if you came to this talk, 312 00:14:22,290 --> 00:14:24,620 you know that this is a vulnerability, and a serious one, 313 00:14:24,620 --> 00:14:28,730 and this is because, whenever we send this kind of request 314 00:14:28,730 --> 00:14:30,330 that you can see in the slides, 315 00:14:30,330 --> 00:14:35,330 which contains a gate request to /SAP/admin, 316 00:14:36,570 --> 00:14:38,610 it will be resolved by internal handler, as we saw. 317 00:14:38,610 --> 00:14:41,700 And actually, the proxy will forward this 318 00:14:41,700 --> 00:14:45,690 as an entire request without seeing any problem. 319 00:14:45,690 --> 00:14:47,370 This is because we don't have nothing 320 00:14:47,370 --> 00:14:50,850 that tells the proxy that this is a special request. 321 00:14:50,850 --> 00:14:55,850 Actually, it is HTTP RFC compliance, so there is no problem. 322 00:14:56,310 --> 00:14:59,070 It's just a gate request with a big content length, 323 00:14:59,070 --> 00:15:02,583 but the entire body is included in that content length. 324 00:15:03,420 --> 00:15:06,030 But when this request arrives to the ICM, 325 00:15:06,030 --> 00:15:08,190 it will be splitted, and the last part, 326 00:15:08,190 --> 00:15:10,410 which is the gate to smuggle 327 00:15:10,410 --> 00:15:12,300 will be used as an isolated request. 328 00:15:12,300 --> 00:15:14,160 Therefore, it will be at a synchronization 329 00:15:14,160 --> 00:15:17,670 between any proxy in the world, because again, 330 00:15:17,670 --> 00:15:21,213 any proxy will see this as an isolated request, and the ICM. 331 00:15:22,470 --> 00:15:23,850 This is a serious vulnerability. 332 00:15:23,850 --> 00:15:26,130 It's actually a CVSS 10, 333 00:15:26,130 --> 00:15:29,520 because it allow us to compromise any SAP installation 334 00:15:29,520 --> 00:15:32,280 in the world in the most exposed service. 335 00:15:32,280 --> 00:15:33,990 I'm going to show you some examples 336 00:15:33,990 --> 00:15:35,220 of how to exploit this, 337 00:15:35,220 --> 00:15:39,390 to actually take control of the victims and the HTTP 338 00:15:39,390 --> 00:15:41,463 and the actual applications. 339 00:15:43,920 --> 00:15:45,630 My first example is going to be using 340 00:15:45,630 --> 00:15:47,250 HTTP request smuggling, 341 00:15:47,250 --> 00:15:50,160 and I'm going to use the NWA endpoint, 342 00:15:50,160 --> 00:15:51,910 which is present again in all SAPs, 343 00:15:52,946 --> 00:15:57,240 and is used to redirect any user to the login URL. 344 00:15:57,240 --> 00:15:59,700 It provides two really interesting features. 345 00:15:59,700 --> 00:16:01,710 First, an open redirect, 346 00:16:01,710 --> 00:16:04,290 which will allow us to set anything we want 347 00:16:04,290 --> 00:16:09,060 in the relocation host by using the host header. 348 00:16:09,060 --> 00:16:13,980 As you can see, I can place the attacker host 349 00:16:13,980 --> 00:16:15,627 in the host header, 350 00:16:15,627 --> 00:16:18,510 and this will be reflected in the location header 351 00:16:18,510 --> 00:16:20,220 of the response. 352 00:16:20,220 --> 00:16:21,300 This is actually a feature. 353 00:16:21,300 --> 00:16:22,800 This is not a vulnerability by itself, 354 00:16:22,800 --> 00:16:25,680 because it cannot be exploited by itself. 355 00:16:25,680 --> 00:16:28,470 And also, we have a parameter reflection, 356 00:16:28,470 --> 00:16:31,560 which will allow us to reflect anything we place in the body 357 00:16:31,560 --> 00:16:36,423 of the request in the query string of the relocation URL. 358 00:16:37,860 --> 00:16:40,410 Again, you can see that the line breaks 359 00:16:40,410 --> 00:16:42,453 are replaced with spaces. 360 00:16:43,770 --> 00:16:45,750 So, how can we combine this 361 00:16:45,750 --> 00:16:48,060 with the synchronization vulnerability 362 00:16:48,060 --> 00:16:49,980 to take control of victims' request, 363 00:16:49,980 --> 00:16:52,530 and also to take control of victim session cookies? 364 00:16:53,610 --> 00:16:56,880 Well, first, the attacker will send a payload 365 00:16:56,880 --> 00:17:01,077 which will smuggle an entire request, 366 00:17:01,077 --> 00:17:02,840 and as you can see the first part, 367 00:17:02,840 --> 00:17:05,100 it will be forwarded entirely by the proxy, 368 00:17:05,100 --> 00:17:06,360 as when I select the request, 369 00:17:06,360 --> 00:17:07,910 it will be splitted in the ICM. 370 00:17:09,390 --> 00:17:12,190 The first part will be resolved by the internal handler, 371 00:17:13,170 --> 00:17:16,110 and the response will be sent back to the attacker. 372 00:17:16,110 --> 00:17:19,590 But the rest of the request, which is the smuggled one, 373 00:17:19,590 --> 00:17:21,660 will stay in the ICM. 374 00:17:21,660 --> 00:17:24,000 And this is because the content length states 375 00:17:24,000 --> 00:17:26,940 that there should be 100 bytes of body, 376 00:17:26,940 --> 00:17:29,010 but we didn't send anything in the body. 377 00:17:29,010 --> 00:17:30,930 So, it will wait for more data. 378 00:17:30,930 --> 00:17:33,750 Also, you can see this is a post-request to NWA 379 00:17:33,750 --> 00:17:36,720 and the host header is evil.com, 380 00:17:36,720 --> 00:17:39,303 so that's a host controlled by the attacker. 381 00:17:41,880 --> 00:17:45,180 Now, when a victim sends a request to the proxy, 382 00:17:45,180 --> 00:17:46,830 the proxy will just forward this. 383 00:17:47,730 --> 00:17:49,157 In the ICM, this will be compagnated 384 00:17:49,157 --> 00:17:52,530 to the smuggle message that we injected. 385 00:17:52,530 --> 00:17:55,890 And so, the first 100 bytes of the victim's request 386 00:17:55,890 --> 00:17:59,010 will be used as part of the body of this request. 387 00:17:59,010 --> 00:18:02,550 If you remember, the NWA endpoint will allow us 388 00:18:02,550 --> 00:18:04,203 to generate a response in this case 389 00:18:04,203 --> 00:18:07,830 that will redirect the victim to evil.com, 390 00:18:07,830 --> 00:18:12,600 and it will send also in the query string of the request, 391 00:18:12,600 --> 00:18:15,930 the first 100 bytes of its original request, 392 00:18:15,930 --> 00:18:19,173 which in this case also contains the cookies. 393 00:18:21,810 --> 00:18:24,480 When this is received by the victim's browser, 394 00:18:24,480 --> 00:18:26,580 the browser will send another request, 395 00:18:26,580 --> 00:18:28,380 but in this case, to evil.com, 396 00:18:28,380 --> 00:18:30,060 which is controlled by the attacker. 397 00:18:30,060 --> 00:18:33,330 And so, the attacker will receive this request, 398 00:18:33,330 --> 00:18:36,513 which will contain also the cookies from the victim. 399 00:18:38,310 --> 00:18:40,620 Now, we will be able to hijack as many requests, 400 00:18:40,620 --> 00:18:44,100 as many cookies and sessions as we want, 401 00:18:44,100 --> 00:18:47,100 but for each of these requests that we hijack, 402 00:18:47,100 --> 00:18:49,053 we will need to send a new request. 403 00:18:51,090 --> 00:18:53,820 Something that is really special about this vulnerability 404 00:18:53,820 --> 00:18:57,090 is that we are not using any kind of request 405 00:18:57,090 --> 00:18:58,320 that is invalid. 406 00:18:58,320 --> 00:18:59,797 Any proxy will see this, and you will say, 407 00:18:59,797 --> 00:19:02,010 "Okay, this is completely RFC compliant. 408 00:19:02,010 --> 00:19:04,710 We are not sending any header, anything strange." 409 00:19:04,710 --> 00:19:06,750 And so, this means that we will be able 410 00:19:06,750 --> 00:19:08,400 to replicate the attack and to send it 411 00:19:08,400 --> 00:19:12,810 using an HTML form, and also JavaScript. 412 00:19:12,810 --> 00:19:15,270 The idea is, as you can see the slide, 413 00:19:15,270 --> 00:19:19,170 I created a form that will send a request to an SAP system 414 00:19:19,170 --> 00:19:21,150 that will be resolved by an internal handler; 415 00:19:21,150 --> 00:19:23,640 in this case, the admin handler. 416 00:19:23,640 --> 00:19:26,760 And it will also contain a pattern to make this request 417 00:19:26,760 --> 00:19:28,320 a long request. 418 00:19:28,320 --> 00:19:31,503 Finally, at the end, it will place the smuggle request. 419 00:19:32,490 --> 00:19:35,040 When a victim receives this form, 420 00:19:35,040 --> 00:19:38,850 the JavaScript will submit this form again. 421 00:19:38,850 --> 00:19:41,730 And so, the attack will be sent by, in this case, 422 00:19:41,730 --> 00:19:44,760 not from the attacker, but from the victim. 423 00:19:44,760 --> 00:19:46,440 Now, the victim became the attacker, 424 00:19:46,440 --> 00:19:50,190 and this actually will continue forever, 425 00:19:50,190 --> 00:19:54,750 because the victims, when making a request to the SAP, 426 00:19:54,750 --> 00:19:57,060 will receive again the payload, 427 00:19:57,060 --> 00:19:59,640 will be redirected to evil.com, 428 00:19:59,640 --> 00:20:02,370 and then again send the attack. 429 00:20:02,370 --> 00:20:05,880 So again, we can place this in the evil.com. 430 00:20:05,880 --> 00:20:06,933 That's the idea. 431 00:20:08,160 --> 00:20:10,230 Also, we can use the same kind of attacks 432 00:20:10,230 --> 00:20:13,260 when we find a vulnerability that does not require 433 00:20:13,260 --> 00:20:14,880 any invalid or forbidden header, 434 00:20:14,880 --> 00:20:17,553 like the one found last year in HI proxy. 435 00:20:19,200 --> 00:20:22,140 We can use in those cases DNS rebinding 436 00:20:22,140 --> 00:20:25,560 to be able to send those extra headers, 437 00:20:25,560 --> 00:20:28,653 but we can use this technique in many other ways. 438 00:20:29,490 --> 00:20:33,450 If you saw yesterday's talk from James Kettle, 439 00:20:33,450 --> 00:20:36,930 you might think this is a really similar technique, 440 00:20:36,930 --> 00:20:40,020 because we are actually using the same technique 441 00:20:40,020 --> 00:20:40,953 or the same idea. 442 00:20:41,826 --> 00:20:43,530 Even though the the nature 443 00:20:43,530 --> 00:20:45,300 of the vulnerabilities are different, 444 00:20:45,300 --> 00:20:47,220 we found that it is possible to cause 445 00:20:47,220 --> 00:20:49,410 this client-side desynchronization, 446 00:20:49,410 --> 00:20:52,320 so we are not only going to be able to persist the attack 447 00:20:52,320 --> 00:20:54,180 and create smuggling botnets, 448 00:20:54,180 --> 00:20:58,230 but also exploit the browser server connection, 449 00:20:58,230 --> 00:21:01,800 so we will be able to desynchronize even systems 450 00:21:01,800 --> 00:21:03,150 that are not using a proxy. 451 00:21:04,397 --> 00:21:06,300 This is a really new idea, 452 00:21:06,300 --> 00:21:08,910 and yesterday James provided a new methodology. 453 00:21:08,910 --> 00:21:11,850 It was a really great talk. I recommend that. 454 00:21:11,850 --> 00:21:15,810 And so, as I said, we can exploit this even without a proxy, 455 00:21:15,810 --> 00:21:17,490 and we could use social engineering 456 00:21:17,490 --> 00:21:19,380 if we are not able to reach the server 457 00:21:19,380 --> 00:21:22,904 to send this attack with fishing, so we can send this form. 458 00:21:22,904 --> 00:21:25,860 Even without sending the first request, 459 00:21:25,860 --> 00:21:26,790 we will be able to attack 460 00:21:26,790 --> 00:21:28,800 and desynchronize the entire system 461 00:21:28,800 --> 00:21:30,350 and obtain the session cookies. 462 00:21:33,030 --> 00:21:34,180 Let's see a small demo. 463 00:21:41,940 --> 00:21:45,630 In this demo, the first step is going to be the client, 464 00:21:45,630 --> 00:21:47,129 and as you can see, 465 00:21:47,129 --> 00:21:49,620 when the guy sends a request to start page, 466 00:21:49,620 --> 00:21:52,440 he will just receive the two handler response. 467 00:21:52,440 --> 00:21:53,970 Nothing strange here. 468 00:21:53,970 --> 00:21:54,960 As many times as he wants, 469 00:21:54,960 --> 00:21:56,580 he will receive the same response, 470 00:21:56,580 --> 00:21:59,520 and he's including the cookies in this request. 471 00:21:59,520 --> 00:22:02,580 Now, when the attacker sends the payload, 472 00:22:02,580 --> 00:22:05,070 which is going to be resolved by internal handler, 473 00:22:05,070 --> 00:22:06,270 and it's a long request, 474 00:22:07,620 --> 00:22:10,350 we will be able to smuggle another message 475 00:22:10,350 --> 00:22:12,180 and inject what is at the end, 476 00:22:12,180 --> 00:22:13,920 which is the post request that we already saw, 477 00:22:13,920 --> 00:22:15,990 the post to NWA. 478 00:22:15,990 --> 00:22:19,653 This will be stored in the ICM until more data arrives. 479 00:22:20,880 --> 00:22:22,503 Again, when we send this, 480 00:22:24,120 --> 00:22:25,140 we just receive a response. 481 00:22:25,140 --> 00:22:26,970 We don't care about that response. 482 00:22:26,970 --> 00:22:28,770 When the victim sends a new request, 483 00:22:28,770 --> 00:22:30,120 instead of receiving a two handler, 484 00:22:30,120 --> 00:22:34,380 he will receive a redirection to the evil.com server. 485 00:22:34,380 --> 00:22:38,310 And now, again, when he follows this redirection, 486 00:22:38,310 --> 00:22:41,580 he will be sending his own cookies, 487 00:22:41,580 --> 00:22:44,820 and therefore we will be able to obtain these cookies. 488 00:22:44,820 --> 00:22:47,613 And of course, the secret session of the victim. 489 00:22:49,080 --> 00:22:52,110 What we are going to see now is that when he follows 490 00:22:52,110 --> 00:22:54,570 the redirection, the evil.com server, 491 00:22:54,570 --> 00:22:55,920 in this case is another server. 492 00:22:55,920 --> 00:22:57,942 I don't remember the name. 493 00:22:57,942 --> 00:23:00,810 Is going to return this form that I already explained. 494 00:23:00,810 --> 00:23:04,140 So, the browser will send an another attack, 495 00:23:04,140 --> 00:23:07,143 and this will keep the attack and the exploit running. 496 00:23:11,184 --> 00:23:12,211 Okay. 497 00:23:12,211 --> 00:23:15,211 (audience applauds) 498 00:23:20,100 --> 00:23:23,460 Okay. This is another exploit I'm going to explain. 499 00:23:23,460 --> 00:23:26,420 This technique is kind of advanced. 500 00:23:26,420 --> 00:23:29,520 I explained these ideas last year in Defcon. 501 00:23:29,520 --> 00:23:31,290 It's called response modeling. 502 00:23:31,290 --> 00:23:32,700 And what we are going to try 503 00:23:32,700 --> 00:23:35,850 is to poison web cache proxy. 504 00:23:35,850 --> 00:23:38,250 Anytime we have a web cache proxy in the middle of us, 505 00:23:38,250 --> 00:23:40,560 and we have a desynchronization vulnerability, 506 00:23:40,560 --> 00:23:42,900 we are going to be able to use this technique. 507 00:23:42,900 --> 00:23:44,550 I'm going to try to explain really fast. 508 00:23:44,550 --> 00:23:45,900 If you don't really understand this, 509 00:23:45,900 --> 00:23:48,150 you can see my last year talk, 510 00:23:48,150 --> 00:23:51,513 and I guess that will make this clear. 511 00:23:53,460 --> 00:23:55,680 The attacker in this case is going to send 512 00:23:55,680 --> 00:23:57,030 two gate requests. 513 00:23:57,030 --> 00:23:59,580 Actually, the proxy will see two gate requests, 514 00:23:59,580 --> 00:24:01,530 but when they are forwarded to the backend, 515 00:24:01,530 --> 00:24:03,957 which in this case would be the ICM, 516 00:24:03,957 --> 00:24:07,640 the first one will be split into three different requests. 517 00:24:07,640 --> 00:24:10,050 In this case, they will not be incomplete request. 518 00:24:10,050 --> 00:24:12,630 As we already saw, with the content length, 519 00:24:12,630 --> 00:24:14,580 being a big content length without a body. 520 00:24:14,580 --> 00:24:17,580 But instead we are going to smuggle three complete requests. 521 00:24:18,540 --> 00:24:19,890 Now, as you can see, 522 00:24:19,890 --> 00:24:23,400 the proxy saw that there were two gate requests, 523 00:24:23,400 --> 00:24:25,830 but in this case, the ICM saw that the first request 524 00:24:25,830 --> 00:24:26,790 is a gate. 525 00:24:26,790 --> 00:24:28,263 The second one is a hit. 526 00:24:29,100 --> 00:24:32,403 The third one, I don't care, and the fourth one is a gate. 527 00:24:34,440 --> 00:24:36,780 You all know that the hit request is special 528 00:24:36,780 --> 00:24:40,800 because when you send this kind of request to a server, 529 00:24:40,800 --> 00:24:43,020 what we are going to receive is the same response 530 00:24:43,020 --> 00:24:45,510 that we will get for a gate request. 531 00:24:45,510 --> 00:24:47,130 But instead, in this case, 532 00:24:47,130 --> 00:24:49,410 we are only going to receive the headers. 533 00:24:49,410 --> 00:24:54,410 What you might not know is that the RFC allow the servers 534 00:24:54,690 --> 00:24:56,640 to send also a content length. 535 00:24:56,640 --> 00:24:58,620 This is almost always true. 536 00:24:58,620 --> 00:25:01,710 You will see this in this behavior in almost any server 537 00:25:01,710 --> 00:25:05,280 and the content length, even though one would expect 538 00:25:05,280 --> 00:25:08,640 to be zero, because the body is empty, it's not. 539 00:25:08,640 --> 00:25:11,730 It's the same one as the content length would be 540 00:25:11,730 --> 00:25:14,370 if we would have issued a gate request. 541 00:25:14,370 --> 00:25:15,570 Therefore, in this case, 542 00:25:15,570 --> 00:25:18,420 we will see that it's quite longer than zero. 543 00:25:18,420 --> 00:25:20,673 It's like 3000 something. 544 00:25:23,534 --> 00:25:25,230 How are the proxies going to know 545 00:25:25,230 --> 00:25:27,540 that they should ignore this content length header? 546 00:25:27,540 --> 00:25:29,820 Well, because they know that they had forwarded 547 00:25:29,820 --> 00:25:30,960 a hit request, 548 00:25:30,960 --> 00:25:32,490 and therefore when they received the response 549 00:25:32,490 --> 00:25:33,690 for this hit request, 550 00:25:33,690 --> 00:25:36,000 they know that this content length shouldn't be used 551 00:25:36,000 --> 00:25:38,292 to generate the response and to know 552 00:25:38,292 --> 00:25:40,890 the length of the body of the response. 553 00:25:40,890 --> 00:25:43,800 But if you see in the slides, 554 00:25:43,800 --> 00:25:46,110 you can also see that this proxy didn't solve 555 00:25:46,110 --> 00:25:47,340 the hit request. 556 00:25:47,340 --> 00:25:50,430 Therefore, he doesn't know that the content length 557 00:25:50,430 --> 00:25:51,330 should be ignored. 558 00:25:52,260 --> 00:25:55,170 The first response will be sent to the attacker, as always. 559 00:25:55,170 --> 00:25:58,470 It's the response for the first gate request. 560 00:25:58,470 --> 00:26:01,530 But now, the second response is going to be used 561 00:26:01,530 --> 00:26:03,000 for a gate request. 562 00:26:03,000 --> 00:26:06,240 And in this case, the content length will be used, 563 00:26:06,240 --> 00:26:10,050 because the proxy doesn't know this is a hit response. 564 00:26:10,050 --> 00:26:14,850 And so, it will use part of the next response as the body. 565 00:26:14,850 --> 00:26:17,280 It will use the headers of the next response 566 00:26:17,280 --> 00:26:20,103 as part of this body and also the rest. 567 00:26:21,420 --> 00:26:23,610 We can build a lot of payloads out of this. 568 00:26:23,610 --> 00:26:26,550 We can use this to actually generate malicious responses 569 00:26:26,550 --> 00:26:27,990 that contain JavaScript. 570 00:26:27,990 --> 00:26:31,200 We can change the content type of different responses. 571 00:26:31,200 --> 00:26:34,140 So, if we have a response where we can reflect data 572 00:26:34,140 --> 00:26:37,710 to explain, and we cannot use this to generate an exploit, 573 00:26:37,710 --> 00:26:40,740 well, this can be used to change the content type. 574 00:26:40,740 --> 00:26:44,487 Also, if we are able to reflect some data or something 575 00:26:44,487 --> 00:26:46,890 in the headers of the response, 576 00:26:46,890 --> 00:26:50,253 we can also use this as part of an HTML body. 577 00:26:51,990 --> 00:26:55,650 And also, you will see that this response 578 00:26:55,650 --> 00:26:59,163 only also contain a cache control header. 579 00:27:00,090 --> 00:27:03,360 If we choose a hit request that the response give us 580 00:27:03,360 --> 00:27:04,680 a cache control header, 581 00:27:04,680 --> 00:27:07,020 then we are going to be able to poison the cache 582 00:27:07,020 --> 00:27:08,820 with this malicious response, 583 00:27:08,820 --> 00:27:12,720 and the request and the URL that's going to be poisoned 584 00:27:12,720 --> 00:27:14,520 is also chosen by the attacker, 585 00:27:14,520 --> 00:27:16,858 and we can choose any kind of URL we want. 586 00:27:16,858 --> 00:27:20,763 We can arbitrarily modify any record in the web cache. 587 00:27:21,930 --> 00:27:23,700 And we can store this payload there, 588 00:27:23,700 --> 00:27:26,910 so that then, when the client generates a request 589 00:27:26,910 --> 00:27:30,300 for the same URL, the proxy will not forward this, 590 00:27:30,300 --> 00:27:33,933 but instead it will send what is stored in the cache. 591 00:27:34,950 --> 00:27:37,023 Now, we are also going to see a demo. 592 00:27:46,170 --> 00:27:48,120 Well, I don't know where the demos are. 593 00:27:52,500 --> 00:27:53,800 Can I have some help here? 594 00:27:57,360 --> 00:27:58,920 Ah. 595 00:27:58,920 --> 00:28:00,480 - [Crew] It should be there. 596 00:28:00,480 --> 00:28:01,943 - [Martin] Yeah, it should be there. 597 00:28:04,344 --> 00:28:05,970 There it is. 598 00:28:05,970 --> 00:28:06,803 Sorry for that. 599 00:28:07,680 --> 00:28:08,513 Okay. 600 00:28:09,900 --> 00:28:11,850 Now, in this demo, 601 00:28:11,850 --> 00:28:13,830 we are going to see how we can poison 602 00:28:13,830 --> 00:28:17,433 and modify the web cache of any proxy. 603 00:28:18,900 --> 00:28:21,750 I create an exploit that is going to poison 604 00:28:21,750 --> 00:28:24,660 any URL we want with a specific penalty. 605 00:28:24,660 --> 00:28:28,200 In this case, it's going to generate a JavaScript 606 00:28:28,200 --> 00:28:29,823 that will generate an alert. 607 00:28:37,260 --> 00:28:38,430 The idea, again: 608 00:28:38,430 --> 00:28:42,213 I use this payload to modify any URL we want, 609 00:28:43,920 --> 00:28:47,230 and generate this and inject the malicious response 610 00:28:48,132 --> 00:28:49,803 for that specific endpoint. 611 00:28:51,090 --> 00:28:52,950 I can use this attack for something even better, 612 00:28:52,950 --> 00:28:55,983 which is to modify the login page of the SAP. 613 00:28:57,990 --> 00:29:00,690 The idea is if we can modify anything we want, 614 00:29:00,690 --> 00:29:05,490 then why don't modifying the URL that is used for login, 615 00:29:05,490 --> 00:29:09,660 so that when a user loads this, or use this HTML, 616 00:29:10,950 --> 00:29:13,980 it will actually send the credentials back to the attacker 617 00:29:13,980 --> 00:29:15,420 instead of the SAP. 618 00:29:15,420 --> 00:29:18,810 And then, we can redirect the victim to another login 619 00:29:18,810 --> 00:29:21,210 with extra query stream parameters, 620 00:29:21,210 --> 00:29:23,643 so that it doesn't use the cache version. 621 00:29:24,930 --> 00:29:28,443 Now, again, as I said, I'm going to replace the login URL. 622 00:29:34,260 --> 00:29:37,290 This is always going to be used by any SAP user 623 00:29:37,290 --> 00:29:39,093 to log into the application. 624 00:29:40,380 --> 00:29:42,480 It start a server that is going to be listening 625 00:29:42,480 --> 00:29:45,723 to what this login sends. 626 00:29:48,240 --> 00:29:51,240 Again, this looks like the original login, nothing strange. 627 00:29:51,240 --> 00:29:53,250 The URL is still the same, 628 00:29:53,250 --> 00:29:56,220 nothing that the user can detect. 629 00:29:56,220 --> 00:29:59,100 When he sends the credentials, 630 00:29:59,100 --> 00:30:01,560 instead of being sent to the SAP, 631 00:30:01,560 --> 00:30:03,260 they will be sent to the attacker. 632 00:30:04,542 --> 00:30:07,542 (audience applauds) 633 00:30:14,370 --> 00:30:16,710 Well, again, it's a repetition, 634 00:30:16,710 --> 00:30:20,130 just to show that this will work anytime we want, 635 00:30:20,130 --> 00:30:21,780 and this will be stored in the cache. 636 00:30:21,780 --> 00:30:25,350 This will work without sending any other payload. 637 00:30:25,350 --> 00:30:26,523 This will keep working. 638 00:30:33,840 --> 00:30:34,830 Okay. 639 00:30:34,830 --> 00:30:37,380 Then I said, "Well, if I found a vulnerability like this, 640 00:30:37,380 --> 00:30:39,390 then I want to learn more about the ICM, 641 00:30:39,390 --> 00:30:42,840 and I want to learn how the more complex requests 642 00:30:42,840 --> 00:30:43,950 are processed." 643 00:30:43,950 --> 00:30:47,490 And then, I found that the ICM can be configured 644 00:30:47,490 --> 00:30:49,020 both for Java or ABAP. 645 00:30:49,020 --> 00:30:51,630 I knew that, but that there is a difference. 646 00:30:51,630 --> 00:30:54,750 When we configure the ICM for Java, 647 00:30:54,750 --> 00:30:57,870 we are going to see that the HTTP server 648 00:30:57,870 --> 00:31:00,000 accepts pipeline request by default. 649 00:31:00,000 --> 00:31:02,340 But when we configure it with ABAP, 650 00:31:02,340 --> 00:31:04,080 this needs to be configured. 651 00:31:04,080 --> 00:31:07,950 So, we are going to see the Java. This will work for ABAP. 652 00:31:07,950 --> 00:31:09,543 It's configured for pipeline. 653 00:31:10,560 --> 00:31:12,450 Pipelining means that we are going to be able 654 00:31:12,450 --> 00:31:14,180 to receive a request that contains actually a payload 655 00:31:14,180 --> 00:31:17,880 that contains two request, 656 00:31:17,880 --> 00:31:20,340 and the ICM will be able to split them. 657 00:31:20,340 --> 00:31:24,030 Now, these are completely valid and legit requests 658 00:31:24,030 --> 00:31:26,550 that can be splitted, used in the content length, 659 00:31:26,550 --> 00:31:31,113 and there is nothing strange from this request. 660 00:31:32,490 --> 00:31:33,957 Now, the process will be the same. 661 00:31:33,957 --> 00:31:37,380 The ICM worker thread will reserve a new MPI buffer. 662 00:31:37,380 --> 00:31:38,980 It will store the request there. 663 00:31:40,680 --> 00:31:42,540 Then, the HTTP parser will be called, 664 00:31:42,540 --> 00:31:44,310 and the HTTP parser will recognize 665 00:31:44,310 --> 00:31:45,660 that there is an extra request. 666 00:31:45,660 --> 00:31:47,027 So, it will reserve a new MPI buffer 667 00:31:47,027 --> 00:31:49,427 and it will place the rest of the request there. 668 00:31:50,670 --> 00:31:52,680 Now, the ICM worker thread will continue 669 00:31:52,680 --> 00:31:54,090 processing the first one. 670 00:31:54,090 --> 00:31:56,463 It will send the request to the Java process. 671 00:31:57,720 --> 00:31:59,610 The Java process will generate the response. 672 00:31:59,610 --> 00:32:01,680 It will place it in the shared memory, 673 00:32:01,680 --> 00:32:04,080 send the reference to the worker thread, 674 00:32:04,080 --> 00:32:06,630 and the worker thread will forward their response. 675 00:32:06,630 --> 00:32:08,823 Then, both MPI buffers will be freed, 676 00:32:09,960 --> 00:32:12,690 and the request response cycle will be completed, 677 00:32:12,690 --> 00:32:15,720 so the ICM worker thread will be able to continue 678 00:32:15,720 --> 00:32:17,583 processing the next pipeline request. 679 00:32:20,730 --> 00:32:24,360 Remember I said that there is a string condition 680 00:32:24,360 --> 00:32:27,900 when we send multi buffer request, so long request, 681 00:32:27,900 --> 00:32:31,410 and that is that the buffers are going to be freed. 682 00:32:31,410 --> 00:32:34,170 All the buffers are going to free freed 683 00:32:34,170 --> 00:32:35,970 using the same function. 684 00:32:35,970 --> 00:32:39,150 What if we send a pipeline request with a long request? 685 00:32:39,150 --> 00:32:40,260 Three, four. 686 00:32:40,260 --> 00:32:41,520 So again, in this example, 687 00:32:41,520 --> 00:32:44,940 we are sending a long request and at the end, a new request, 688 00:32:44,940 --> 00:32:47,730 so when the worker thread receives this, 689 00:32:47,730 --> 00:32:51,240 it will place the first one in the MPI buffer, 690 00:32:51,240 --> 00:32:54,840 it will call the HCP parser, it will call the handlers. 691 00:32:54,840 --> 00:32:57,990 And then, when the worker thread is ready 692 00:32:57,990 --> 00:32:59,850 to send the request to the worker process, 693 00:32:59,850 --> 00:33:01,440 which is the Java process, 694 00:33:01,440 --> 00:33:04,380 it will place the rest of the request in a new MPI buffer. 695 00:33:04,380 --> 00:33:06,870 But now, the HTTP parser will also recognize 696 00:33:06,870 --> 00:33:08,420 that there is an extra request, 697 00:33:09,870 --> 00:33:11,460 and it will resolve a new MPI buffer 698 00:33:11,460 --> 00:33:13,590 and place the extra request there. 699 00:33:13,590 --> 00:33:16,320 Now, everything will continue as we expect. 700 00:33:16,320 --> 00:33:17,970 This will be sent to the Java process. 701 00:33:17,970 --> 00:33:19,830 The Java process will generate the response, 702 00:33:19,830 --> 00:33:21,003 send it to the ICM. 703 00:33:21,864 --> 00:33:23,670 The ICM will forward the response. 704 00:33:23,670 --> 00:33:27,060 But now, remember, we have a long request. 705 00:33:27,060 --> 00:33:30,270 So therefore, we are going to use the MPI free all buffers 706 00:33:30,270 --> 00:33:32,670 to free all these buffers. 707 00:33:32,670 --> 00:33:34,710 This is going to free all the buffers, as you see, 708 00:33:34,710 --> 00:33:37,323 with the worker thread, including the pipeline one. 709 00:33:38,550 --> 00:33:42,480 Now, the three first references will be lost, 710 00:33:42,480 --> 00:33:44,820 but not the one with the pipeline request, 711 00:33:44,820 --> 00:33:48,243 because free all buffers does not remove references. 712 00:33:49,320 --> 00:33:52,050 This means we will be able to use a request 713 00:33:52,050 --> 00:33:53,940 that is inside a free MPI buffer, 714 00:33:53,940 --> 00:33:56,520 and it will cause some problems. 715 00:33:56,520 --> 00:34:00,540 Of course, if the worker thread tries to send this 716 00:34:00,540 --> 00:34:02,670 to a Java process, this will generate an error 717 00:34:02,670 --> 00:34:06,810 because the MPI handler knows that this worker thread 718 00:34:06,810 --> 00:34:09,270 does not have any reserve buffer, 719 00:34:09,270 --> 00:34:10,500 so this will generate an error 720 00:34:10,500 --> 00:34:12,250 and we will not receive a response. 721 00:34:13,620 --> 00:34:18,620 But what would happen if another client 722 00:34:19,050 --> 00:34:20,820 from another HTTP connection 723 00:34:20,820 --> 00:34:23,220 send a request while we have the reference 724 00:34:23,220 --> 00:34:24,753 to this free MPI buffer? 725 00:34:25,830 --> 00:34:28,260 The worker thread will actually reserve 726 00:34:28,260 --> 00:34:29,760 the same MPI buffer, 727 00:34:29,760 --> 00:34:33,363 and we will have a reference to another's connection buffer. 728 00:34:34,470 --> 00:34:36,000 This can be a real problem, 729 00:34:36,000 --> 00:34:38,280 and I'm going to show to show you why. 730 00:34:38,280 --> 00:34:41,010 But first, let me say that this is going to happen 731 00:34:41,010 --> 00:34:44,040 a lot of times, because the MPI handler 732 00:34:44,040 --> 00:34:46,440 will store the free buffers in a stack, 733 00:34:46,440 --> 00:34:48,810 even though SAP states that this is a queue. 734 00:34:48,810 --> 00:34:50,910 When I reverse engineer the component, 735 00:34:50,910 --> 00:34:52,350 I understood that this is a stack; 736 00:34:52,350 --> 00:34:56,130 therefore, the last free buffer is going to be used 737 00:34:56,130 --> 00:34:58,083 in the next generation. 738 00:35:00,420 --> 00:35:01,890 This means that the worker thread too 739 00:35:01,890 --> 00:35:04,713 will write on top of our request. 740 00:35:05,880 --> 00:35:07,590 You might think, "Okay, we can use this 741 00:35:07,590 --> 00:35:10,980 to obtain a response that is intended for another client." 742 00:35:10,980 --> 00:35:11,813 This is not true. 743 00:35:11,813 --> 00:35:14,160 We still have the problem of the MPI handler 744 00:35:14,160 --> 00:35:16,773 knowing that we don't have a reserve buffer. 745 00:35:18,450 --> 00:35:19,380 What we are going to try to do 746 00:35:19,380 --> 00:35:22,440 is to write on top of a victim's request. 747 00:35:22,440 --> 00:35:25,050 And to do so, we are going to send a pipeline request 748 00:35:25,050 --> 00:35:26,640 that is not completed, 749 00:35:26,640 --> 00:35:28,620 and this can be done by sending a request, 750 00:35:28,620 --> 00:35:31,800 which does not contain two line breaks after the headers, 751 00:35:31,800 --> 00:35:34,110 or that contains a body that is shorter 752 00:35:34,110 --> 00:35:36,010 than the message length header states. 753 00:35:36,930 --> 00:35:39,810 When this happens, the worker thread will be set 754 00:35:39,810 --> 00:35:40,800 to read mode. 755 00:35:40,800 --> 00:35:42,540 It will wait for more data, 756 00:35:42,540 --> 00:35:45,330 and once this data arrives to the ICM, 757 00:35:45,330 --> 00:35:48,270 it will be written in the same buffer 758 00:35:48,270 --> 00:35:52,620 at the end of the last position that the worker thread 759 00:35:52,620 --> 00:35:53,463 wrote in a byte. 760 00:35:55,050 --> 00:35:58,923 You can see that if we send to the request in two parts, 761 00:36:00,690 --> 00:36:02,640 all the data will be written in the same buffer, 762 00:36:02,640 --> 00:36:05,313 and that the offset will be updated. 763 00:36:08,303 --> 00:36:09,660 So, the idea in this case will be, 764 00:36:09,660 --> 00:36:12,780 we were going to try to tamper the victim's request 765 00:36:12,780 --> 00:36:15,330 and make him obtain a different response 766 00:36:15,330 --> 00:36:17,373 than the one he expected. 767 00:36:18,540 --> 00:36:20,940 Again, we are going to send a long request 768 00:36:20,940 --> 00:36:22,500 with a pipeline request 769 00:36:22,500 --> 00:36:27,500 that is going to create a new buffer. 770 00:36:27,673 --> 00:36:29,573 You can see the MPI buffer at the top. 771 00:36:30,540 --> 00:36:32,640 The first request is going to be resolved. 772 00:36:34,620 --> 00:36:36,990 It will send the response back to the client. 773 00:36:36,990 --> 00:36:39,930 And now, the MPI free buffers will be called. 774 00:36:39,930 --> 00:36:42,240 All the buffers will be freed. 775 00:36:42,240 --> 00:36:47,240 So then, we have an extra reference to this buffer, 776 00:36:49,770 --> 00:36:51,360 but this is a free buffer. 777 00:36:51,360 --> 00:36:53,610 Therefore, other worker threads could use it. 778 00:36:54,780 --> 00:36:57,930 When the parser tries to read the request we sent, 779 00:36:57,930 --> 00:37:00,183 which is just an extra byte, an X, 780 00:37:01,350 --> 00:37:03,480 it will see that this is an incomplete request, 781 00:37:03,480 --> 00:37:05,640 and therefore it will be set into the read mode 782 00:37:05,640 --> 00:37:06,790 and wait for more data. 783 00:37:07,650 --> 00:37:11,130 If we are lucky enough, another worker thread 784 00:37:11,130 --> 00:37:15,000 will reserve this buffer and will place the request 785 00:37:15,000 --> 00:37:16,263 of a victim. 786 00:37:17,940 --> 00:37:20,820 Now, at this point, we will try to send more data, 787 00:37:20,820 --> 00:37:24,750 so that this data is written in the same place, 788 00:37:24,750 --> 00:37:27,780 or in this hijacking buffer. 789 00:37:27,780 --> 00:37:31,920 And then, we are going to write in the second position, 790 00:37:31,920 --> 00:37:33,450 because the worker thread one 791 00:37:33,450 --> 00:37:38,450 thought that the only byte that was in this buffer is an X. 792 00:37:38,550 --> 00:37:41,160 Therefore, it will start writing in the second position, 793 00:37:41,160 --> 00:37:44,130 and we will be able to tamper all the requests 794 00:37:44,130 --> 00:37:45,363 from the victim. 795 00:37:45,363 --> 00:37:48,540 Actually not the first byte, but the rest of the request. 796 00:37:48,540 --> 00:37:50,320 So then, when the worker thread two 797 00:37:51,810 --> 00:37:54,630 send the MBA pointer to the Java process, 798 00:37:54,630 --> 00:37:56,850 the Java process will use this request 799 00:37:56,850 --> 00:37:59,100 and will generate the malicious response. 800 00:37:59,100 --> 00:38:01,680 Then, it will place it in the MPI buffer, 801 00:38:01,680 --> 00:38:03,960 forward it to the worker thread two, 802 00:38:03,960 --> 00:38:06,710 and the worker thread two will send this to the victim. 803 00:38:08,970 --> 00:38:10,850 The steps to reproduce this attack, again, 804 00:38:10,850 --> 00:38:12,840 is the attacker needs to hijack a buffer. 805 00:38:12,840 --> 00:38:15,060 This is easy and is deterministic. 806 00:38:15,060 --> 00:38:16,650 The victim will send a request, 807 00:38:16,650 --> 00:38:20,313 and the request will be placed in the same MPI buffer. 808 00:38:22,110 --> 00:38:25,143 This is not deterministic, but it happens a lot. 809 00:38:26,010 --> 00:38:28,620 The attacker then will tamper the victim's data 810 00:38:28,620 --> 00:38:29,730 or the victim's request, 811 00:38:29,730 --> 00:38:31,980 and the victim will receive the malicious response. 812 00:38:31,980 --> 00:38:33,533 As you can see in the example, 813 00:38:33,533 --> 00:38:37,440 sometimes when a victim sends a request to start page, 814 00:38:37,440 --> 00:38:40,320 he will receive instead of the two handler response, 815 00:38:40,320 --> 00:38:42,483 a redirection to evil.com. 816 00:38:43,950 --> 00:38:46,920 And this attack does not require a proxy, 817 00:38:46,920 --> 00:38:48,960 just as I already explained, 818 00:38:48,960 --> 00:38:52,320 because we are tampering another HTTP connection, 819 00:38:52,320 --> 00:38:56,073 so we can launch each attack with or without a proxy. 820 00:38:57,810 --> 00:38:59,280 But maybe you are also wondering 821 00:38:59,280 --> 00:39:03,540 why some of these responses does not contain a status code. 822 00:39:03,540 --> 00:39:07,380 And that is because the buffers are multipurpose. 823 00:39:07,380 --> 00:39:09,210 This means that we can use the same buffer 824 00:39:09,210 --> 00:39:10,860 for request and responses. 825 00:39:10,860 --> 00:39:13,890 So, in those cases, we are not tampering a request, 826 00:39:13,890 --> 00:39:15,940 but instead, we are tampering a response. 827 00:39:18,450 --> 00:39:21,489 The idea, and this is going to be the best idea 828 00:39:21,489 --> 00:39:23,640 to use this vulnerability, 829 00:39:23,640 --> 00:39:25,530 is instead of tampering a request, 830 00:39:25,530 --> 00:39:27,690 we are going to try to tamper a response, 831 00:39:27,690 --> 00:39:29,190 and I'm going to show you why. 832 00:39:30,120 --> 00:39:34,710 Again, we have a free buffer, and we have a reference to it 833 00:39:34,710 --> 00:39:36,800 so we can write more data. 834 00:39:36,800 --> 00:39:41,040 We are going to wait for another client to send a request. 835 00:39:41,040 --> 00:39:43,620 Now, in some cases, the worker thread 836 00:39:43,620 --> 00:39:45,120 will not use the same buffer 837 00:39:45,120 --> 00:39:48,990 that we already have a reference to, but instead a new one, 838 00:39:48,990 --> 00:39:52,173 and that is because of just timing. 839 00:39:53,100 --> 00:39:58,100 If the client of the worker thread two send a request 840 00:39:58,946 --> 00:40:02,370 when we do not have a reference to a free buffer, 841 00:40:02,370 --> 00:40:04,650 but instead to a reserve buffer, 842 00:40:04,650 --> 00:40:07,413 then the worker thread two will use a new one. 843 00:40:08,280 --> 00:40:10,140 So in this case, the worker thread two 844 00:40:10,140 --> 00:40:13,620 will just place the request in this new MPI buffer. 845 00:40:13,620 --> 00:40:15,870 This will be sent to the Java process. 846 00:40:15,870 --> 00:40:18,520 The Java process will generate the response for this, 847 00:40:20,430 --> 00:40:23,370 and this response in this case will be stored 848 00:40:23,370 --> 00:40:26,760 in the same MPI buffer that we have our reference to. 849 00:40:26,760 --> 00:40:30,150 So now, we are able to write in the same buffer 850 00:40:30,150 --> 00:40:32,853 that the worker process placed the response. 851 00:40:38,100 --> 00:40:41,133 If at that point we are able to send more data, 852 00:40:41,970 --> 00:40:44,220 this data will tamper the response, 853 00:40:44,220 --> 00:40:45,870 and therefore we will be able to write 854 00:40:45,870 --> 00:40:49,140 whatever we want in the response. 855 00:40:49,140 --> 00:40:52,680 So, we are going to be able to generate any response we want 856 00:40:52,680 --> 00:40:56,760 and to exploit this by injecting any script, any headers, 857 00:40:56,760 --> 00:40:57,633 anything we want. 858 00:40:58,770 --> 00:41:00,750 Now, when this response is received 859 00:41:00,750 --> 00:41:01,800 by the worker thread two, 860 00:41:01,800 --> 00:41:04,860 the response parser will be called, 861 00:41:04,860 --> 00:41:08,100 and it will forward the response to the client. 862 00:41:08,100 --> 00:41:11,670 But then, the response cache handler will be called also. 863 00:41:11,670 --> 00:41:16,530 And if you see the MPI buffer that is in the slide, 864 00:41:16,530 --> 00:41:18,810 you might notice that there is an extra header 865 00:41:18,810 --> 00:41:19,710 that you might not know, 866 00:41:19,710 --> 00:41:22,173 which is called SAP cache control header. 867 00:41:23,870 --> 00:41:26,100 This is an internal header that is going to be used, 868 00:41:26,100 --> 00:41:27,900 and it's going to be by the cache handler, 869 00:41:27,900 --> 00:41:30,300 to know if the response should be stored or not. 870 00:41:31,631 --> 00:41:33,930 What we are going to do is to place this, 871 00:41:33,930 --> 00:41:37,110 so that the response for this is stored 872 00:41:37,110 --> 00:41:38,343 in the internal cache. 873 00:41:41,250 --> 00:41:44,703 And now, we can modify any resource we want 874 00:41:44,703 --> 00:41:46,890 with an arbitrary response. 875 00:41:46,890 --> 00:41:49,590 If we play the role of the worker thread two, 876 00:41:49,590 --> 00:41:51,840 instead of waiting for a victim to send this request, 877 00:41:51,840 --> 00:41:55,020 we can choose which of the URLs are going to be modified. 878 00:41:55,020 --> 00:41:58,113 And so, we can modify any URL with anything we want. 879 00:42:06,704 --> 00:42:09,330 In this demo, I'm going to do the exact thing 880 00:42:09,330 --> 00:42:10,713 I just explained. 881 00:42:11,700 --> 00:42:13,367 In this case, we are not using proxy. 882 00:42:13,367 --> 00:42:17,190 We are just attacking the ICM. We can do it with a proxy. 883 00:42:17,190 --> 00:42:18,630 We can encapsulate the same attack 884 00:42:18,630 --> 00:42:20,923 using the previous vulnerability I explained. 885 00:42:22,133 --> 00:42:26,730 And so, this exploit is going to try to hijack a buffer, 886 00:42:26,730 --> 00:42:29,583 send a lot of requests that will generate a response, 887 00:42:30,960 --> 00:42:32,610 a lot of requests in this case to start page, 888 00:42:32,610 --> 00:42:34,530 because we are trying to poison the start page 889 00:42:34,530 --> 00:42:37,460 in the internal ICM cache. 890 00:42:37,460 --> 00:42:40,290 And so, this will require a few attempts. 891 00:42:40,290 --> 00:42:42,570 Of course, this is not deterministic, 892 00:42:42,570 --> 00:42:44,583 but it is quite reliable. 893 00:42:45,720 --> 00:42:48,990 As you can see, we are going to try to do it a few times. 894 00:42:48,990 --> 00:42:51,330 The script will adjust the times, 895 00:42:51,330 --> 00:42:55,320 and it will also verify if the response has been modified 896 00:42:55,320 --> 00:42:56,310 in the cache, 897 00:42:56,310 --> 00:42:59,463 just by requesting the start page and seeing the response. 898 00:43:00,720 --> 00:43:05,720 After a few attempts, we got a successful attack. 899 00:43:06,840 --> 00:43:10,200 What's important now: if we have one successful attack, 900 00:43:10,200 --> 00:43:11,600 then this will be persisted. 901 00:43:13,050 --> 00:43:15,600 With one attack, we will see all the clients 902 00:43:15,600 --> 00:43:18,960 that request the start page will receive this response, 903 00:43:18,960 --> 00:43:22,323 which is an arbitrary response with an arbitrary HTML. 904 00:43:24,856 --> 00:43:27,856 (audience applauds) 905 00:43:34,740 --> 00:43:37,440 Finally, I'm going to try to explain this really fast. 906 00:43:37,440 --> 00:43:39,150 We can also use this attack to cause 907 00:43:40,950 --> 00:43:43,770 a buffer overflow in the hip, 908 00:43:43,770 --> 00:43:46,353 and eventually obtain remote execution. 909 00:43:47,220 --> 00:43:48,540 This can be done. 910 00:43:48,540 --> 00:43:51,120 Remember I said we are going to tamper our response. 911 00:43:51,120 --> 00:43:52,443 But in this example, 912 00:43:53,550 --> 00:43:55,410 we have not tampered the response already. 913 00:43:55,410 --> 00:43:58,050 The worker thread two generates a request, 914 00:43:58,050 --> 00:44:00,840 which generate a response that contains 915 00:44:00,840 --> 00:44:03,240 a SAP cache control header already. 916 00:44:03,240 --> 00:44:05,310 This is a valid response. 917 00:44:05,310 --> 00:44:08,400 When the worker thread two receive this response, 918 00:44:08,400 --> 00:44:10,127 it will use the response parser. 919 00:44:11,250 --> 00:44:15,190 It will send the response back to the victim 920 00:44:16,170 --> 00:44:17,250 or to the client. 921 00:44:17,250 --> 00:44:19,350 And then, the cache handler will be called. 922 00:44:19,350 --> 00:44:21,049 The cache handler will store this. 923 00:44:21,049 --> 00:44:24,240 Actually, the response is going to be stored 924 00:44:24,240 --> 00:44:26,283 in a file in the file system. 925 00:44:27,390 --> 00:44:31,680 First, the cache handler will set some headers in the file, 926 00:44:31,680 --> 00:44:34,653 which contains the length of the entire response. 927 00:44:36,540 --> 00:44:41,460 If we are able to tamper the response at this exact point, 928 00:44:41,460 --> 00:44:44,430 then we are going to be able to force the cache handler 929 00:44:44,430 --> 00:44:49,050 into placing the malicious response in this file, 930 00:44:49,050 --> 00:44:52,140 which does not contain the same length 931 00:44:52,140 --> 00:44:54,003 that the header states. 932 00:44:55,290 --> 00:44:59,823 So, when another client request this poisoned resource, 933 00:45:00,720 --> 00:45:03,600 the request cache handler will look in the cache, 934 00:45:03,600 --> 00:45:05,618 it will find a response, 935 00:45:05,618 --> 00:45:09,160 and it will use the headers of the cache file 936 00:45:10,260 --> 00:45:13,500 to create a buffer in the hip. 937 00:45:13,500 --> 00:45:18,500 And then, it will write all the data in that buffer. 938 00:45:18,690 --> 00:45:22,620 But as the data is longer than this 85 bytes, 939 00:45:22,620 --> 00:45:25,320 then we are going to be able to write over 940 00:45:25,320 --> 00:45:28,623 and write other data structures in the hip. 941 00:45:30,120 --> 00:45:32,100 I know, and we have demonstrated that it's possible 942 00:45:32,100 --> 00:45:33,783 to obtain remote execution. 943 00:45:35,700 --> 00:45:39,930 The only problem is we need to defeat the randomization. 944 00:45:41,070 --> 00:45:46,070 So, SAP released two pads for all their systems. 945 00:45:47,310 --> 00:45:51,240 They must be applied in any system using SAP, 946 00:45:51,240 --> 00:45:53,100 because it's part of the SAP kernel, 947 00:45:53,100 --> 00:45:57,120 and the two CVs, which the first one is a CVSS 10 948 00:45:57,120 --> 00:45:58,410 for the first vulnerability. 949 00:45:58,410 --> 00:46:00,870 The second one they use after free is 8.1. 950 00:46:00,870 --> 00:46:05,640 In this case, they said that the complexity of the attack 951 00:46:05,640 --> 00:46:07,470 is high and the scope is unchanged. 952 00:46:07,470 --> 00:46:10,860 We disagree, but that's how they saw it. 953 00:46:10,860 --> 00:46:13,830 And also, it's important to see that it can be used 954 00:46:13,830 --> 00:46:15,660 in any SAP in the world. 955 00:46:15,660 --> 00:46:17,850 Also, there are some workarounds that can be implemented 956 00:46:17,850 --> 00:46:19,650 in Netweaver and with WebDispatcher. 957 00:46:19,650 --> 00:46:22,590 And we provided a tool that can be used 958 00:46:22,590 --> 00:46:23,640 to detect the attack. 959 00:46:24,810 --> 00:46:26,110 Finally, some conclusions: 960 00:46:28,259 --> 00:46:31,950 we saw that HTTP servers are really interesting targets, 961 00:46:31,950 --> 00:46:35,530 and this is because we can use reverse engineering. 962 00:46:35,530 --> 00:46:40,164 But using the RFC, in our mind, 963 00:46:40,164 --> 00:46:44,190 we know that this HTTP server must follow the RFC. 964 00:46:44,190 --> 00:46:48,273 So, it's easier to understand what the HTTP server is doing. 965 00:46:49,260 --> 00:46:51,630 Also, they have similar functionalities, 966 00:46:51,630 --> 00:46:54,600 and we can use the request and responses 967 00:46:54,600 --> 00:46:57,060 and locate them in memory to know 968 00:46:57,060 --> 00:46:58,860 what we can modify and what not. 969 00:46:58,860 --> 00:47:02,280 We also saw many talks that are using different attacks, 970 00:47:02,280 --> 00:47:06,577 like the one presented yesterday by Orange, which is in IAS. 971 00:47:08,970 --> 00:47:11,670 But again, we see that these attacks in HTTP servers 972 00:47:11,670 --> 00:47:12,503 are increasing, 973 00:47:12,503 --> 00:47:15,000 so it's really important to understand them 974 00:47:15,000 --> 00:47:17,853 and to keep looking for new vulnerabilities. 975 00:47:18,840 --> 00:47:21,390 Also, it was interesting to demonstrate 976 00:47:21,390 --> 00:47:23,760 that we can escalate low level vulnerabilities 977 00:47:23,760 --> 00:47:25,983 with HTTP exploitation. 978 00:47:27,180 --> 00:47:28,560 This includes these new techniques 979 00:47:28,560 --> 00:47:30,630 called client side desynchronization. 980 00:47:30,630 --> 00:47:34,140 And also, we can use DNS rebinding to bypass some VPNs 981 00:47:34,140 --> 00:47:36,420 and to leverage other attacks that in the past 982 00:47:36,420 --> 00:47:38,403 were not possible to be exploited. 983 00:47:39,930 --> 00:47:42,600 And finally, I want to say that ICMAD, 984 00:47:42,600 --> 00:47:45,390 as the code name of the vulnerabilities, 985 00:47:45,390 --> 00:47:48,270 was added by the cybersecurity infrastructure, 986 00:47:48,270 --> 00:47:49,803 security agency of the US. 987 00:47:51,000 --> 00:47:52,620 All these vulnerabilities had a critical impact, 988 00:47:52,620 --> 00:47:57,210 because the components that were vulnerable 989 00:47:57,210 --> 00:47:58,800 were exposed to the internet, 990 00:47:58,800 --> 00:48:02,430 and were present in all SAP installations. 991 00:48:02,430 --> 00:48:05,543 SAP stated that these were one of the worst 992 00:48:05,543 --> 00:48:08,430 vulnerabilities that they ever found 993 00:48:08,430 --> 00:48:09,663 or that they ever fixed. 994 00:48:12,240 --> 00:48:14,550 This is also because we are finding a vulnerability 995 00:48:14,550 --> 00:48:17,200 in a really exposed service, which is HTTP and HTTPS. 996 00:48:18,450 --> 00:48:19,947 Questions? 997 00:48:19,947 --> 00:48:23,398 (audience applauds) 998 00:48:23,398 --> 00:48:25,788 (drumming music)