OpenNMS Şifre Karmalarını Kırma – ropnop blogu


Arka plan

Son dahili sızma testimde OpenNMS çalıştıran bir sunucunun güvenliğini tehlikeye attım. Kullanım sonrası sırasında, yerel OpenNMS kullanıcıları için birkaç şifre karmasını kurtardım, ancak hayatım boyunca bunların nasıl karma hale getirildiğini çözemedim. Sunucuda root erişimim olmasına rağmen, kullanıcıların şifrelerini ortamın başka bir yerinde yeniden kullanıyor olabileceğini düşündüğümden yine de bu karmaları kırmayı denemek istedim.

Googling’im beni başarısızlığa uğrattı ve OpenNMS şifre karmaları hakkında çevrimiçi herhangi bir iyi kaynak bulamadım, bu yüzden öğrendiklerimi belgelemeye ve bir OpenNMS sunucusunu tehlikeye atacak gelecekteki pentester’lara yardımcı olacağını umduğum bir Python aracı yayınlamaya karar verdim.

tl;doktor. Bunlar, ilk 16 baytın tuz olduğu ve geri kalan 32 baytın 100.000 yineleme olduğu base64 kodlu dizelerdir. sha256(salt.password). Araç burada yayınlandı:

https://github.com/ropnop/opennms_hash_cracker

İlk Uzlaşma

Bilinen bir Java seri durumdan çıkarma güvenlik açığına sahip, OpenNMS’in eski bir sürümünü çalıştıran bir sunucu keşfettik. FoxGlove Security, bu güvenlik açığını inceleyen harika bir yazı yayınladı:

What Do WebLogic, WebSphere, JBoss, Jenkins, OpenNMS, and Your Application Have in Common? This Vulnerability.

Metasploit modülüyle kullanım daha kolay olamazdı. Modülü 1099 numaralı porttaki RMI arayüzüne yönlendirdik ve yükü şu şekilde ayarladık: linux/x86/shell_reverse_tcp ve hızlı bir şekilde kök ayrıcalıklarıyla çalışan bir kabuk verildi:

OpenNMS Oturumu

OpenNMS kuruldu /opt/opennms bu yüzden bu dizini keşfetmek için kabuğu kullandım ve hızlı bir şekilde OpenNMS için yerel kullanıcı hesaplarını tanımlayan bir dosya buldum. Kullanıcı adlarından bazılarını kuruluşun ayrıcalıklı yöneticileri olarak tanıdım, bu nedenle şifrelerin başka bir yerde yeniden kullanıldığını umarak bu karmalardan bazılarını kırmayı denemek istedim.

Karmaların saklandığı yer /opt/opennms/etc/users.xml ve şöyle görünüyordu:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20

 xmlns="http://xmlns.opennms.org/xsd/users">
  
> >.9 >Wednesday, February 6, 2002 10:10:00 AM EST >master.nmanage.com
> > >ropnop >Rop Nop > salt="true">L5j2hiVX4B+LTHnY3Mwq5m5dBZzNdHhiBpvBjyCerBsBqqJcxRUsRAxaDQtjRkcn >ROLE_RTC ...(more users)...

Açıkçası, XML’e göre tuzlanmış olan şifre karmasıyla ilgileniyordum:
L5j2hiVX4B+LTHnY3Mwq5m5dBZzNdHhiBpvBjyCerBsBqqJcxRUsRAxaDQtjRkcn

Her ikisini de hızlıca aradım john Ve hashcat OpenNMS karmaları için bir mod olup olmadığını görmek için yardım sayfalarını aradım ancak hiçbir şey bulamadım. Daha sonra Google’a başvurdum ancak hash’in nasıl tuzlandığına ve/veya hesaplandığına dair hala hiçbir ipucu bulamadım.

Bu noktada bunu kendi başıma çözmem gerektiğini fark ettim.

Hash Tanımlaması

Çoğu şifre kırma programı karmaların hex temsillerini kullanır, bu yüzden XML’deki base64 değerini hex’e dönüştürdüm:

1
2
>>> "L5j2hiVX4B+LTHnY3Mwq5m5dBZzNdHhiBpvBjyCerBsBqqJcxRUsRAxaDQtjRkcn".decode('base64').encode('hex')
'2f98f6862557e01f8b4c79d8dccc2ae66e5d059ccd747862069bc18f209eac1b01aaa25cc5152c440c5a0d0b63464727'

Daha sonra olası karmaları görmek için Python paketi hashID’sini kullandım:

HashID

Yani potansiyel olarak SHA-384, ancak bu o kadar nadir ki bundan gerçekten şüpheliyim. Daha derine inme zamanı.

Düz Metin Tanımlaması

Kullanılan karma algoritmasını doğru bir şekilde çözmüş olsam bile, bırakın tuzun gerçekte ne olduğundan, tuzun nasıl uygulandığından hâlâ emin değildim. İlk düşüncem tuzun OpenNMS tarafından kullanılan PostgresSQL veritabanında depolanmış olabileceğiydi. Sunucuda root olduğum için veritabanına bağlanıp tabloları inceleyebildim ancak şifreler veya tuzlarla ilgili hiçbir şey bulamadım. Yani uygulamanın bir yerinde olması gerekiyordu.

OpenNMS açık kaynak olduğundan ilk döndüğüm yer Github sayfası oldu ve “tuz” diye arama yaptım. Bu bir örnek ortaya çıktı users.xml Test amaçlı kullanılan dosyalar.

Oradaki kaynak kodunu takip ederek nihayet tuzlu şifre karmalarını kullanan bazı iddia testleriyle karşılaştım:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
@Test
    public void testAuthenticateRtc() {
        org.springframework.security.core.Authentication authentication = new UsernamePasswordAuthenticationToken("rtc", "rtc");
        org.springframework.security.core.Authentication authenticated = m_provider.authenticate(authentication);
        assertNotNull("authenticated Authentication object not null", authenticated);
        Collection<? extends GrantedAuthority> authorities = authenticated.getAuthorities();
        assertNotNull("GrantedAuthorities should not be null", authorities);
        assertEquals("GrantedAuthorities size", 1, authorities.size());
        assertContainsAuthority(Authentication.ROLE_RTC, authorities);
    }

Bunu testteki “rtc” kullanıcı karma değeriyle eşleştirmek users.xml Artık eşleşen bir düz metin ve karma değerim vardı:

  • Düz metin: rtc
  • Tuzlu Haş: L5j2hiVX4B+LTHnY3Mwq5m5dBZzNdHhiBpvBjyCerBsBqqJcxRUsRAxaDQtjRkcn

Bana hâlâ tuzun ne olduğunu ya da nasıl kullanıldığını söylemedi ama pozitif bir test vakasına sahip olmak, karma planını anlamak açısından önemliydi.

Karma Algoritma Tanımlaması

Github koduna odaklanmak yerine sunucudaki kök kabuğuma geri döndüm. Kodun Github ile uğraştığım şey arasında ne kadar eski veya ne kadar farklı olabileceğinden emin değildim, bu yüzden karmanın hesaplandığı sunucuda kaynak kodunu bulmaya çalışmak istedim.

İçinden opennms dizininde, nerede kullanıldığını görmek için “tuz” dizesini aradım:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
$ find . -type f -exec grep -i -l salt {} \;
./etc/users.xml
./jetty-webapps/opennms/includes/angular.js
./jetty-webapps/opennms/RemotePollerMap/openlayers/lib/OpenLayers/Layer/HTTPRequest.js
./jetty-webapps/opennms/RemotePollerMap/openlayers/lib/OpenLayers/Tile/Image/IFrame.js
./jetty-webapps/opennms/RemotePollerMap/openlayers/OpenLayers.js
./jetty-webapps/opennms-remoting/webstart/jasypt-1.9.0.jar
./jetty-webapps/opennms-remoting/webstart/snmp4j-1.11.1.jar
./jetty-webapps/opennms-remoting/webstart/spring-security-config-3.1.0.RELEASE.jar
./jetty-webapps/opennms-remoting/webstart/spring-security-core-3.1.0.RELEASE.jar
./lib/bcprov-jdk14-1.38.jar
./lib/jasypt-1.9.0.jar
./lib/joda-time-2.1.jar
./lib/snmp4j-1.11.1.jar
./lib/spring-security-config-3.1.0.RELEASE.jar
./lib/spring-security-core-3.1.0.RELEASE.jar
./system/joda-time/joda-time/1.6.2/joda-time-1.6.2.jar
./system/org/apache/servicemix/bundles/org.apache.servicemix.bundles.jasypt/1.6_1/org.apache.servicemix.bundles.jasypt-1.6_1.jar

Tamam, içinde “tuz” kelimesi bulunan bazı JAR kütüphaneleri var, özellikle ./lib/jasypt-1.9.0.jar

Ana sayfalarına göre:

Jasypt, geliştiricinin projelerine minimum çabayla ve kriptografinin nasıl çalıştığına dair derin bilgiye ihtiyaç duymadan temel şifreleme yeteneklerini eklemesine olanak tanıyan bir Java kütüphanesidir.

Dokümanları incelerken, sonunda oldukça umut verici görünen bir şeyle karşılaştım: StandardStringDigester adında başka bir sınıfı kullanan StrongPasswordEncryptor adında bir sınıf. Dokümanlara göre StrongPasswordEncryptor bir:

Tuz Boyutu bilgisi

Jasypt ayrıca Github’da ve her iki sınıfın da kaynak kodunu burada ve burada buldum. StandardStringDigester kaynak kodunun yorumlarına baktığımda sonunda özetin nasıl oluşturulduğuna dair cevabımı buldum:

Özet İnşaat

Şu anda ihtiyacım olan tüm parçalara sahibim (umarım):

  • Düz metin: “rtc”
  • Özet: L5j2hiVX4B+LTHnY3Mwq5m5dBZzNdHhiBpvBjyCerBsBqqJcxRUsRAxaDQtjRkcn
  • Tuz Boyutu: 16 bayt
  • Özet Formatı: (tuz.şifre)
  • Algoritma: sha256
  • Yinelemeler: 100.000

Hepsini bir araya getirmek

Bunun doğru algoritma olduğunu ve aslında özeti düz metinden çıkarabildiğimi gerçekten doğrulamak istedim.

Şimdi bunu test etmek için tuzun baytlarını düz metinle birleştirmem ve ardından sha256 özetini 100.000 kez hesaplamam gerekiyordu. Düz metni ve şifreyi doğrulamak için bir Python betiği yazdım:

Ve bunu bilinen düz metinle test ederek 100.000 yinelemeyle başarıya ulaştık!

Düz Metin Kontrolü

Kelime listesiyle kırma

Artık PoC’yi çalıştırdığım için, tehlikeye attığım karmalara bir kelime listesi oluşturmak istedim. Sadece tuz içeren bir sha256 karma olduğundan, kullanabileceğimi düşündüm. john veya hashcat. sordum heyecan Eğer tur sayısını belirtmek mümkün olsaydı, ancak ne yazık ki işe yarayan bir cevap buldum. @coffeetocode John’un kaynak kodunu araştırdım ve sha256crypt’in muhtemelen bulabildiğim en yakın kod olduğunu gördüm. Sorun şu ki, sha256crypt’in tuz için maksimum 16 karaktere sahip olması ve bunların 16 karakter kullanmasıdır. bayt tuzlar.

Bir cracking programı kullanma konusunda şansım yaver gitmemiş gibi görünüyordu. Herhangi birinin herhangi bir önerisi veya geçici çözümü varsa, lütfen bana bildirin!

Kraker yazmak

Hala karmalarda bazı düz metin şifreleri çalıştırmak istediğimden ve tüm bu çile beni tamamen kandırdığından, Python’da basit bir kaba kuvvet programı yazdım.

Github’ımda burada:

https://github.com/ropnop/opennms_hash_cracker

Python betiği bir users.xml dosyasını çıkarır, karmaları çıkarır ve ardından sağlanan bir kelime listesini kullanarak karmalara karşı bir kırma saldırısı gerçekleştirir.

Ayrıca OpenNMS için (yalnızca MD5 özetleri olan) tuzsuz karmaları ayrıştırmak ve test etmek için de bazı mantığı vardır.

Örnek üzerinde çalıştırma users.xml OpenNMS test verilerinden alınan dosya basit bir kelime listesiyle çalıştığını gösteriyor:

Hash'leri kırma

Çok hızlı veya verimli değil, ancak küçük bir kelime listeniz varsa veya yalnızca bazı ortak şifreleri denemek istiyorsanız amaca hizmet etmelidir. Hızlandırmak veya hatta hashcat’e taşımak konusunda biraz yardım almak isterim!

Sonuçta, zamanım kısıtlı olduğundan ve başka yollar izlemek zorunda kaldığımdan dolayı bu bana sızma sınavımda hiç yardımcı olmadı, ancak yine de eğlenceli bir egzersizdi. Umuyoruz ki bu blog ve araç, gelecekte bir OpenNMS kutusunu tehlikeye atması durumunda pentester’lara yardımcı olacaktır.

Eğlence! -ropnop


Ayrıca bakınız





Source link