CommVault Komuta Merkezine Karşı Kimliği Doğrulanmamış Uzaktan Kod Yürütme


Ne zaman Justin Kennedy Ve Brandon Perry birlikte küçük bir denetim yapmak isteyip istemediğimi sordu, dayanamadım. Zaman sınırlı olmasına rağmen bu işe katılmaya karar verdim çünkü gerçek hack işbirliği bugünlerde nadir görülen bir şey.

CommVault Komuta Merkezi Arayüzünü hedeflemeye ve CommVault’tan alıntı yapmaya karar verdik:

Komuta Merkezi, rutin veri koruma ve kurtarma görevleri için varsayılan yapılandırma değerleri ve kolaylaştırılmış prosedürler sağlayan, yönetim görevlerine yönelik web tabanlı bir kullanıcı arayüzüdür. Veri koruma ortamınızı kurmak, korumak istediğiniz içeriği belirlemek ve yedekleme ve geri yüklemeleri başlatmak ve izlemek için Komuta Merkezi’ni kullanabilirsiniz.

Bu ilginç bir hedef çünkü:

  1. Çeşitli bileşenleri (CommCell Konsolu, Komuta Merkezi, Web Konsolu, CommServe Sunucusu, vb.) içeren bir üründür.
  2. CommVault’ta ciddi bir güvenlik açığı eksikliği vardı. Son zamanlarda bulabildiğim tek hata, açıklama etkisi olan ve kavram kanıtı olmayan, kimliği doğrulanmış bir dizin geçişi olan CVE-2020-25780’di.
  3. Denetimi oldukça çekici kılan C#’tan Java’ya kadar çeşitli teknolojilerin bulunması.

Bir süre sonra, hedef CommVault düğümüne karşı SİSTEM olarak kimliği doğrulanmamış uzaktan kod yürütmeyi gerçekleştirmek için 3 hatayı (iki hata olarak açıklanan – ZDI-21-1328 ve ZDI-21-1331) zincirleme başardık.

CVAuthHttpModule OnEnter Kısmi Kimlik Doğrulamayı Atlama

İçinde CVInfoMgmtService.dll dosyalamak CVAuthHttpModule.OnEnter yöntem, kimlik doğrulama kontrolüdür. CVSearchService web hizmeti:

private void OnEnter(object sender, EventArgs e)
{
    bool flag = true;
    this.reject = true;
    string empty = string.Empty;
    bool flag2 = true;
    this._token = "";
    this._sw = Stopwatch.StartNew();
    this._request = "";
    try
    {
        string[] array = CVAuthHttpModule.readHeader();
        string text = array[0]; // 1
        string text2 = array[1];
        string text3 = array[2];
        string text4 = array[3];
        bool flag3 = this.IsRestWebService(); // 2
        ...
        bool flag11 = !string.IsNullOrEmpty(text) && !flag3 && NonSecureOperations.canByPassCheck(text); // 3
        if (flag11)
        {
            flag = false;
            this.reject = false;
        ...

Şu tarihte: [1] the text çerez başlığından geliyor ve [2] kod, isteğin şunun için olup olmadığını kontrol eder: CVSearchService.svc hizmeti görebiliriz NonSecureOperations.canByPassCheck en [3].

public static bool canByPassCheck(string messageName)
{
    string item = dmConf.encodePass(messageName); // 4
    return NonSecureOperations.list.Contains(item); // 5
}

dmConf.encodePass aramak [4]:

// DM2WebLib.dmConf
// Token: 0x060000E8 RID: 232 RVA: 0x00006C10 File Offset: 0x00004E10
public static string encodePass(string dataTobeEncoded)
{
	string text = string.Empty;
	bool flag = string.IsNullOrEmpty(dataTobeEncoded);
	string result;
	if (flag)
	{
		result = dataTobeEncoded;
	}
	else
	{
		try
		{
			byte[] inArray = new byte[dataTobeEncoded.Length];
			inArray = Encoding.UTF8.GetBytes(dataTobeEncoded);
			text = Convert.ToBase64String(inArray);
		}
		catch (Exception ex)
		{
			throw new Exception(string.Format("Error in base64Encode. Exception Message:[{0}], Data to be decoded:[{1}] ", ex.Message, dataTobeEncoded));
		}
		result = text;
	}
	return result;
}

…ve NonSecureOperations inşaatçı [5]:

static NonSecureOperations()
{
    NonSecureOperations.list = new ArrayList();
    NonSecureOperations.list.Add("TG9naW4uR2V0TG9nb25MaXN0");
    NonSecureOperations.list.Add("TG9naW4uTG9naW4=");
    NonSecureOperations.list.Add("Q0kuR2V0RE1TZXR0aW5n");
    NonSecureOperations.list.Add("TG9naW4=");
    NonSecureOperations.list.Add("Q0kuR2V0RE1TZXR0aW5ncw==");
    NonSecureOperations.list.Add("UmV0cmlldmVJdGVt");
    NonSecureOperations.list.Add("U2VhcmNoLkdldFBhbmVsQ29sdW1uQ29uZmln");
    NonSecureOperations.list.Add("RGF0YVNlcnZpY2UuUG9wdWxhdGVEYXRh");
    NonSecureOperations.list.Add("Z2V0T2VtSWQ=");
    NonSecureOperations.list.Add("TG9naW4uV2ViQ2xpZW50TG9naW4=");
    NonSecureOperations.list.Add("Z2V0R2xvYmFsUGFyYW0=");
}
  1. Login.GetLogonList
  2. Giriş. Giriş
  3. CI.GetDMSetting
  4. Giriş yapmak
  5. CI.GetDMSettings
  6. Öğeyi Al
  7. Search.GetPanelColumnConfig
  8. DataService.PopulateData
  9. getOemId
  10. Login.WebClientLogin
  11. getGlobalParam

Bu sadece çerezi base64 olarak kodlar ve onu sabit kodlanmış dizelerin bir listesiyle karşılaştırır. Bu yüzden ilkini şu şekilde ayarladım: Login.GetLogonList hangisi eşleşiyor TG9naW4uR2V0TG9nb25MaXN0. Şimdi this.reject false olarak ayarlandığında bu web hizmeti için kimlik doğrulamasını atlayabiliriz!

CVSearchSvc downLoadFile Dosya Açıklaması

Görünen o ki, bu hizmetin API’sinde bir dosya ifşa güvenlik açığı var. Hadi kontrol edelim CVSearchSvc sınıf:

public byte[] downLoadFile(string path)
{
    DownLoad downLoad = new DownLoad();
    return downLoad.downLoadFile(path); // 4
}

Şu tarihte: [4] kod çağrıları com.commvault.biz.restore.DownLoad.downLoadFile Saldırganın kontrolü altında path:

public byte[] downLoadFile(string path)
{
    bool flag = string.IsNullOrEmpty(path);
    byte[] result;
    if (flag)
    {
        result = null;
    }
    else
    {
        bool flag2 = !File.Exists(path);
        if (flag2)
        {
            result = null;
        }
        else
        {
            FileInfo fileInfo = new FileInfo(path);
            long length = fileInfo.Length;
            FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read);
            BinaryReader binaryReader = new BinaryReader(fileStream);
            byte[] array = binaryReader.ReadBytes((int)length);
            binaryReader.Close();
            fileStream.Close();
            result = array;
        }
    }
    return result;
}

Bu, saldırganın sağladığı dosya yolunu okumak için açar ve dosyanın içeriğini döndürür. Yanıt base64 ile kodlandığı ve saldırgana geri gönderildiği için bu bir ikili dosya olabilir.

Sömürü

Bu noktada aslında kimliği doğrulanmamış bir dosya okuma güvenlik açığıyla karşı karşıyaydık. Uzaktan kod yürütme veya kimlik doğrulamayı atlama için bundan nasıl yararlanacaktık? Yalnızca ağ hizmeti hesabının izinlerine sahip dosyaları okuyabildiğimiz için sınırlı bir dosya okumasıydı. Bu nedenle, zaten açık dosya tanıtıcısına sahip olan dosyaları başka bir işlemde açamadık. Korkunçtu.

Daha iyisi için

Birkaç gün sonra Brandon akıllıca bir sömürü stratejisi buldu. E-posta sunucusunu yapılandırırken ve test ederken, şifreyi sıfırlamaya çalıştığında şunu fark etti: SystemCreatedAdmin hesapta bir hataya neden olur c:/Program Files/Commvault/ContentStore/Log Files/WebServer.log dosya:

4424  3     05/13 17:00:37 3   ###  - Processing [POST] request : /user/Password/ForgotRequest : Headers :[Content-Type=application/x-www-form-urlencoded][Expect=100-continue][Host=127.0.0.1:81][Content-Length=50][locale=en_US][LookupNames=false][client-location=192.168.1.152][CVRequestRouted=true][MS-ASPNETCORE-TOKEN=cba64f3f-885a-4d1e-bcfe-cbda5c6e5e19][X-Original-Proto=http][trace-id=wse7e5af76c93c][X-Original-For=127.0.0.1:51285] : Parameters : (empty) : AdditionalInfo[ClientIP[192.168.1.152] ConsoleType[Unknown] Operation[CV.WebServer.Controllers.UserController.ForgotPasswordRequest (CVWebControllerClient)] isTokenSupplied?[False] Username[]]
4424  3     05/13 17:00:38 3   ### SetTinyWebConsoleTinyUrl - Error sending reset password email with tinyURL : http://WIN-9BHJU583I26:80/webconsole/gtl.do?gid=sqmyEqVeOftkV
4424  3     05/13 17:00:43 3   ### SendResetPasswordEmail - Reset password email set successfully to: 
4424  3     05/13 17:00:43 3   ### Invoke - POST /user/Password/ForgotRequest : HTTP code 'OK'

Bunun nedeni, varsayılan tanrı modu kullanıcısının SystemCreatedAdmin tasarım gereği bağlantılı bir e-posta hesabı yoktu ve bu nedenle geliştiriciler, parola sıfırlama belirtecini günlük dosyasına bırakmanın uygun olacağını düşündüler. Dosya ifşa güvenlik açığımız nedeniyle bu günlük dosyasını sızdırabilir ve parola sıfırlama belirtecini (sqmyEqVeOftkV bu durumda) böylece sıfırlayabiliriz SystemCreatedAdmin şifrenizi girin ve Komuta Merkezine erişim kazanın.

Bu başarıldığında, iş akışlarını, bir komutun SİSTEM olarak yürütülmesine izin veren varsayılan bir iş akışıyla, düşük ve dikkat çekici bir şekilde yürütebildiğimizi gördük!

CommVault'un kilidini açma

Savunma keyfiniz için bir konsept kanıtı yayınladık.

Çözüm

Keşfettiğimiz tek sorun bunlar değil, yalnızca en yüksek etkiyi yarattığı için odaklanıp sunmaya zamanımız olan sorunlar. Tabii ki KP Choubey hatalarımızı analiz ederken ZDI-21-1332’yi de keşfetti.





Source link