
Tutorial paso a paso del exploit para CVE-2023-22515, una vulnerabilidad crítica de control de acceso roto en Atlassian Confluence Server y Data Center, que permite la creación remota de cuentas de administrador.
Producto afectado: Atlassian Confluence Data Center & Confluence Server.
Fecha de publicación: 04/10/2023.
Gravedad: Critical (CVSS ~ 10.0).
Tipo de vulnerabilidad: Broken Access Control / Improper Authorization → permite al atacante crear una cuenta de administrador de forma remota.
El fallo se encuentra en el mecanismo de configuración de Confluence
Impacto: Confluence Data Center & Server 8.0.0 → 8.5.1.

Esto proviene de uno de los interceptores, que es de
SetupCheckInterceptorstruts.xmlstruts.xml es el archivo de configuración central para Struts.
Define cómo Confluence mapea URL → Action class → View template.
También declara interceptors (clases que interceptan y procesan la petición antes/después de ejecutar la action).

En SetupCheckInterceptor se llama a BootstrapUtils.getBootstrapManager().isSetupComplete()
public String intercept(ActionInvocation actionInvocation) throws Exception {
if (BootstrapUtils.getBootstrapManager().isSetupComplete() && ContainerManager.isContainerSetup())
return "alreadysetup";
return actionInvocation.invoke();
}
Explicación
BootstrapUtils.getBootstrapManager().isSetupComplete()
→ Comprueba si Confluence ha completado el proceso de configuración (mediante el asistente, introducción de licencia, creación del usuario admin) o no.
ContainerManager.isContainerSetup()
→ Comprueba si el contenedor Spring IoC se ha inicializado por completo.
Si ambas condiciones son verdaderas:
→ Significa que el sistema ya está completamente configurado → el interceptor devuelve "alreadysetup" inmediatamente.
→ No permite continuar con la action (normalmente las actions de configuración como SetupDatabaseAction, SetupLicenseAction, …).
Si la configuración no está completa:
→ Se llama a actionInvocation.invoke() → es decir, continúa ejecutando la action que solicitó el usuario.
getBootstrapManager() → normalmente devuelve DefaultAtlassianBootstrapManager, que gestiona toda la información de configuración central durante el proceso de configuración.
DefaultAtlassianBootstrapManager.isSetupComplete podemos ver que se llama al método de configuración de la aplicación isSetupComplete para comprobar si el proceso de configuración ha finalizado.
=> Si hacemos que isSetupComplete = False, entonces SetupCheckInterceptor no devolverá “alreadysetup” y /setup/setupadministrator.action será accesible.
A continuación tenemos un ServerInfoAction
ServerInfoAction = Action pública en Confluence → permite que cualquier usuario la invoque sin necesidad de iniciar sesión ni token CSRF. Al ejecutarse, solo devuelve "success" → se asigna a una plantilla que muestra la información del servidor.
ConfluenceActionSupportConfluenceActionSupport vemos que getBootstrapStatusProvider devuelve BootstrapStatusProviderImpl, la implementación que estamos buscando.
BootstrapStatusProviderImpl encontramos getApplicationConfig que devuelve la configuración de la aplicación.
ApplicationConfig se puede ver que implementa la comprobación de setSetupComplete.
setSetupComplete = falsegetBootstrapStatusProvider(). getApplicationConfig (). setSetupComplete ( false );
bootstrapStatusProvider.applicationConfig.setupComplete=false
/server-info.action, una URL en Confluence gestionada por ServerInfoAction, porque es un endpoint público que no requiere autenticación./server-info.action?bootstrapStatusProvider.applicationConfig.setupComplete=false

Comprobemos el Debug:
setupComplete (parámetro pasado al método)
→ false
Es decir, el método se está llamando con el parámetro false.
this.setupComplete (variable de instancia del objeto ApplicationConfig)
→ true (antes de la asignación).
Cuando el comando termina de ejecutarse → this.setupComplete pasará a ser false.

/setup/setupadministrator.action y veremos que se accede correctamente.
