Posible malware: deserialización de clase phpupdate desconocida en sesiones PHP #65

Closed
opened 2026-06-28 19:13:59 +00:00 by rafa · 0 comments
Owner

Labels: area:infra, area:joomla, bug:critical, security

Síntoma

Tras cerrar #46 (PHP 8.3 estable + hotfix itemlistfilter.php), el log capturó un fatal nuevo a la 01:20:27 (CET):

[26-May-2026 01:20:27 Europe/Madrid] PHP Fatal error:
phpupdate::__construct(): Cannot use output buffering in output buffering display handlers
in /usr/home/feadulta.com/tmp/ssess_4a986b7a6932253fd6d051f1114a4f8e on line 37

El path tmp/ssess_* es un fichero de sesión PHP. El error se dispara al deserializar un objeto phpupdate desde la sesión, y el constructor intenta hacer ob_start() (output buffering) durante un handler de output ya activo — operación prohibida.

Por qué huele a malware

  • No hay ninguna class phpupdate declarada en el árbol Joomla actual (verificado en /web/ remoto y joomla-php83/ local).
  • La sesión deserializa un objeto cuya clase NO existe en el código del sitio → o vino de un plugin desinstalado o lo metió código externo.
  • El nombre phpupdate simula un componente de actualización del sistema. Patrón habitual de cloaking.

Lo que NO sabemos todavía

  • Contenido del fichero de sesión (permisos restrictivos en /usr/home/feadulta.com/tmp/).
  • Si la sesión es huérfana de algún plugin desinstalado (ej. mySites.guru/bfnetwork ya retirado) o si hay backdoor activo creándolas.
  • Si solo hay esa sesión o muchas con la misma firma.
  • Si la clase phpupdate se llega a cargar dinámicamente (require/autoload) desde algún punto.

Líneas de investigación

  1. Leer contenido del fichero de sesión (probar paths alternativos o desde root del jail).
  2. Listar tmp/ y cache/ buscando otras ssess_* con phpupdate.
  3. Grep recursivo de phpupdate (no solo class phpupdate) en todo /web/.
  4. Revisar cli/, tmp/, cache/, administrator/cache/, sesiones DB y cualquier sitio donde se serializan objetos.
  5. Si encontramos la clase: analizar qué hace (probable cron de re-infección o C2).
  6. Si no la encontramos: la sesión es huérfana → vaciar tmp/ssess_* resuelve el síntoma.

Relación con #46

#46 limpió 7 inyecciones SEO en templates/fe_adulta_1/index.php + barrido general que no encontró webshells. Este hallazgo apunta a una segunda vía de persistencia (vía sesiones) que el barrido estático no podía ver. Trato como follow-up de seguridad de #46.

Prioridad

Alta. Aunque el síntoma actual es solo un fatal en log (no afecta UX), si hay malware activo creando sesiones con su clase es un compromiso vivo que debe cerrarse antes del cutover DNS.

**Labels:** area:infra, area:joomla, bug:critical, security ## Síntoma Tras cerrar #46 (PHP 8.3 estable + hotfix `itemlistfilter.php`), el log capturó un fatal nuevo a la 01:20:27 (CET): ``` [26-May-2026 01:20:27 Europe/Madrid] PHP Fatal error: phpupdate::__construct(): Cannot use output buffering in output buffering display handlers in /usr/home/feadulta.com/tmp/ssess_4a986b7a6932253fd6d051f1114a4f8e on line 37 ``` El path `tmp/ssess_*` es un fichero de sesión PHP. El error se dispara al **deserializar** un objeto `phpupdate` desde la sesión, y el constructor intenta hacer `ob_start()` (output buffering) durante un handler de output ya activo — operación prohibida. ## Por qué huele a malware - No hay ninguna `class phpupdate` declarada en el árbol Joomla actual (verificado en `/web/` remoto y `joomla-php83/` local). - La sesión deserializa un objeto cuya clase NO existe en el código del sitio → o vino de un plugin desinstalado o lo metió código externo. - El nombre `phpupdate` simula un componente de actualización del sistema. Patrón habitual de cloaking. ## Lo que NO sabemos todavía - Contenido del fichero de sesión (permisos restrictivos en `/usr/home/feadulta.com/tmp/`). - Si la sesión es huérfana de algún plugin desinstalado (ej. mySites.guru/bfnetwork ya retirado) o si hay backdoor activo creándolas. - Si solo hay esa sesión o muchas con la misma firma. - Si la clase `phpupdate` se llega a cargar dinámicamente (require/autoload) desde algún punto. ## Líneas de investigación 1. Leer contenido del fichero de sesión (probar paths alternativos o desde root del jail). 2. Listar `tmp/` y `cache/` buscando otras `ssess_*` con `phpupdate`. 3. Grep recursivo de `phpupdate` (no solo `class phpupdate`) en todo `/web/`. 4. Revisar `cli/`, `tmp/`, `cache/`, `administrator/cache/`, sesiones DB y cualquier sitio donde se serializan objetos. 5. Si encontramos la clase: analizar qué hace (probable cron de re-infección o C2). 6. Si no la encontramos: la sesión es huérfana → vaciar `tmp/ssess_*` resuelve el síntoma. ## Relación con #46 #46 limpió 7 inyecciones SEO en `templates/fe_adulta_1/index.php` + barrido general que no encontró webshells. Este hallazgo apunta a una segunda vía de persistencia (vía sesiones) que el barrido estático no podía ver. Trato como follow-up de seguridad de #46. ## Prioridad Alta. Aunque el síntoma actual es solo un fatal en log (no afecta UX), si hay malware activo creando sesiones con su clase es un compromiso vivo que debe cerrarse antes del cutover DNS.
rafa closed this issue 2026-06-28 19:13:59 +00:00
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: rafa/feadulta#65