{"id":442,"date":"2024-12-27T15:34:09","date_gmt":"2024-12-27T15:34:09","guid":{"rendered":"https:\/\/fin3ss3g0d.net\/?p=442"},"modified":"2024-12-27T16:00:09","modified_gmt":"2024-12-27T16:00:09","slug":"static-keys-shattered-security-dreams-a-cve-2024-5764-story","status":"publish","type":"post","link":"https:\/\/fin3ss3g0d.net\/index.php\/2024\/12\/27\/static-keys-shattered-security-dreams-a-cve-2024-5764-story\/","title":{"rendered":"Static Keys, Shattered Security Dreams: A CVE-2024\u20135764 Story"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-post\" data-elementor-id=\"442\" class=\"elementor elementor-442\">\n\t\t\t\t<div class=\"elementor-element elementor-element-5603a8a e-flex e-con-boxed e-con e-parent\" data-id=\"5603a8a\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-d66f094 elementor-widget elementor-widget-text-editor\" data-id=\"d66f094\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<section>\n<div><img decoding=\"async\" class=\"aligncenter\" style=\"font-style: inherit; font-weight: inherit; text-align: var(--text-align); color: var( --e-global-color-text ); font-family: var( --e-global-typography-text-font-family ), Sans-serif; background-color: var(--ast-global-color-5);\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/0*ADTADvUJ5GnEmO4Q\" data-image-id=\"0*ADTADvUJ5GnEmO4Q\" data-width=\"488\" data-height=\"621\" data-is-featured=\"true\"><\/div>\n<div>\n<p><br><\/p><p>Red teaming is all about seizing opportunities, and in a recent assessment, we did just that. We came across a Sonatype Nexus Repository 3 instance\u200a\u2014\u200aperfect timing, as a fresh vulnerability (CVE-2024\u20134956) was burning a hole in our pocket thanks to a timely tip-off from Phithon (@phithon_xg) on <a href=\"https:\/\/x.com\/phithon_xg\/status\/1793517567560335428\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/x.com\/phithon_xg\/status\/1793517567560335428\">X<\/a>.<\/p><p><br><\/p>\n<p><\/p>\n<figure><img decoding=\"async\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/0*nAqwO6iUqDSKYXmR\" data-image-id=\"0*nAqwO6iUqDSKYXmR\" data-width=\"590\" data-height=\"506\"><\/figure>\n<p><\/p>\n<p><br><\/p><p>This unauthenticated path traversal flaw had the potential to expose critical files on the server, and we couldn\u2019t resist taking a closer look. After some creative maneuvering, we successfully accessed the system\u2019s file structure and began pulling back some intriguing finds. Among the files we retrieved were OrientDB&nbsp;.pcl files, containing a treasure trove of encrypted secrets and password hashes.<\/p>\n<p>As we unraveled the data, we uncovered another issue now known as CVE-2024\u20135764. Security researchers at Maveris were the first to discover the issue and report it to Sonatype. The encryption protecting these secrets relied on a static key\u200a\u2014\u200ahidden in plain sight within the public source code. With this key in hand, we managed to decrypt sensitive information, exposing flaws that could allow attackers to pivot to other systems by obtaining credentials.<\/p>\n<p>In this post, we\u2019ll walk you through how we exploited both vulnerabilities, from initial access to the ultimate discovery of CVE-2024\u20135764. Buckle up as we dive into the details and reveal how these critical missteps can expose environments to serious risk.<\/p>\n<figure><img decoding=\"async\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/0*a45AHy_Grsy43sQN\" data-image-id=\"0*a45AHy_Grsy43sQN\" data-width=\"1024\" data-height=\"1024\"><\/figure>\n<h3>Unauthenticated Path Traversal Exploitation<\/h3>\n<p>Once we spotted the Nexus Repository Manager instance in the environment, we knew it was game on. With CVE-2024\u20134956 in our arsenal, we quickly spun up a vulnerable Docker instance to test exploitation.<\/p><p><br><\/p>\n<p><\/p>\n<figure><img decoding=\"async\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/0*YmCfziMDDI583Ijc\" data-image-id=\"0*YmCfziMDDI583Ijc\" data-width=\"650\" data-height=\"195\"><\/figure>\n<p><\/p>\n<p><br><\/p><p>We launched our attack against the test server, expecting quick success. But, as is often the case, the path wasn\u2019t as straightforward as we hoped:<\/p><p><br><\/p>\n<p><\/p>\n<figure><img decoding=\"async\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/0*_kzakHGJhQuBtPMm\" data-image-id=\"0*_kzakHGJhQuBtPMm\" data-width=\"1600\" data-height=\"1363\"><\/figure>\n<p><\/p>\n<p><br><\/p><p>It was time to get creative. Realizing the manual approach wasn\u2019t cutting it, we switched tactics and began creating a <a href=\"https:\/\/github.com\/fin3ss3g0d\/CVE-2024-4956\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/github.com\/fin3ss3g0d\/CVE-2024-4956\">Python script<\/a> to automate the exploitation process. By programmatically walking the directory paths, we finally struck gold\u200a\u2014\u200asuccessfully exfiltrating<em> \/etc\/passwd<\/em> and confirming the vulnerability:<\/p><p><br><\/p>\n<p><\/p>\n<figure><img decoding=\"async\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/0*p4nUWN-oZvPbWldb\" data-image-id=\"0*p4nUWN-oZvPbWldb\" data-width=\"1339\" data-height=\"1027\"><\/figure><figure><br><\/figure>\n<figure><\/figure>\n<figure><img decoding=\"async\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/0*oEVN5ExvZR0wTDv2\" data-image-id=\"0*oEVN5ExvZR0wTDv2\" data-width=\"1226\" data-height=\"717\"><\/figure>\n<h3>OrientDB<\/h3>\n<p>With this initial win under our belt, we decided to dive deeper. This led to taking a look at the database Repository Manager 3 was using. At the time we discovered the vulnerability, it used OrientDB by default, but now OrientDB has been deprecated according to the information <a href=\"https:\/\/help.sonatype.com\/en\/database-options.html\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/help.sonatype.com\/en\/database-options.html\">here<\/a>.<\/p><p><br><\/p>\n<p><\/p>\n<figure><img decoding=\"async\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/0*BfGhZWABkMhCdwMx\" data-image-id=\"0*BfGhZWABkMhCdwMx\" data-width=\"1600\" data-height=\"1536\"><\/figure>\n<p><\/p>\n<p><br><\/p><p>Not to worry as all versions from 3.0.0 up to 3.71.0 use OrientDB and CVE-2024\u20135746 impacts versions 3.0.0 through 3.72.0, so this is good for our blog piece. Understanding that Repository Manager 3 uses OrientDB (up to 3.71.0) is a key piece of information as it allows us to dissect the structure of the database for potential abuse cases. The key pieces of information were:<\/p>\n<p>In OrientDB, a <a href=\"https:\/\/orientdb.com\/docs\/latest\/internals\/Clusters.html\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/orientdb.com\/docs\/latest\/internals\/Clusters.html\">cluster<\/a> is a fundamental storage unit that groups related records (such as documents or vertices) together within a database.<\/p><p><br><\/p>\n<p><\/p>\n<figure><img decoding=\"async\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/0*O62z0XRr-v4uq-sS\" data-image-id=\"0*O62z0XRr-v4uq-sS\" data-width=\"1181\" data-height=\"511\"><\/figure><figure><br><\/figure>\n<figure><\/figure>\n<p>Each OrientDB database is made up of multiple clusters, each of which stores data associated with specific classes (tables, in SQL terms). Clusters allow OrientDB to manage data at scale, distributing it across storage segments for efficient retrieval and manipulation.<\/p>\n<p>OrientDB uses <a href=\"https:\/\/www.orientdb.org\/docs\/3.0.x\/internals\/Paginated-Local-Storage.html\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/www.orientdb.org\/docs\/3.0.x\/internals\/Paginated-Local-Storage.html\">Plocal<\/a> storage, which stands for \u201cPaginated Local\u201d storage, a binary format optimized for high-performance disk I\/O. In this format, OrientDB stores each cluster\u2019s data in its own&nbsp;.pcl file, making it the primary container for the records associated with that cluster. These&nbsp;.pcl files contain raw, serialized records stored in binary format, representing anything from documents to edges and vertices in the graph.<\/p>\n<p>Basically, we knew that files ending with the&nbsp;.pcl extension were going to contain the cluster records data for the database in actual files on disk and we could access data in the database while being unauthenticated via the directory traversal vulnerability. Bingo!<\/p><p><br><\/p>\n<p><\/p>\n<figure><img decoding=\"async\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/0*U3cXt9_SqjFkBIUa\" data-image-id=\"0*U3cXt9_SqjFkBIUa\" data-width=\"1024\" data-height=\"1024\"><\/figure><figure><br><\/figure>\n<p><\/p>\n<p>With this information in hand, it is possible to issue a simple <em>find<\/em> command to find all of the&nbsp;.pcl files within the server directory:<\/p><p><br><\/p>\n<p><\/p>\n<figure><img decoding=\"async\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/0*6QizeMDAo_kF3M7d\" data-image-id=\"0*6QizeMDAo_kF3M7d\" data-width=\"745\" data-height=\"1103\"><\/figure>\n<p><\/p>\n<p><br><\/p><p>Looking at the filenames, some of them piqued our interest. Notably, some files under <em>nexus3\/db\/config<\/em> including <em>email.pcl<\/em>, <em>http_client.pcl<\/em>, and <em>ldap_&lt;INTEGER&gt;.pcl<\/em>. We suspected these would contain configuration details and possibly credentials pertaining to Email Server, HTTP, and LDAP in the web console. We decided to fill out some dummy settings for these configurations on our test server.<\/p><p><br><\/p>\n<p><\/p>\n<figure><img decoding=\"async\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/0*EhPmM6bPI6iLoWkO\" data-image-id=\"0*EhPmM6bPI6iLoWkO\" data-width=\"1600\" data-height=\"1536\"><\/figure><figure><br><\/figure>\n<figure><\/figure>\n<figure><img decoding=\"async\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/0*fOVGA98-tmY-NGxR\" data-image-id=\"0*fOVGA98-tmY-NGxR\" data-width=\"1600\" data-height=\"1536\"><\/figure><figure><br><\/figure>\n<figure><\/figure>\n<figure><img decoding=\"async\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/0*djcpG5Ro_m_sQByl\" data-image-id=\"0*djcpG5Ro_m_sQByl\" data-width=\"1600\" data-height=\"1536\"><\/figure>\n<p><\/p>\n<p><br><\/p><p>After filling out the dummy data, we then decided to take a look at the files mentioned previously by concatenating their contents. Seen below is displaying the contents of <em>email.pcl<\/em>.<\/p><p><br><\/p>\n<p><\/p>\n<figure><img decoding=\"async\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/0*C1ejpVZHHCwEDSzc\" data-image-id=\"0*C1ejpVZHHCwEDSzc\" data-width=\"1600\" data-height=\"150\"><\/figure>\n<p><\/p>\n<p><br><\/p><p>We noticed right away what appeared to be encrypted\/hashed strings surrounded by curly braces inside of the <em>email.pcl<\/em> file after configuring SMTP credentials under the Email Server tab of the web console. We noticed a similar pattern for the <em>http_client.pcl <\/em>and <em>ldap_&lt;INTEGER&gt;.pcl<\/em> files.<\/p><p><br><\/p>\n<p><\/p>\n<figure><img decoding=\"async\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/0*kxXrCNqGYjusfW-a\" data-image-id=\"0*kxXrCNqGYjusfW-a\" data-width=\"1468\" data-height=\"967\"><\/figure><figure><br><\/figure>\n<p><\/p>\n<p>Following this discovery, we decided to take a look at the public source code for the community edition of Sonatype Nexus Repository Manager 3, which is hosted on GitHub <a href=\"https:\/\/github.com\/sonatype\/nexus-public\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/github.com\/sonatype\/nexus-public\">here<\/a> in an attempt to identify the encryption\/hashing logic for these strings.<\/p>\n<h3>Source Code&nbsp;Analysis<\/h3>\n<p>We quickly identified the code base was using MyBatis as an ORM for OrientDB and we were able to hone in on some code that appeared to be handling the encryption of passwords in the database.<\/p><p><br><\/p>\n<p><\/p>\n<figure><img decoding=\"async\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/0*BSIUrwRG3xogprO9\" data-image-id=\"0*BSIUrwRG3xogprO9\" data-width=\"1600\" data-height=\"659\"><\/figure>\n<figure><\/figure>\n<p><br><\/p><p>The class responsible for this encryption was named <em>PasswordHelper<\/em>. A recursive <em>grep <\/em>command throughout the source directory can reveal all files using the class and can be seen below. We will be taking a closer look at some of the files in the output, so make note of the file names as they will correlate to classes we observe.<\/p><p><br><\/p>\n<p><\/p>\n<figure><img decoding=\"async\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/0*_br_bY5bqvlf7ig7\" data-image-id=\"0*_br_bY5bqvlf7ig7\" data-width=\"1600\" data-height=\"637\"><\/figure>\n<p><\/p>\n<p><br><\/p><p>Taking a look at the <em>PasswordHelper <\/em>class itself and the <em>encrypt <\/em>method, there are some interesting things of note. The class has three variables that are members of the class including <em>ENC<\/em>, <em>mavenCipher<\/em>, and <em>phraseService<\/em>. In the call to the <em>encrypt <\/em>method of the <em>MavenCipher <\/em>object, the password to be encrypted is passed as an argument along with the return value from <em>phraseService.getPhrase(ENC)<\/em>.<\/p><p><br><\/p>\n<p><\/p>\n<figure><img decoding=\"async\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/0*NgHNyzoIRbrjqY68\" data-image-id=\"0*NgHNyzoIRbrjqY68\" data-width=\"1153\" data-height=\"1028\"><\/figure>\n<p><\/p>\n<p><br><\/p><p>The method signature for <em>encrypt <\/em>and the <em>MavenCipher <\/em>class implementation can be seen below. The takeaway here is that the string passed as <em>passPhrase <\/em>will be the password for encryption.<\/p><p><br><\/p>\n<p><\/p>\n<figure><img decoding=\"async\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/0*Xa-16DRRWwnvHYik\" data-image-id=\"0*Xa-16DRRWwnvHYik\" data-width=\"1320\" data-height=\"889\"><\/figure>\n<p><\/p>\n<p><br><\/p><p>If your senses are tingling like mine are at this moment, you are interested in the logic of <em>getPhrase <\/em>and the use of a static string value being passed to it. On the surface, it looks like the makings for a static encryption password responsible for encrypting other passwords and sensitive data in a database. Sounds like no encryption to me!<\/p><p><br><\/p>\n<p><\/p>\n<figure><img decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/0*gPHbMxT4PDbH3eUU\" data-image-id=\"0*gPHbMxT4PDbH3eUU\" data-width=\"480\" data-height=\"320\"><\/figure>\n<figure><\/figure>\n<p><br><\/p>\n<p>Let\u2019s verify our assumptions though. Ultimately, the <em>getPhrase <\/em>logic can be seen below in the <em>AbstractPhraseService <\/em>class.<\/p><p><br><\/p>\n<p><\/p>\n<figure><img decoding=\"async\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/0*_GQhVHdwAN4F_rsx\" data-image-id=\"0*_GQhVHdwAN4F_rsx\" data-width=\"878\" data-height=\"1274\"><\/figure>\n<p><\/p>\n<p><br><\/p><p>The logic of <em>getPhrase <\/em>is simple: if <em>hasMasterPhrase <\/em>is <em>true<\/em>, the value of <em>getMasterPhrase <\/em>is returned, otherwise defaultPhrase is returned. As you might imagine, in this context this means the static string (ENC) value is used for all password\/secret encryption unless a custom password is specified by an administrator.<\/p>\n<p>Remember that <em>mark <\/em>method I outlined earlier? That is also of serious interest here. The reason being the developers are tracking encrypted passwords\/secrets using \u201clegacy\u201d encryption (a.k.a. using a static encryption password) so that they can decrypt them using the static password later on. This is interesting because it is an indicator that there is no functionality to re-encrypt all data in the database with a custom password created by an administrator. If there was, this marking strategy wouldn\u2019t be necessary. This theory was verified in collaboration with one of our clients, then later verified by Sonatype.<\/p>\n<p>We can also verify the sensitive attributes filters used for <em>encryptSensitiveFields <\/em>in the MyBatis code along with the <em>SensitiveJsonFactory <\/em>class.<\/p><p><br><\/p>\n<p><\/p>\n<figure><img decoding=\"async\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/0*3P1k1s7Ji1DKwwWh\" data-image-id=\"0*3P1k1s7Ji1DKwwWh\" data-width=\"1335\" data-height=\"1152\"><\/figure>\n<figure><img decoding=\"async\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/0*gKBkb0O-Y4t0Sa0K\" data-image-id=\"0*gKBkb0O-Y4t0Sa0K\" data-width=\"1343\" data-height=\"1413\"><\/figure>\n<p><\/p>\n<p><br><\/p><p>This would indicate all passwords\/secrets stored in JSON data processed by MyBatis are using this encryption logic based on a static hardcoded key. This logic would encapsulate all passwords\/secrets except for the HTTP proxy credentials and the SMTP configuration credentials. An example of this is shown below with <em>OrientEmailConfigurationEntityAdapter <\/em>class.<\/p><p><br><\/p>\n<p><\/p>\n<figure><img decoding=\"async\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/0*0JBY5X-l07FnCCZt\" data-image-id=\"0*0JBY5X-l07FnCCZt\" data-width=\"1384\" data-height=\"1598\"><\/figure>\n<p><\/p>\n<p><br><\/p><p>The SMTP password is encrypted using this logic as shown above. The same can be said for the HTTP proxy configuration details. Seen below is the serialization logic for the HTTP proxy configuration.<\/p><p><br><\/p>\n<p><\/p>\n<figure><img decoding=\"async\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/0*oWm1dI4HO_MW3pyl\" data-image-id=\"0*oWm1dI4HO_MW3pyl\" data-width=\"1470\" data-height=\"770\"><\/figure>\n<p><\/p>\n<p><br><\/p><p>As you can see, depending on the authentication type used, the logic will either encrypt the password for a basic\/NTLM authentication using <em>PasswordHelper<\/em>, or a bearer token. With all of our discoveries so far and our suspicions after source code review, it\u2019s time to put everything to the test and see if the encrypted strings we found earlier are using that static encryption key. The encryption wrappers ultimately lead to the <em>encrypt <\/em>method of the <em>PasswordCipher <\/em>class and can be seen below.<\/p><p><br><\/p>\n<p><\/p>\n<figure><img decoding=\"async\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/0*w44OQ35ztqMHPRht\" data-image-id=\"0*w44OQ35ztqMHPRht\" data-width=\"1110\" data-height=\"1600\"><\/figure>\n<p><\/p>\n<p><br><\/p><p>There are multiple ways to go about testing the static encryption key. If you want the fastest testing, they include their own encryption tests for use with Maven and you could run the <em>PasswordHelper <\/em>tests with some modifications. If you want something more dynamic and easier to use, you could create a Python script capable of decrypting the Java encryption logic. We obviously chose the latter and our script can be seen below. It is also hosted on GitHub and available for public download\/use <a href=\"https:\/\/github.com\/fin3ss3g0d\/CVE-2024-5764\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/github.com\/fin3ss3g0d\/CVE-2024-5764\">here<\/a>.<\/p><p><br><\/p>\n<p><\/p>\n<figure><img decoding=\"async\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/0*1e5o87o88j4E_tJu\" data-image-id=\"0*1e5o87o88j4E_tJu\" data-width=\"1471\" data-height=\"1600\"><\/figure>\n<p><\/p>\n<p><br><\/p><p>Remember our dummy LDAP credentials from earlier and how we revealed them from a&nbsp;.pcl file? I couldn\u2019t think of a better test for our script!<\/p><p><br><\/p>\n<p><\/p>\n<figure><img decoding=\"async\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/0*MKYYLnpuVXR8RFoE\" data-image-id=\"0*MKYYLnpuVXR8RFoE\" data-width=\"1600\" data-height=\"228\"><\/figure><figure><br><\/figure>\n<figure><\/figure>\n<figure><img decoding=\"async\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/0*3PEY55ahEmGmlUEo\" data-image-id=\"0*3PEY55ahEmGmlUEo\" data-width=\"1163\" data-height=\"136\"><\/figure>\n<p><\/p>\n<p><br><\/p><p>As you can see, the decryption was successful using the static encryption key we identified in the source code! Mission success! Did someone say lateral movement into Active Directory via decrypted LDAP credentials? How about sending a phish through a trusted SMTP server at an organization with decrypted SMTP credentials to evade email filtering? I like the sound of that!<\/p><p><br><\/p>\n<p><\/p>\n<figure><img decoding=\"async\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/0*FCQyRtZYUtZsisXw\" data-image-id=\"0*FCQyRtZYUtZsisXw\" data-width=\"1024\" data-height=\"1024\"><\/figure>\n<p><\/p>\n<p><br><\/p><p>I know we are having so much fun, but that\u2019s not the only fun we can have here using the directory traversal vulnerability.<\/p><p><br><\/p>\n<p><\/p>\n<figure><img decoding=\"async\" class=\"aligncenter\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/0*hDpsFdav8IeTOehD\" data-image-id=\"0*hDpsFdav8IeTOehD\" data-width=\"501\" data-height=\"498\"><\/figure>\n<p><\/p>\n<p><br><\/p><p>There are also Apache Shiro hashes stored within these&nbsp;.pcl files that are capable of being cracked with a custom hashcat module developed during this research. Read all about this attack vector <a href=\"https:\/\/medium.com\/maverislabs\/crack-faster-hack-smarter-c0c4defbcae7\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/medium.com\/maverislabs\/crack-faster-hack-smarter-c0c4defbcae7\">here<\/a>.<\/p>\n<h3>Remediation Evaluation<\/h3>\n<p>Sonatype has addressed the vulnerability and communicated that the issue has been resolved. Their prompt action is commendable, but I wanted to take a closer look to evaluate the effectiveness of the implemented solutions. Sonatype introduced the ability to perform re-encryption of secrets in the database and released a post outlining the steps for re-encryption <a href=\"https:\/\/help.sonatype.com\/en\/re-encryption-in-nexus-repository.html\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/help.sonatype.com\/en\/re-encryption-in-nexus-repository.html\">here<\/a>. The fix involves setting custom encryption passwords per secret in a JSON file on disk versus the global static, hardcoded key. The problem is the approach still relies on static encryption keys.<\/p><p><br><\/p>\n<p><\/p>\n<figure><img decoding=\"async\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/0*8ojfK7LBtdZTUzqY\" data-image-id=\"0*8ojfK7LBtdZTUzqY\" data-width=\"1024\" data-height=\"1024\"><\/figure>\n<p><\/p>\n<p><br><\/p><p>Below are the steps for re-encryption according to Sonatype:<\/p><p><br><\/p>\n<p><\/p>\n<figure><img decoding=\"async\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/1*ZovNtVgYgBZjjlW1LqcSEw.png\" data-image-id=\"1*ZovNtVgYgBZjjlW1LqcSEw.png\" data-width=\"1077\" data-height=\"1459\"><\/figure>\n<p><\/p>\n<p><br><\/p><p>You then can inform Nexus about the path to the file by specifying it inside of the <em>nexus.properties<\/em> file or an environment variable.<\/p><p><br><\/p>\n<figure><img decoding=\"async\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/0*h_aJZFdGqOrFoOLO\" data-image-id=\"0*h_aJZFdGqOrFoOLO\" data-width=\"1090\" data-height=\"760\"><\/figure>\n<p><br><\/p><p>It is a good initiative from Sonatype to create this re-encryption functionality and allow administrators to set custom encryption passwords per secret in the database. If administrators decide to use the functionality and data were to get leaked from a system, attackers will not be able to decrypt it using the default static key without file system access. In other words, it offers <em>some<\/em> protection but is not bulletproof by <em>any<\/em> means.<\/p>\n<p>If an attacker <em>were<\/em> to gain file system access, because they do <em>not<\/em> need to be authenticated to Nexus to view this file or the environment variable (<em>\/proc\/&lt;pid&gt;\/environ<\/em>), they are easily able to view the path and display the contents of the file. Since the file contains all of the encryption passwords in plaintext, an attacker can easily use the decryption script shared earlier to decrypt credentials in the database.<\/p><p><br><\/p>\n<p><\/p>\n<figure><img decoding=\"async\" src=\"https:\/\/cdn-images-1.medium.com\/max\/1200\/0*DpIVEQ-oQe15y-4T\" data-image-id=\"0*DpIVEQ-oQe15y-4T\" data-width=\"1024\" data-height=\"1024\"><\/figure>\n<p><\/p>\n<p><br><\/p><p>During discussions with Sonatype, I explained the use of a global static encryption key that is hardcoded is unnecessary and risky in and of itself. I bring this up because Sonatype is still shipping the application with this default static, hardcoded key until an administrator goes through the re-encryption process. Not all administrators may choose to do the re-encryption for whatever reason and there will still be traces of this key throughout Nexus instances. I suggested a randomly generated key that gets created upon initial installation per instance would be a much better approach, <em>if<\/em> you even wanted to go the route of static encryption keys saved to disk. We very well might see decrypted secrets for years to come due to this static key and installations still coming shipped with it by default.<\/p>\n<h3>Conclusion<\/h3>\n<p>In conclusion, CVE-2024\u20135764 allows anyone with file system access to decrypt passwords\/secrets stored within the Nexus Repository Manager 3 OrientDB database. An administrator can set a custom password at any point, but anything encrypted with the default static passphrase will remain encrypted with the default indefinitely until the instance is patched and re-encryption takes place. This attack vector allows attackers to decrypt highly sensitive information such as passwords\/secrets, allowing access to other systems and can serve as a lateral movement primitive.<\/p>\n<\/div>\n<\/section>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Red teaming is all about seizing opportunities, and in a recent assessment, we did just that. We came across a [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[1],"tags":[],"class_list":["post-442","post","type-post","status-publish","format-standard","hentry","category-blog"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/fin3ss3g0d.net\/index.php\/wp-json\/wp\/v2\/posts\/442","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fin3ss3g0d.net\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fin3ss3g0d.net\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fin3ss3g0d.net\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fin3ss3g0d.net\/index.php\/wp-json\/wp\/v2\/comments?post=442"}],"version-history":[{"count":21,"href":"https:\/\/fin3ss3g0d.net\/index.php\/wp-json\/wp\/v2\/posts\/442\/revisions"}],"predecessor-version":[{"id":464,"href":"https:\/\/fin3ss3g0d.net\/index.php\/wp-json\/wp\/v2\/posts\/442\/revisions\/464"}],"wp:attachment":[{"href":"https:\/\/fin3ss3g0d.net\/index.php\/wp-json\/wp\/v2\/media?parent=442"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fin3ss3g0d.net\/index.php\/wp-json\/wp\/v2\/categories?post=442"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fin3ss3g0d.net\/index.php\/wp-json\/wp\/v2\/tags?post=442"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}