QuietPolyfill, ένα σταγονόμετρο NPM που ανέστησε

QuietPolyfill: Ένα σταγονόμετρο NPM που ανέστησε

TL? DR

Είκοσι πακέτα npm που δημοσιεύθηκαν σε δύο ημέρες στα τέλη Ιουλίου και στις αρχές Αυγούστου 2026 παρουσιάζονται ως εσωτερικές βιβλιοθήκες στοιχείων UI και κοινόχρηστα βοηθητικά προγράμματα backend. Κανένα από αυτά δεν εφαρμόζει τη λειτουργικότητα που διαφημίζουν. Κάθε ένα διαθέτει μια κλάση stub, ένα README που περιγράφει το πακέτο ως εσωτερικό και ένα αρχείο με όνομα _polyfill.js.

Το ενδιαφέρον κομμάτι είναι από πού καλείται αυτό το αρχείο. Δεν είναι άγκιστρο εγκατάστασης — τα μανιφέστα δεν δηλώνουν καθόλου προεγκατάσταση, εγκατάσταση ή μεταεγκατάσταση. Αντ' αυτού, η τελευταία γραμμή του index.js έχει ως εξής: try { require("./_polyfill"); } catch (_) {}Το ωφέλιμο φορτίο εκτελείται την πρώτη φορά που ο κώδικας εφαρμογής εισάγει το πακέτο. Εγκατάσταση με --ignore-scripts, standard συμβουλές για τη μείωση της έκθεσης στην αλυσίδα εφοδιασμού κατά την εγκατάσταση, δεν το εμποδίζει.

Τι _polyfill.js Το μόνο που κάνει είναι να ανακτήσει ένα εκτελέσιμο αρχείο για συγκεκριμένη πλατφόρμα από έναν από τους τρεις κεντρικούς υπολογιστές Cloudflare Workers, να το γράψει σε έναν προσωρινό κατάλογο με ένα τυχαίο όνομα, να το επισημάνει ως εκτελέσιμο και να το εκκινήσει αποκομμένο από τη γονική διεργασία. Αυτό το εκτελέσιμο αρχείο είναι το ίδιο ένα πρόγραμμα φόρτωσης: απαριθμεί τα προϊόντα ασφάλειας τελικού σημείου με το όνομα της διεργασίας, ελέγχει το τρέχον όνομα χρήστη σε σχέση με γνωστούς λογαριασμούς περιβάλλοντος ανάλυσης, επιδιορθώνει τις διεπαφές τηλεμετρίας AMSI και ETW στη μνήμη, εγκαθιστά την persistence με το όνομα ενός στοιχείου ήχου των Windows και ανακτά ένα τρίτο δυαδικό αρχείο μεγέθους αρκετών megabyte. Το τρίτο στάδιο φτάνει κρυπτογραφημένο και είναι... αποκρυπτογραφείται και εκτελείται στη μνήμη αντί να γράφεται στον δίσκο.

Την 1η Αυγούστου, περίπου τέσσερις ώρες αφότου τα πακέτα επιβεβαιώθηκαν ως κακόβουλα μετά από χειροκίνητο έλεγχο, δεκαεννέα από τα είκοσι ονόματα αφαιρέθηκαν από το npm από τον δικό τους εκδότη σε μια ακολουθία είκοσι πέντε δευτερολέπτων. Στις 2 Αυγούστου, ένα από αυτά τα ονόματα καταχωρήθηκε ξανά — από διαφορετικό λογαριασμό, που έφερε τον ίδιο κωδικό. Η υποδομή παράδοσης εξυπηρετούσε και τα τρία στάδια όταν γράφτηκε αυτό.

Πακέτα20 ονόματα npm, ~74 δημοσιευμένες εκδόσεις
Ονομασία θεμάτωνbeaver-ui-* (13) accounts-* (3), συν afisha-storybook-default, bcore-bravo-eslint-config, arbocrate-sla-prober-arbocrate-sla-prober-core, a.poltoradnev-package-c
ΣκανδάληΕισαγωγή ενότητας (require), όχι ένα σενάριο κύκλου ζωής npm
Στάδιο 1_polyfill.js — ανάκτηση και εκτόξευση
Στάδιο 2Στατικά συνδεδεμένος φορτωτής, UPX-packed σε Linux· απαρίθμηση ασφάλειας τελικού σημείου, ενημέρωση κώδικα AMSI/ETW, διατήρηση
Στάδιο 3beacon_linux.bin / beacon_mac.bin / update_win.exe, 4–13 MB; παραδίδεται κρυπτογραφημένο, εκτελείται στη μνήμη
ΠλατφόρμεςLinux x64 και arm64, macOS universal, Windows x64
ΕκδότεςΔύο λογαριασμοί, μία βάση κώδικα
Κατάσταση19 από τα 20 ονόματα δεν έχουν δημοσιευτεί από τον χειριστή· 1 αναδημοσιεύτηκε και είναι διαθέσιμο· υποδομή παράδοσης σε πραγματικό χρόνο

Ανατομία επίθεσης

Στάδιο 1 — το πακέτο

Κάθε μέλος αποστέλλει το ίδιο σχήμα τριών αρχείων. index.js εξάγει μια κλάση με ένα μέσα σε αυτό() που ορίζει μια λογική τιμή, ένα εκδοχή(), και ένα διαμόρφωση() που συγχωνεύει ένα αντικείμενο επιλογών. Τίποτα άλλο. README.md δίνει μια γραμμή εγκατάστασης, ένα απαιτούν γραμμή και η πρόταση «Εσωτερικό πακέτο. Δείτε το CONTRIBUTING.md για οδηγίες» — ΣΥΝΤΕΛΕΣΤΙΚΑ.μδ δεν βρίσκεται στο tarball.

_polyfill.js έχει μέγεθος λίγο κάτω από 5 KB και διαβάζεται ως συνηθισμένος κώδικας υποδομής. Ανοίγει με τρεις ελέγχους περιβάλλοντος:

if (process.env.DISABLE_TELEMETRY ||
    process.env.ANALYTICS_OPT_OUT ||
    process.env.DO_NOT_TRACK)
  return;

Αυτές οι μεταβλητές είναι συμβατικοί έλεγχοι απορρήτου. Εδώ ελέγχουν εάν ένα δυαδικό αρχείο λαμβάνεται και εκτελείται. Ένα μηχάνημα που ορίζει ΜΗΝ_ΠΑΡΑΚΟΛΟΥΘΕΙΤΕ παραλείπεται εντελώς.

Στη συνέχεια έρχεται μια σφραγίδα που εκτελείται μία φορά: ένα αρχείο στο /tmp/.analytics_stateΤο HIFU, ή Υψηλής Έντασης Εστιασμένος Υπέρηχος, στοχεύει επίσης στο πρόσωπο και τον λαιμό. Προσφέρει θεραπεία σε γρήγορες εκπομπές, γεγονός που κάνει τις συνεδρίες θεραπείας συντομότερες. αναλυτική_κατάσταση υπό % TEMP% σε Windows, των οποίων ο χρόνος τροποποίησης συγκρίνεται με ένα παράθυρο 20,357 δευτερολέπτων. Μέσα σε αυτό το παράθυρο η ενότητα επιστρέφει αμέσως, επομένως οι επαναλαμβανόμενες εισαγωγές κατά τη διάρκεια μιας δημιουργίας παράγουν μία προσπάθεια ανάκτησης αντί για δεκάδες.

Οι κεντρικοί υπολογιστές προορισμού δεν υπάρχουν ως κυριολεκτικά. Συγκεντρώνονται κατά τον χρόνο εκτέλεσης από θραύσματα:

["oob-worker.cf102-","baf.workers.d","ev"].join("") 

Τρεις κεντρικοί υπολογιστές κατασκευάζονται με αυτόν τον τρόπο και αναμειγνύονται πριν από τη χρήση, επομένως η σειρά ποικίλλει ανά εκτέλεση. Η ανάκτηση είναι ένα HTTPS GET που συνδέεται με IPv4 με ένα User-Agent of ανάκτηση-κόμβου/2.6 — μια εύλογη τιμή για να εκπέμψει μια διεργασία Node. Μια απόκριση κάτω των 1,000 byte απορρίπτεται και δοκιμάζεται ο επόμενος κεντρικός υπολογιστής.

Εάν και τα τρία αποτύχουν, η ενότητα επιστρέφει στο DNS. Εκδίδει ένα ερώτημα TXT για ντο. για να λάβετε έναν αριθμό κομματιών, στη συνέχεια ζητά 0. μέσω ν. σε ομάδες των δέκα, συνενώνει τις απαντήσεις και αποκωδικοποιεί το αποτέλεσμα με βάση64. Αυτή η διαδρομή μεταφέρει το ίδιο εκτελέσιμο αρχείο μέσω εγγραφών DNS TXT, το οποίο επιβιώνει σε περιβάλλοντα όπου το εξερχόμενο HTTP φιλτράρεται αλλά η ανάλυση DNS όχι.

Τα ανακτημένα byte γράφονται σε /var/tmp/.cache_<8-hex> σε Unix, ή %TEMP%\dotnet_diag_<8-hex>.exe στα Windows — ένα όνομα αρχείου που διαβάζεται ως τεχνούργημα διαγνωστικών .NET. Στο Unix, το αρχείο έχει τη λειτουργία 0755. Η εκκίνηση είναι ώα ψαριών μαζί σου, αποσπασματικός: αληθινός, stdio: «αγνόηση»και unref(), έτσι ώστε το παιδί να επιβιώνει περισσότερο από τη διεργασία Node που το ξεκίνησε. στα Windows η κλήση προσθέτει windowsHide: true.

Δύο λεπτομέρειες συμπληρώνουν την εικόνα. Ένας βοηθός που ορίζεται ως const _l = (…a) => process.stderr.write(“”) καλείται σε κάθε βήμα της ανάκτησης — γράφει μια κενή συμβολοσειρά και απορρίπτει τα ορίσματά της, καταλαμβάνοντας τη θέση όπου θα βρισκόταν η καταγραφή. Και κάθε πακέτο στέλνει ένα αρχείο 81 KB στη διεύθυνση lib/telemetry.js του οποίου το σχόλιο κεφαλίδας περιγράφει ένα "Analytics SDK" με "Μεταφορά HTTPS με εναλλαγή τελικού σημείου και επανάληψη" και "Ανακάλυψη υπηρεσίας που βασίζεται σε DNS για ανακατεύθυνση". Στην τρέχουσα έκδοση δεν απαιτείται τίποτα.

Στάδιο 2 — ο φορτωτής

Το δυαδικό αρχείο Linux x64 είναι ένα στατικά συνδεδεμένο ELF συμπιεσμένο με UPX 3.96. Η έκδοση macOS είναι ένα καθολικό δυαδικό αρχείο που καλύπτει τα x86_64 και arm64. Η έκδοση των Windows είναι ένα απογυμνωμένο εκτελέσιμο αρχείο κονσόλας PE32+. Και τα τέσσερα ανακτήθηκαν και εξετάστηκαν στατικά. Κανένα δεν εκτελέστηκε.

Οι εισαγωγές και ο πίνακας συμβολοσειρών της έκδοσης των Windows περιγράφουν με σαφήνεια τη συμπεριφορά της. Επιλύει το πρόβλημα IsDebuggerPresent, CheckRemoteDebuggerPresentκαι Διαδικασία Πληροφοριών NtQuery, και διαβάζει SYSTEM\CurrentControlSet\Services\Disk\Enum — μια διαδρομή μητρώου της οποίας οι τιμές προσδιορίζουν τους ελεγκτές εικονικού δίσκου. Καλεί GetDiskFreeSpaceExW και GlobalMemoryStatusEx, σύμφωνα με τον έλεγχο του κατά πόσον οι πόροι του κεντρικού υπολογιστή αντιστοιχούν σε μια βραχύβια παρουσία ανάλυσης.

Περιλαμβάνει μια λίστα με ονόματα χρήστη: Τρέχων Χρήστης, Διαχειριστής πληροφορικής, Χονγκ Λι, ΔΟΚΙΜΑΣΤΙΚΟ ΚΟΥΤΙ, hapubws, μιλόζ, Τιμ, διαχειριστής, malware, δείγμα, ιός, θετική ατμόσφαιραΑρκετά από αυτά είναι τεχνουργήματα δημόσια τεκμηριωμένων περιβαλλόντων ανάλυσης.

Περιλαμβάνει επίσης μια λίστα με προϊόντα ασφάλειας τελικών σημείων και τα ονόματα των διεργασιών τους, τα οποία απαριθμούνται μέσω CreateToolhelp32Snapshot και Process32FirstW/Process32NextW:

  • CrowdStrike Falcon (csfalconservice, CSFalconContainer)
  • Carbon Black (cb.exe)
  • Cylance (cylancesvc.exe)
  • Bitdefender (bdagent.exe)
  • Kaspersky (avp.exe, kavfs.exe)
  • Trend Micro και Deep Security (coreServiceShell, ds_agent.exe)
  • FireEye/Trellix (xagt.exe)
  • Τιτάνιο (taniumclient.exe)
  • HitmanPro (hmpalert.exe)
  • Ελαστικό (elastic-agent.exe, elastic-endpoint, filebeat.exe, winlogbeat.exe)
  • Wazuh και OSSEC (wazuh-agent.exe, ossec-agent.exe)
  • Check Point
  • windows Defender

Υπάρχουν δύο επιπλέον σύμβολα: AmsiScanBuffer, το σημείο εισόδου που εκθέτει τα Windows για σάρωση περιεχομένου εντός της μνήμης και EtwEventWrite, η συνάρτηση μέσω της οποίας το Event Tracing για Windows καταγράφει συμβάντα. Και τα δύο είναι συνήθεις στόχοι για τροποποίηση κατά τη διάρκεια της διεργασίας που καταστέλλει την τηλεμετρία που διαφορετικά θα παρήγαγαν αυτές οι διεπαφές.

Η ένδειξη Persistence εμφανίζεται δύο φορές στα Windows. Το δυαδικό αρχείο αντιγράφεται στο %APPDATA%\Microsoft\Windows\Themes\SystemSoundsService.exeκαι δύο μηχανισμοί που το αναφέρουν: μια τιμή κάτω από ΛΟΓΙΣΜΙΚΟ\Microsoft\Windows\ΤρέχουσαΈκδοση\Εκτέλεσηκαι μια προγραμματισμένη εργασία καταχωρημένη ως

schtasks /Create /F /SC ONLOGON
  /TN "\Microsoft\Windows\Multimedia\SystemSoundsService"
  /TR "\"%s\""
  /RL HIGHEST

Η διαδρομή εργασίας, το όνομα εργασίας και το όνομα εκτελέσιμου αρχείου αντικατοπτρίζουν όλα ένα γνήσιο στοιχείο ήχου των Windows. /RL ΥΨΗΛΟΤΕΡΟ ζητά το υψηλότερο διαθέσιμο επίπεδο δικαιωμάτων.

Η έκδοση macOS ακολουθεί το ίδιο μοτίβο με ονόματα κατάλληλα για την πλατφόρμα: γράφει μια λίστα ιδιοτήτων σε ~/Βιβλιοθήκη/LaunchAgents/com.apple.windowserver.helper.plist και τοποθετεί το εκτελέσιμο αρχείο του στη διεύθυνση ~/.local/share/runtime/com.apple.runtime. Ελέγχει για /Εφαρμογές/VMware Fusion.app και /Βιβλιοθήκη/Υποστήριξη εφαρμογών/Εργαλεία VMware.

Η δυνατότητα δικτύου εκτείνεται σε τρεις μεταφορές: WININET.dll για HTTPS με ένα https://%s:%d%s μορφοποίηση συμβολοσειράς, WS2_32.dll πρίζες, και DNSAPI.dll μαζί σου, DnsQuery_A μαζί με ένα γ.%s.%s format string — το ίδιο σχήμα ερωτήματος chunk-count που χρησιμοποιεί το πρώτο στάδιο.

Η παραπάνω περιγραφή είναι αυτό που δείχνουν οι εισαγωγές, οι συμβολοσειρές και οι διαδρομές μητρώου του δυαδικού αρχείου κατά την επιθεώρηση. Η δημόσια ανάλυση πολλαπλών μηχανών του ίδιου δείγματος των Windows προσθέτει λεπτομέρειες που μια στατική ανάγνωση ενός πίνακα εισαγωγής δεν μπορεί να διαπιστώσει από μόνη της και αποδίδεται εδώ αντί να επαναδιατυπώνεται ως παρατήρηση από πρώτο χέρι. Αυτή η ανάλυση αναφέρει ότι οι αναφορές AMSI και ETW δεν έχουν απλώς επιλυθεί αλλά έχουν διορθωθεί — AmsiScanBuffer in amsi.dll και EtwEventWrite in ntdll.dll — το οποίο καταστέλλει τη σάρωση περιεχομένου στη μνήμη και την παρακολούθηση συμβάντων για τη διεργασία. Αναφέρει τους ελέγχους κατά της ανάλυσης ως βασισμένους σε χρονισμό, επιπλέον των CheckRemoteDebuggerPresent, και προσδιορίζει το GetThreadContext κλήση ως έλεγχος σημείου διακοπής υλικού που διαβάζει τους καταχωρητές εντοπισμού σφαλμάτων. Αναφέρει επίσης ένα mutex μίας μόνο παρουσίας, Global\{7A3B9E1F-C2D4-4F8A-B5E6-D7A1F0C3E2B9}, και ονόματα Υπηρεσία Ήχων Συστήματος ως τιμή Run-key. Αυτή η τιμή mutex δεν ήταν μεταξύ των συμβολοσειρών που ανακτήθηκαν εδώ — το φίλτρο εξαγωγής που χρησιμοποιήθηκε απέκλεισε τα tokens με κεφαλαία γράμματα δεκαεξαδικού με αγκύλες — και καταγράφεται στον πίνακα δεικτών με βάση την ισχύ αυτής της δημόσιας ανάλυσης και όχι την άμεση παρατήρηση.

Στάδιο 3

Ο φορτωτής αναφέρεται σε ένα περαιτέρω σύνολο διαδρομών στους ίδιους κεντρικούς υπολογιστές. Όλες ήταν προσβάσιμες κατά την ανάλυση: beacon_linux.bin στα 5.3 MB, beacon_mac.bin στα 13.3 MB, update_win.exe στα 10.3 MB, και arm.bin στα 4.3 MB. Αυτά δεν ανακτήθηκαν και η συμπεριφορά τους είναι άγνωστη.

Για τη διαδρομή των Windows, η δημόσια ανάλυση του φορτωτή περιγράφει τον τρόπο χειρισμού αυτού του τρίτου σταδίου: ανακτάται μέσω WinINet, φτάνει κρυπτογραφημένο, αποκρυπτογραφείται στη μνήμη και εκτελείται ανακλαστικά — εκχωρείται μνήμη, επιλύονται εισαγωγές, διεκπεραιώνονται μετεγκαταστάσεις και ο έλεγχος μεταβιβάζεται σε ένα νέο νήμα μέσω ΔημιουργίαΝήματοςΓια αυτόν τον λόγο, το τρίτο στάδιο δεν εγγράφεται ποτέ στο σύστημα αρχείων, επομένως η ανίχνευση που βασίζεται σε αρχεία και η εγκληματολογία δίσκων μετά από συμβάν δεν έχουν τίποτα να ανακτήσουν από αυτό. Σημαίνει επίσης ότι η ανάκτηση των byte από τον κεντρικό υπολογιστή παράδοσης θα απέδιδε κρυπτογραφημένο κείμενο, όχι ένα εκτελέσιμο αρχείο που μπορεί να αναλυθεί.

 

Χρονολόγιο

Όλες οι χρονικές σημάνσεις είναι UTC και προέρχονται από μεταδεδομένα μητρώου npm, τα οποία καταγράφουν τη δημιουργία και τη μη δημοσίευση πακέτων ανεξάρτητα από οποιονδήποτε παρατηρητή.

Κατά τη Τι
2026-07-31 09:25:05 → 09:29:56 Δέκα ονόματα δημιουργήθηκαν, το καθένα ξεκινώντας από την έκδοση 0.0.1, με διαφορά περίπου δεκατριών δευτερολέπτων.
2026-08-01 09:38 → 11:29 Τα υπάρχοντα ονόματα ανεβαίνουν μέσα από τους διογκωμένους αριθμούς έκδοσης, 6.1.9 μέσω 6.1.12, 9.9.9 μέσω 9.9.12, 8.9.3 μέσω 8.9.6, 5.4.6 μέσω 5.4.9.
2026-08-01 13:04:14 → 13:04:18 Εννέα ακόμη beaver-ui-* ονόματα που δημιουργήθηκαν σε μια ριπή τεσσάρων δευτερολέπτων, το καθένα δημοσιεύτηκε απευθείας σε έκδοση 12.x χωρίς προηγούμενο ιστορικό.
2026-08-01 ~13:00–14:30 Εκδόσεις που ταξινομήθηκαν ως κακόβουλες κατά τον χειροκίνητο έλεγχο.
2026-08-01 17:39:49 → 17:40:14 Δεκαεννέα από τα είκοσι ονόματα αδημοσίευσαν σε είκοσι πέντε δευτερόλεπτα, διαδοχικά, με διαφορά περίπου 1.2 δευτερολέπτων μεταξύ τους.
2026-08-02 18:58:41 a.poltoradnev-package-c δημιουργήθηκε ξανά με διαφορετικό λογαριασμό διαχειριστή, έκδοση 0.0.2.
2026-08-02 19:20:28 Έκδοση 33.9.5 δημοσιεύτηκε με το ίδιο όνομα.
2026-08-02 20:14 Και οι τρεις κεντρικοί υπολογιστές παράδοσης εξυπηρετούν τα στάδια δύο και τρία. Το εφεδρικό DNS απαντά με αριθμήσεις μπλοκ.

Δύο από αυτές τις καταχωρήσεις αξίζει να σχολιάσουμε.

Η έκρηξη των 13:04 έβαλε εννέα πακέτα στο μητρώο σε τέσσερα δευτερόλεπτα, το καθένα με μία μόνο έκδοση στα δώδεκα και κανένα 0.0.1 από κάτω. Οι αριθμοί έκδοσης σε αυτήν την κλίμακα, σε ονόματα που είναι παλαιότερα μιας ημέρας, δεν περιγράφουν ένα ιστορικό κυκλοφορίας.

Η ακολουθία μη δημοσίευσης είναι εξίσου μηχανική: δεκαεννέα ονόματα, είκοσι πέντε δευτερόλεπτα, ίσο διάστημα. Το npm τα καταγράφει ως συνηθισμένα συμβάντα μη δημοσίευσης και όχι ως το σύμβολο κράτησης θέσης που αφήνει πίσω μια αφαίρεση που ξεκινά από το μητρώο, η οποία τοποθετεί την ενέργεια στον λογαριασμό δημοσίευσης και όχι στο μητρώο.

 

Δείκτες συμβιβασμού

Οι κεντρικοί υπολογιστές και οι διαδρομές έχουν απενεργοποιηθεί. Μην τα επιλύετε ή τα ανακτάτε από ένα σύστημα παραγωγής.

Χαρακτηριστικά αξία
Ο οικοδεσπότης παράδοσης oob-worker[.]cf99-9b3[.]workers[.]dev
Ο οικοδεσπότης παράδοσης oob-worker[.]cf102-baf[.]workers[.]dev
Ο οικοδεσπότης παράδοσης oob-worker[.]cf103-070[.]workers[.]dev
Μεταφορά DNS tin[.]dl[.]well1[.]site (Linux x64), tina[.] (βραχίονας 64), ldr[.] (macOS), win[.] (Windows) — αριθμός τμημάτων στο c.<domain>, δεδομένα στο <n>.<domain>
Διαδρομές Σταδίου 2 /pkg/package, /pkg/package-arm64, /pkg/loader_mac, /pkg/package.exe
Διαδρομές Σταδίου 3 /pkg/beacon_linux.bin, /pkg/beacon_mac.bin, /pkg/update_win.exe, /pkg/arm.bin
Διαδρομή απόθεσης (Unix) /var/tmp/.cache_<8-hex>
Διαδρομή απόθεσης (Windows) %TEMP%\dotnet_diag_<8-hex>.exe
Επιμονή (Windows) %APPDATA%\Microsoft\Windows\Themes\SystemSoundsService.exe; εργασία \Microsoft\Windows\Multimedia\SystemSoundsService; Τιμή κλειδιού εκτέλεσης SOFTWARE\Microsoft\Windows\CurrentVersion\Run\SystemSoundsService
Mutex (Windows) Global\{7A3B9E1F-C2D4-4F8A-B5E6-D7A1F0C3E2B9}
Επιμονή (macOS) ~/Library/LaunchAgents/com.apple.windowserver.helper.plist; δυαδικό στο ~/.local/share/runtime/com.apple.runtime
Σφραγίδα μίας εκτέλεσης /tmp/.analytics_state, %TEMP%\analytics_state (παράθυρο 20,357 δευτερολέπτων)
Αίτημα υπογραφής HTTPS GET, με IPv4 pin, User-Agent: node-fetch/2.6
Αρχείο Σταδίου-1 _polyfill.js, SHA-256 392dc9ec85042ce1796bfa9b8c7bf6e05c7710579aab8b7b1eb73788683883af
Μη αναφερόμενο αρχείο lib/telemetry.js, SHA-256 2266c9b8e199daebe31a9afcb61d9b0d76706b63c92312fc8223d22de42e63c7
Στάδιο 2 (Linux x64) SHA-256 7e486657f30594afda379b97030252a09a19fe8055e25c9e371544f59bd8e9e3
Στάδιο 2 (Linux arm64) SHA-256 aafc37589c0d21fb729761a1579ca3b278b95bce152aacfa29243ffd27f5eeb7
Στάδιο 2 (macOS) SHA-256 c214746c74cae8ece8bdaf69aa05da4db6ce013f9e77452d1eed1a002fd9ba00
Στάδιο 2 (Windows) SHA-256 d632c2c0c7801c3da57cf849fe4b4ca8351d9a7fe73c31050bf5dbcc96a16791

Ονόματα πακέτων

συρτάρι-UI-Beaver κουμπί-ενεργειών-UI-Beaver μεγάλη κάρτα-ui-κάρτας-beaver επιλογή-εύρους-ημερομηνίας-beaver-ui μορφή-UI-κάστορα beaver-ui-form-modal αντικείμενο-μορφής-UI-beaver πλέγμα χρήστη-beaver κεφαλίδα-ui-του-beaver κάστορας-ui-hooks εικονίδιο-κλειδώματος-ui-beaver αντικείμενα-ui-του-beaver-με-περισσότερα διάταξη-UI-Beaver τελική-μορφή-λογαριασμών κατάσταση-φόρτωσης-λογαριασμών χρονοδιάγραμμα λογαριασμών προεπιλογή-του-βιβλίου-ιστοριών-afisha διαμόρφωση bcore-bravo-eslint arbocrate-sla-prober-arbocrate-sla-prober-core πακέτο-c-a.poltoradnev

Απόδοση και παρατηρούμενη συμπεριφορά

Εμπλέκονται δύο λογαριασμοί npm. Τα δεκαεννέα αδημοσίευτα ονόματα δημοσιεύθηκαν από έναν λογαριασμό. πακέτο-c-a.poltoradnev επανεγγράφηκε στις 2 Αυγούστου με διαφορετικό όνομα λογαριασμού και διαφορετικό τομέα email. Ο κώδικας είναι η ίδια γενεαλογία και στα δύο και η δεύτερη εγγραφή φέρει τους ίδιους κεντρικούς υπολογιστές παράδοσης, τους ίδιους εφεδρικούς τομείς DNS, την ίδια δομή διαδρομής απόθεσης και την ίδια σφραγίδα εκτέλεσης μία φορά.

Το αναδημοσιευμένο ζεύγος δείχνει επίσης πώς συναρμολογήθηκε. Εκδόσεις 0.0.2 και 33.9.5 είναι πανομοιότυπα κατά byte εκτός από τη συμβολοσειρά έκδοσης στο πακέτο.json, και το index.js αποστέλλεται ως 0.0.2 δηλώνει const VERSION = "33.9.5"Και τα δύο αντικείμενα κόπηκαν από το ίδιο δέντρο προέλευσης και αριθμήθηκαν στη συνέχεια. Δεν υπάρχει 0.0.2 ιστορικό ανάπτυξης για το 0.0.2 απελευθέρωση για να εκπροσωπήσω.

Η αρίθμηση εκδόσεων σε ολόκληρο το σύνολο ακολουθεί την ίδια λογική. Τα ονόματα πακέτων σε αυτήν την καμπάνια διαβάζονται ως πράγματα που θα υπήρχαν μέσα σε έναν οργανισμό και όχι σε ένα δημόσιο μητρώο: ένα σύνολο στοιχείων UI, μια διαμόρφωση ESLint, ένας έλεγχος SLA, ένα πακέτο που ονομάζεται από ένα άτομο. Όταν μια έκδοση επιλύει μια εξάρτηση με βάση το όνομα και συμβουλεύεται ένα δημόσιο μητρώο παράλληλα με ένα ιδιωτικό, ο υψηλότερος αριθμός έκδοσης είναι αυτός που κερδίζει. Ένα όνομα που δημιουργήθηκε στο 0.0.1 τη Δευτέρα και μεταφέροντας 12.9.6 την Τρίτη είναι τοποθετημένο για αυτή τη σύγκριση.

Τα δύο κύματα δημοσίευσης διαφέρουν επίσης με τρόπο που υποδηλώνει επανάληψη. Ο προηγούμενος κώδικας ονόμασε το αρχείο ωφέλιμου φορτίου του setup.js και απαριθμούσε πέντε κεντρικούς υπολογιστές παράδοσης. Το τρέχον αρχείο ονομάζεται _polyfill.js και παραθέτει τρία. Η προηγούμενη έκδοση αφαίρεσε το αρχείο που είχε αποσυρθεί πέντε δευτερόλεπτα μετά την εκκίνηση, αφήνοντας τη διεργασία να εκτελείται από ένα διαγραμμένο inode. Η τρέχουσα έκδοση δεν το κάνει. Το μη αναφερόμενο lib/telemetry.js παραμένει στο tarball και στα δύο, εξακολουθεί να είναι σε αποστολή, δεν είναι πλέον συνδεδεμένο.

Αξίζει να αναφερθεί μια παρατήρηση σχετικά με τους διακόπτες kill.cisely, επειδή αντιβαίνει σε μια συνηθισμένη ανάγνωση. DISABLE_TELEMETRY, ΑΝΑΛΥΤΙΚΑ_ΑΠΑΓΟΡΕΥΣΗ_ΕΞΑΙΡΕΣΗΣκαι ΜΗΝ_ΠΑΡΑΚΟΛΟΥΘΕΙΤΕ τιμώνται και ελέγχονται πριν συμβεί οτιδήποτε άλλο. Ένας ερευνητής του οποίου το περιβάλλον ανάλυσης ορίζει οποιοδήποτε από αυτά παρατηρεί ένα πακέτο που δεν κάνει τίποτα απολύτως.

Αντίκτυπος και τι μπορούν να κάνουν οι αμυντικοί

Η πρακτική συνέπεια της ενεργοποίησης χρόνου εισαγωγής είναι περιορισμένη και αξίζει να αναφερθεί από μόνη της. npm install –ignore-scripts αποτρέπει την εκτέλεση σεναρίων κύκλου ζωής και είναι μια καλή συμβουλή. Δεν έχει καμία επίδραση εδώ, επειδή αυτός ο κώδικας δεν χρησιμοποιεί ένα σενάριο κύκλου ζωής. Το ωφέλιμο φορτίο εκτελείται όταν ο κώδικας εφαρμογής, μια δοκιμαστική εκτέλεση, ένα bundler ή ένα linter εισάγουν πρώτα τη λειτουργική μονάδα. Σε έναν εκτελέστη CI που εγκαθίσταται και στη συνέχεια δημιουργεί αμέσως, τα δύο έχουν διαφορά δευτερολέπτων.

Για το κυνήγι, τα ανθεκτικά σήματα είναι δομικά και όχι κυριολεκτικά. Οι κεντρικοί υπολογιστές, το όνομα αρχείου και οι διαδρομές απόθεσης θα αλλάξουν. Αυτά τα σχήματα είναι πιο δύσκολο να μεταβληθούν:

  • Ένα σημείο εισόδου ενότητας του οποίου η τελική δήλωση είναι ένα δοκιμάστε { require("./x"); } catch (_) {} γύρω από ένα αρχείο που δεν αποτελεί μέρος του εξαγόμενου API. Ένα πακέτο με γνήσιο polyfill το εισάγει στην κορυφή και χρησιμοποιεί το αποτέλεσμά του. Η αποδοχή κάθε σφάλματος από μια εισαγωγή από το κάτω μέρος του αρχείου δεν αποτελεί χειρισμό σφαλμάτων.
  • Συμβολοσειρές κεντρικού υπολογιστή που συναρμολογούνται από .ενώνω("") από μια σειρά από θραύσματα. Ο νόμιμος κώδικας δεν έχει κανένα λόγο να διαιρεί ένα όνομα κεντρικού υπολογιστή σε στοιχεία πίνακα.
  • Ένα πακέτο του οποίου οι δηλωμένες εξαρτήσεις είναι κενές αλλά το οποίο φτάνει για https, dnsκαι παιδί_διαδικασία κατά την ώρα εισαγωγής. Η ανάκτηση συν την εκτέλεση σε ένα πακέτο που διαφημίζει ένα στοιχείο UI είναι το όλο εύρημα.
  • Οι αριθμοί έκδοσης δεν είναι συμβατοί με την ηλικία ενός πακέτου. Ένα όνομα που δημοσιεύτηκε για πρώτη φορά πριν από μέρες σε διψήφια έκδοση, χωρίς ενδιάμεσες κυκλοφορίες, περιγράφει κάτι άλλο εκτός από την ανάπτυξή του.
  • Γράφει σε / var / tmp or % TEMP% που ακολουθείται από ένα chmod έως 07:55 και ένα αποκολλημένο γόνο. Η ακολουθία είναι σύντομη, διατεταγμένη και σπάνια καλοήθης μαζί.

Σε υπολογιστές-κεντρικούς υπολογιστές των Windows υπάρχουν δύο φθηνοί έλεγχοι υψηλής αξιοπιστίας. Τα αντικείμενα persistence είναι σταθερές συμβολοσειρές και καμία από αυτές δεν ανήκει σε ένα καθαρό σύστημα: μια προγραμματισμένη εργασία στο \Microsoft\Windows\Multimedia\SystemSoundsService, μια τιμή κλειδιού εκτέλεσης με όνομα Υπηρεσία Ήχων Συστήματοςκαι ένα εκτελέσιμο αρχείο με αυτό το όνομα με την ένδειξη %APPDATA%\Microsoft\Windows\Θέματα\Η γνήσια υπηρεσία ήχου των Windows δεν βρίσκεται σε κανένα από αυτά τα μέρη. Δεύτερον, ο φορτωτής χρησιμοποιεί ένα σταθερό mutex μίας μόνο παρουσίας, Global\{7A3B9E1F-C2D4-4F8A-B5E6-D7A1F0C3E2B9}Η παρουσία του σε έναν κεντρικό υπολογιστή είναι μια ένδειξη και επειδή ο φορτωτής αντιμετωπίζει ένα υπάρχον mutex ως «ήδη εκτελούμενο», η προ-δημιουργία του είναι μια βιώσιμη βραχυπρόθεσμη ενίσχυση ενώ έχει προγραμματιστεί η αποκατάσταση.

Η ανίχνευση στο τρίτο στάδιο είναι ένα πιο δύσκολο πρόβλημα και αξίζει να διευκρινιστεί. Σύμφωνα με την περιγραφή που δίνεται από τη δημόσια ανάλυση, αποκρυπτογραφείται και αντιστοιχίζεται στη μνήμη αντί να γράφεται στον δίσκο, επομένως η σάρωση αρχείων και η εγκληματολογία δίσκων δεν θα το δουν. Αυτό που παραμένει παρατηρήσιμο είναι το αποτύπωμα του ίδιου του φορτωτή - οι καταχωρήσεις persistence, το mutex και τα εξερχόμενα αιτήματα προς τους κεντρικούς υπολογιστές παράδοσης ή τους τομείς DNS-TXT.

Για περιβάλλοντα που επιλύουν εξαρτήσεις τόσο από ένα ιδιωτικό όσο και από ένα δημόσιο μητρώο, ο μετριασμός δεν αλλάζει από οτιδήποτε εδώ: εσωτερικά ονόματα πεδίου εφαρμογής, ώστε ένα δημόσιο όνομα να μην μπορεί να τα ικανοποιήσει, και καρφίτσωμα ανάλυσης στο εσωτερικό μητρώο για αυτά τα πεδία εφαρμογής. Η συμπεριφορά διόγκωσης έκδοσης που περιγράφεται παραπάνω λειτουργεί μόνο όπου μια υψηλότερη δημόσια έκδοση μπορεί να κερδίσει ένα όνομα.

Τέλος, η μη δημοσίευση αξίζει να διαβαστεί προσεκτικά και όχι ως τέλος. Δεκαεννέα ονόματα έφυγαν από το μητρώο σε είκοσι πέντε δευτερόλεπτα και ένα επέστρεψε μια μέρα αργότερα με νέο λογαριασμό, με την υποδομή παράδοσης ανέπαφη καθ' όλη τη διάρκεια. Η αφαίρεση πακέτων δεν αποτελεί αφαίρεση της λειτουργίας. Οι κεντρικοί υπολογιστές συνέχισαν να εξυπηρετούν κάθε στάδιο κατά τη διάρκεια της σύνταξης αυτού του κειμένου. Οποιοδήποτε δέντρο εξαρτήσεων που επέλυσε ένα από αυτά τα ονόματα μεταξύ 31 Ιουλίου και 1 Αυγούστου θα πρέπει να αντιμετωπίζεται ως να είχε την ευκαιρία να εκτελέσει το πρώτο στάδιο, ανεξάρτητα από το αν το όνομα εξακολουθεί να υπάρχει ή όχι.

Αναφορές

εργαλεία-ανάλυσης-σύνθεσης-λογισμικού-sca
Ιεράρχηση, αποκατάσταση και ασφάλεια των κινδύνων λογισμικού σας
Αποκτήστε τον Δωρεάν Λογαριασμό σας.
Δεν απαιτείται πιστωτική κάρτα.

Ασφαλίστε την ανάπτυξη και την παράδοση λογισμικού σας

με το Xygeni Product Suite