{"id":5144,"date":"2024-09-04T15:18:54","date_gmt":"2024-09-04T20:18:54","guid":{"rendered":"https:\/\/www.darkreading.com\/application-security\/revival-hijack-on-pypi-disguises-malware-with-legitimate-file-names"},"modified":"2024-09-04T15:18:54","modified_gmt":"2024-09-04T20:18:54","slug":"revival-hijack-on-pypi-disguises-malware-with-legitimate-file-names","status":"publish","type":"post","link":"https:\/\/ddi.mohflo.net\/index.php\/2024\/09\/04\/revival-hijack-on-pypi-disguises-malware-with-legitimate-file-names\/","title":{"rendered":"&#8216;Revival Hijack&#8217; on PyPI Disguises Malware with Legitimate File Names"},"content":{"rendered":"<div class=\"media_block\"><a href=\"https:\/\/i0.wp.com\/eu-images.contentstack.com\/v3\/assets\/blt6d90778a997de1cd\/blt1acf8b621fa9bc83\/66d8b47cc929b203eb46cd20\/software_Zakharchuk_shutterstock.jpg?ssl=1\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/ddi.mohflo.net\/wp-content\/uploads\/2024\/09\/revival-hijack-on-pypi-disguises-malware-with-legitimate-file-names.jpg?w=640&#038;ssl=1\" class=\"media_thumbnail\"><\/a><\/div>\n<div><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/ddi.mohflo.net\/wp-content\/uploads\/2024\/09\/revival-hijack-on-pypi-disguises-malware-with-legitimate-file-names.jpg?w=640&#038;ssl=1\" class=\"ff-og-image-inserted\"><\/div>\n<p class=\"ContentParagraph ContentParagraph_align_left\" data-testid=\"content-paragraph\"><span class=\"ContentText ContentText_variant_bodyNormal\" data-testid=\"content-text\">Security researchers have discovered a simple and troubling way for attackers to distribute malicious payloads via the PyPI package repository.<\/span><\/p>\n<p class=\"ContentParagraph ContentParagraph_align_left\" data-testid=\"content-paragraph\"><span class=\"ContentText ContentText_variant_bodyNormal\" data-testid=\"content-text\">All that the technique involves is re-registering a malicious package on PyPI using the same name as any legitimate, previously registered but now removed package from the repository and then waiting for organizations to download it. Since PyPI does not prohibit the reuse of names of removed packages, it&#8217;s easy for adversaries to pass off rogue packages that once were available on the registry as legitimate ones.<\/span><\/p>\n<h2 class=\"ContentText ContentText_variant_h2 ContentText_align_left\" data-testid=\"content-text\" id=\"Revival Hijack\">Revival Hijack<\/h2>\n<p class=\"ContentParagraph ContentParagraph_align_left\" data-testid=\"content-paragraph\"><span class=\"ContentText ContentText_variant_bodyNormal\" data-testid=\"content-text\">&#8220;The &#8216;Revival Hijack&#8217; method can be used by attackers as an easy supply chain attack, targeting organizations and infiltrating a wide variety of environments,&#8221; researchers at <\/span><span class=\"ContentText ContentText_variant_bodyNormal\" data-testid=\"content-text\"><a class=\"ContentText-BodyTextChunk ContentText-BodyTextChunk_link\" target=\"_blank\" href=\"https:\/\/jfrog.com\/blog\/revival-hijack-pypi-hijack-technique-exploited-22k-packages-at-risk\/#summary\" rel=\"noopener\">JFrog warned in a report<\/a><\/span><span class=\"ContentText ContentText_variant_bodyNormal\" data-testid=\"content-text\"> this week. &#8220;PyPI users should stay vigilant and make sure their CI\/CD machines are not trying to install packages that were already removed from PyPI,&#8221; they noted, after recently discovering a threat actor using the tactic in an apparent attempt to distribute malware.<\/span><\/p>\n<p class=\"ContentParagraph ContentParagraph_align_left\" data-testid=\"content-paragraph\"><span class=\"ContentText ContentText_variant_bodyNormal\" data-testid=\"content-text\">The attack method that JFrog discovered is one of several that adversaries have used in recent years to try and sneak malware into enterprise environments via public code repositories such as PyPI, npm, Maven Central, NuGet, and RubyGems. Common tactics have included <\/span><span class=\"ContentText ContentText_variant_bodyNormal\" data-testid=\"content-text\"><a class=\"ContentText-BodyTextChunk ContentText-BodyTextChunk_link\" target=\"_blank\" href=\"https:\/\/www.darkreading.com\/application-security\/millions-of-malicious-repositories-flood-github\" rel=\"noopener\">cloning and infecting<\/a><\/span><span class=\"ContentText ContentText_variant_bodyNormal\" data-testid=\"content-text\"> popular repositories, <\/span><span class=\"ContentText ContentText_variant_bodyNormal\" data-testid=\"content-text\"><a class=\"ContentText-BodyTextChunk ContentText-BodyTextChunk_link\" target=\"_blank\" href=\"https:\/\/www.darkreading.com\/application-security\/millions-of-malicious-repositories-flood-github\" rel=\"noopener\">poisoning artifacts,<\/a><\/span><span class=\"ContentText ContentText_variant_bodyNormal\" data-testid=\"content-text\"> and looking for and <\/span><span class=\"ContentText ContentText_variant_bodyNormal\" data-testid=\"content-text\"><a class=\"ContentText-BodyTextChunk ContentText-BodyTextChunk_link\" target=\"_blank\" href=\"https:\/\/www.darkreading.com\/application-security\/leaked-development-secrets-a-major-issue-for-repositories\" rel=\"noopener\">leveraging leaked secrets<\/a><\/span><span class=\"ContentText ContentText_variant_bodyNormal\" data-testid=\"content-text\"> like private keys and database certificates in attacks.<\/span><\/p>\n<p class=\"ContentParagraph ContentParagraph_align_left\" data-testid=\"content-paragraph\"><span class=\"ContentText ContentText_variant_bodyNormal\" data-testid=\"content-text\">Threat actors have also attempted to trick developers into accidentally installing malicious packages by exploiting common typing errors or using slight variations in the name of a legitimate package (&#8220;g00gle&#8221; instead of &#8220;google,&#8221; for instance). Such <\/span><span class=\"ContentText ContentText_variant_bodyNormal\" data-testid=\"content-text\"><a class=\"ContentText-BodyTextChunk ContentText-BodyTextChunk_link\" target=\"_blank\" href=\"https:\/\/www.darkreading.com\/threat-intelligence\/typosquatting-wave-shows-no-signs-of-abating\" rel=\"noopener\">typosquatting attacks<\/a><\/span><span class=\"ContentText ContentText_variant_bodyNormal\" data-testid=\"content-text\"> continue unabated, despite efforts by organizations and the maintainers of PyPI and other registries to protect against them.<\/span><\/p>\n<p class=\"ContentParagraph ContentParagraph_align_left\" data-testid=\"content-paragraph\"><span class=\"ContentText ContentText_variant_bodyNormal\" data-testid=\"content-text\">The challenge with Revival Hijack is that the technique does not rely on a victim making a mistake, as is typically the case with typosquatting and some of the other attack methods. &#8220;Updating a &#8216;once safe&#8217; package to its latest version is viewed as a safe operation by many users (although it shouldn&#8217;t!),&#8221; JFrog noted. &#8220;Many CI\/CD machines are already set up to install these packages automatically.&#8221;<\/span><\/p>\n<h2 class=\"ContentText ContentText_variant_h2 ContentText_align_left\" data-testid=\"content-text\" id=\"Reusing Abandoned Package Names\">Reusing Abandoned Package Names<\/h2>\n<p class=\"ContentParagraph ContentParagraph_align_left\" data-testid=\"content-paragraph\"><span class=\"ContentText ContentText_variant_bodyNormal\" data-testid=\"content-text\">According to JFrog, when a developer removes a project from PyPI, the associated package names become immediately available for anyone else to use. This means an attacker can easily hijack the package names and infect any user of the original packages that might try to update to the latest version. Any user that might want to install it for the first time on the assumption that it is the original would be similarly affected.<\/span><\/p>\n<p class=\"ContentParagraph ContentParagraph_align_left\" data-testid=\"content-paragraph\"><span class=\"ContentText ContentText_variant_bodyNormal\" data-testid=\"content-text\">To test the effectiveness of the attack vector, JFrog researchers first created an empty project and published it to PyPI as &#8220;revival-package version 1.0.0,&#8221; using a test &#8220;origin_author&#8221; account. After publishing the project, the researchers removed it from PyPI and almost immediately published another empty package with the same name to PyPI, but from a different &#8220;new_authr&#8221; account and different version number 4.0.0.<\/span><\/p>\n<p class=\"ContentParagraph ContentParagraph_align_left\" data-testid=\"content-paragraph\"><span class=\"ContentText ContentText_variant_bodyNormal\" data-testid=\"content-text\">The exercise showed PyPI displaying JFrog&#8217;s second empty package simply as a new version of the company&#8217;s original &#8220;revival-package&#8221; with no indication that it contained very different code. Had JFrog&#8217;s original package actually been legitimate code that developers were using, a CI\/CD system would have downloaded the &#8220;new&#8221; version on the assumption it was an update.<\/span><\/p>\n<p class=\"ContentParagraph ContentParagraph_align_left\" data-testid=\"content-paragraph\"><span class=\"ContentText ContentText_variant_bodyNormal\" data-testid=\"content-text\">&#8220;After demonstrating that hijacking removed legitimate packages can be easily done, [we] decided to analyze how many packages on PyPI were susceptible to &#8216;Revival Hijack,&#8217; meaning that they were previously removed and can now be replaced\/hijacked,&#8221; JFrog said.<\/span><\/p>\n<h2 class=\"ContentText ContentText_variant_h2 ContentText_align_left\" data-testid=\"content-text\" id=\"A Clear and Present Threat\">A Clear and Present Threat<\/h2>\n<p class=\"ContentParagraph ContentParagraph_align_left\" data-testid=\"content-paragraph\"><span class=\"ContentText ContentText_variant_bodyNormal\" data-testid=\"content-text\">The JFrog researchers&#8217; search showed a staggering 120,000 removed packages that attackers could potentially hijack to sneak malware onto PyPI. When the researchers filtered the results to only include packages that had been active for at least months or that users had previously downloaded more than 100,000 times, that number dropped to around 22,000 packages.<\/span><\/p>\n<p class=\"ContentParagraph ContentParagraph_align_left\" data-testid=\"content-paragraph\"><span class=\"ContentText ContentText_variant_bodyNormal\" data-testid=\"content-text\">To prevent adversaries from misusing these abandoned package names, JFrog researchers &#8220;hijacked&#8221; the most popular of these packages and replaced them with empty ones. They also ensured that the version number on all the empty packages was 0.0.0.1, to ensure that no one using the original packages would accidentally download the empty package as an update.<\/span><\/p>\n<p class=\"ContentParagraph ContentParagraph_align_left\" data-testid=\"content-paragraph\"><span class=\"ContentText ContentText_variant_bodyNormal\" data-testid=\"content-text\">Even despite this precaution JFrog&#8217;s empty packages racked up nearly 200,000 automatic and manual downloads over a three-month period, showing that the Revival Hijack threat is very real, the security vendor said. &#8220;This seems to indicate that there are outdated jobs and scripts out there which are still looking for the deleted packages, or users that manually downloaded these packages due to typosquatting,&#8221; JFrog said.<\/span><\/p>\n<p class=\"ContentParagraph ContentParagraph_align_left\" data-testid=\"content-paragraph\"><span class=\"ContentText ContentText_variant_bodyNormal\" data-testid=\"content-text\">In an actual attack scenario, an adversary would have likely attached a high version number to each hijacked package so CI\/CD systems would automatically download them believing them to be updates, JFrog said. The company has recommended that PyPI completely prohibit the reuse of abandoned package names. Organizations using PyPI also need to be aware of this attack vector when upgrading to new package versions, JFrog warned.<\/span><\/p>\n<p><a href=\"https:\/\/www.darkreading.com\/application-security\/revival-hijack-on-pypi-disguises-malware-with-legitimate-file-names\">Source<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Security researchers have discovered a simple and troubling way for<\/p>\n","protected":false},"author":12,"featured_media":5145,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[1],"tags":[809],"class_list":["post-5144","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-dark-reading"],"featured_image_urls":{"full":["https:\/\/i0.wp.com\/ddi.mohflo.net\/wp-content\/uploads\/2024\/09\/revival-hijack-on-pypi-disguises-malware-with-legitimate-file-names.jpg?fit=1920%2C1080&ssl=1",1920,1080,false],"thumbnail":["https:\/\/i0.wp.com\/ddi.mohflo.net\/wp-content\/uploads\/2024\/09\/revival-hijack-on-pypi-disguises-malware-with-legitimate-file-names.jpg?resize=150%2C150&ssl=1",150,150,true],"medium":["https:\/\/i0.wp.com\/ddi.mohflo.net\/wp-content\/uploads\/2024\/09\/revival-hijack-on-pypi-disguises-malware-with-legitimate-file-names.jpg?fit=300%2C169&ssl=1",300,169,true],"medium_large":["https:\/\/i0.wp.com\/ddi.mohflo.net\/wp-content\/uploads\/2024\/09\/revival-hijack-on-pypi-disguises-malware-with-legitimate-file-names.jpg?fit=640%2C360&ssl=1",640,360,true],"large":["https:\/\/i0.wp.com\/ddi.mohflo.net\/wp-content\/uploads\/2024\/09\/revival-hijack-on-pypi-disguises-malware-with-legitimate-file-names.jpg?fit=640%2C360&ssl=1",640,360,true],"1536x1536":["https:\/\/i0.wp.com\/ddi.mohflo.net\/wp-content\/uploads\/2024\/09\/revival-hijack-on-pypi-disguises-malware-with-legitimate-file-names.jpg?fit=1536%2C864&ssl=1",1536,864,true],"2048x2048":["https:\/\/i0.wp.com\/ddi.mohflo.net\/wp-content\/uploads\/2024\/09\/revival-hijack-on-pypi-disguises-malware-with-legitimate-file-names.jpg?fit=1920%2C1080&ssl=1",1920,1080,true],"chromenews-featured":["https:\/\/i0.wp.com\/ddi.mohflo.net\/wp-content\/uploads\/2024\/09\/revival-hijack-on-pypi-disguises-malware-with-legitimate-file-names.jpg?fit=1024%2C576&ssl=1",1024,576,true],"chromenews-large":["https:\/\/i0.wp.com\/ddi.mohflo.net\/wp-content\/uploads\/2024\/09\/revival-hijack-on-pypi-disguises-malware-with-legitimate-file-names.jpg?resize=825%2C575&ssl=1",825,575,true],"chromenews-medium":["https:\/\/i0.wp.com\/ddi.mohflo.net\/wp-content\/uploads\/2024\/09\/revival-hijack-on-pypi-disguises-malware-with-legitimate-file-names.jpg?resize=590%2C410&ssl=1",590,410,true]},"author_info":{"display_name":"Dark Reading","author_link":"https:\/\/ddi.mohflo.net\/index.php\/author\/darkreading\/"},"category_info":"<a href=\"https:\/\/ddi.mohflo.net\/index.php\/category\/uncategorized\/\" rel=\"category tag\">Uncategorized<\/a>","tag_info":"Uncategorized","comment_count":"0","jetpack_featured_media_url":"https:\/\/i0.wp.com\/ddi.mohflo.net\/wp-content\/uploads\/2024\/09\/revival-hijack-on-pypi-disguises-malware-with-legitimate-file-names.jpg?fit=1920%2C1080&ssl=1","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/ddi.mohflo.net\/index.php\/wp-json\/wp\/v2\/posts\/5144","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ddi.mohflo.net\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ddi.mohflo.net\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ddi.mohflo.net\/index.php\/wp-json\/wp\/v2\/users\/12"}],"replies":[{"embeddable":true,"href":"https:\/\/ddi.mohflo.net\/index.php\/wp-json\/wp\/v2\/comments?post=5144"}],"version-history":[{"count":0,"href":"https:\/\/ddi.mohflo.net\/index.php\/wp-json\/wp\/v2\/posts\/5144\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/ddi.mohflo.net\/index.php\/wp-json\/wp\/v2\/media\/5145"}],"wp:attachment":[{"href":"https:\/\/ddi.mohflo.net\/index.php\/wp-json\/wp\/v2\/media?parent=5144"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ddi.mohflo.net\/index.php\/wp-json\/wp\/v2\/categories?post=5144"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ddi.mohflo.net\/index.php\/wp-json\/wp\/v2\/tags?post=5144"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}