Ένα νέο κύμα επιθέσεων στην αλυσίδα εφοδιασμού πλήττει το οικοσύστημα npm μέσω μιας εκστρατείας κακόβουλου λογισμικού που διαδίδεται μόνος του, γνωστή ως CanisterWorm.
Η απειλή, που συνδέεται με μια ομάδα που παρακολουθείται ως “TeamPCP”, θέτει σε κίνδυνο τους νόμιμους χώρους ονομάτων εκδοτών και ωθεί τις δηλητηριασμένες εκδόσεις πακέτων, μετατρέποντας ουσιαστικά τα αξιόπιστα εργαλεία προγραμματιστών σε σιωπηλούς μηχανισμούς παράδοσης κώδικα κλοπής διαπιστευτηρίων.
Το CanisterWorm ήρθε για πρώτη φορά στο κοινό μέσω πρώιμων αναφορών από ερευνητές ασφαλείας στα Socket and Endor Labs, οι οποίοι εντόπισαν ένα επαναλαμβανόμενο μοτίβο κακόβουλων ενημερώσεων πακέτων σε πολλούς λογαριασμούς εκδοτών npm.
Το κακόβουλο λογισμικό είναι προσεκτικά κρυμμένο μέσα σε αυτό που φαίνεται να είναι συνηθισμένες εκδόσεις SDK, καθιστώντας εύκολο για τους προγραμματιστές να το εγκαταστήσουν χωρίς να εγείρουν καμία υποψία.
Οι ερευνητές του JFrog εντόπισαν νέο, μη αναφερόμενο προηγουμένως παραβιασμένο πακέτο εκδόσεις που συνδέονται με την επίθεση CanisterWorm, επεκτείνοντας το γνωστό εύρος της εκστρατείας πολύ πέρα από αυτό που είχαν καλύψει οι προηγούμενες αποκαλύψεις.
Η συνεχής παρακολούθησή τους έδειξε πρόσθετες επηρεαζόμενες εκδόσεις σε πολλούς χώρους ονομάτων — συμπεριλαμβανομένων των πακέτων που διατηρούνται κάτω @emilgroup και @teale.io — αυτό δεν είχε εντοπιστεί σε προηγούμενες δημόσιες αναφορές.
Ο αντίκτυπος μιας επιτυχημένης μόλυνσης υπερβαίνει κατά πολύ ένα μόνο μηχάνημα. Μόλις ένας προγραμματιστής εγκαταστήσει ένα από τα μολυσμένα πακέτα, το CanisterWorm ρίχνει ένα Η Python κάνει backdoor στον κεντρικό υπολογιστή, αρχίζει να συγκομίζει διακριτικά ελέγχου ταυτότητας npm και χρησιμοποιεί αυτά τα διαπιστευτήρια για να εξαπλωθεί αυτόνομα σε κάθε πακέτο που διατηρεί ο παραβιασμένος προγραμματιστής.
Αυτή η συμπεριφορά αλυσιδωτής αντίδρασης σημαίνει ότι ένας επηρεασμένος λογαριασμός προγραμματιστή μπορεί να γίνει σημείο εκκίνησης για τη δηλητηρίαση δεκάδων μεταγενέστερων πακέτων, θέτοντας σε άμεσο κίνδυνο ένα ευρύ φάσμα εξαρτημένων έργων και των χρηστών τους.
Αυτό που κάνει το CanisterWorm ιδιαίτερα δύσκολο να συγκρατηθεί είναι το πόσο φυσικά αναμιγνύεται σε κανονικές ροές εργασιών ανάπτυξης.
Κρύβοντας πίσω από τις ενημερώσεις εκδόσεων και αξιοποιώντας την αποκεντρωμένη υποδομή για επικοινωνία εντολών, παρακάμπτει τους παραδοσιακούς δείκτες που τα εργαλεία ασφαλείας αναζητούν, επεκτείνοντας αθόρυβα την εμβέλειά του προτού κάποιος παρατηρήσει ότι κάτι δεν πάει καλά.
Μέσα στην αλυσίδα μόλυνσης του σκουληκιού
Η διαδικασία μόλυνσης ξεκινά τη στιγμή που εκτελείται ένας προγραμματιστής npm install σε ένα συμβιβασμένο πακέτο.
Ένα κακόβουλο postinstall γάντζος ενσωματωμένος μέσα στο package.json Το αρχείο εκτελείται αυτόματα και ρίχνει αθόρυβα μια κερκόπορτα Python στο κεντρικό σύστημα χωρίς ορατή προειδοποίηση.
Σε μηχανές Linux, ο ιός τύπου worm καταχωρεί μια μόνιμη υπηρεσία παρασκηνίου με το όνομα pgmon διά μέσου systemdδιασφαλίζοντας ότι παραμένει ενεργό και επιβιώνει από τις επανεκκινήσεις του συστήματος.
Μόλις εγκατασταθεί, η κερκόπορτα μετράει συνεχώς ένα δοχείο πρωτοκόλλου υπολογιστή Διαδικτύου (ICP) — ένα αποκεντρωμένο τελικό σημείο που φιλοξενείται σε blockchain — που λειτουργεί ως διακομιστής εντολών και ελέγχου νεκρής απόθεσης.
Αυτός ο σχεδιασμός κάνει την κακόβουλη επισκεψιμότητα να συνδυάζεται φυσικά με τα κανονικά αιτήματα ιστού, παρεμποδίζοντας σημαντικά τον εντοπισμό από εργαλεία παρακολούθησης δικτύου.
Τα δευτερεύοντα ωφέλιμα φορτία που ανακτώνται μέσω αυτού του καναλιού εγγράφονται σε /tmp/pglogενώ το σκουλήκι παρακολουθεί την κατάσταση εκτέλεσής του μέσα /tmp/.pg_state.
Η πιο επικίνδυνη φάση της επίθεσης είναι η ρουτίνα αυτόνομης εξάπλωσης. Σαρώνει το κακόβουλο λογισμικό .npmrc αρχεία στον κατάλογο του έργου, τον αρχικό φάκελο του χρήστη και τις διαδρομές διαμόρφωσης σε όλο το σύστημα, αναζητώντας _authToken αξίες.
Διαβάζει επίσης το NPM_TOKEN και NPM_TOKENS μεταβλητές περιβάλλοντος. Με αυτά τα κλεμμένα διαπιστευτήρια, ένα ενσωματωμένο deploy.js Η δέσμη ενεργειών θέτει ερωτήματα στο μητρώο npm, εντοπίζει κάθε πακέτο που διατηρεί το θύμα, αυξάνει τον αριθμό έκδοσης της ενημέρωσης κώδικα και δημοσιεύει αυτόματα την αλλοιωμένη ενημέρωση.
Γνωστά παραβιασμένα πακέτα:-
| Όνομα πακέτου | Παραβιασμένες εκδόσεις | Ταυτότητα ακτίνων Χ JFrog |
|---|---|---|
@pypestream/floating-ui-dom |
2.15.1 | XRAY-955001 |
@leafnoise/mirage |
2.0.3 | XRAY-954938 |
@opengov/ppf-backend-types |
1.141.2 | XRAY-954962 |
eslint-config-ppf |
0.128.2 | XRAY-954936 |
react-leaflet-marker-layer |
0.1.5 | XRAY-954942 |
react-leaflet-cluster-layer |
0.0.4 | XRAY-954943 |
react-autolink-text |
2.0.1 | XRAY-954959 |
opengov-k6-core |
1.0.2 | XRAY-954926 |
jest-preset-ppf |
0.0.2 | XRAY-954956 |
cit-playwright-tests |
1.0.1 | XRAY-954934 |
eslint-config-service-users |
0.0.3 | XRAY-954950 |
babel-plugin-react-pure-component |
0.1.6 | XRAY-954955 |
@opengov/form-renderer |
0.2.20 | XRAY-955058 |
@opengov/qa-record-types-api |
1.0.3 | XRAY-954970 |
@opengov/form-builder |
0.12.3 | XRAY-954953 |
@opengov/ppf-eslint-config |
0.1.11 | XRAY-954967 |
@opengov/form-utils |
0.7.2 | XRAY-954958 |
react-leaflet-heatmap-layer |
2.0.1 | XRAY-954931 |
@virtahealth/substrate-root |
1.0.1 | XRAY-955055 |
@airtm/uuid-base32 |
1.0.2 | XRAY-954937 |
@emilgroup/setting-sdk |
0.2.3, 0.2.2, 0.2.1 | XRAY-955067 |
@emilgroup/partner-portal-sdk |
1.1.3, 1.1.2, 1.1.1 | XRAY-955063 |
@emilgroup/gdv-sdk-node |
2.6.3, 2.6.2, 2.6.1 | XRAY-955060 |
@emilgroup/docxtemplater-util |
1.1.4, 1.1.3, 1.1.2 | XRAY-955062 |
@emilgroup/accounting-sdk |
1.27.3, 1.27.2, 1.27.1 | XRAY-955054 |
@emilgroup/task-sdk |
1.0.4, 1.0.3, 1.0.2 | XRAY-955056 |
@emilgroup/setting-sdk-node |
0.2.3, 0.2.2, 0.2.1 | XRAY-955064 |
@emilgroup/task-sdk-node |
1.0.4, 1.0.3, 1.0.2 | XRAY-954923 |
@emilgroup/partner-sdk |
1.19.3, 1.19.2, 1.19.1 | XRAY-955065 |
@emilgroup/numbergenerator-sdk-node |
1.3.3, 1.3.2, 1.3.1 | XRAY-955066 |
@emilgroup/customer-sdk |
1.54.5, 1.54.4, 1.54.3, 1.54.2, 1.54.1 | XRAY-954924 |
@emilgroup/commission-sdk |
1.0.3, 1.0.2, 1.0.1 | XRAY-955068 |
@emilgroup/process-manager-sdk |
1.4.2, 1.4.1 | XRAY-955069 |
@emilgroup/changelog-sdk-node |
1.0.3, 1.0.2 | XRAY-955061 |
@emilgroup/document-sdk-node |
1.43.6, 1.43.5, 1.43.4, 1.43.3, 1.43.2, 1.43.1 | XRAY-954947 |
@emilgroup/commission-sdk-node |
1.0.3, 1.0.2, 1.0.1 | XRAY-955053 |
@emilgroup/document-uploader |
0.0.12, 0.0.11, 0.0.10 | XRAY-955057 |
@emilgroup/discount-sdk |
1.5.3, 1.5.2, 1.5.1 | XRAY-954929 |
@emilgroup/discount-sdk-node |
1.5.2, 1.5.1 | XRAY-955059 |
@teale.io/eslint-config |
1.8.16–1.8.9 (8 εκδόσεις) | XRAY-954945 |
@emilgroup/insurance-sdk |
1.97.6–1.97.1 (6 εκδόσεις) | XRAY-954928 |
@emilgroup/account-sdk |
1.41.2, 1.41.1 | XRAY-954949 |
@emilgroup/account-sdk-node |
1.40.2, 1.40.1 | XRAY-954927 |
@emilgroup/accounting-sdk-node |
1.26.2, 1.26.1 | XRAY-954965 |
@emilgroup/api-documentation |
1.19.2, 1.19.1 | XRAY-954960 |
@emilgroup/auth-sdk |
1.25.2, 1.25.1 | XRAY-954966 |
@emilgroup/auth-sdk-node |
1.21.2, 1.21.1 | XRAY-954964 |
@emilgroup/billing-sdk |
1.56.2, 1.56.1 | XRAY-954951 |
@emilgroup/billing-sdk-node |
1.57.2, 1.57.1 | XRAY-954948 |
@emilgroup/claim-sdk |
1.41.2, 1.41.1 | XRAY-954961 |
@emilgroup/claim-sdk-node |
1.39.2, 1.39.1 | XRAY-954925 |
@emilgroup/customer-sdk-node |
1.55.2, 1.55.1 | XRAY-954944 |
@emilgroup/document-sdk |
1.45.2, 1.45.1 | XRAY-954941 |
@emilgroup/gdv-sdk |
2.6.2, 2.6.1 | XRAY-954930 |
@emilgroup/insurance-sdk-node |
1.95.2, 1.95.1 | XRAY-954933 |
@emilgroup/notification-sdk-node |
1.4.2, 1.4.1 | XRAY-954957 |
@emilgroup/partner-portal-sdk-node |
1.1.2, 1.1.1 | XRAY-954952 |
@emilgroup/partner-sdk-node |
1.19.2, 1.19.1 | XRAY-954935 |
@emilgroup/payment-sdk |
1.15.2, 1.15.1 | XRAY-954963 |
@emilgroup/payment-sdk-node |
1.23.2, 1.23.1 | XRAY-954969 |
@emilgroup/process-manager-sdk-node |
1.13.2, 1.13.1 | XRAY-954939 |
@emilgroup/public-api-sdk |
1.33.2, 1.33.1 | XRAY-954940 |
@emilgroup/public-api-sdk-node |
1.35.2, 1.35.1 | XRAY-954946 |
@emilgroup/tenant-sdk |
1.34.2, 1.34.1 | XRAY-954932 |
@emilgroup/tenant-sdk-node |
1.33.2, 1.33.1 | XRAY-954954 |
@emilgroup/translation-sdk-node |
1.1.2, 1.1.1 | XRAY-954968 |
Οποιοσδήποτε εκτελεί οποιαδήποτε από τις αναγνωρισμένες εκδόσεις πακέτων που έχουν παραβιαστεί θα πρέπει να αντιμετωπίζει το περιβάλλον του ως ήδη μολυσμένο. Οι προγραμματιστές πρέπει να εναλλάσσουν αμέσως όλα τα διακριτικά δημοσίευσης npm που είναι αποθηκευμένα .npmrc αρχεία, μεταβλητές περιβάλλοντος και μυστικά αγωγών CI/CD.
Στο Linux, το pgmon η υπηρεσία πρέπει να διακοπεί και να απενεργοποιηθεί η χρήση systemctlμε τα σχετικά αρχεία και τους καταλόγους υπηρεσιών του να έχουν αφαιρεθεί εντελώς.
Τα προσωρινά αρχεία /tmp/pglog και /tmp/.pg_state πρέπει να διαγραφεί. Προσβεβλημένος node_modules οι κατάλογοι θα πρέπει να εκκαθαριστούν και να ξαναχτιστούν από την αρχή χρησιμοποιώντας επαληθευμένες, ασφαλείς εκδόσεις πακέτων.
Οι προγραμματιστές των οποίων τα διακριτικά κλάπηκαν πρέπει να καταργήσουν τη δημοσίευση των παραβιασμένων εκδόσεων πακέτων από το μητρώο npm, καθώς η απλή δημοσίευση μιας νεότερης έκδοσης δεν προστατεύει τους μεταγενέστερους χρήστες που ενδέχεται να εγκαταστήσουν τη μολυσμένη έκδοση.
Τρέξιμο npm config set ignore-scripts true αποτρέπει παγκοσμίως postinstall Τα άγκιστρα από την αθόρυβη πυροδότηση σε μελλοντικές εγκαταστάσεις, χρησιμεύοντας ως πρακτικό αμυντικό μέτρο έναντι αυτής της κατηγορίας επίθεσης στην αλυσίδα εφοδιασμού.
