2021年8月6日 星期五

A New Attack Surface on MS Exchange Part 2 - ProxyOracle!

Author: Orange Tsai(@orange_8361)
P.S. This is a cross-post blog from DEVCORE


Hi, this is the part 2 of the New MS Exchange Attack Surface. Because this article refers to several architecture introductions and attack surface concepts in the previous article, you could find the first piece here:


This time, we will be introducing ProxyOracle. Compared with ProxyLogon, ProxyOracle is an interesting exploit with a different approach. By simply leading a user to visit a malicious link, ProxyOracle allows an attacker to recover the user’s password in plaintext format completely. ProxyOracle consists of two vulnerabilities:


Where is ProxyOracle

So where is ProxyOracle? Based on the CAS architecture we introduced before, the Frontend of CAS will first serialize the User Identity to a string and put it in the header of X-CommonAccessToken . The header will be merged into the client’s HTTP request and sent to the Backend later. Once the Backend receives, it deserializes the header back to the original User Identity in Frontend.

We now know how the Frontend and Backend synchronize the User Identity. The next is to explain how the Frontend knows who you are and processes your credentials. The Outlook Web Access (OWA) uses a fancy interface to handle the whole login mechanism, which is called Form-Based Authentication (FBA). The FBA is a special IIS module that inherits the ProxyModule and is responsible for executing the transformation between the credentials and cookies before entering the proxy logic.



The FBA Mechanism

HTTP is a stateless protocol. To keep your login state, FBA saves the username and password in cookies. Every time you visit the OWA, Exchange will parse the cookies, retrieve the credential and try to log in with that. If the login succeed, Exchange will serialize your User Identity into a string, put it into the header of X-CommonAccessToken, and forward it to the Backend

HttpProxy\FbaModule.cs

protected override void OnBeginRequestInternal(HttpApplication httpApplication) {

    httpApplication.Context.Items["AuthType"] = "FBA";
    if (!this.HandleFbaAuthFormPost(httpApplication)) {
        try {
            this.ParseCadataCookies(httpApplication);
        } catch (MissingSslCertificateException) {
            NameValueCollection nameValueCollection = new NameValueCollection();
            nameValueCollection.Add("CafeError", ErrorFE.FEErrorCodes.SSLCertificateProblem.ToString());
            throw new HttpException(302, AspNetHelper.GetCafeErrorPageRedirectUrl(httpApplication.Context, nameValueCollection));
        }
    }
    base.OnBeginRequestInternal(httpApplication);
}


All the cookies are encrypted to ensure even if an attacker can hijack the HTTP request, he/she still couldn’t get your credential in plaintext format. FBA leverages 5 special cookies to accomplish the whole de/encryption process:

  • cadata - The encrypted username and password
  • cadataTTL - The Time-To-Live timestamp
  • cadataKey - The KEY for encryption
  • cadataIV - The IV for encryption
  • cadataSig - The signature to prevent tampering



The encryption logic will first generate two 16 bytes random strings as the IV and KEY for the current session. The username and password will then be encoded with Base64, encrypted by the algorithm AES and sent back to the client within cookies. Meanwhile, the IV and KEY will be sent to the user, too. To prevent the client from decrypting the credential by the known IV and KEY directly, Exchange will once again use the algorithm RSA to encrypt the IV and KEY via its SSL certificate private key before sending out!

Here is a Pseudo Code for the encryption logic:

 @key = GetServerSSLCert().GetPrivateKey()
 cadataSig = RSA(@key).Encrypt("Fba Rocks!")
 cadataIV  = RSA(@key).Encrypt(GetRandomBytes(16))
 cadataKey = RSA(@key).Encrypt(GetRandomBytes(16))

 @timestamp = GetCurrentTimestamp()
 cadataTTL  = AES_CBC(cadataKey, cadataIV).Encrypt(@timestamp)

 @blob  = "Basic " + ToBase64String(UserName + ":" + Password)
 cadata = AES_CBC(cadataKey, cadataIV).Encrypt(@blob)


The Exchange takes CBC as its padding mode. If you are familiar with Cryptography, you might be wondering whether the CBC mode here is vulnerable to the Padding Oracle Attack? Bingo! As a matter of fact, Padding Oracle Attack is still existing in such essential software like Exchange in 2021!



CVE-2021-31196 - The Padding Oracle

When there is something wrong with the FBA, Exchange attaches an error code and redirects the HTTP request back to the original login page. So where is the Oracle? In the cookie decryption, Exchange uses an exception to catch the Padding Error, and because of the exception, the program returned immediately so that error code number is 0, which means None:

Location: /OWA/logon.aspx?url=…&reason=0


In contrast with the Padding Error, if the decryption is good, Exchange will continue the authentication process and try to login with the corrupted username and password. At this moment, the result must be a failure and the error code number is 2, which represents InvalidCredntials:

Location: /OWA/logon.aspx?url=…&reason=2


The diagram looks like:


With the difference, we now have an Oracle to identify whether the decryption process is successful or not.


HttpProxy\FbaModule.cs

private void ParseCadataCookies(HttpApplication httpApplication)
{
    HttpContext context = httpApplication.Context;
    HttpRequest request = context.Request;
    HttpResponse response = context.Response;
    
    string text = request.Cookies["cadata"].Value;    
    string text2 = request.Cookies["cadataKey"].Value;    
    string text3 = request.Cookies["cadataIV"].Value;    
    string text4 = request.Cookies["cadataSig"].Value;    
    string text5 = request.Cookies["cadataTTL"].Value;
    
    // ...
    RSACryptoServiceProvider rsacryptoServiceProvider = (x509Certificate.PrivateKey as RSACryptoServiceProvider);
    
    byte[] array = null;
    byte[] array2 = null;
    byte[] rgb2 = Convert.FromBase64String(text2);
    byte[] rgb3 = Convert.FromBase64String(text3);
    array = rsacryptoServiceProvider.Decrypt(rgb2, true);
    array2 = rsacryptoServiceProvider.Decrypt(rgb3, true);
    
    // ...
    
    using (AesCryptoServiceProvider aesCryptoServiceProvider = new AesCryptoServiceProvider()) {
        aesCryptoServiceProvider.Key = array;
        aesCryptoServiceProvider.IV = array2;
        
        using (ICryptoTransform cryptoTransform2 = aesCryptoServiceProvider.CreateDecryptor()) {
            byte[] bytes2 = null;
            try {
                byte[] array5 = Convert.FromBase64String(text);
                bytes2 = cryptoTransform2.TransformFinalBlock(array5, 0, array5.Length);
            } catch (CryptographicException ex8) {
                if (ExTraceGlobals.VerboseTracer.IsTraceEnabled(1)) {
                    ExTraceGlobals.VerboseTracer.TraceDebug<CryptographicException>((long)this.GetHashCode(), "[FbaModule::ParseCadataCookies] Received CryptographicException {0} transforming auth", ex8);
                }
                httpApplication.Response.AppendToLog("&CryptoError=PossibleSSLCertrolloverMismatch");
                return;
            } catch (FormatException ex9) {
                if (ExTraceGlobals.VerboseTracer.IsTraceEnabled(1)) {
                    ExTraceGlobals.VerboseTracer.TraceDebug<FormatException>((long)this.GetHashCode(), "[FbaModule::ParseCadataCookies] Received FormatException {0} decoding caData auth", ex9);
                }
                httpApplication.Response.AppendToLog("&DecodeError=InvalidCaDataAuthCookie");
                return;
            }
            string @string = Encoding.Unicode.GetString(bytes2);
            request.Headers["Authorization"] = @string;
        }
    }
}


It should be noted that since the IV is encrypted with the SSL certificate private key, we can’t recover the first block of the ciphertext through XOR. But it wouldn’t cause any problem for us because the C# internally processes the strings as UTF-16, so the first 12 bytes of the ciphertext must be B\x00a\x00s\x00i\x00c\x00 \x00. With one more Base64 encoding applied, we will only lose the first 1.5 bytes in the username field.

(16−6×2) ÷ 2 × (3/4) = 1.5

 

The Exploit

As of now, we have a Padding Oracle that allows us to decrypt any user’s cookie. BUT, how can we get the client cookies? Here we find another vulnerability to chain them together.


XSS to Steal Client Cookies

We discover an XSS (CVE-2021-31195) in the CAS Frontend (Yeah, CAS again) to chain together, the root cause of this XSS is relatively easy: Exchange forgets to sanitize the data before printing it out so that we can use the \ to escape from the JSON format and inject arbitrary JavaScript code.

https://exchange/owa/auth/frowny.aspx
?app=people
&et=ServerError
&esrc=MasterPage
&te=\
&refurl=}}};alert(document.domain)//




But here comes another question: all the sensitive cookies are protected by the HttpOnly flag, which makes us unable to access the cookies by JavaScript. WHAT SHOULD WE DO?


Bypass the HttpOnly

As we could execute arbitrary JavaScript on browsers, why don’t we just insert the SSRF cookie we used in ProxyLogon? Once we add this cookie and assign the Backend target value as our malicious server, Exchange will become a proxy between the victims and us. We can then take over all the client’s HTTP static resources and get the protected HttpOnly cookies!





By chaining bugs together, we have an elegant exploit that can steal any user’s cookies by just sending him/her a malicious link. What’s noteworthy is that the XSS here is only helping us to steal the cookie, which means all the decryption processes wouldn’t require any authentication and user interaction. Even if the user closes the browser, it wouldn’t affect our Padding Oracle Attack!

Here is the demonstration video showing how we recover the victim’s password:



23 則留言:

  1. Easy to apply, guaranteed to be 100% safe. If pg168
    anyone is interested in playing slots games with us, they can apply easily by themselves, just a few steps with an automated system. pg168
    on the website Access the pgslot888 online slots website by following the steps and filling in a few information.

    回覆刪除
  2. สล็อตโจ๊กเกอร์ เว็บไซต์ สล็อต ที่มีโบนัส เครดิตฟรีในตัวเกม ดาวน์โหลด Joker ได้ง่ายๆ ผ่านโทรศัพท์มือถือหรือคอมพิวเตอร์
    สามารถ ทดลองเล่นสล็อต ได้ทั้งในระบบ Android และ iOS

    回覆刪除
  3. owner immediately. Our administrative pg168
    work in detail and professional terms. Taking care of administrative work 24 hours a day. Accommodation is convenient.

    回覆刪除
  4. superslot เกมสล็อตออนไลน์ เว็บตรงที่ดีที่สุดมีเกมสล็อตที่แตกง่ายที่สุดให้ท่านได้เลือกเล่นมากมาย ทดลองเล่นสล็อต ทุกค่ายเกม
    อาทิ PG SLOT , EVOPLAY , SLOTXO , PRAGMATIC PLAY , JILI GAME , RELAX GAMING , DAFABET , JOKER เราชื่อเว็บสล็อตเว็บตรงที่ให้บริการไม่ผ่าน agent สมัครซุปเปอร์สล็อต

    回覆刪除
  5. Hi there to every one, the contents existing at this web site are truly amazing for people knowledge, well, keep up the good work fellows.
    고스톱

    回覆刪除
  6. Say no to paying tons of cash for overpriced Facebook advertising! Let me show you a platform that charges only a very small payment and provides an almost endless volume of web traffic to your website.
    토토사이트

    回覆刪除
  7. I have recently started a web site, the information you provide on this site has helped me tremendously. Thank you for all of your time & work.
    성인웹툰

    回覆刪除
  8. Admiring the hard work you put into your blog and detailed information you provide. Great read! I’ve bookmarked your site and I’m including your RSS feeds to my Google account.
    토토사이트

    回覆刪除
  9. Hi there, after reading this amazing piece of writing I am as well delighted to share my familiarity here with friends. สล็อตออนไลน์

    回覆刪除
  10. After I originally left a comment, I appear to have clicked on the -Notify me บาคาร่า when new comments are added- checkbox and now every time a comment is added I receive 4 emails with the same comment.

    回覆刪除
  11. 먹튀검증커뮤니티 Park Sang-hyun, the "No. 1 Korean golf prize money ranking," who has won twice at the GS Caltex Maekyung Open, called the "Korea Masters," could not hide his excitement at the news that spectators were allowed

    回覆刪除
  12. 안전놀이터추천 I can't concentrate and I'm less nervous. In my case, it's a little bad. I get energy only when I have galleries." Fortunately, this year, Heo In-hoe will be able to challenge for the "second consecutive year of winning


    回覆刪除
  13. 먹튀검증커뮤니티 One of the reasons why domestic top golfers pick the GS Caltex Maekyung Open as the tournament they want to win the most is the spectators. This is because when standing in the tea box, numerous galleries

    回覆刪除
  14. 먹튀검증커뮤니티 Lee Jae-kyung, who reached the top of the Genesis Championship last season, said, "I'm finally happy to hear that spectators can enter," adding, "I'm looking forward to this season as I'm more focused on the game

    回覆刪除
  15. 안전놀이터 However, due to COVID-19, champions over the past two years have not been cheered by cloud spectators, leaving them regrettable. Last year's champion Heo In-hoe said at the time of winning, "Since there are

    回覆刪除
  16. 토토사이트
    토토
    Good day very cool web site!! Man .. Beautiful
    .. Wonderful .. I'll bookmark your website and take the feeds also?
    I am satisfied to find so many helpful info here in the put up, we want
    work out more strategies on this regard, thank you for sharing.

    回覆刪除

  17. 스포츠토토
    배트맨토토


    your site is very interesting.. please visit my webpage!

    回覆刪除
  18. If you want to know about the game of บาคาร่า, you can play here immediately. With a formula that will help you to be profitable for sure as well.

    回覆刪除
  19. Sakura Fortune 2 ซากุระ ฟอร์จูน เป็นเลิศในเกมที่พวกเราตั้งหน้าตั้งตาคอยสูงที่สุดและก็เป็นโปรเจ็กต์ความรักที่จริงจริง เสนอกลไกเกมที่ได้รับการรับรองแล้วด้วยแบบอย่างเลขที่ล้ำสมัย ​​การชำระเงินสูงสุดที่สูงขึ้น สล็อต

    回覆刪除
  20. Hello! I just would like to give you a huge thumbs up for your great info you have got right here on this post. I will be coming back to your web site for more สล็อต
    soon.

    回覆刪除
  21. เว็บแจกเครดิตฟรี 200 แค่สมัคร ไม่ต้องลงทุนเยอะ สมัครฟรีกับ ufac4 สมัครฟรี เล่นพนันออนไลน์ เว็บตรงไม่มีขั้นต่ำ สล็อตรองรับ วอเลท

    回覆刪除