So yeah, this is internal server error, exploiting inter-process communication with new de-synchronization primitives. Please welcome Martin Doinehart. Hello everyone, welcome to internal server error, exploiting inter-process communication with new de-synchronization primitives. My name is Martin Doinehart. I'm a security researcher at Onapsis, which is a company focused on enterprise software security. And among the different enterprise software developers, SAP is probably the most popular one with over 400,000 customers, and this includes 90% of Fortune 500 companies. Most of the services that SAP provides are for managing business processes, such as financials, operations, human capital, customer relationships, supply chain, and many other services. There are many other software that manage the critical assets of a company. And to do so, they provide a lot of modules that are based on web services that are accessible through HTTP, and this is true for both Java and ABAP, and also for S4 HANA and the cloud. And to expose these kind of services, they use the same proprietary HTTP server in all their products, which is called the Internet Communication Manager. And so what is this Internet Communication Manager, or ICM? Well, it's a component that is used to handle all the communication with the outside world, and with the SAP system, and this includes all communication with clients, such as different employees or customers, also with other systems, and with other SAP systems. Among the different protocols that can be used, there is P4, which is a proprietary protocol similar to RMA, also IOP, SMTP, but the main purpose of this, the Internet Communication Manager, is to handle the HTTP and HTTPS communications. And this is really important. This is the component that will be exposed, and it will be present by default in all SAP installations in the world. Therefore, we will find it in all SAP products, and it is quite important, and that's why I decided to make a research on this, because anytime we find an SAP, the service, the HTTP service, will be exposed, and we will find many SAP systems exposed to it, this to the Internet. But before I can find any vulnerability, I needed to understand how this Internet Communication Manager worked. And, of course, we don't have the source code. That is not because SAP does not like open source. They know that would kill the fans, so I had to reverse-engine the entire component. And you can see that SAP provided us with a small diagram, which says not too much about the architecture. We can see some components, but it's not really descriptive, so I had to make a small instruction of this diagram so that you understand how this works. Also, I will have a lot of internals. If you want to learn more or want to know more about this, you can ask me later or you can write me through my Twitter or see the white paper. So, first, we will say that the ICM is the HTTP server that will receive data from the Internet. So, the ICM is the HTTP server that will receive data from the Internet. It will receive the connections from clients. And when a client starts a TCP connection, a worker thread, which is an internal thread from the process, will be assigned to this TCP connection. And the idea is that this worker thread handles all the requests and responses for this specific client. So, when a client sends a request, it will be received by the worker thread, which will use the HTTP parser to understand the request. Then it will use some internal HTTP handlers, which I will talk later about them, and to try to resolve this request internally. And if it's not possible to do it, which will be the most cases that will be the case, it will send the request to another process. And this is because the business logic of the NSAP is not inside the ICM. It's actually programmed in Java or ABAP. Therefore, it will be sent to another process. And to do so, it will use something that is called memory pipes, which I will also explain in a minute, to efficiently send this data to the other process which is called the worker process, which will generate a response, send it back through these memory pipes to the ICM. And the ICM will forward it to the client. So, again, what are these memory pipes? Well, MPI, it's how SAP calls it, it's a framework that supports the exchange of data between the SAP and the worker process, which can be Java or other systems. It's used to generate and send the data to the about. So the idea is this framework will be used to send the data but not to copy all the requests and responses because that wouldn't be any efficient. So the MPI uses the shared memory to do so. So it will use MPI buffers which are just fixed size buffers of 65 kilobytes and they will be stored in the shared memory and instead of sending the entire request and response and copying from one process to another, it will just send a pointer which is called an MPI pointer to these MPI buffers. It will use the MPI handler which is a class that will manage all these communications. So let's see an example. First when a request arrives to the ICM, actually to the worker thread, the input output handler will receive this. This is just a TCP socket that will have an internal buffer to store everything that comes from the internet. And when the ICM worker thread is ready to receive and handle the request, it will receive the request. And when the request is ready to receive and handle the request, it will first reserve an MPI buffer, then it will store the request there, this is all going to be done using the MPI handler. And now when it will use the NXTB parser, then it will try to resolve the request using internal handlers and if it fails, it will send the request to the worker process. This is going to be done by sending just the MPI pointer, and now the Java or a process will have the reference to the worker request, if it fails just send the reference to this request. Then it will generate a response and it will also reserve a new MPI buffer which will store the response. Then it will send the MPI pointer back to the worker thread and the worker thread will forward this response back to the client. Then all the MPI, both MPI buffers will be freed one by one and then the references will be lost. So I also said that there are some internal handlers that are going to be used to try to resolve the request and they are inside the ACM. Functions that will try to generate a response out of a request. And they will be included when a request arrives. There will be a list of handlers that will be used. The component that will decide which handlers should be included is the HTTP parser so it will see at the URL and depending on the URL it will know which handlers should be included in the list and then those handlers will try to resolve the request. So when an internal handler is able to resolve a request, actually when any handler is able to resolve a request, the other handlers will be deleted from this list and the response will be sent back to the client. So first we have the cache handler. I'm going to show the handlers in order as they are being called when they are included in the list. So first we have the cache handler. This is present by default and it's always included in the list. No matter what the URL is, it's always included in the handler's list. And the cache handler will do what we all expect. It will try to resolve the request by looking at the cache and if it has a store object for that URL, then it will return the response back to the client. Then we have the admin handler and the authentication handler. They are both going to be called, they are both present by default, sorry, but they are only going to be called the depending on the URL and if the pattern is correct. So for the admin handler, there is a prefix being slash SAP slash admin. And for the authentication handler, we will have some hard coded values in the ICM that will be used to know if the handler should be included or not. Then we have the modification handler, the file access handler, and the redirect handler. They are not present by default. They need to be set in a configuration file before the SAP starts, so we are not going to see more of them. And finally, we will have the Java and the ABAP handler. That depends on how the system is configured. And they also are going to be always included by default, but they are not going to try to resolve the request internally. They will just send the request to the worker process. As you can see, there is a specific function for each of these handlers. We also have other handlers like the log handler, but that's not really interesting for us because it cannot generate a response out of our request. So let's see an example of how a request is resolved using internal handlers. Again, when a request arrives, it will be stored in the input of the handler. And in this case, we see that the request is a get to slash SAP slash admin. Again, the worker thread will try to, will reserve a new MPI buffer. It will place the request there. And now the HTTP parser will start calling different handlers. It will actually include these handlers in the list. First, the cache handler is always, because it's always a request, included. Then in this case, the admin handler, because of the slash SAP slash admin prefix. And then the Java or ABAP handler, depending on the worker process that is going to be used. Now, the cache handler is going to be called. In this case, let's say it fails. It cannot resolve the request. So in this case, the admin handler is also going to be called after this. And in this case, we see that we can, we obtain a response out of the cache handler. So this is not going to be placed in the shared memory because it's not necessary. We will not send it to the worker process. The response is going to be placed in the heap. And then this will be forwarded. All the other handlers will be deleted. And this will be forwarded to the client. Again, the MPI buffer will be freed and the reference will be lost. So as I said, MPI buffers are fixed size. This means that they can only hold 65 kilobytes of data. So what if we send a longer request, okay? And I'm going to call this a long request, even though it's not that long. It's just 65 kilobytes. But what if we send something that cannot fit inside the MPI buffer? So let's see an example. We send a request with a content length of 66,000 bytes. And the ICM will first reserve an MPI buffer, as always. And it will only place this first 65 kilobytes of the request that has received the request. And the ICM will first reserve an MPI buffer, as always. And it will only place this first 65 kilobytes of the request that has received the request that has arrived from the client. And this is because the internal handlers are supposed to resolve requests that does not contain body, that are just simple requests with some special hitters. And so the ICM is not expecting to use the rest of the body or the rest of the request until the worker process is required. So again, the HTTP parser will read the request, will call some handlers. In this case, the cache handler is not able to resolve the request. And so when the Java debug process is culled, so when we send this request to the worker process, then, in this case, we will need the rest of the request, because the, of course, the job array of process will use the body of our request, and the business logic needs this kind of data. So the ICM will reserve as many MPI buffers as required. It will store the rest of the requs there, and it will send all the MPI pointers to the worker process. Now, the worker process will have a reference. and will use them to generate a response. And again, it will be, uh, the worker process will reserve an MPI buffer, store the response, send it to the worker thread, and the worker thread will forward this response back to the client. And now, as I said previously, um, these MPI buffers are going to be free one by one when we have a simple request. However, when we have a multi-buffer request, the MPI free buffer function is going to be called, which will delete or will free all the MPI buffers that are associated with this worker thread. And then the references will be lost. So, let's see the first vulnerability. As I said, um, the worker thread is not expecting to use, uh, or to resolve a request, um, reusing the body, because in turn, it's not going to respond to the request. So, it's not going to respond to the request. So, the internal handlers shouldn't, shouldn't use that kind of information. But what if we send a long request that is not handled by the worker process, but instead is handled by an internal handler? So, again, as, as I already explained, we will see, uh, in this case, we have a get request to slash SAP slash admin, and it's a long request containing 66,000 bytes. Therefore, only the first 65 kilobytes will be stored in an MPI buffer, and then the parser will include these different handlers. The cache handler again will fail, but in this case, the admin handler was able to generate a response. So, this response will again be sent to the client, then all the handlers will be removed, the MPI point, the MPI buffer will be freed, and the request response cycle will be completed. But as you can see, we have more data from the previous request in the input output handler. So, now, when the worker thread tries to read a new request, it will consider this as, of course, a new isolated request. So, if you know something about this HTTP synchronization, which I hope you do if you came to this talk, uh, you know that this is a vulnerability, and a serious one. And this is because whenever we send these kind of requests that you can see in the slides, which contains, um, a get request to SAP slash SAP slash admin, it will be resolved by an internal handler, as we saw, and... actually, the proxy will forward this as an entire, as an entire request without seeing any, any problem. And this is because we don't have nothing that tells the proxy that this is a special request. Actually, it is, uh, HTTP RFC compliance, compliance, so there is no problem. It's just a get request with a big content length, but the entire body is including that, uh, content length. But when this request arrives to the ICM, it will be split, and the last part, which is the get to smuggle, will be used as an isolated request. Therefore, it will be a synchronization between the proxy, any proxy in the world, because, again, any proxy will see this as an isolated request, and the ICM. And this is a serious vulnerability. It's actually, uh, CPSS10, because it was, uh, it allows us to compromise any SAP installation in the world in the most exposed service, and I'm going to show you some examples of how to exploit this to actually take control of the victims and the... HTTP and the actual, uh, applications. So, first, the, my first example is going to be using HTTP request smuggling, and I'm going to use the NWA endpoint, which is present, again, in all SAPs, and it's used to redirect any user to the login URL. And it provides two really interesting features. First, an open redirect, which will allow us to set anything we want in the relocation host by using the host header. So, this is an open redirect, which will allow us to set anything we want in the relocation URL. As you can see, I can place the attacker, uh, the attacker host in the, in the host header, and this will be reflected in the location header of the response. This is actually a feature. This is not a vulnerability by itself, because it cannot be exploited by itself. And also, we have a parameter reflection, which will allow us to reflect anything we place in the body of the request, um, in the query string of the relocation URL. Again, this is a feature, but you can see that the, uh, line breaks are replaced with spaces. So, how can we combine this with the, the synchronization vulnerability to take control of victim's request, and also to take control of victim's session cookies? Well, first, the attacker will send a payload, which will smuggle, uh, an entire, uh, request, and as you can see, the first part, it will be forwarded entirely by the proxy, as when I saw the request, it will be splitted in the ICM, and, uh, the first part will be resolved by the internal handler, and the response will be sent back to the attacker. But the rest of the request, which is the smuggled one, uh, will stay in the ICM, and this is because the content length states that there should be a hundred bytes of body, but we didn't send anything in the body. So, it will wait for more data. Also, you can see this is a post request to NWA, and the host header is, uh, evil.com, so that's, uh, host controlled by the attacker. Now, when a victim sends a request to the, uh, to the proxy, the proxy will just forward this, and in the ICM, this will be concatenated to the smuggled message that we injected, and so the first hundred bytes of the victim's request will be used as part of the body of this request. And if you remember, the, the NW endpoint will allow us to generate a response in this case that will redirect the, the victim to evil.com, and it will send a request to the attacker. So, uh, the attacker will send, also, in the, in the query string of the request, the first hundred bytes of its original request, which in this case also contains the cookies. So, when this is received by the victim's browser, the, the browser will send another request, but in this case to evil.com, which is controlled by the attacker, and so the attacker will receive this request, which will contain also the cookies from the victim. We will, we will be able to hijack as many r- as many requests as as many cookies, and sessions as we want, but for each of these, uh, requests that we hijack, we will need to send a new request, okay? So, something that is really special about this vulnerability, is that we are not using, uh, any, any kind of requests that is invalid. So, any proxy will see this and it will say, okay, this is completely RFC compliance, we are not sending any heater, uh, anything strange, and, so, this means we will be able to replicate the attack and to send it, usually a very � email and, using a form, an HTML form and also JavaScript. So the idea is, as you can see in the slide, I created a form that will send a request to an SAP system that will be resolved by an internal handler, in this case the admin handler, and it will also contain a padding to make this request a long request and finally at the end it will place the smuggle request. So when a victim receives this form, the JavaScript will submit this form again and so the attack will be sent in this case not from the attacker but from the victim. So now the victim became the attacker and this will continue as long as we, actually it will continue forever because the attacker, the victims will, when making a request to the SAP will receive again the payload, will be redirected to the evil.com and then again send the attack. Okay? So the So again, we can place this in theable.com. That's the idea. Also, we can use the same kind of attacks when we find a vulnerability that does not require any invalid or forbidden header, like the one found last year in HIProxy. So we can use, in those cases, DNS rebinding to be able to send those extra headers, but we can use this technique in many other ways. And if you saw yesterday's talk from James Kettle, you might think this is a really similar technique because we're actually using the same technique or the same idea. And even though the vulnerabilities, the nature of the vulnerabilities are different, we found that it is possible to cause this client-side desynchronization, so we are not only going to be able to persist the attack and create smuggling botnets, but also exploit the browser-server connection. So we will be able to desynchronize even systems that are not using a proxy. This is a really new idea, and yesterday James provided a new methodology. It was a really great talk. I recommend that. And so as I said, we can exploit this even without a proxy, and we could use social engineering if we are not able to reach the server to send this attack with phishing, so we can send this form, and even without sending the first request, we will be able to attack, and desynchronize. So we can desynchronize the entire system and obtain the session cookies. So let's see a small demo. Okay, so in this demo, the first step is going to be the client, and as you can see, when the client sends a request to start page, he will just receive the 200 response. Nothing strange here. As many times as he wants, he will receive the same response, and he's including the cookies in this request. Now, when the attacker sends the payload, which is going to be resolved by an internal handler, and it's a long request, we will be able to smuggle another message and inject what is at the end, which is the post request that we already saw, the post to NWA. This will be stored in the ICM until more data arrives. So again, when we send this, we just receive a response. We don't care about that response, and when the victim sends a new request, instead of receiving a 200, he will receive a redirection to the evil.com server. And now again, he will be sending, when he follows this redirection, he will be sending his own credentials, his own cookies, and therefore we will be able to obtain these cookies, and of course, the secret session of the victim. And what we are going to see now is that when he follows the redirection, the evil.com server, in this case it's another server, I don't remember the name, is going to return this form that I already explained, so the browser will send another attack, and this will keep the attack and the exploit running. Okay, this is another exploit I'm going to explain. This technique is kind of advanced, so I explained these ideas last year in DEF CON, it's called response muggling, and what we're going to try is to poison a web cache proxy, so anytime we have a web cache proxy in the middle of us, and we have a desynchronization vulnerability, we are going to be able to use this technique. I'm going to try to explain really fast, if you don't really understand this, you can see my last year talk, and I guess that will make this clear. So, the attacker in this case is going to send two get requests. Actually, the proxy will see two get requests, but when they are forwarded to the backend, which in this case would be the ICM, the first one will be split into three different requests. And in this case, they will not be in complete requests, as we already saw, like with a content length, being a big content length without a body, but instead we are going to smuggle three complete requests. Now, as you can see, the proxy saw that there were two get requests, but in this case the ICM saw that the first request is a get, the second one is a hit, the third one I don't care, and the fourth one is a get. So, you all know that the head request is special because when you send this kind of request to a server, what we are going to receive is the same response that we would get for a get request, but instead in this case, we are only going to receive the hitters. What you might not know is that the RFC allow the servers to send also a content length, and this is almost always true. You will see this behavior in almost any server. And the content length, even though one would expect to be zero because the body is empty, is not, it's the same one as the content length would be if we would have issued a get request. Therefore, in this case, we will see that it's quite longer than zero. It's like 3,000 something. So, how are the proxies going to do this? How are they going to know that they should ignore this content length hitter? Well, because they know that they have forwarded a head request, and therefore, when they receive the response for this head request, they know that this content length shouldn't be used to generate the response and to know the length of the body of the response. But, if you see in the slides, you can also see that this proxy didn't saw the hit request. Therefore, he doesn't know that the content length should be ignored. So, the first response will be sent to the attacker, as always, is the response for the first get request. But now, the second response is going to be used for a get request. And, in this case, the content length will be used because the proxy doesn't know this is a head response. And so, it will use part of the next response as the body. So, it will use the hitters of the next response as part of this body and also the rest. And we can build a lot of payloads out of this. We can use this to actually generate malicious responses that contain JavaScript. We can change the content type of different responses. So, if we have a response where we can reflect data, like text plain, and we cannot use it to generate an exploit, well, this can be used to change the content type. Also, if we are able to reflect some data or something in the hitters of the response, we can also use this as part of an HTML body. And also, you will see that this response only also contain a cache control hitter. So, if we choose a head request that the response give us a cache control hitter, then we are going to be able to poison the cache with this malicious response. And the request and the URL that's going to be poisoned is also chosen by the attacker. And we can choose any kind of URL we want. So, we can arbitrarily modify any record in the web cache. And we can store this payload there, so that then, when the client generates a record for the same URL, the proxy will not forward this, but instead it will send what is stored in the cache. Now, we are also going to see a demo. Well, I don't know where the demos are. Can I have some help here? Ah, it should be there. Yeah, it should be there. There it is. Sorry for that. OK. Now, in this demo, we are going to see how we can poison and modify the web cache of any proxy. I created an exploit that is going to be a proxy. It's going to poison any URL we want with a specific payload. In this case, it's going to generate a JavaScript that will generate an alert. So, the idea again, I use this payload to modify any URL we want, and generate this, and inject the malicious response for that specific endpoint. And I can use this attack for something even better, which is to modify the login page of the SAP. So, the idea is, if we can modify anything we want, then why not modify the URL that is used for login, so that when a user loads this, or uses this HTML, it will actually send the credentials back to the attacker instead of the SAP. And then we can redirect the victim to another login with extra queries. So, we're going to do that by using the query string parameters so that it doesn't use the cache version. So, now again, as I said, I'm going to replace the login URL. This is always going to be used by any SAP user to log into the application. So, we start a server that is going to be listening to what this login sends. So, again, this looks like the original login. Nothing strange. The URL is still the same. Nothing that the user can detect. And when he sends the credentials, instead of being sent to the SAP, they will be sent to the attacker. Well, again, it's a repetition just to show that this will work anytime we want. And this will be stored in the cache. So, this will work without sending any other payload. This will keep working. Okay, so then I said, well, if I found a vulnerability like this, then I want to learn more about the ICM and I want to learn how the more complex requests are processed. And then I found that the ICM can be configured both for Java or ABAP. I knew that. But that there was a reason. When we configure the ICM for Java, we are going to see that the HTTP server accepts pipeline requests by default. But when we configure with ABAP, this needs to be configured. So, we are going to see that Java, this is what will work for ABAP if it's configured for a pipeline. So, pipelining means that we are going to be able to receive a request that contains two. Actually, a payload that contains two requests. And the ICM will be able to split them. Now these are completely valid and legit requests that can be split using the content length and there is nothing strange from this request. Now the process will be the same. The ICM worker thread will reserve a new MPI buffer. It will store the request there. It will then the HTTP parser will be called and the HTTP parser will recognize that there is an extra request. So it will reserve a new MPI buffer and it will place the rest of the request there. Now the ICM worker thread will continue processing the first one. It will send the request to the Java process. The Java process will generate the response. It will place it in the shared memory, send the reference to the worker thread and the worker thread will forward the response. Then both MPI buffers will be freed and the request response cycle will be completed so the ICM worker thread will be able to continue processing the next pipeline request. So remember I said that there is a string condition when we send multi-buffer requests, so long requests, and that is that the buffers are going to be freed all by all the buffers are going to be freed using the same function. So what if we send a pipeline request with a long request before? So again in this example we are sending a long request and at the end a new request so when the worker thread receives this it will place the first request. Now the request will be sent to the next one in the MPI buffer. It will call the ACP parser, it will call the handlers, and then when the worker thread is ready to send the request to the worker process, which is the Java process, it will place the rest of the request in a new MPI buffer. But now the ACP parser will also recognize that there is an extra request and it will resolve a new MPI buffer and place the extra request there. Now everything will continue as we expect. This will be sent to the Java process. The Java process will generate the response, send it to the ICM, the ICM will forward the response, but now, remember, we have a long request so therefore we are going to use the MPI free all buffers to free all these buffers. And this is going to free all the buffers associated with the worker thread, including the pipeline one. So now the three first references will be lost but not the one with the pipeline request because free all buffers does not remove references. So this is a request. So this means we will be able to use a request that is inside a free MPI buffer and this will cause some problems. Of course, if this is ‑‑ if the worker thread tries to send this to a Java process, it will generate an error because the work ‑‑ the MPI handler knows that this worker thread does not have any reserve buffer, so this will generate an error and we will not receive a response. But what if ‑‑ what would happen if a client is going to send a request to the client, another client from another TCP connection, sends a request where we have the reference to this free MPI buffer. So the worker thread will actually reserve the same MPI buffer and we will have a reference to another connection buffer. This can be a real problem. I'm going to show you why. But first let me say that this is going to happen a lot of times because the MPI handler will store the free buffers in a stack even though SAP states that this is free and thus, in the is a queue, when I reverse the component, I understood that this is a stack, therefore the last free buffer is going to be used in the next iteration. So this means that the worker thread 2 will write on top of our request and you might think, okay, we can use this to obtain a response that is intended for another client. This is not true. We still have the problem of the MPI handler knowing that we don't have a reserve buffer. So what we are going to try to do is to write on top of a victim's request. And to do so, we are going to send a pipeline request that is not completed. And this can be done by sending a request which does not contain two line breaks after the hitters or that contains a body that is shorter than the message line hitter states. So when this happens, the worker thread will be set to read mode. It will wait for more data. And once this happens, the worker thread will be set to read mode and once this data arrives to the ICM, it will be written in the same buffer at the end of the last, at the last position that the worker thread wrote in a byte. So you can see that if we send to the request in two parts, they will all be, all the data will be written in the same buffer and that the offset will be updated. So the idea in this case will be we are going to try to tamper the victim's request. And we are going to try to tamper the victim's request and make him obtain a different response that he, that the one he expected. Again, we are going to send a long request with a pipeline request that is going to hijack a new, that is going to create a new buffer. You can see the MPI buffer at the top. The first request is going to be resolved. Okay. It will send a response back to the client and now the MPI for your buffers will will be called, all the buffers will be freed, and so then we have an extra buffer, an extra reference to this buffer, but this is a free buffer. Therefore, other worker threads could use it. And when the parser tries to read this, the request we sent, which is just an extra byte, an x, it will see that this is an incomplete request and therefore it will be set into the read mode and wait for more data. And if we are lucky enough, another worker thread will reserve this buffer and it will place the request of a victim. Now at this point we will try to send more data so that this data is written in the same place or in this hijacking buffer. And then we are going to write in the second position because the worker thread 1 thought that the only way to fix this is to send a request. And then we are going to write in the second byte that was in this buffer is an x. Therefore, it will start writing in the second position. And we will be able to tamper all the requests from the beginning. Actually, not the first byte, but the rest of the request. So then, when the worker thread 2 forward the, or send the MPI pointer to the Java process, the Java process will use this request and will generate the malicious response. Then it will place it in the MPI buffer, forward it to the worker thread 2, and the worker thread 2 will send this to the victim. So the steps to reproduce this attack, again, is the attacker needs to hijack a buffer. This is easy and it's deterministic. The victim will send a request and the request will be placed in the same MPI buffer. This is not that easy, I mean, this is not deterministic but it happens a lot. The attacker then will tamper the victim's data or the victim's request and the victim will receive the malicious response. As you can see, there is a lot of data on this. The attacker will see the request, the victim's data, and the victim will receive the malicious response. As you can see in the example, when a victim, sometimes when a victim sends a request to start page, he will receive instead of the 200 response, a redirection to evil.com. And this attack does not require a proxy, just as I already explained, because we are, we are tampering another TCP connection so we can launch this attack with or without a proxy. But that is because the, the buffers are multipurpose. This means that we can use the same buffer for request and responses. So in those cases, we are not tampering a request, but instead we are tampering a response. So the idea, and this is going to be the, the best idea for, for, to use this, this vulnerability, is to, instead of tampering a request, we are going to try to tamper a response. And I'm going to show you why. Again, we have high, we have a buffer, a free buffer, and we have a reference to it, so we can write more data. And we are going to wait for a, for another client to send a request. Now, in some cases, the worker thread will not use the same buffer that we already, that we have a reference to, but instead a new one. And that is because of, just because of timing, if the worker thread has, has sent, if the client of the worker thread to send a request when we already, when we do not have a reference to a free buffer, but instead to a, to a reserved buffer, then the worker thread two will use a new one. So in this case, the worker thread two will just place the request in this new MPI buffer, this will be sent to the Java process, the Java process will generate a response for this, and this response in this case will be stored in the same MPI buffer that we have our reference to. So now, we are able to write, in the same buffer that the worker process, place the response. So if at that point we are able to send more data, this data will tamper the response and therefore we will be able to write whatever we want in the response. So we are going to be able to generate any response we want and to exploit this by injecting any script, any heaters, anything we want. Now when this response is received by the worker thread 2, the response parser will be called and it will forward the response to the client. But then the cache handler, the response cache handler will be called also. And if you see the MPI buffer that is in the slide, you might notice that there is an extra heater that you might not know, which is called SAP cache control heater. This is an internal heater that is going to be used and it's going to be used by the cache handler to know if the response should be stored or not. So what we are going to do is to place this so that the response for this is stored in the internal cache. And now we can modify any resource we want with an arbitrary response. If we play the role of the worker thread 2, instead of waiting for a victim to send this request, we can choose which of the URLs are going to be modified. And so we can modify any URL with anything we want. . In this demo, I'm going to do the exact thing as I just explained. In this case we are not using a proxy. We are just attacking the request in this case to start page because we are trying to poison the start page in the internal ICM cache. And so this will require a few attempts. Of course, this is not deterministic. But it is quite reliable. As you can see, we are going to try to do it a few times. This script will adjust the times and it will also verify if the response has been modified in the cache just by requesting the start page and seeing the response. And after a few attempts, yeah, after a few attempts, we got a successful attack. And what's important about this is if we have one successful attack, then this will be persisted. So with one attack, we will see that all the clients that request the start page will receive this response, which is an arbitrary response with an arbitrary HTML. . Okay. Finally, I'm going to try to explain this really fast. We can also use this attack to cause a buffer overflow in the heap and eventually obtain remote execution. This can be done. So remember I said we are going to tamper our response. But in this example, we are not, we are not, we have not tampered the response already. The, the work that we are going to do is we are going to generate the request, which generate the response that contains a cache control header already. Okay. This is a valid response. When the worker to receive this response, it will use the response It will send the, the client, the request, the response back to the victim, or to the client, and then the cache handler will be called. The cache handler will store this, it actually is going to be stored, the response is going to be stored in a, in a file, in the file system. And And first the cache handler will set some headers in this file, which contains the length of the entire response. And if we are able to tamper the response at this exact point, then we are going to be able to force the cache handler into placing the malicious response in this file, which does not contain the same length that the header states. Okay? So when another client requests this poisoned resource, the request cache handler will look in the cache, it will find a response, and it will use the headers of the cache file to create a buffer in the heap. And then it will write all the data in that heap, in that buffer. But as the data is longer than these 85 bytes, then we are going to be able to use this buffer to be able to write over and write other data structures in the heap. We have demonstrated, I know, and we have demonstrated that it's possible to obtain remote execution, only the only problem is we need to defeat the randomization. Okay, so SAP released two paths for all their systems. They must be applied in any system using SAP because it's part of the SAP kernel. And the two CVEs, which is the first one is a CBSS10 for the first vulnerability. The second one they use after free is 8.1. In this case they said that the complexity of the attack is high and the scope is unchanged. We disagree, but that's how they saw it. And also it's important to see that it can be used in any SAP in the world. Also there are some workarounds that can be implemented in NetWeaver and Web Dispatcher, and we provided a tool that can be used to detect the attack. Okay. So, finally, some conclusions. We saw that HTTP servers are really interesting targets, and this is because we can use, we can use reverse engineering by using the RFC in our mind, okay? We know that this HTTP server must follow the RFC, so it's easier to understand what the HTTP server is doing. Also they have similar functionalities. And we can use them. We can use the request and responses and locate them in memory to know what we can modify and what not. And we also saw many talks that are using different attacks, like the one presented yesterday by Orange, which is used, which is in IIS. But again, we see that these attacks in HTTP servers are increasing, so it's really important to understand them and to keep looking for new vulnerabilities. Also, it was interesting to demonstrate that we can escalate low-level vulnerabilities, with HTTP exploitation, and this includes this new technique called client-side desynchronization, and also we can use DNS rebinding to bypass some VPNs and to leverage other attacks that in the past were not possible to be exploited. And finally, I want to say that ICMAT is the code name of the vulnerabilities, was added by the cybersecurity infrastructure security agency of the U.S., they, all these vulnerabilities had a critical impact. Because the components that were exposed, that were vulnerable, were exposed to the Internet and were present in all SAP installations, SAP stated that these were one of the worst vulnerabilities that they ever found, or that they ever fixed. And so, and this is also because we are finding a vulnerability in a really exposed service which is HTTP and HTTPS. Questions? No.