 Hi, it's good to be back. Thank you all for being here. Result of Microsoft Exchange Server is the most widely deployed mail solution within governments and enterprises. It is an integration of their daily operations and security. This January, we report a series of vulnerabilities on Exchange Server to Microsoft and named it as ProxyLogang. If you are paying attention to the industry news, you must have heard this name. ProxyLogang may be the most severe vulnerability in Exchange history ever. However, as we went into deep dive on ProxyLogang, it came to us that it is not just a single bug, but a whole new attack service to help researchers to uncover more vulnerabilities. To unveil the beauty of this attack service, we will start from explaining the architecture, analyzing the root codes, and ending up with a vulnerabilities we find. By understanding the basics of this new attack service, you won't be surprised why we can pop out zero days easily. Let me introduce myself first, I'm Orange and now the Principal Security Researcher at Deathcore and a zero day researcher and focusing on web and application security. My job is to find out the most severe vulnerabilities that can impact the world ahead of the bad guys and report them to the vendors directly. Apart from that, I'm also a speaker, CTF player and bug bounty hunter. I got several rules from my researches, such as the pounding a rose and the champion of pound to own. If you are interested, welcome to follow my Twitter and blog. Before I get started, here's the disclaimer. All the series mentioned today have been repaid responsibly and have been patched by Microsoft. So why were we targeting exchange server? In terms of enterprise security, mail servers are high value assets since they are the place to keep corporate confidentials. With that being said, if someone controls the mail server, they can dominate the lifeline of the corporation. Exchange server is the most well-known and important mail solution in the world. With this in mind, exchange has also been the top target for nation's debt hackers for a long time. That's our research. There are more than 400,000 exchange servers exposed on the internet. Every server represents a company. You can imagine how severe it could be when there's a critical vulnerability on exchange server. Normally, I will review the existing papers and bugs before starting a research. Another whole exchange history, is there any interesting bug? Of course, also most bugs are best unknown attack vectors such as the deserialization or input validation. There are several bugs that are worth mentioning. The most special one is the arsenal from Equation Group in 2017. It's the only practical and public pre-oath RCE in the exchange history. Unfortunately, the arsenal only works on an ancient exchange server. If the arsenal leak happened earlier, it could lead to another nuclear labor crisis. Among all, I would say the most surprising one is CVE 2020 06AA. The nature of this bug is due to a hard code crypto key. It's 2020 now, such a common weakness could still be found in a crucial software, which inspired me to dig more into the security of exchange. So what have we done? We have revealed the exchange security from the architectural levels and find a new attack service. Through this new attack service, we uncovered any vulnerabilities and changed these bugs into three attacking exploits. The first and the most famous one is ProxyLogang. It's the pre-oath RCE. The second one is ProxyAllocle, an exploit that can recover any user's password in plaintext format. The last one is ProxyShell, an exploit with damage chat at Pong2Own 2021. It's also a pre-oath RCE. I would like to highlight that all vulnerabilities we uncovered here are logic bugs, which means they could be reproduced and exploit easily than any memory corruption bugs. Here's my bug list. The ones in red indicates the bug is relapsed to the attack service directly. And others are the bugs we chat together. For your references, there are other bugs we led to this new attack service. You can see from this table, NSA and nation state hackers are also playing that, which means the attack service we shared today is a critical hit for exchange server. Exchange is a very sophisticated application. Before we cut to the chess, let me introduce the architecture first. Since 2000, Exchange has released a new version every three years. Whenever Exchange released a new version, the architecture changes a lot and becomes different. The chance of architecture and iterations make it difficult to upgrade an exchange server. In order to ensure the compatibility between the new architecture and old ones, several design depths were incurred and led to the new attack service we found. So where did we focus? We focused on the client access service, CAS. CAS is a fundamental component in exchange. The official document indicates CAS is a front-end that accepts client connections for all protocols. And they're responsible for routing and proxy in connections. CAS was where we paid attention to and where the attack service existed. Because the CAS is located at a very early stage of exchange request processing, all bugs here are authentication free. So you can imagine how dangerous it is when this fundamental service is vulnerable. Here is the CAS architecture copied from the document. As you can see, the left side is the client. No matter where the connection comes from, either HTTP, POP3, IMAP, or SMTP, CAS in the middle part proxies all connections and proxy to the backend service on the right side. The backend service will continue to handle further business logics. Because I specialize in web security, so we focused on the web part. The CAS web is built on Microsoft IIS. As you can see, there are two websites inside the IIS. The default website is the front-end we mentioned before. And the exchange backend is where the business logic is. If you look at the configuration carefully, you will notice the front-end is listening on post 80 and 443. And the backend is listening on post 81 and 444. It should be noted that the posts are exposed on all interfaces. You may sense something wrong here. All the posts are open to all interfaces, which means you can access the backend directly. Wouldn't it be dangerous? Please keep this question in mind and we will answer that later. The CAS is composed of civil IIS modules. Applications in front-end include a proxy module which is responsible for passing all incoming requests, applying protocol-specific settings and forwarding them to the backend. As for the backend, applications include a rehydration module which is taking charge of passing front-end requests, populating the client information back and continue the business logic. So here is a question for you. How did the front-end and backend exchange the information? They synchronize the information and internal status by HTTP headers. For client request, it will first be handled by the front-end and the request will be passed through civil IIS modules, such as the filter, validation, login, and the last proxy module. The proxy module then picks up a handler based on the current application path, such as the slash OWA or slash ECP. The handler will do the proxy work and forward the request to the backend. When the backend receives the request, it passes the request to the rehydration module to restore the original client stack and continue the business logics. Our idea is simple. Could we access the backend intentionally? Since the exchange synchronized information by HTTP headers, it seems like most of the access control is done by the front-end. If we can access the backend without restrictions, maybe there are several internal API we can abuse. We all know implementing a proxy isn't easy. And the front-end seems like a well-imprinted HTTP client. If there are some magic tricks to manipulate the context between the front-end and backend, it must be found. In order to abuse the context, we have to know how the proxy module works first. The proxy request handler is the most important part of the front-end. All handlers should inherit this class to implement their methods, such as how to handle the client cookies or headers and how to proxy the client request to the backend. We separate the methods into three sections. The first is request, which will pass and modify the client request. Next is proxy section, which will proxy and send the HTTP request to the backend. And the last section is response. This section will receive the response from the backend and decide which header or cookie should be sent back to the client. Because this handler is important, we will explain the methods one by one. The first method of request section is copy headers to server request. It will decide which HTTP header from the client can be sent to the backend. As we said, the front-end and backend synchronized in formation and internal status by HTTP headers. Maybe you are thinking I could forge the header to confuse something. This is a nice try, but unfortunately, you can see here is the backlist in the method. The front-end blocks several HTTP headers which are used internally. Please keep in mind that the header as common as the token is an important one, and we will learn this later. The second is copy cookies to server request. The functionality is the same as the previous one, but it copies cookies instead. The last method of request is add protocol-specific headers to server request. This method allows a handler to apply customized protocol settings. So example, if the front-end OWA would like to pass information to the backend, here is the place it can insert information to headers. Besides the customized protocol settings, the method also cross the user identity to a new HTTP header. The identity is the client authentication result in IIS, also consisting of your security identifier. This method serialize it to a string and put it into the headers, which will be forward to the backend later. As of now, you know how the front-end and backend synchronize your identity. They do it by the header as common as the token. Once the request passing is done, it will lead to the proxy section. The proxy first uses the get target backend server URL to calculate the URL where the front-end should send to. This method is also a buggy plus and full of vulnerabilities. We will discuss this later. The second step of proxy is create a server request which first initialize an HTTP client, set up the HTTP method and headers, and forward it to the backend. We mentioned that posts in IIS are open to anyone and this is dangerous. So that's why Exchange has a mechanism to avoid the situation. While the front-end is creating a request, it will generate a Kerberos sticky and put it in the authorization header. This header will be sent to the backend along with the request. So how does backend know which connection is from a valid front-end? It do it by verifying this Kerberos sticky. We look into the generate Kerberos OS header and know that the header is generated with the HTTP SPN of the Exchange machine account. If you observe the traffic between the front-end and backend, you will see two headers shown in the request. One is the authorization header, which is the Kerberos sticky used to indicate you are valid front-end. The other is the header X command as this token. It's a theorized token indicates your identity. For example, if you look in with the non-orange, the header is the theorized result of your security identifier. After sending the request to the backend, the front-end receives the response and enter the last section. The response section is similar to request. It checks the response from the backend and decide which headers or cookies are allowed to be sent back to the client. Now you understand how the front-end works. Let's move on to see how the backend processes and populates the request from the front-end. The backend rehydration module first uses the method to check whether the incoming request is authenticated or not. It is the time to leverage the Kerberos sticky the front-end generate. By handing over this sticky, the backend knows you are valid front-end now. The backend then call the method try get common access token to restore the user's identity from the front-end. The method retrieves the header, deseries it back to the original access token and puts it in the HTTP context object for later use. So far you learned how the front-end and backend synchronize the user's identity and how the header examine access token plus an important role in the CSS architecture. Since the method just checks if the users are looking or not, it doesn't check the identity. Here comes a question. Could we authenticate as a normal user in the backend? If you access the backend directly and authenticate with a normal account, we can specify whatever values in the header, ex-comment, access token and impersonate as any users. The idea is good and actually you can test the IIS authentication of the backend. But there's one more checkpoint. The method is token serialization allowed, magnifies the current local user and writes a rehydration exception if the checkpoint is failed. It checks if you have a token serialization right. By default, only the exchange machine account has this right. So that's why the Kerbal sticky generated by front-end can pass the checkpoint, but you will fail even you are using a correct credential. So here is a quick summary for you. When there is a client request, the front-end IIS first tries to authenticate the request. If succeed, the front-end serialize the user identity and ask it into the header, ex-comment, access token. The front-end then generates a Kerbal sticky by its HTTP SPN and puts it into the authorization header. It will forward these headers along with the client request to the backend. The backend also tries to authenticate the request at the beginning. The rehydration module will verify whether the user have the right of token serialization. Since we are using a Kerbal sticky generated by the front-end, we pass. Lastly, the rehydration restores the user identity from the header, ex-comment, access token and continue the backend business logic. So far, we briefly explained the communication between the front-end and backend in show. Let's start the hack. Okay, the first exploit is proxy logon. As introduced before, this may be the most severe vulnerability in the exchange history. Proxy logon is chained with two bugs together RCE. One is an SSRF on the front-end and the other is an arbitrary file write on the control panel of the backend. So where is the proxy logon? The bug is mainly located at the proxy section in the front-end. We mentioned that the front-end handler targets the backend URL and forwards the request to that URL. One of the handlers is in charge of processing the static resources. It will assign the backend target from the cookie. You will figure out how simple this bug is after learning the architecture. The front-end treats the user's supplied cookie as the domain name, and the domain name will be concatenated as the backend URL. We use a bit of passing checks to enclose the URL and force the exchange to fetch example.com. The exchange will then return the whole response back to us. So what is the root cause of this arbitrary backend assignment? As we mentioned that the exchange server changed its architecture while releasing new versions. This cookie is a quick solution for exchange to make the front-end in new architecture to identify where the old backend is. It looks like a design depth to adapt back-world compatibility. With the backend assignment, we have a super SSRF that can control almost all the request and get all the responses. The most impressive is that it will generate a Kerberos ticket for us, which means even when we are attaining a protected and domain-joined HTTP service, we can still hack with the authentication of exchange machine account. Thanks to the super SSRF, we can leverage the internal API slash proxy logon.acp to get a valid session to access the control panel. The API is also the reason why we called it proxy logon. As for the rest of the exploitation, I believe there are already lots of technical analysis out there. We will skip it today for the consideration of time. We will not do the demonstration today, but if you are interested, we will come to check the demo on our website. Next, I will be sharing details about proxy oracle. Compared to proxy logon, proxy oracle is an interesting exploit with a different approach. Proxy oracle will allow the attacker to recover the victim's plain text password simply by leading them to a malicious link. We use the cross-site scripting and padding oracle to complete the exploit. First, we would like to explain how the OWA or ECP or Sandcap uses. If the native IRS authentication is used, an ugly prompt will pop out asking you to enter the password instead of this fancy interface, which means Exchange is using a certain mechanism to ask you the transformation between the credentials and cookies. So let's take a look at how this fancy interface is working with the original architecture. Let's get back to the CSS architecture. All the OWA and ECP logon mechanism are done by the phone-dised authentication module. The FBA is an authentication module prior to the Exchange front end and responsible for converting the username and password into cookies or translating cookies to the original credential pairs. The implementation stored your username and password in cookies directly. Of course, the cookie is encrypted to avoid bad guys catching your password in plain text on the fly. If you read the logon traffic carefully, you will see several cookies which stand for your identity. For the later mail operation, you have to attach cookies to identify who you are. Among all cookies, there are five important ones with the prefix CA data. You can see from the screen the CA data contains your encrypted username and password. Here is the pseudocode for the encryption logic. Exchange generates two random strings as the IV and key for every session. The IV and key will be sent and stored on the client side. However, to avoid someone stealing the cookies and decrypting it with the IV and key, Exchange uses RSA to encrypt with its private key again before sending. The Exchange then uses the AES to encrypt your encoded credential with the IV and key and put the result into the cookies. And yes, you can find pading protocol here. Exchange text the CBC as its pading mode. If you are familiar with cryptography, you must know that CBC is vulnerable to the pading protocol attack. The Exchange implementation catches the pading error and returns immediately. When the login process fails, Exchange redirects the HTTP back to the login patch with an error code. Due to the return, we have an protocol here. If the encryption fails, the error code is zero, which stands for none. And if we corrupt the cyber text successfully, the Exchange will try to login with the corrupted credential pair. At this moment, the result must be a failure and the error code is two, which stands for the invalid credentials. By differing from the error number, we have an protocol to recover the plain text. Now we know we can decrypt any cookies with the pading protocol. But the problem is how to get the cookies from the victim. In order to get a cookie on clients, we uncover a cross-size scripting to chain together. But because of with another problem, in Exchange, all sensitive cookies are protected by HTTP only. So we can't access the cookies by JavaScript. So what can we do? Since we can ask you the arbitrary JavaScript on client side, why don't we just insert the SSI cookie, which is used in Proxies Logon? Once we add a cookie to the browser, we can sniff and tag over all the users' web requests. All we need to do is to sit on our server and wait for the cookies to come back. I will elaborate the process further. We first send a malicious link to the victim. And once the victim triggers our cross-size scripting, we insert the SSI cookie to pretend we are the backend of Exchange. Then the Exchange server becomes the proxy between the victim and us. We will take over all the traffic to bypass the HTTP only to gather encrypted cookies. Okay, the demo part. First, we have the victim. And we pass his mail address to our Explorer. The Explorer first send a malicious link to the target. And once the victim triggers our cross-size scripting, we insert a SSI cookie and wait for the connection back to obtain the encrypted cookies. Okay, we got a connection. We can now decrypt the blocks by padding Oracle. It should be noted that all the decryption could be done without the cross-size scripting. Even the user close the browser, we can still recover the password. With a little bit waiting, we recover the password in plain text successfully. The last exploit I will share today is ProxyShare. This is the exploit we demonstrate at Pound2Own 2021. The result of ProxyShare is the same as ProxyLogun. An authentic attacker can execute arbitrary commands on the exchange server. But the exploit chain is different. ProxyShare is chained with an ACL bypass in the front end, an iteration of Privilege in the Exchange PowerShell backend, and an arbitrary file write to get RCE. So, here is the ProxyShare. The first pre-host bug is also located at the backend URL calculation. ProxyShare begins with a patch confusion. Exchange has a feature called the explicit logun feature. This feature is used to display another user's mailbox or calendar in a new browser window. Of course, the displayed mailbox must have to be configured with permission to publish first. In order to open with a single get request, the URL format must be simple, and the mailbox address must be included in the URL such as the highlight part in the slide. The Exchange normalizes this spatial URL and rerows it to the existing handlers. Of course, the patch is not the only way to specify the mailbox address. We find that a spatial cast in the auto-discover handle Exchange will consider address from the query stream if the pass end with slash auto-discover dot season. After getting the address, the handler tries to normalize the URL. You see that Exchange won't conduct too much checking on the pattern of removing mailbox address, which led us to use the substring to erase any part of the URL. As you can see from the slide, this is the URL we will be visiting. And this is the mailbox address we use the query stream to specify. And here is the part will be removed from Exchange according to our pattern. With the erase, this is the actual URL the request will be sent to the backend. As for now, we can access any Exchange backend again. Also, this bug is not as powerful as the SSRF in Proxy Loggon. It's sufficient to access arbitrary backends. We try to access the end API in the FAST to identify our privilogy. From the screenshot, you could see that we de-assess the backend with the Exchange since then privilogy again. Here comes the post-exploitation part. The approach of original Proxy Loggon fails due to some Exchange in-depth protections. So we have to discover a new approach. Now let's turn the focus to Exchange PowerShell Remoting, a feature for Exchange automations. Through the defined PowerShell commands, users can read mail, send mail, and even configure settings by comment lines. The Exchange PowerShell implementation is built up in the PowerShell API. By calling the API, Exchange could realize a PowerShell server and use this the run space to limit and isolate the command execution. All the operations are based on the WinRN protocol. It should be noted that also we can access the PowerShell backend directly. We can still interact with it because we are the system. We will fail the business logic since there is no mailbox for the system user. We also can't forge our identity by the Hader Excommon access token due to the blacklist in the front end. So what should I do? We dive into the PowerShell server implementation and find a piece of code that extracts the access token from the URL. The code is sitting after the IIS backend authentication and before the rehydration. It checks if there is no Excommon access token Hader. The code will call out another method to get the access token from the URL. The common access token from URL is a short method and retrieves the value of XRPS CIT from query string. And then deserialize it back to the access token. But for now we have an elevation of privilogy because we can access the PowerShell backend and specify the access token directly. The intention of this operation is to be a quick proxy for internal exchange PowerShell communication. By abusing this feature, we can impersonate as any user. Here we use the EOP to downgrade ourselves from the system with all mailbox to exchange admin. I can now execute arbitrary exchange PowerShell commands as admin. And then the last piece of the puzzle is to find the post-os RCE to chain everything together. Because we are the admin and there are hundreds of exchange PowerShell commands out there, it's easy to find a post-os book. We abuse the command new mailbox explore request to explore the user's mailbox into the web loop to be our web shell. Now we can create files on arbitrary test. The next problem is how to embed our malicious payload into this file. It's also easy. We can deliver our payload by mail. However, the exported file is encoded. By reading the Microsoft document, we learn it's in PST format and the encoding is just a simple table making. We can just encode the payload before sending out. While the server tries to save and encode our payload, it turns into the original malicious code. Let's change everything together. We first deliver our encoded web shell to the target mailbox and then launch the Windows PowerShell client to connect to our proxy server. We use the proxy server because we have to modify the WinRM protocol to rewrite the pass link to the vulnerable auto discover handle which will eventually trigger the pass confusion bug and add the access token to the query stream. Once the station has been established, we can ask you the apparel shield command to grant ourself the mailbox explore law and involve the mailbox exporting. And the last step is to enjoy the shell. Let's go to the demonstration. So this is the exchange server and we run our exploit. The exploit first send our encoded panel to the mailbox and launch the PowerShell to establish the WinRM connection. We use the proxy server to rewrite the traffic to implement our exploit. Okay, we see our shell is dropped and we are the same thing. Let's talk about mitigations. Since it's an architectural problem, it's hard to mitigate a tech service with one single action. All you can do is keep your exchange server up to date and with the support of a firewall or a ACL to not externally facing the internet. Microsoft has enhanced the CAS architecture in Apollo. The authentication part of this attack service has been reduced in the patch. So if you are lazy, please update the actual patch at least. And if you are super lazy, maybe you can give a shot at the Office 365. Okay, conclusion. Modern problems require modern solutions. It's hard to find traditional bugs in modern architecture. Sometimes comprehending the architecture from a higher point of view can help you find new interesting bugs. The CAS is still a good attack service or so Microsoft has patched it in Apollo. However, in fact, we still find a few bugs after the Apollo patch. But since the authentication part of this attack service is reduced, the result may not be as powerful as before due to the lack of pre-auth bugs. Lastly, the exchange is still a chaser waiting for you to find bugs. As mentioned, even in 2020, a hard code crypto key can still be found in exchange server. I can assure you that Microsoft will fix more exchange vulnerabilities in the future. But here comes the story a lot. Even if you find a super critical vulnerability like proxy logon, Microsoft will not reward you any bounty because the exchange server on premiums is out of scope. So is it was file hunting bugs on exchange servers? You tell me. This is the end of my presentation. If you have any questions, here's my contact information. By the way, I will post a detailed article on my blog. Please look forward to that. Thank you again for being here. Thanks.