[CVE-2017-3066] AMF Deserialization Remote Code Execution in Adobe ColdFusion

Tổng quan
Adobe ColdFusion là một nền tảng phát triển ứng dụng web mạnh mẽ, được Adobe Systems duy trì và phát triển. Nó cho phép các lập trình viên xây dựng các ứng dụng web động và mạnh mẽ một cách nhanh chóng bằng cách sử dụng ngôn ngữ lập trình CFML (ColdFusion Markup Language).
Lỗ hổng CVE-2017-3066 có liên quan tới AMF deserialization và được mô tả như sau:
Phân tích
Qua bài phân tích của codewhitesec ta biết được entrypoint của lỗ hổng nằm ở endpoint /flex2gateway/amf
và theo config của web.xml, MessageBrokerServlet
sẽ handle endpoint này với 1 init param là coldfusion.flex.ColdFusionMessageBrokerServlet
Đặt breakpoint tại MessageBrokerServlet.service()
-> ColdFusionMessageBrokerServlet.service()
-> MessageBrokerServlet.service()
, tại đây sẽ gọi tiếp endpoint.service
và vì endpoint class của flex2gateway/amf
là flex.messaging.endpoints.AMFEndpoint
nên call tới AMFEndpoint.service()
AMFEndpoint
kế thừa BasePollingHTTPEndpoint
, BasePollingHTTPEndpoint
kế thừa BaseHTTPEndpoint
.
hai class trên không có override method HttpServlet.service()
, nên khi MessageBrokerServlet invoke endpoint service, nó sẽ invoke 1 override method gần nhất, đó là BaseHTTPEndpoint.service()
.
tại hàm này gọi tiếp tới filterchain.invoke()
filterChain
lại được init tại AMFEndpoint.createFilterChain()
hàm này trả về object serializationFilter ở đây là flex.messaging.endpoints.amf.SerializationFilter
.
Như vậy filterchain.invoke()
sẽ call tới SerializationFilter.invoke()
, đây cũng chính là class sẽ handle AMF message của người dùng.
Tại đây body request sẽ được đưa vào AmfMessageDeserializer.readMessage()
để thực hiện AMF deserialize
tiếp tục debug vào AmfMessageDeserializer.readBody()
, method này tiếp tục gọi AmfMessageDeserializer.readObject()
để reconstruct object
Từ đây tiếp tục gọi tới Amf0Input.readObject()
-> Amf0Input.readObjectValue()
rồi lại call tới Amf3Input.readObject()
-> Amf3Input.readObjectValue()
-> Amf3Input.readScriptObject()
Method Amf3Input.readScriptObject()
kiểm tra class đang được xử lý có implement Externalizable
hay không.
Nếu ta dùng 1 Object có implement Externalizable
thì sẽ call tới method readExternal()
của object đang được xử lý -> object.readExternal()
Nếu object không implement Externalizable
sẽ chuyển sang 1 nhánh khác để xử lý. Nhánh này sẽ lấy các property của class và sử dụng BeanProxy.setValue()
để set lại các giá trị này.
lúc này BeanProxy
sẽ cố gắng tìm các setter method của class và invoke nó.
Như vậy ta sẽ có hai hướng để khai thác AMF deser.
- Tìm một chain mà có thể lead từ
Externalizable.readExternal
tớiobject.readObject()
- Tìm một chain mà có setter method có thể gọi tới
readObject()
Setter-based Exploit
Codewhitesec đã tìm được một class có thể lợi dụng setter method để trigger RCE.
Class org.jgroups.blocks.ReplicatedTree
có method setState(byte[] new_state)
có thể thấy method này nhận vào mảng byte, sau đó gọi tiếp Util.objectFromByteBuffer()
.
Util.objectFromByteBuffer()
nhận vào mảng byte và sau đó khởi tạo ObjectInputStream và gọi readObject()
Như vậy ta chỉ cần gói serialized object vào field state, ròi serialize tiếp bằng AMF là xong.
Trong lib của server có Commons BeanUtils 1.8.0 nên mình sẽ dùng chain CommonsBeanutils1 của ysoserial để RCE
Externalizable-based Exploit
Trong các class implement Externalizable
thì có class org.apache.axis2.util.MetaDataEntry
với method readExternal()
như sau:
Tại đây gọi tới SafeObjectInputStream.readObject()
-> SafeObjectInputStream.readObjectOverride()
cuối cùng readObjectOverride
thực hiện gọi readObject
của Java Native
Như vậy lúc này ta chỉ cần wrap serialized object vào MetaDataEntry
.
Ref
- https://codewhitesec.blogspot.com/2017/04/amf.html
- https://codewhitesec.blogspot.com/2018/03/exploiting-adobe-coldfusion.html
- https://docs.google.com/presentation/d/116DwvGitgknoiq_AOLmRlrkjCrUWfi38t_u-GdU4k2k/edit#slide=id.g8b4eedddee_0_773
Subscribe to my newsletter
Read articles from gumgum directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
